예제 #1
0
plPXPhysical::~plPXPhysical()
{
    SpamMsg(plSimulationMgr::Log("Destroying physical %s", GetKeyName().c_str()));

    if (fActor)
    {
        // Grab any mesh we may have (they need to be released manually)
        NxConvexMesh* convexMesh = nil;
        NxTriangleMesh* triMesh = nil;
        NxShape* shape = fActor->getShapes()[0];
        if (NxConvexShape* convexShape = shape->isConvexMesh())
            convexMesh = &convexShape->getConvexMesh();
        else if (NxTriangleMeshShape* trimeshShape = shape->isTriangleMesh())
            triMesh = &trimeshShape->getTriangleMesh();

        if (!fActor->isDynamic())
            plPXPhysicalControllerCore::RebuildCache();

        if (fActor->isDynamic() && fActor->readBodyFlag(NX_BF_KINEMATIC))
        {
            if (fGroup == plSimDefs::kGroupDynamic)
                fNumberAnimatedPhysicals--;
            else
                fNumberAnimatedActivators--;
        }

        // Release the actor
        NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey);
        scene->releaseActor(*fActor);
        fActor = nil;

        // Now that the actor is freed, release the mesh
        if (convexMesh)
            plSimulationMgr::GetInstance()->GetSDK()->releaseConvexMesh(*convexMesh);
        if (triMesh)
            plSimulationMgr::GetInstance()->GetSDK()->releaseTriangleMesh(*triMesh);

        // Release the scene, so it can be cleaned up if no one else is using it
        plSimulationMgr::GetInstance()->ReleaseScene(fWorldKey);
    }

    if (fWorldHull)
        delete [] fWorldHull;
    if (fSaveTriangles)
        delete [] fSaveTriangles;

    delete fProxyGen;

    // remove sdl modifier
    plSceneObject* sceneObj = plSceneObject::ConvertNoRef(fObjectKey->ObjectIsLoaded());
    if (sceneObj && fSDLMod)
    {
        sceneObj->RemoveModifier(fSDLMod);
    }
    delete fSDLMod;
}
예제 #2
0
void AddUserDataToShapes(NxActor* actor)
{
    NxU32 i = 0;

	NxShape*const* shapes = actor->getShapes();
	NxU32 nbShapes = actor->getNbShapes();
	while (nbShapes--)
	{
		NxShape* shape = shapes[nbShapes];
        shape->userData = new ShapeUserData;
		ShapeUserData* sud = (ShapeUserData*)(shape->userData);
		sud->id = i++;
		if (shape->getType() == NX_SHAPE_CONVEX)
		{
			sud->mesh = new NxConvexMeshDesc;
			shape->isConvexMesh()->getConvexMesh().saveToDesc(*(NxConvexMeshDesc*)sud->mesh);
		}
		if (shape->getType() == NX_SHAPE_MESH)
		{
			sud->mesh = new NxTriangleMeshDesc;
			shape->isTriangleMesh()->getTriangleMesh().saveToDesc(*(NxTriangleMeshDesc*)sud->mesh);
		}
	}
}
예제 #3
0
// 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;
}
예제 #4
0
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;
    }
}
예제 #5
0
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
		}
	}
}