// Make a visible object that can be viewed by users for debugging purposes.
plDrawableSpans* plPXPhysical::CreateProxy(hsGMaterial* mat, hsTArray<uint32_t>& idx, plDrawableSpans* addTo)
{
    plDrawableSpans* myDraw = addTo;
    hsMatrix44 l2w, unused;
    GetTransform(l2w, unused);
    
    bool blended = ((mat->GetLayer(0)->GetBlendFlags() & hsGMatState::kBlendMask));

    NxShape* shape = fActor->getShapes()[0];

    NxTriangleMeshShape* trimeshShape = shape->isTriangleMesh();
    if (trimeshShape)
    {
        NxTriangleMeshDesc desc;
        trimeshShape->getTriangleMesh().saveToDesc(desc);

        hsTArray<hsPoint3>  pos;
        hsTArray<uint16_t>    tris;

        const int kMaxTris = 10000;
        const int kMaxVerts = 32000;
        if ((desc.numVertices < kMaxVerts) && (desc.numTriangles < kMaxTris))
        {
            pos.SetCount(desc.numVertices);
            tris.SetCount(desc.numTriangles * 3);

            for (int i = 0; i < desc.numVertices; i++ )
                pos[i] = GetTrimeshVert(desc, i);

            for (int i = 0; i < desc.numTriangles; i++)
                GetTrimeshTri(desc, i, &tris[i*3]);

            myDraw = plDrawableGenerator::GenerateDrawable(pos.GetCount(), 
                                            pos.AcquireArray(),
                                            nil,    // normals - def to avg (smooth) norm
                                            nil,    // uvws
                                            0,      // uvws per vertex
                                            nil,    // colors - def to white
                                            true,   // do a quick fake shade
                                            nil,    // optional color modulation
                                            tris.GetCount(),
                                            tris.AcquireArray(),
                                            mat,
                                            l2w,
                                            blended,
                                            &idx,
                                            myDraw);
        }
        else
        {
            int curTri = 0;
            int trisToDo = desc.numTriangles;
            while (trisToDo > 0)
            {
                int trisThisRound = trisToDo > kMaxTris ? kMaxTris : trisToDo;
                
                trisToDo -= trisThisRound;

                pos.SetCount(trisThisRound * 3);
                tris.SetCount(trisThisRound * 3);

                for (int i = 0; i < trisThisRound; i++)
                {
                    GetTrimeshTri(desc, curTri, &tris[i*3]);
                    pos[i*3 + 0] = GetTrimeshVert(desc, tris[i*3+0]);
                    pos[i*3 + 1] = GetTrimeshVert(desc, tris[i*3+1]);
                    pos[i*3 + 2] = GetTrimeshVert(desc, tris[i*3+2]);

                    curTri++;
                }
                myDraw = plDrawableGenerator::GenerateDrawable(pos.GetCount(), 
                                                pos.AcquireArray(),
                                                nil,    // normals - def to avg (smooth) norm
                                                nil,    // uvws
                                                0,      // uvws per vertex
                                                nil,    // colors - def to white
                                                true,   // do a quick fake shade
                                                nil,    // optional color modulation
                                                tris.GetCount(),
                                                tris.AcquireArray(),
                                                mat,
                                                l2w,
                                                blended,
                                                &idx,
                                                myDraw);
            }
        }
    }

    NxConvexShape* convexShape = shape->isConvexMesh();
    if (convexShape)
    {
        NxConvexMeshDesc desc;
        convexShape->getConvexMesh().saveToDesc(desc);

        hsTArray<hsPoint3>  pos;
        hsTArray<uint16_t>    tris;

        pos.SetCount(desc.numVertices);
        tris.SetCount(desc.numTriangles * 3);

        for (int i = 0; i < desc.numVertices; i++ )
            pos[i] = GetConvexVert(desc, i);

        for (int i = 0; i < desc.numTriangles; i++)
            GetConvexTri(desc, i, &tris[i*3]);

        myDraw = plDrawableGenerator::GenerateDrawable(pos.GetCount(), 
            pos.AcquireArray(),
            nil,    // normals - def to avg (smooth) norm
            nil,    // uvws
            0,      // uvws per vertex
            nil,    // colors - def to white
            true,   // do a quick fake shade
            nil,    // optional color modulation
            tris.GetCount(),
            tris.AcquireArray(),
            mat,
            l2w,
            blended,
            &idx,
            myDraw);
    }

    NxSphereShape* sphere = shape->isSphere();
    if (sphere)
    {
        float radius = sphere->getRadius();
        hsPoint3 offset = plPXConvert::Point(sphere->getLocalPosition());
        myDraw = plDrawableGenerator::GenerateSphericalDrawable(offset, radius,
            mat, l2w, blended,
            nil, &idx, myDraw);
    }

    NxBoxShape* box = shape->isBox();
    if (box)
    {
        hsPoint3 dim = plPXConvert::Point(box->getDimensions());
        myDraw = plDrawableGenerator::GenerateBoxDrawable(dim.fX*2.f, dim.fY*2.f, dim.fZ*2.f,
            mat,l2w,blended,
            nil,&idx,myDraw);
    }
    return myDraw;
}
Exemple #2
0
int pWorld::overlapOBBShapes(const VxBbox& worldBounds, CK3dEntity*shapeReference, pShapesType shapeType,CKGroup *shapes,int activeGroups/* =0xffffffff */, const pGroupsMask* groupsMask/* =NULL */, bool accurateCollision/* =false */)
{

	int result=0;

	NxBox box;

	if (shapeReference)
	{

		NxShape *shape  = getShapeByEntityID(shapeReference->GetID());
		if (shape)
		{
			//shape->checkOverlapAABB()

			NxBoxShape*boxShape  = static_cast<NxBoxShape*>(shape->isBox());
			if (boxShape)
			{
				boxShape->getWorldOBB(box);
			}
		}

	}else{

		box.center = getFrom(worldBounds.GetCenter());
		box.extents = getFrom(worldBounds.GetSize());
	}

	int total = 0;
	if (shapeType & ST_Dynamic )
	{
		total+=getScene()->getNbDynamicShapes();
	}

	if (shapeType & ST_Static)
	{
		total+=getScene()->getNbStaticShapes();
	}

	NxShape** _shapes = (NxShape**)NxAlloca(total*sizeof(NxShape*));
	for (NxU32 i = 0; i < total; i++)  _shapes[i] = NULL;



	NxGroupsMask mask;
	if (groupsMask)
	{
		mask.bits0 = groupsMask->bits0;
		mask.bits1 = groupsMask->bits1;
		mask.bits2 = groupsMask->bits2;
		mask.bits3 = groupsMask->bits3;
	}else{

		mask.bits0 = 0;
		mask.bits1 = 0;
		mask.bits2 = 0;
		mask.bits3 = 0;

	}




	result = getScene()->overlapOBBShapes(box,(NxShapesType)shapeType,total,_shapes,NULL,activeGroups,&mask,accurateCollision);

	if (_shapes && shapes )
	{
		for (int i  = 0 ; i < result ; i++)
		{
			NxShape *s = _shapes[i];
			if (s)
			{
				const char* name =s->getName();
				pSubMeshInfo *sInfo  = static_cast<pSubMeshInfo*>(s->userData);
				if (sInfo->entID)
				{
					CKObject *obj = (CKObject*)GetPMan()->m_Context->GetObject(sInfo->entID);
					if (obj)
					{

						shapes->AddObject((CKBeObject*)obj);
					}
				}
			}
		}
	}

	int op=2;




	return result;

}
void plPXPhysical::Write(hsStream* stream, hsResMgr* mgr)
{
    plPhysical::Write(stream, mgr);

    hsAssert(fActor, "nil actor");  
    hsAssert(fActor->getNbShapes() == 1, "Can only write actors with one shape. Writing first only.");
    NxShape* shape = fActor->getShapes()[0];

    NxMaterialIndex matIdx = shape->getMaterial();
    NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey);
    NxMaterial* mat = scene->getMaterialFromIndex(matIdx);
    float friction = mat->getStaticFriction();
    float restitution = mat->getRestitution();

    stream->WriteLEScalar(fActor->getMass());
    stream->WriteLEScalar(friction);
    stream->WriteLEScalar(restitution);
    stream->WriteByte(fBoundsType);
    stream->WriteByte(fGroup);
    stream->WriteLE32(fReportsOn);
    stream->WriteLE16(fLOSDBs);
    mgr->WriteKey(stream, fObjectKey);
    mgr->WriteKey(stream, fSceneNode);
    mgr->WriteKey(stream, fWorldKey);
    mgr->WriteKey(stream, fSndGroup);

    hsPoint3 pos;
    hsQuat rot;
    IGetPositionSim(pos);
    IGetRotationSim(rot);
    pos.Write(stream);
    rot.Write(stream);

    fProps.Write(stream);

    if (fBoundsType == plSimDefs::kSphereBounds)
    {
        const NxSphereShape* sphereShape = shape->isSphere();
        stream->WriteLEScalar(sphereShape->getRadius());
        hsPoint3 localPos = plPXConvert::Point(sphereShape->getLocalPosition());
        localPos.Write(stream);
    }
    else if (fBoundsType == plSimDefs::kBoxBounds)
    {
        const NxBoxShape* boxShape = shape->isBox();
        hsPoint3 dim = plPXConvert::Point(boxShape->getDimensions());
        dim.Write(stream);
        hsPoint3 localPos = plPXConvert::Point(boxShape->getLocalPosition());
        localPos.Write(stream);
    }
    else
    {
        if (fBoundsType == plSimDefs::kHullBounds)
            hsAssert(shape->isConvexMesh(), "Hull shape isn't a convex mesh");
        else
            hsAssert(shape->isTriangleMesh(), "Exact shape isn't a trimesh");

        // We hide the stream we used to create this mesh away in the shape user data.
        // Pull it out and write it to disk.
        hsVectorStream* vecStream = (hsVectorStream*)shape->userData;
        stream->Write(vecStream->GetEOF(), vecStream->GetData());
        delete vecStream;
    }
}
void CPhysicsActor::AddVisualization()
{
	// get the CPhysicsObject's name
	PHYSICSUSERDATA* userData = (PHYSICSUSERDATA*)m_Actor->userData;
	
	if( userData == NULL )
		return;

	CPhysicsObject* physObj = userData->physObj;
	IHashString* cpoName = physObj->GetParentName();

	// Loop through shapes in the actor
	unsigned int numShapes = m_Actor->getNbShapes();
	NxShape*const* shapes = m_Actor->getShapes();
   	NxShape* shape;

	// we need to unscale before feeding it to the shape objects since they
	// get the scale from the parent
	Vec3 invScale;
	invScale.x = 1.0f / m_CurrentScale.x;
	invScale.y = 1.0f / m_CurrentScale.y;
	invScale.z = 1.0f / m_CurrentScale.z;

	// Add visualizations for each shape
	while( numShapes-- )
	{
		shape = shapes[numShapes];
   		
		// Add shape to be rendered
		if( shape->isBox() )
		{
			NxBoxShape* boxShape = (NxBoxShape*)shape;

			Matrix4x4 localTransform;
			localTransform.SetIdentity();

			float tempRot[9];
			boxShape->getLocalOrientation().getColumnMajor( tempRot );
			localTransform.SetFrom3x3( tempRot );

			NxVec3 tempPos = boxShape->getLocalPosition();
			tempPos.x *= invScale.x;
			tempPos.y *= invScale.y;
			tempPos.z *= invScale.z;
			localTransform.SetTranslation( Vec3(tempPos.x, tempPos.y, tempPos.z) );

			NxVec3 boxDimensions = boxShape->getDimensions();
			float halfXDimension = boxDimensions.x * invScale.x;
			float halfYDimension = boxDimensions.y * invScale.y;
			float halfZDimension = boxDimensions.z * invScale.z;

			// Add a debug render object to visualize the object
			ADDOBJECTORIENTEDBOXPARAMS oobbParams;
			oobbParams.name = cpoName;
			oobbParams.min = Vec3( -halfXDimension, -halfYDimension, -halfZDimension );
			oobbParams.max = Vec3( halfXDimension, halfYDimension, halfZDimension );
			oobbParams.localTransform = localTransform;
			static DWORD msgHash_AddObjectOrientedBox = CHashString(_T("AddObjectOrientedBox")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_AddObjectOrientedBox, sizeof(ADDOBJECTORIENTEDBOXPARAMS), &oobbParams );
		}
		if( shape->isSphere() )
		{
			NxSphereShape* sphereShape = (NxSphereShape*)shape;

			float radius = sphereShape->getRadius();

			// Add a debug render object to visualize the object
			ADDSPHEREPARAMS sphereParams;
			sphereParams.name = cpoName;
			sphereParams.radius = radius * invScale.x;
			sphereParams.red = 0;
			sphereParams.green = 255; // making the sphere green to distinguish it from AABBs
			sphereParams.blue = 0;
			static DWORD msgHash_AddSphere = CHashString(_T("AddSphere")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_AddSphere, sizeof(ADDSPHEREPARAMS), &sphereParams );
		}
		if( shape->isCapsule() )
		{
			// Draw as a red box for now
			NxCapsuleShape* capsuleShape = (NxCapsuleShape*)shape;

			Matrix4x4 localTransform;
			localTransform.SetIdentity();

			float tempRot[9];
			capsuleShape->getLocalOrientation().getColumnMajor( tempRot );
			localTransform.SetFrom3x3( tempRot );

			NxVec3 tempPos = capsuleShape->getLocalPosition();
			tempPos.x *= invScale.x;
			tempPos.y *= invScale.y;
			tempPos.z *= invScale.z;
			localTransform.SetTranslation( Vec3(tempPos.x, tempPos.y, tempPos.z) );

			float halfXDimension = capsuleShape->getRadius();
			float halfYDimension = capsuleShape->getHeight() - capsuleShape->getRadius();
			float halfZDimension = capsuleShape->getRadius();

			// Add a debug render object to visualize the object
			ADDOBJECTORIENTEDBOXPARAMS oobbParams;
			oobbParams.name = cpoName;
			oobbParams.min = Vec3( -halfXDimension, -halfYDimension, -halfZDimension );
			oobbParams.max = Vec3( halfXDimension, halfYDimension, halfZDimension );
			oobbParams.localTransform = localTransform;
			oobbParams.red = 255;
			oobbParams.green = 0;
			oobbParams.blue = 0;
			static DWORD msgHash_AddObjectOrientedBox = CHashString(_T("AddObjectOrientedBox")).GetUniqueID();
			m_ToolBox->SendMessage(msgHash_AddObjectOrientedBox, sizeof(ADDOBJECTORIENTEDBOXPARAMS), &oobbParams );
		}
		if( shape->isConvexMesh() )
		{
			// not yet implemented
		}
	}
}