예제 #1
0
bool GrabTutorial::checkVolBounds()
{
	glm::vec4 bbMin(glm::vec3(-0.5f), 1.f);
	glm::vec4 bbMax(glm::vec3(0.5f), 1.f);

	std::vector<glm::vec4> ptsToCheck;

	ptsToCheck.push_back(glm::vec4(bbMin.x, bbMin.y, bbMin.z, 1.f));
	ptsToCheck.push_back(glm::vec4(bbMax.x, bbMin.y, bbMin.z, 1.f));
	ptsToCheck.push_back(glm::vec4(bbMin.x, bbMax.y, bbMin.z, 1.f));
	ptsToCheck.push_back(glm::vec4(bbMin.x, bbMin.y, bbMax.z, 1.f));
	ptsToCheck.push_back(glm::vec4(bbMax.x, bbMax.y, bbMin.z, 1.f));
	ptsToCheck.push_back(glm::vec4(bbMax.x, bbMin.y, bbMax.z, 1.f));
	ptsToCheck.push_back(glm::vec4(bbMin.x, bbMax.y, bbMax.z, 1.f));
	ptsToCheck.push_back(glm::vec4(bbMax.x, bbMax.y, bbMax.z, 1.f));

	glm::mat4 demoVolToWorld = m_pDemoVolume->getTransformVolume();
	glm::mat4 worldToGoalVol = glm::inverse(m_pGoalVolume->getTransformVolume());
	glm::mat4 demoVolToGoalVol = worldToGoalVol * demoVolToWorld;

	for (auto const &pt : ptsToCheck)
	{
		glm::vec4 ptXformed = demoVolToGoalVol * pt;

		if (ptXformed.x < bbMin.x || ptXformed.y < bbMin.y || ptXformed.z < bbMin.z ||
			ptXformed.x > bbMax.x || ptXformed.y > bbMax.y || ptXformed.z > bbMax.z)
			return false;
	}

	return true;
}
예제 #2
0
void AmbientOcclusionEngine::computeBoundingBox()
{
   Vec bbMin(vertex(0));
   Vec bbMax(bbMin);
   Vec v;
   for (unsigned i = 1; i < m_nVertices; ++i) {
       v = vertex(i);
       bbMin.x = std::min(bbMin.x, v.x);  bbMax.x = std::max(bbMax.x, v.x);
       bbMin.y = std::min(bbMin.y, v.y);  bbMax.y = std::max(bbMax.y, v.y);
       bbMin.z = std::min(bbMin.z, v.z);  bbMax.z = std::max(bbMax.z, v.z);
   }
   m_boundingBoxOrigin = bbMin;
   // give ourselves a bit of wiggle room in the box
   bbMax += Vec(0.0001,0.0001,0.0001);

   // Determine the cell length
   v = bbMax-bbMin;

   m_cellLength = std::max(v.x, v.y);
   m_cellLength = std::max(m_cellLength, v.z)/MaxCellCount;

   //double lambda(0.01); 
   //double volume(v.x*v.y*v.z);
   //m_cellLength = std::min(std::pow(lambda*m_nTriangles/volume, 0.333333), m_cellLength);

   // and the number of cells in each direction
   v /= m_cellLength;
   m_nx = v.x;  if (bbMin.x + m_nx*m_cellLength < bbMax.x) ++m_nx;
   m_ny = v.y;  if (bbMin.y + m_ny*m_cellLength < bbMax.y) ++m_ny;
   m_nz = v.z;  if (bbMin.z + m_nz*m_cellLength < bbMax.z) ++m_nz;
}
예제 #3
0
py::tuple coordsAndDisplacements(int axis,py::tuple Aabb){
	Vector3r bbMin(Vector3r::Zero()), bbMax(Vector3r::Zero()); bool useBB=py::len(Aabb)>0;
	if(useBB){bbMin=py::extract<Vector3r>(Aabb[0])();bbMax=py::extract<Vector3r>(Aabb[1])();}
	py::list retCoord,retDispl;
	FOREACH(const shared_ptr<Body>&b, *Omega::instance().getScene()->bodies){
		if(useBB && !isInBB(b->state->pos,bbMin,bbMax)) continue;
		retCoord.append(b->state->pos[axis]);
		retDispl.append(b->state->pos[axis]-b->state->refPos[axis]);
	}
	return py::make_tuple(retCoord,retDispl);
}
예제 #4
0
void KnotsViewer::set_scene(Bbox_3 &box)
{

    Mesh::Point     bbMin(box.xmin(), box.ymin(), box.zmin());
    Mesh::Point     bbMax(box.xmax(), box.ymax(), box.zmax());
    Mesh::Point     center= (bbMin + bbMax)*0.5;
    double radius=0.5*(bbMin - bbMax).norm();
    setSceneCenter(Vec(center[0], center[1], center[2]));
    setSceneRadius(radius);
    camera()->showEntireScene();
}
예제 #5
0
void RigidBody::CreateHeightFieldFromTerrain()
{
    CheckForPlaceableAndTerrain();
    
    Terrain* terrain = impl->terrain;
    if (!terrain)
        return;
    
    uint width = terrain->PatchWidth() * Terrain::cPatchSize;
    uint height = terrain->PatchHeight() * Terrain::cPatchSize;
    if (!width || !height)
        return;
    
    impl->heightValues.Resize(width * height);
    
    float xzSpacing = 1.0f;
    float ySpacing = 1.0f;
    float minY = 1000000000;
    float maxY = -1000000000;
    for(uint z = 0; z < height; ++z)
        for(uint x = 0; x < width; ++x)
        {
            float value = terrain->GetPoint(x, z);
            if (value < minY)
                minY = value;
            if (value > maxY)
                maxY = value;
            impl->heightValues[z * width + x] = value;
        }

    float3 scale = terrain->nodeTransformation.Get().scale;
    float3 bbMin(0, minY, 0);
    float3 bbMax(xzSpacing * (width - 1), maxY, xzSpacing * (height - 1));
    float3 bbCenter = scale.Mul((bbMin + bbMax) * 0.5f);
    
    impl->heightField = new btHeightfieldTerrainShape(width, height, &impl->heightValues[0], ySpacing, minY, maxY, 1, PHY_FLOAT, false);
    
    /** \todo Terrain uses its own transform that is independent of the placeable. It is not nice to support, since rest of RigidBody assumes
        the transform is in the placeable. Right now, we only support position & scaling. Here, we also counteract Bullet's nasty habit to center 
        the heightfield on its own. Also, Bullet's collisionshapes generally do not support arbitrary transforms, so we must construct a "compound shape"
        and add the heightfield as its child, to be able to specify the transform.
     */
    impl->heightField->setLocalScaling(scale);
    
    float3 positionAdjust = terrain->nodeTransformation.Get().pos;
    positionAdjust += bbCenter;
    
    btCompoundShape* compound = new btCompoundShape();
    impl->shape = compound;
    compound->addChildShape(btTransform(btQuaternion(0,0,0,1), positionAdjust), impl->heightField);
}
예제 #6
0
void CDispInfo::ApplyTerrainMod( ITerrainMod *pMod )
{
    // New bbox.
    Vector bbMin(  1e24,  1e24,  1e24 );
    Vector bbMax( -1e24, -1e24, -1e24 );

    int nVerts, nIndices;
    CalcMaxNumVertsAndIndices( m_Power, &nVerts, &nIndices );

    // Ok, it probably touches us. Lock our buffer and change the verts.
    CMeshBuilder mb;
    mb.BeginModify( m_pMesh->m_pMesh, m_iVertOffset, nVerts );

    for( int iVert=0; iVert < nVerts; iVert++ )
    {
        if( m_AllowedVerts.Get( iVert ) )
        {
            Vector &vPos = m_Verts[iVert].m_vPos;
            Vector &vOriginalPos = m_Verts[iVert].m_vOriginalPos;

            if( pMod->ApplyMod( vPos, vOriginalPos ) )
                mb.Position3f( VectorExpand( vPos ) );

            VectorMin( vPos, bbMin, bbMin );
            VectorMax( vPos, bbMax, bbMax );
        }

        mb.AdvanceVertex();
    }

    mb.EndModify();

    // Set our new bounding box.
    m_BBoxMin = bbMin;
    m_BBoxMax = bbMax;
    UpdateCenterAndRadius();

    // Next time this displacement is seen, force it to rebuild and retesselate.
    m_bForceRebuild = true;
}
예제 #7
0
py::tuple interactionAnglesHistogram(int axis, int mask, size_t bins, py::tuple aabb, Real minProjLen){
	if(axis<0||axis>2) throw invalid_argument("Axis must be from {0,1,2}=x,y,z.");
	Vector3r bbMin(Vector3r::Zero()), bbMax(Vector3r::Zero()); bool useBB=py::len(aabb)>0; if(useBB){bbMin=py::extract<Vector3r>(aabb[0])();bbMax=py::extract<Vector3r>(aabb[1])();}
	Real binStep=Mathr::PI/bins; int axis2=(axis+1)%3, axis3=(axis+2)%3;
	vector<Real> cummProj(bins,0.);
	shared_ptr<Scene> rb=Omega::instance().getScene();
	FOREACH(const shared_ptr<Interaction>& i, *rb->interactions){
		if(!i->isReal()) continue;
		const shared_ptr<Body>& b1=Body::byId(i->getId1(),rb), b2=Body::byId(i->getId2(),rb);
		if(!b1->maskOk(mask) || !b2->maskOk(mask)) continue;
		if(useBB && !isInBB(b1->state->pos,bbMin,bbMax) && !isInBB(b2->state->pos,bbMin,bbMax)) continue;
		GenericSpheresContact* geom=dynamic_cast<GenericSpheresContact*>(i->geom.get());
		if(!geom) continue;
		Vector3r n(geom->normal); n[axis]=0.; Real nLen=n.norm();
		if(nLen<minProjLen) continue; // this interaction is (almost) exactly parallel to our axis; skip that one
		Real theta=acos(n[axis2]/nLen)*(n[axis3]>0?1:-1); if(theta<0) theta+=Mathr::PI;
		int binNo=theta/binStep;
		cummProj[binNo]+=nLen;
	}
	py::list val,binMid;
	for(size_t i=0; i<(size_t)bins; i++){ val.append(cummProj[i]); binMid.append(i*binStep);}
	return py::make_tuple(binMid,val);
}
예제 #8
0
py::tuple bodyNumInteractionsHistogram(py::tuple aabb){
	Vector3r bbMin(Vector3r::Zero()), bbMax(Vector3r::Zero()); bool useBB=py::len(aabb)>0; if(useBB){bbMin=py::extract<Vector3r>(aabb[0])();bbMax=py::extract<Vector3r>(aabb[1])();}
	const shared_ptr<Scene>& rb=Omega::instance().getScene();
	vector<int> bodyNumIntr; bodyNumIntr.resize(rb->bodies->size(),0);
	int maxIntr=0;
	FOREACH(const shared_ptr<Interaction>& i, *rb->interactions){
		if(!i->isReal()) continue;
		const Body::id_t id1=i->getId1(), id2=i->getId2(); const shared_ptr<Body>& b1=Body::byId(id1,rb), b2=Body::byId(id2,rb);
		if((useBB && isInBB(b1->state->pos,bbMin,bbMax)) || !useBB) {
			if (b1->isClumpMember()) bodyNumIntr[b1->clumpId]+=1; //count bodyNumIntr for the clump, not for the member 
			else bodyNumIntr[id1]+=1;
		}
		if((useBB && isInBB(b2->state->pos,bbMin,bbMax)) || !useBB) {
			if (b2->isClumpMember()) bodyNumIntr[b2->clumpId]+=1; //count bodyNumIntr for the clump, not for the member 
			else bodyNumIntr[id2]+=1;
		}
		maxIntr=max(max(maxIntr,bodyNumIntr[b1->getId()]),bodyNumIntr[b2->getId()]);
		if (b1->isClumpMember()) maxIntr=max(maxIntr,bodyNumIntr[b1->clumpId]);
		if (b2->isClumpMember()) maxIntr=max(maxIntr,bodyNumIntr[b2->clumpId]);
	}
	vector<int> bins; bins.resize(maxIntr+1,0);
	for(size_t id=0; id<bodyNumIntr.size(); id++){
		const shared_ptr<Body>& b=Body::byId(id,rb);
		if (b) {
			if(bodyNumIntr[id]>0) bins[bodyNumIntr[id]]+=1;
			// 0 is handled specially: add body to the 0 bin only if it is inside the bb requested (if applicable)
			// otherwise don't do anything, since it is outside the volume of interest
			else if(((useBB && isInBB(b->state->pos,bbMin,bbMax)) || !useBB) && !(b->isClumpMember())) bins[0]+=1;
		}
	}
	py::list count,num;
	for(size_t n=0; n<bins.size(); n++){
		if(bins[n]==0) continue;
		num.append(n); count.append(bins[n]);
	}
	return py::make_tuple(num,count);
}
예제 #9
0
파일: Ray.cpp 프로젝트: dotv0id/SCTEngine2
bool Ray::CheckIntersection(const BoundingBox &aabb, Vector3 &point)
{
	Vector3 maxVal(-1, -1, -1);
	Vector3 bbMin(aabb.mMin), bbMax(aabb.mMax);
	bool	rayInside = false; // false

	// X check
	if(mOrigin.x < bbMin.x)
	{
		point.x		= bbMin.x;
		rayInside	= false;

		if(mDirection.x != 0)
			maxVal.x = (bbMin.x - mOrigin.x) / mDirection.x;
	}
	else if(mOrigin.x > bbMax.x)
	{
		point.x		= bbMax.x;
		rayInside	= false;

		if(mDirection.x != 0)
			maxVal.x = (bbMax.x - mOrigin.x) / mDirection.x;
	}

	// Y check
	if(mOrigin.y < bbMin.y)
	{
		point.y		= bbMin.y;
		rayInside	= false;

		if(mDirection.y != 0)
			maxVal.y = (bbMin.y - mOrigin.y) / mDirection.y;
	}
	else if(mOrigin.y > bbMax.y)
	{
		point.y		= bbMax.y;
		rayInside	= false;

		if(mDirection.y != 0)
			maxVal.y = (bbMax.y - mOrigin.y) / mDirection.y;
	}

	// Z check
	if(mOrigin.z < bbMin.z)
	{
		point.z		= bbMin.z;
		rayInside	= false;

		if(mDirection.z != 0)
			maxVal.z = (bbMin.z - mOrigin.z) / mDirection.z;
	}
	else if(mOrigin.z > bbMax.z)
	{
		point.z		= bbMax.z;
		rayInside	= false;

		if(mDirection.z != 0)
			maxVal.z = (bbMax.z - mOrigin.z) / mDirection.z;
	}

	if(rayInside)
	{
		point = mOrigin;
		return true;
	}

	int index = 0;
	float temp[3];
	temp[0] = maxVal.x; temp[1] = maxVal.y; temp[2] = maxVal.z;

	if(maxVal.y > temp[index])
		index = 1;

	if(maxVal.z > temp[index])
		index = 2;

	if(temp[index] < 0)
		return false;
   
	if(index != 0)
	{
		point.x = mOrigin.x + maxVal.x * mDirection.x;

		if(point.x < bbMin.x - 0.00001f || point.x < bbMax.x + 0.00001f)
			return false;
	}

	if(index != 1)
	{
		point.y = mOrigin.y + maxVal.y * mDirection.y;

		if(point.y < bbMin.y - 0.00001f || point.y < bbMax.y + 0.00001f)
			return false;
	}

	if(index != 2)
	{
		point.z = mOrigin.z + maxVal.z * mDirection.z;

		if(point.z < bbMin.z - 0.00001f || point.z < bbMax.z + 0.00001f)
			return false;
	}

	return true;
}
예제 #10
0
파일: ccOctree.cpp 프로젝트: dshean/trunk
ccBBox ccOctree::getDisplayBB()
{
    CCVector3 bbMin(m_dimMin[0],m_dimMin[1],m_dimMin[2]);
    CCVector3 bbMax(m_dimMax[0],m_dimMax[1],m_dimMax[2]);
    return ccBBox(bbMin,bbMax);
}
예제 #11
0
파일: ccOctree.cpp 프로젝트: dshean/trunk
ccBBox ccOctree::getMyOwnBB()
{
    CCVector3 bbMin(m_pointsMin[0],m_pointsMin[1],m_pointsMin[2]);
    CCVector3 bbMax(m_pointsMax[0],m_pointsMax[1],m_pointsMax[2]);
    return ccBBox(bbMin,bbMax);
}