Exemple #1
0
void RenderCube()
{
    AABB3 box;
    box.min.x = box.min.y = box.min.z = -5.0f;
    box.max = -box.min;

    RenderVertex vl[8];
    for (int i = 0 ; i < 8 ; ++i) {
        vl[i].p = box.corner(i);
        //vl[i].argb = MAKE_ARGB(255, (i & 1) ? 255 : 0, (i & 2) ? 255 : 0, (i & 4) ? 255 : 0);
        vl[i].n = vl[i].p;
        vl[i].n.normalize();
        vl[i].u = (i & 1) ? 1.0f : 0.0f;
        vl[i].v = (i & 2) ? 1.0f : 0.0f;
    }

    RenderTri pl[6*2] = {
        { 0,4,6 },
        { 0,6,2 },
        { 1,3,7 },
        { 1,7,5 },
        { 0,1,5 },
        { 0,5,4 },
        { 2,6,7 },
        { 2,7,3 },
        { 0,2,3 },
        { 0,3,1 },
        { 4,5,7 },
        { 4,7,6 },
    };

    gRenderer.renderTriMesh(vl, 8, pl, 12);
}
/**
 * updates position, velocity, and animation time of particles
 *  - rParticleSet.aabb is also updated
 *
 */
inline void CBE_ParticleSet::UpdateParticles( ParticleSetExtraData& rParticleSet, float dt, AABB3& aabb )
{
//	Vector3 vGravityAccel = m_pStage->GetGravityAccel();
//	float fGravityInfluenceFactor = m_fGravityInfluenceFactor;
	Vector3 vGravityAccel = m_pStage->GetGravityAccel() * m_fGravityInfluenceFactor;

//	AABB3 aabb;
	aabb.Nullify();

	int i, num_particles = rParticleSet.iNumParticles;
	for(i=0; i<num_particles; i++)
	{
		// update velocity
//		rParticleSet.pavVelocity[i] += (vGravityAccel * fGravityInfluenceFactor) * dt;
		rParticleSet.pavVelocity[i] += vGravityAccel * dt;

		// update position
		rParticleSet.pavPosition[i] += rParticleSet.pavVelocity[i] * dt;

		// update animation time
		rParticleSet.pafAnimationTime[i] += dt;

		aabb.AddPoint( rParticleSet.pavPosition[i] );
	}

	const float r = m_fParticleRadius;
	aabb.vMin -= Vector3(r,r,r);
	aabb.vMax += Vector3(r,r,r);

	rParticleSet.aabb = aabb;
}
Exemple #3
0
TerrainChunk::TerrainChunk(
    int xChunkIndex,
    int yChunkIndex,
    int zChunkIndex,
    Terrain *terrain
):
    Entity("TerrainChunk"),
    _xChunkIndex(xChunkIndex),
    _yChunkIndex(yChunkIndex),
    _zChunkIndex(zChunkIndex),
    _terrain(terrain)
{
    std::ostringstream stringStream;
    stringStream << "TerrainChunk [" <<
        _xChunkIndex << ", " <<
        _yChunkIndex << ", " <<
        _zChunkIndex << "]";

    _name = stringStream.str();

    _paletteRenderables.reserve(DefaultCapacity);

    _grid = new MatrixVoxelGrid(ChunkSize, ChunkSize, ChunkSize);

    // Setup for a correct model matrix.
    setPosition(
        _xChunkIndex * ChunkSize,
        _yChunkIndex * ChunkSize,
        _zChunkIndex * ChunkSize);

    // Setup for correct frustum culling.
    AABB3 localAABB;
    localAABB.setMinMax(Vector3(0, 0, 0), Vector3(ChunkSize, ChunkSize, ChunkSize));
    expandLocalAABB(localAABB);
}
Exemple #4
0
	Matrix44 MatrixUtils::orthographic_off_center( AABB3& bounds )
	{
		return orthographic_off_center(	
			bounds.vmin().x, bounds.vmax().x,
			bounds.vmin().y, bounds.vmax().y,
			bounds.vmin().z, bounds.vmax().z);
	}
Exemple #5
0
/// \param m Specifies the transformation matrix to be applied.
/// \return The bounding box for the mesh under m.
AABB3 TriMesh::getBoundingBox(const Matrix4x3 &m) const
{
  AABB3 bb;
  bb.empty();
  for (int i = 0; i < vertexCount; ++i)
    bb.add(vertexList[i].p * m);
  return bb;
}
/// \param m Specifies the transformation matrix applied to the model.
/// \return The bounding box of the model in transformed space.
AABB3 Model::getBoundingBox(const Matrix4x3 &m) const
{
    AABB3 bb;
    bb.empty();
    for(int i = 0; i < m_partCount; ++i)
        bb.add(m_partMeshList[i].getBoundingBox(m));
    return bb;
}
/// \param submodel Specifies the submodel whose bounding box is to be fetched.
/// \param m Specifies the transformation matrix representing the submodel in world space.
AABB3 ArticulatedModel::getSubmodelBoundingBox(int submodel, const Matrix4x3 &m) const
{
  assert(submodel < m_nSubmodelCount);
  AABB3 bb;
  bb.empty();
  for(int i = 0; i < m_nNextSubmodelPart[submodel]; ++i)
    bb.add(m_partMeshList[m_nSubmodelPart[submodel][i]].getBoundingBox(m));
  return bb;
}
inline void IndexedPolygon::UpdateAABB()
{
	m_AABB.Nullify();

	const size_t num_vertices = m_index.size();
	for( size_t i=0; i<num_vertices; i++ )
	{
		m_AABB.AddPoint( GetVertex(i).m_vPosition );
	}
}
Exemple #9
0
/** 
    Adopted from Real Time Collision Detection
    5.2.3
*/
bool gh::Plane3::IntersectsWithAABB3( const AABB3& box ) const
{
    Vector3 center = box.calcCenter();
    Vector3 extents = box.getMax() - center;

    float r = extents.x * fabs( normal.x ) + extents.y * fabs( normal.y ) + extents.z * fabs( normal.z );
    float s = normal.dotProduct( center ) - distanceFromOrigin;

    return fabs( s ) <= r;
}
Exemple #10
0
	void PrimitiveBatch::draw_aabb( const AABB3& box, const ColourRGBA8& colour/*=ColourARGB8::White()*/ )
	{
		Vector3 v[8];

		v[0] = box.center() + box.dimensions() * Vector3(-0.5f,-0.5f,-0.5f);
		v[1] = box.center() + box.dimensions() * Vector3(+0.5f,-0.5f,-0.5f);
		v[2] = box.center() + box.dimensions() * Vector3(-0.5f,+0.5f,-0.5f);
		v[3] = box.center() + box.dimensions() * Vector3(+0.5f,+0.5f,-0.5f);
		v[4] = box.center() + box.dimensions() * Vector3(-0.5f,-0.5f,+0.5f);
		v[5] = box.center() + box.dimensions() * Vector3(+0.5f,-0.5f,+0.5f);
		v[6] = box.center() + box.dimensions() * Vector3(-0.5f,+0.5f,+0.5f);
		v[7] = box.center() + box.dimensions() * Vector3(+0.5f,+0.5f,+0.5f);

		draw_line(Line3(v[0],v[1]), colour);
		draw_line(Line3(v[2],v[3]), colour);
		draw_line(Line3(v[4],v[5]), colour);
		draw_line(Line3(v[6],v[7]), colour);

		draw_line(Line3(v[0],v[4]), colour);
		draw_line(Line3(v[1],v[5]), colour);
		draw_line(Line3(v[2],v[6]), colour);
		draw_line(Line3(v[3],v[7]), colour);

		draw_line(Line3(v[0],v[2]), colour);
		draw_line(Line3(v[1],v[3]), colour);
		draw_line(Line3(v[4],v[6]), colour);
		draw_line(Line3(v[5],v[7]), colour);
	}
Exemple #11
0
	// clip trace at the point of contact
void CTriangleMesh::ClipLineSegment( CJL_LineSegment& segment )
{
	Vector3 vStart = segment.vStart;
	Vector3 vEnd;
	if( segment.fFraction == 1.0f )
		vEnd = segment.vGoal;
	else
		vEnd = segment.vEnd;	// the line segment has been already clipped - set the current end point

	static vector<int> s_veciTriList;
	s_veciTriList.resize( 0 );

	AABB3 aabb;
	aabb.Nullify();
	aabb.AddPoint( vStart );
	aabb.AddPoint( vEnd );

	GetIntersectingTriangles( s_veciTriList, aabb );

	size_t i, iNumTris = s_veciTriList.size();

	if( iNumTris == 0 )
		return;	// no intersection

	Vector3 vOrigLineSegment = vEnd - vStart;

	for( i=0; i<iNumTris; i++ )
	{
		IndexedTriangle& tri = GetTriangle( s_veciTriList[i] );
		Triangle triangle( GetVertex( tri.GetIndex(0) ),
			                GetVertex( tri.GetIndex(1) ),
							GetVertex( tri.GetIndex(2) ),
							tri.m_vNormal );

		// check intersection between ray and triangle
		if( triangle.RayIntersect( vStart, vEnd ) )
		{	// found intersection
			// 'vEnd' now represents the intersection point

			// save contact surface
			segment.plane = triangle.GetPlane();

			// record surface material to 'tr'
			segment.iMaterialIndex = tri.m_iMaterialID;
		}
	}

	segment.fFraction *= Vec3Dot( vEnd - vStart, vOrigLineSegment ) / Vec3LengthSq( vOrigLineSegment );
	segment.vEnd = vEnd;
}
Exemple #12
0
void CBSPMapData::SetLightsFromLightSourceFaces()
{
	vector<CMapFace> vecTempLightSourceFace;	// temporary buffer to hold light source faces
	size_t i,j;
	size_t iNumInteriorFaces = m_aInteriorFace.size();

	for(i=0; i<iNumInteriorFaces; i++)
	{	// set all the flags of light source faces to false
		m_aInteriorFace[i].m_bFlag = false;
	}

	// cluster light source faces	
	for(i=0; i<iNumInteriorFaces; i++)
	{
		vecTempLightSourceFace.clear();
		CMapFace& rFace1 = m_aInteriorFace[i];

		if( !rFace1.ReadTypeFlag(CMapFace::TYPE_LIGHTSOURCE) )
			continue;	// doesn't emit light by itself

		if( rFace1.m_bFlag == true )
			continue;	// already registered as a light source face

		rFace1.m_bFlag = true;
		vecTempLightSourceFace.push_back( rFace1 );

		// adjacent light source faces are converted into one point light
		SearchAdjacentLightSourceFaces_r( &vecTempLightSourceFace, rFace1, &m_aInteriorFace );

		// convert each cluster of light source faces into a point light
		AABB3 aabb;
		aabb.Nullify();
		for(j=0; j<vecTempLightSourceFace.size(); j++)
			vecTempLightSourceFace[j].AddToAABB( aabb );

		SPointLightDesc light = FindPointLightDesc( rFace1.m_acSurfaceName );
		CPointLight* pPointLight = new CPointLight;
		pPointLight->vPosition = aabb.GetCenterPosition();
		pPointLight->Color.fRed   = light.fRed;
		pPointLight->Color.fGreen = light.fGreen;
		pPointLight->Color.fBlue  = light.fBlue;
		pPointLight->fIntensity   = light.fIntensity;
		pPointLight->fAttenuation0 = light.fAttenuation[0];
		pPointLight->fAttenuation1 = light.fAttenuation[1];
		pPointLight->fAttenuation2 = light.fAttenuation[2];
		m_vecpLight.push_back( pPointLight );
	}
}
Exemple #13
0
void UniformGrid<T,CellType>::InitGrid(const AABB3<T> &boundingBox, const AABB3<T> &element)
{

    m_dCellSize = 2.0 * element.getBoundingSphereRadius();
    m_bxBox = boundingBox;

    int x = (2.0*m_bxBox.extents_[0]+m_dCellSize)/m_dCellSize;
    int y = (2.0*m_bxBox.extents_[1]+m_dCellSize)/m_dCellSize;
    int z = (2.0*m_bxBox.extents_[2]+m_dCellSize)/m_dCellSize;

    // int nGhostLayerCells = (2 * xy + 2 * xz + 2 * yz) + (4 * x + 4 * y + 4 * z) + 8;

    // pass a bounding box that is m_dCellSize bigger in each dimension
    m_pCells = new CellType[x*y*z];

    // printf("cell size: %f\n",m_dCellSize);
    // printf("domain extends : %f %f %f\n",boundingBox.extents_[0],boundingBox.extents_[1],boundingBox.extents_[2]);
    // printf("element extends : %f %f %f\n",element.extents_[0],element.extents_[1],element.extents_[2]);
    // printf("Dimensions : %d %d %d\n",x,y,z);
    // printf("Number of cells in uniform grid : %d\n",x*y*z);

    m_iDimension[0] = x;
    m_iDimension[1] = y;
    m_iDimension[2] = z;

    m_iTotalEntries=0;

}
Exemple #14
0
bool Ned3DObjectManager::enforcePositions(GameObject &obj1, GameObject &obj2)
{
  const AABB3 &box1 = obj1.getBoundingBox(), &box2 = obj2.getBoundingBox();
  AABB3 intersectBox;
  if(AABB3::intersect(box1, box2, &intersectBox))
  {
    // Collision:  Knock back both objects
    //   - Kludge method:  Push back on smallest dimension
    Vector3 delta = intersectBox.size();
    Vector3 obj1Pos = obj1.getPosition(), obj2Pos = obj2.getPosition();
    if(delta.x <= delta.y)
      if(delta.x <= delta.z)
      {
        // Push back on x
        float dx = (box1.min.x < box2.min.x) ? -delta.x : delta.x;
        obj1Pos.x += dx;
        obj2Pos.x -= dx;
      }
      else
      {
        // Push back on z
        float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z;
        obj1Pos.z += dz;
        obj2Pos.z -= dz;
      }
    else if(delta.y <= delta.z)
    {
        // Push back on y
        float dy = (box1.min.y < box2.min.y) ? -delta.y : delta.y;
        obj1Pos.y += dy;
        obj2Pos.y -= dy;
    }
    else
    {
      // Push back on z
      float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z;
      obj1Pos.z += dz;
      obj2Pos.z -= dz;
    }
    obj1.setPosition(obj1Pos);
    obj2.setPosition(obj2Pos);
    return true;
  }
  return false;
}
void CBE_NozzleExhaust::UpdateNozzleExhaust( CCopyEntity* pCopyEnt, SBE_ParticleSetExtraData& rParticleSet, float dt )
{
	int i, num_particles = m_MaxNumParticlesPerSet;

//	float dt = fFrameTime;
	AABB3 aabb;
	aabb.Nullify();
//	UpdateParticles( rParticleSet, fFrameTime, aabb );
	float radius = m_fParticleRadius;
	for(i=0; i<num_particles; i++)
	{
		// update animation time
		rParticleSet.pafAnimationTime[i] += dt;

		if( rParticleSet.pafAnimationTime[i] < 0 )
			continue;

		// update velocity
//		rParticleSet.pavVelocity[i] += vGravityAccel * dt;

		// update position
		rParticleSet.pavPosition[i] += rParticleSet.pavVelocity[i] * dt;

		aabb.AddSphere( Sphere(rParticleSet.pavPosition[i],radius) );
	}

	pCopyEnt->world_aabb.MergeAABB( aabb );

	Vector3	vBasePos = Vector3(0,0,0);//pCopyEnt->Position();// + pCopyEnt->GetDirection() * pCopyEnt->f1;
	Vector3 vDir	= Vector3(0,0,1);//pCopyEnt->GetDirection();
	Vector3 vRight	= Vector3(1,0,0);//pCopyEnt->GetRightDirection();
	Vector3	vUp		= Vector3(0,1,0);//pCopyEnt->GetUpDirection();
	float cycle_time = m_fDuration;
	for( i=0; i<num_particles; i++ )
	{
		if( cycle_time <= rParticleSet.pafAnimationTime[i] )
		{
			// set new position & velocity

			CreateNewParticle( pCopyEnt, rParticleSet, i );
//			rParticleSet.pafAnimationTime[i] = 0;
		}
	}
}
Exemple #16
0
void AABB3::TransformBy(Matrix& matrix)
{
	AABB3	bb;

	Vector3f v(minVec);
	Vector3f w(maxVec);
	
	bb.Encapsulate(matrix.Transform(Vector3f(v.x(),v.y(),v.z())));
	bb.Encapsulate(matrix.Transform(Vector3f(w.x(),v.y(),v.z())));
	bb.Encapsulate(matrix.Transform(Vector3f(v.x(),w.y(),v.z())));
	bb.Encapsulate(matrix.Transform(Vector3f(w.x(),w.y(),v.z())));
	bb.Encapsulate(matrix.Transform(Vector3f(v.x(),v.y(),w.z())));
	bb.Encapsulate(matrix.Transform(Vector3f(w.x(),v.y(),w.z())));
	bb.Encapsulate(matrix.Transform(Vector3f(v.x(),w.y(),w.z())));
	bb.Encapsulate(matrix.Transform(Vector3f(w.x(),w.y(),w.z())));

	minVec.Set(bb.minVec);
	maxVec.Set(bb.maxVec);
}
Exemple #17
0
inline bool Camera::ViewFrustumIntersectsWith( const AABB3& raabb ) const
{
	int i;
	float d;

	Vector3 vCenter, vExtents;
	vCenter = raabb.GetCenterPosition();
	vExtents = raabb.GetExtents();

	for( i=0; i<6; i++ )
	{
		const SPlane& rPlane = m_WorldBSPTree[i].plane;

		d = Vec3Dot( rPlane.normal, vCenter ) - rPlane.dist - raabb.GetRadiusForPlane(rPlane);

		if(0 < d)
			return false;
	}
	return true;
}
inline AABB3 GetAABB( const std::vector<IndexedPolygon>& polygon_buffer )
{
	AABB3 aabb;
	aabb.Nullify();

	size_t i, num_pols = polygon_buffer.size();
	size_t j, num_verts;
	for( i=0; i<num_pols; i++ )
	{
		// polygon_buffer[i].Update();
		// aabb.MergeAABB( polygon_buffer[i].GetAABB() );

		num_verts = polygon_buffer[i].m_index.size();
		for( j=0; j<num_verts; j++ )
		{
			aabb.AddPoint( polygon_buffer[i].GetVertex((int)j).m_vPosition );
		}
	}

	return aabb;
}
	ParticleSetExtraData()
		:
	iNumParticles(0),
	pavPosition(nullptr),
	pavVelocity(nullptr),
	pavOrigDirection(nullptr),
	pafAnimationTime(nullptr),
	pafAnimDuration(nullptr),
	pasPattern(nullptr),
	pafFadeVel(nullptr)
	{
		aabb.Nullify();
	}
/**
 * updates position, velocity, and animation time of particles
 *  - rParticleSet.aabb is also updated
 *
 */
inline void CBE_ParticleSet::UpdateParticlePositions( ParticleSetExtraData& rParticleSet, float dt, AABB3& aabb )
{
//	AABB3 aabb;
	aabb.Nullify();

	int i, num_particles = rParticleSet.iNumParticles;
	for(i=0; i<num_particles; i++)
	{
		// update position
		rParticleSet.pavPosition[i] += rParticleSet.pavVelocity[i] * dt;

		// update animation time
		rParticleSet.pafAnimationTime[i] += dt;

		aabb.AddPoint( rParticleSet.pavPosition[i] );
	}

	const float r = m_fParticleRadius;
	aabb.vMin -= Vector3(r,r,r);
	aabb.vMax += Vector3(r,r,r);

	rParticleSet.aabb = aabb;
}
Exemple #21
0
    bool FrustumCuller::isCullable(const Chunk& chunk, const RenderData& data) {
        // Calculate the MVP matrix
        dmat4 modelTransform = chunk.owner()->modelTransform();
        dmat4 viewTransform = dmat4(data.camera.combinedViewMatrix());
        dmat4 modelViewProjectionTransform = dmat4(data.camera.projectionMatrix())
            * viewTransform * modelTransform;

        const std::vector<glm::dvec4>& corners = chunk.getBoundingPolyhedronCorners();
        

        // Create a bounding box that fits the patch corners
        AABB3 bounds; // in screen space
        std::vector<vec4> clippingSpaceCorners(8);
        for (size_t i = 0; i < 8; i++) {
            dvec4 cornerClippingSpace = modelViewProjectionTransform * corners[i];
            clippingSpaceCorners[i] = cornerClippingSpace;

            dvec3 cornerScreenSpace = (1.0f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace;
            bounds.expand(cornerScreenSpace);
        }
        
        return !_viewFrustum.intersects(bounds);
    }
Exemple #22
0
AABB3 SoccerBase::GetAgentBoundingBox(const Leaf& base)
{
    AABB3 boundingBox;

    boost::shared_ptr<Space> parent = base.FindParentSupportingClass<Space>().lock();

    if (!parent)
    {
        base.GetLog()->Error()
                << "(GetAgentBoundingBox) ERROR: can't get parent node.\n";
        return boundingBox;
    }

    /* We can't simply use the GetWorldBoundingBox of the space node, becuase
     * (at least currently) it'll return a wrong answer. Currently, the space
     * object is always at (0,0,0) which is encapsulated in the result of it's
     * GetWorldBoundingBox method call.
     */

    Leaf::TLeafList baseNodes;
    parent->ListChildrenSupportingClass<BaseNode>(baseNodes);

    if (baseNodes.empty())
        {
            base.GetLog()->Error()
                    << "(GetAgentBoundingBox) ERROR: space object doesn't have any"
                    << " children of type BaseNode.\n";
        }

    for (Leaf::TLeafList::iterator i = baseNodes.begin(); i!= baseNodes.end(); ++i)
    {
        boost::shared_ptr<BaseNode> node = shared_static_cast<BaseNode>(*i);
        boundingBox.Encapsulate(node->GetWorldBoundingBox());
    }

    return boundingBox;
}
Exemple #23
0
bool Ned3DObjectManager::enforcePosition(GameObject &moving, GameObject &stationary)
{
  const AABB3 &box1 = moving.getBoundingBox(), &box2 = stationary.getBoundingBox();
  AABB3 intersectBox;
  if(AABB3::intersect(box1, box2, &intersectBox))
  {
    // Collision:  Knock back obj1
    //   - Kludge method:  Push back on smallest dimension
    Vector3 delta = intersectBox.size();
    Vector3 obj1Pos = moving.getPosition(), obj2Pos = stationary.getPosition();
    if(delta.x <= delta.y)
      if(delta.x <= delta.z)
      {
        // Push back on x
        obj1Pos.x += (box1.min.x < box2.min.x) ? -delta.x : delta.x;
      }
      else
      {
        // Push back on z
        obj1Pos.z += (box1.min.z < box2.min.z) ? -delta.z : delta.z;
      }
    else if(delta.y <= delta.z)
    {
      // Push back on y
      obj1Pos.y += (box1.min.y < box2.min.y) ? -delta.y : delta.y;
    }
    else
    {
      // Push back on z
      obj1Pos.z += (box1.min.z < box2.min.z) ? -delta.z : delta.z;
    }
    moving.setPosition(obj1Pos);
    return true;
  }
  return false;
}
	void Init( int flag, int num_particles )
	{
		Release();

		iNumParticles = 0;
		aabb.Nullify();

		if( flag & ParticleSetFlag::POSITION )      pavPosition      = new Vector3 [num_particles];
		if( flag & ParticleSetFlag::VELOCITY )      pavVelocity      = new Vector3 [num_particles];
		if( flag & ParticleSetFlag::ORIG_DIR )      pavOrigDirection = new Vector3 [num_particles];
		if( flag & ParticleSetFlag::ANIM_TIME )     pafAnimationTime = new float   [num_particles];
		if( flag & ParticleSetFlag::ANIM_DURATION ) pafAnimDuration  = new float   [num_particles];
		if( flag & ParticleSetFlag::PATTERN )       pasPattern       = new short   [num_particles];
		if( flag & ParticleSetFlag::FADE_VEL )      pafFadeVel       = new float   [num_particles];
//		if( flag & ParticleSetFlag::LOCAL_POSITION )pavLocalPosition = new Vector3 [num_particles];
	}
Exemple #25
0
UniformGrid<T,CellType>::UniformGrid(const AABB3<T> &boundingBox, const AABB3<T> &element)
{

    m_dCellSize = 2.0 * element.getBoundingSphereRadius();

    int x = (m_bxBox.extents_[0]+m_dCellSize)/m_dCellSize;
    int y = (m_bxBox.extents_[1]+m_dCellSize)/m_dCellSize;
    int z = (m_bxBox.extents_[2]+m_dCellSize)/m_dCellSize;

    int xy = x*y;
    int xz = x*z;
    int yz = y*z;

    // pass a bounding box that is m_dCellSize bigger in each dimension
    m_pCells = new CellType[x*y*z];

    m_iTotalEntries=0;

}
bool Ned3DObjectManager::enforcePositions(GameObject &obj1, GameObject &obj2) 
{	 // TODO: replace with http://code.google.com/p/bullet/source/browse/trunk/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp HullAgainstHull for OOBBs
	/*
	// Bullet stuff:
	
	btVector3 v(0.0f,0.0f,0.0f);
	const btConvexPolyhedron* cP = NULL;
	const btConvexPolyhedron* cP2 = NULL;
	if ( obj1.colOb->getCollisionShape()->isPolyhedral() ) {
		btPolyhedralConvexShape* pCS = ((btPolyhedralConvexShape*) obj1.colOb->getCollisionShape());
		//pCS->initializePolyhedralFeatures();
		cP = pCS->getConvexPolyhedron();
	}
	if (obj2.colOb->getCollisionShape()->isPolyhedral() ) {
		btPolyhedralConvexShape* pCS = ((btPolyhedralConvexShape*) obj2.colOb->getCollisionShape());
		//pCS->initializePolyhedralFeatures();
		cP2 = pCS->getConvexPolyhedron();
	}

	bool collision = false;

	if (cP && cP2) {
	    collision = btPolyhedralContactClipping::findSeparatingAxis(*cP,*cP2,
		obj1.colOb->getWorldTransform(),obj2.colOb->getWorldTransform(),
		v,renderCallback);
	}

	btVector3 v1 = obj1.colOb->getWorldTransform().getOrigin();
	btVector3 v2 = obj2.colOb->getWorldTransform().getOrigin();


	bool invert = false;
    if (obj1.getType() == ObjectTypes::BOX || obj2.getType() == ObjectTypes::BOX) {
	    invert = true;
    }
	if (collision) {
		if (!invert) {
			//normal collision stuff
			
		} else {

		}
	}
	return collision;*/

  bool invert = false;
  if (obj1.getType() == ObjectTypes::BOX || obj2.getType() == ObjectTypes::BOX) {
	  invert = true;
  }

  const AABB3 &box1 = obj1.getBoundingBox(), &box2 = obj2.getBoundingBox();
  AABB3 intersectBox;

  if(! invert && AABB3::intersect(box1, box2, &intersectBox))
  {
    // Collision:  Knock back both objects
    //   - Kludge method:  Push back on smallest dimension
    Vector3 delta = intersectBox.size();
    Vector3 obj1Pos = obj1.getPosition(), obj2Pos = obj2.getPosition();
	
	if(delta.x <= delta.y)
		if(delta.x <= delta.z)
		{
		// Push back on x
		float dx = (box1.min.x < box2.min.x) ? -delta.x : delta.x;
		obj1Pos.x += dx;
		obj2Pos.x -= dx;
		}
		else
		{
		// Push back on z
		float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z;
		obj1Pos.z += dz;
		obj2Pos.z -= dz;
		}
	else if(delta.y <= delta.z)
	{
		// Push back on y
		float dy = (box1.min.y < box2.min.y) ? -delta.y : delta.y;
		obj1Pos.y += dy;
		obj2Pos.y -= dy;
	}
	else
	{
		// Push back on z
		float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z;
		obj1Pos.z += dz;
		obj2Pos.z -= dz;
	}
	
    obj1.setPPosition(obj1Pos);
    obj2.setPPosition(obj2Pos);
    return true;
  } else if (AABB3::intersect(box1, box2, &intersectBox) ) { // inverted bounding box collision)

	char* tp = (char*)malloc(sizeof(char*)*500); // allocate char
	sprintf_s(tp,500,"hello world %f\n\0",box1.min.x);

	 

	Vector3 delta = intersectBox.size();
    Vector3 obj1Pos = obj1.getPosition(), obj2Pos = obj2.getPosition();
	float dx,dy,dz=0.0f;
	dx=dy=dz=0.0f;


	// check if plane should leave the box
	GameObject* p = &obj2;
	BoxObject* b = (BoxObject*)p;
	p = &obj1;
	PlaneObject* plane = (PlaneObject*)p;

	bool posChanged = false;

	// since one is much bigger than the other, we can use maxes to determine relative position:
	
	if (box1.min.x < box2.min.x + 1.0f) {
		// move obj2 to the left and move obj1 to the right
		dx = box2.min.x - box1.min.x;
		//obj1Pos.x += dx;

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_LEFT;
		//OutputDebugString(tp);
		if (b->l == BoxObject::LEFT) {
			setNextBox(b,b->left);
			return true;
		}
	}
	
	if (box1.min.x < box2.min.x) {
		// move obj2 to the left and move obj1 to the right
		dx = box2.min.x - box1.min.x;
		obj1Pos.x += dx;

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_LEFT;
		//OutputDebugString(tp);
		if (b->l == BoxObject::LEFT) {
			setNextBox(b,b->left);
			return true;
		}
	}

	if (box1.max.x + 1.0f > box2.max.x) {
		dx = box2.max.x - box1.max.x;
		//obj1Pos.x += dx;
		//OutputDebugString(tp);

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_RIGHT;
		if (b->l == BoxObject::RIGHT) {
			setNextBox(b,b->right);
			return true;
		}
	}

	if (box1.max.x > box2.max.x) {
		dx = box2.max.x - box1.max.x;
		obj1Pos.x += dx;
		//OutputDebugString(tp);

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_RIGHT;
		if (b->l == BoxObject::RIGHT) {
			setNextBox(b,b->right);
			return true;
		}
	}

	if (box1.min.y < box2.min.y + 1.0f) {
		// move obj2 to the left and move obj1 to the right
		dy = box2.min.y - box1.min.y;
		//obj1Pos.y += dy;
		//OutputDebugString(tp);

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_DOWN;
		if (b->l == BoxObject::BOTTOM) {
			setNextBox(b,b->bottom);
			return true;
		}
	}

	if (box1.min.y < box2.min.y) { // TODO: Make plane not able to go slightly over
		// move obj2 to the left and move obj1 to the right
		dy = box2.min.y - box1.min.y;
		obj1Pos.y += dy;
		//OutputDebugString(tp);

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_DOWN;
		if (b->l == BoxObject::BOTTOM) {
			setNextBox(b,b->bottom);
			return true;
		}
	}

	if (box1.max.y + 1.0f > box2.max.y) {
		dy = box2.max.y - box1.max.y;
		//obj1Pos.y += dy;
		//OutputDebugString(tp);

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_UP;
		if (b->l == BoxObject::TOP) {
			setNextBox(b,b->top);
			return true;
		}
	}

	if (box1.max.y > box2.max.y) {
		dy = box2.max.y - box1.max.y;
		obj1Pos.y += dy;
		//OutputDebugString(tp);

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_UP;
		if (b->l == BoxObject::TOP) {
			setNextBox(b,b->top);
			return true;
		}
	}


	if (box1.min.z < box2.min.z + 1.0f) {
		// move obj2 to the left and move obj1 to the right
		dz = box2.min.z - box1.min.z;
		//obj1Pos.z += dz;
		
		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_NEAR;
		if (b->l == BoxObject::FRONT) {
			setNextBox(b,b->back);
			return true;
		}
	}

	if (box1.min.z < box2.min.z) {
		// move obj2 to the left and move obj1 to the right
		dz = box2.min.z - box1.min.z;
		obj1Pos.z += dz;
		
		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_NEAR;
		if (b->l == BoxObject::FRONT) {
			setNextBox(b,b->back);
			return true;
		}
	}

	if (box1.max.z + 1.0f > box2.max.z) {
		dz = box2.max.z - box1.max.z;
		//obj1Pos.z += dz;

		//char* tp = (char*)malloc(sizeof(char*)*500); // allocate char
		//sprintf_s(tp,500,"In with the new?????\n\0");
		//OutputDebugString(tp);

		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_FAR;
		if (b->l == BoxObject::BACK) {
			setNextBox(b,b->front);
			return true;
		}
	}

	if (box1.max.z > box2.max.z) {
		dz = box2.max.z - box1.max.z;
		obj1Pos.z += dz;



		posChanged = true;
		plane->m_stopState = plane->m_stopState | PlaneObject::STOP_FAR;
		if (b->l == BoxObject::BACK) {
			setNextBox(b,b->front);
			return true;
		}
	}

	if (!posChanged) {
		// No walls hit, so plane can move normally
		plane->m_stopState = PlaneObject::NO_STOP;
	}

	
    obj1.setPPosition(obj1Pos);


	



	return true;
  }

  return false;
}
bool Ned3DObjectManager::enforcePosition(GameObject &moving, GameObject &stationary)
{
	// Bullet stuff:
	//collisionWorld->contactPairTest(moving.colOb,stationary.colOb, *renderCallback);
	/*
	btVector3 v(0.0f,0.0f,0.0f);
	const btConvexPolyhedron* cP = NULL;
	const btConvexPolyhedron* cP2 = NULL;
	if ( moving.colOb->getCollisionShape()->isPolyhedral() ) {
		btPolyhedralConvexShape* pCS = ((btPolyhedralConvexShape*) moving.colOb->getCollisionShape());
		//pCS->initializePolyhedralFeatures();  // TODO wasn't doing this on startup, now I am
		cP = pCS->getConvexPolyhedron();
	}
	if (stationary.colOb->getCollisionShape()->isPolyhedral() ) {
		btPolyhedralConvexShape* pCS = ((btPolyhedralConvexShape*) stationary.colOb->getCollisionShape());
		//pCS->initializePolyhedralFeatures(); // TODO wasn't doing this on startup, now I am
		cP2 = pCS->getConvexPolyhedron();
	}

	bool collision = false;
	if (cP && cP2) {
	    collision = btPolyhedralContactClipping::findSeparatingAxis(*cP,*cP2,
		moving.colOb->getWorldTransform(),stationary.colOb->getWorldTransform(),
		v,renderCallback);
	}

	btVector3 v2 = moving.colOb->getWorldTransform().getOrigin();

	if (collision) {
		char* tp = (char*)malloc(sizeof(char*)*500); // allocate char
		sprintf_s(tp,500,"hello world %f %f %f\n\0",v2.getX(),v2.getY(),v2.getZ());
		OutputDebugString(tp);

		delete tp;
	}
	return collision;*/
  
  const AABB3 &box1 = moving.getBoundingBox(), &box2 = stationary.getBoundingBox();
  AABB3 intersectBox;
  if(AABB3::intersect(box1, box2, &intersectBox))
  {
    // Collision:  Knock back obj1
    //   - Kludge method:  Push back on smallest dimension
    Vector3 delta = intersectBox.size();
    Vector3 obj1Pos = moving.getPosition(), obj2Pos = stationary.getPosition();
    if(delta.x <= delta.y)
      if(delta.x <= delta.z)
      {
        // Push back on x
        obj1Pos.x += (box1.min.x < box2.min.x) ? -delta.x : delta.x;
      }
      else
      {
        // Push back on z
        obj1Pos.z += (box1.min.z < box2.min.z) ? -delta.z : delta.z;
      }
    else if(delta.y <= delta.z)
    {
      // Push back on y
      obj1Pos.y += (box1.min.y < box2.min.y) ? -delta.y : delta.y;
    }
    else
    {
      // Push back on z
      obj1Pos.z += (box1.min.z < box2.min.z) ? -delta.z : delta.z;
    }
    moving.setPPosition(obj1Pos);
    return true;
  }
  return false;
}
static void AddContactPoint( TCFixedVector< CJL_CollPointInfo, MAX_CONTACTS_PER_BOX_PAIR >& vecCollPointInfo,
 							 Vector3& rvNormal,
							 Scalar fPenetrationDepth,
							 CJL_Shape_Box& rBox0,
							 CJL_Shape_Box& rBox1,
							 CJL_CollisionFunctor& rColFunctor )
/*
static void AddContactPoint( Vector3& rvNormal, Scalar fPenetrationDepth,
												CJL_Shape_Box& rBox0,
												CJL_Shape_Box& rBox1,
												CJL_CollisionFunctor& rColFunctor )*/
{
	CJL_ContactInfo contact;

	contact.pBody0 = &rBox0;
	contact.pBody1 = &rBox1;

	// same normal and penetration depths are applied to contact points
	contact.vNormal = rvNormal;
	contact.fPenetrationDepth = fPenetrationDepth;

	///// check box edges against box
	float fFraction = 1.0f;
	Vector3 vEnd = Vector3(0,0,0);

	BSPTreeForBox bsp_tree;

	// transform edges to the local space of the box
	bool b0, b1;
	Vector3 vWorldStart, vWorldGoal, vLocalStart, vLocalGoal;
	Vector3 vHalfLength;
	Matrix34 actor_world_pose;
	Matrix34 box_local_pose;
	AABB3 aabb;
	int i, j;
	CJL_Shape_Box *pBox[2];
	pBox[0] = &rBox0;
	pBox[1] = &rBox1;

	TCFixedVector< Vector3, MAX_CONTACTS_PER_BOX_PAIR > vecPts;

	for( i=0; i<2; i++ )
	{
		// check the edges of box[(i+1)%2] against box[i] (swap boxes and do this for each other)

		vHalfLength = pBox[i]->GetSideLength() * 0.5f;
///		bsptree.SetAABB( vHalfLength );
		aabb.vMin = -vHalfLength;
		aabb.vMax =  vHalfLength;

		Vector3 vSideLength = pBox[i]->GetSideLength();
		bsp_tree.SetSize( vSideLength.x, vSideLength.y, vSideLength.z );


		for( j=0; j<12; j+=2 )
		{
			pBox[(i+1)%2]->GetWorldEdge( j, vWorldStart, vWorldGoal );

			// transform from world space to 'pBox[i]' space
			pBox[i]->GetWorldPose().InvTransform( vLocalStart, vWorldStart );
			pBox[i]->GetWorldPose().InvTransform( vLocalGoal,  vWorldGoal );

			b0 = aabb.IsPointInside( vLocalStart );
			b1 = aabb.IsPointInside( vLocalGoal );

			if( b0 && b1 )
				continue;	// the entire line segment is inside the box[i]

			if( !b0 )
			{
				fFraction = 1.0f;
				bsp_tree.ClipTrace( vEnd, fFraction, vLocalStart, vLocalGoal, 0 );
				if( fFraction < 1.0f )
				{
					// found collision
					if( fFraction < SCALAR_TINY )
					{
						fFraction = 0;
						vEnd = vLocalStart;
					}
					else if( 1 - SCALAR_TINY < fFraction )
					{
						fFraction = 1.0f;
						vEnd = vLocalGoal;
					}
					// transform contact point from the local space of pBox[i] to the world space
					pBox[i]->GetWorldPose().Transform( contact.vContactPoint, vEnd );
					
					// transform contact normal (orientation only)
//					contact.vNormal = pBox[i]->GetWorldOrient() * tr.plane.normal;
//					contact.fPenetrationDepth = fPenetrationDepth;

					if( vecPts.size() < MAX_CONTACTS_PER_BOX_PAIR )
						vecPts.push_back( contact.vContactPoint );
				}
			}
			if( !b1 )
			{
				fFraction = 1.0f;
				bsp_tree.ClipTrace( vEnd, fFraction, vLocalGoal, vLocalStart, 0 );
				if( fFraction < 1.0f )
				{
					// found collision
					if( fFraction < SCALAR_TINY )
					{
						fFraction = 0;
						vEnd = vLocalStart;
					}
					else if( 1 - SCALAR_TINY < fFraction )
					{
						fFraction = 1.0f;
						vEnd = vLocalGoal;
					}
					// transform contact point from the local space of pBox[i] to the world space
					pBox[i]->GetWorldPose().Transform( contact.vContactPoint, vEnd );
					
					if( vecPts.size() < MAX_CONTACTS_PER_BOX_PAIR )
						vecPts.push_back( contact.vContactPoint );
				}
			}
			
		}
	}

	CJL_PhysicsActor *pActor0 = rBox0.GetPhysicsActor();
	CJL_PhysicsActor *pActor1 = rBox1.GetPhysicsActor();
//	const Vector3& vOldPos0 = pActor0 ? pActor0->GetOldPosition() : Vector3(0,0,0);
//	const Vector3& vOldPos1 = pActor1 ? pActor1->GetOldPosition() : Vector3(0,0,0);
	const Vector3& vNewActorPos0 = pActor0 ? pActor0->GetPosition() : Vector3(0,0,0);
	const Vector3& vNewActorPos1 = pActor1 ? pActor1->GetPosition() : Vector3(0,0,0);

	const Vector3& vOldPos0 = pActor0 ? rBox0.GetOldWorldPose().vPosition : Vector3(0,0,0);
	const Vector3& vOldPos1 = pActor1 ? rBox1.GetOldWorldPose().vPosition : Vector3(0,0,0);
	const Vector3& vNewPos0 = pActor0 ? rBox0.GetWorldPose().vPosition : Vector3(0,0,0);
	const Vector3& vNewPos1 = pActor1 ? rBox1.GetWorldPose().vPosition : Vector3(0,0,0);

	const Vector3 vBodyDelta = (vNewPos0 - vOldPos0) - (vNewPos1 - vOldPos1);
	const Scalar fBodyDeltaLen = Vec3Dot( vBodyDelta, rvNormal );
	Scalar fOldDepth = fPenetrationDepth + fBodyDeltaLen;

	// if oldDepth > 0 then reduce it so that the penetration code will
	// result in a torque???
	if( 0 < fOldDepth )
		fOldDepth *= 0.8f;


#ifndef USE_COMBINED_COLLISION_POINTS_INFO


	contact.InitialPenetration = fOldDepth;
	contact.pBody0 = (CJL_ShapeBase *)&rBox0;
	contact.pBody1 = (CJL_ShapeBase *)&rBox1;

	int num_pnts = vecPts.size();
	for( i=0; i<num_pnts; i++ )
	{
		contact.vContactPoint = vecPts[i];
//		contact.vR0 = vecPts[i] - vNewPos0;
//		contact.vR1 = vecPts[i] - vNewPos1;
		contact.vR0 = vecPts[i] - vNewActorPos0;
		contact.vR1 = vecPts[i] - vNewActorPos1;

		rColFunctor.AddTemporaryContact( contact );
	}

#else

//	TCFixedVector< CJL_CollPointInfo, MAX_CONTACTS_PER_BOX_PAIR > vecCollPointInfo;
	int num_pnts = vecPts.size();
	for( i=0; i<num_pnts; i++ )
	{
		vecCollPointInfo.push_back( CJL_CollPointInfo( vecPts[i] - vNewActorPos0,
			                                           vecPts[i] - vNewActorPos1,
													   fOldDepth ) );

		// store contact position
		vecCollPointInfo.back().vContactPosition = vecPts[i];
	}

///	rColFunctor.AddTemporaryContacts( &rBox0,
///		                              &rBox1,
///									  rvNormal,
///									  &vecCollPointInfo[0],
///									  vecCollPointInfo.size() );


#endif

/*	rColFunctor.AddTemporaryContacts( (CJL_ShapeBase *)&rBox0,
		                              (CJL_ShapeBase *)&rBox1,
									  rvNormal,
									  &vecPts[0],
									  vecPts.size(),
									  fOldDepth );*/
}
Exemple #29
0
/// Transforms the box and computes a new AABB.  This always results in an
/// AABB that is at least as large as the original.
/// \param box Specifies the box to be transformed.
/// \param m Specifies the transformation to be performed.
void    AABB3::setToTransformedBox(const AABB3 &box, const Matrix4x3 &m) {

	// If we're empty, then bail

	if (box.isEmpty()) {
		empty();
		return;
	}

	// Start with the translation portion

	min = max = m.getTranslation();

	// Examine each of the 9 matrix elements
	// and compute the new AABB

	if (m.m11 > 0.0f) {
		min.x += m.m11 * box.min.x; max.x += m.m11 * box.max.x;
	} else {
		min.x += m.m11 * box.max.x; max.x += m.m11 * box.min.x;
	}

	if (m.m12 > 0.0f) {
		min.y += m.m12 * box.min.x; max.y += m.m12 * box.max.x;
	} else {
		min.y += m.m12 * box.max.x; max.y += m.m12 * box.min.x;
	}

	if (m.m13 > 0.0f) {
		min.z += m.m13 * box.min.x; max.z += m.m13 * box.max.x;
	} else {
		min.z += m.m13 * box.max.x; max.z += m.m13 * box.min.x;
	}

	if (m.m21 > 0.0f) {
		min.x += m.m21 * box.min.y; max.x += m.m21 * box.max.y;
	} else {
		min.x += m.m21 * box.max.y; max.x += m.m21 * box.min.y;
	}

	if (m.m22 > 0.0f) {
		min.y += m.m22 * box.min.y; max.y += m.m22 * box.max.y;
	} else {
		min.y += m.m22 * box.max.y; max.y += m.m22 * box.min.y;
	}

	if (m.m23 > 0.0f) {
		min.z += m.m23 * box.min.y; max.z += m.m23 * box.max.y;
	} else {
		min.z += m.m23 * box.max.y; max.z += m.m23 * box.min.y;
	}

	if (m.m31 > 0.0f) {
		min.x += m.m31 * box.min.z; max.x += m.m31 * box.max.z;
	} else {
		min.x += m.m31 * box.max.z; max.x += m.m31 * box.min.z;
	}

	if (m.m32 > 0.0f) {
		min.y += m.m32 * box.min.z; max.y += m.m32 * box.max.z;
	} else {
		min.y += m.m32 * box.max.z; max.y += m.m32 * box.min.z;
	}

	if (m.m33 > 0.0f) {
		min.z += m.m33 * box.min.z; max.z += m.m33 * box.max.z;
	} else {
		min.z += m.m33 * box.max.z; max.z += m.m33 * box.min.z;
	}
}