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; }
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); } } }
// 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; }
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 CPhysicsManager::DrawActor (NxActor* actor, CRenderManager* render) { CPhysicUserData* physicUserData = NULL; physicUserData =(CPhysicUserData*)actor->userData; //Si está petando aquí quiere decir que se ha registrado un objeto físico sin proporcionarle UserData assert(physicUserData); if( !physicUserData->GetPaint()) { return; } NxShape*const* shapes = actor->getShapes(); NxU32 nShapes = actor->getNbShapes(); nShapes = actor->getNbShapes(); while (nShapes--) { switch(shapes[nShapes]->getType()) { case NX_SHAPE_PLANE: { CColor color = physicUserData->GetColor(); float distance = shapes[nShapes]->isPlane()->getPlane().d; NxVec3 normal = shapes[nShapes]->isPlane()->getPlane().normal; Vect3f n(normal.x,normal.y,normal.z); render->DrawPlane(100.f, n, distance,color,40,40); } break; case NX_SHAPE_BOX: { NxF32 m_aux[16]; shapes[nShapes]->getGlobalPose().getColumnMajor44(m_aux); Mat44f m( m_aux[0], m_aux[4], m_aux[8], m_aux[12], m_aux[1], m_aux[5], m_aux[9], m_aux[13], m_aux[2], m_aux[6], m_aux[10], m_aux[14], m_aux[3], m_aux[7], m_aux[11], m_aux[15]); render->SetTransform(m); NxVec3 boxDim = shapes[nShapes]->isBox()->getDimensions(); CColor color = physicUserData->GetColor(); render->DrawCube(Vect3f(boxDim.x*2,boxDim.y*2,boxDim.z*2), color); //render->DrawCube(boxDim.y*2,color); } break; case NX_SHAPE_SPHERE: { NxF32 m_aux[16]; shapes[nShapes]->getGlobalPose().getColumnMajor44(m_aux); Mat44f m( m_aux[0], m_aux[4], m_aux[8], m_aux[12], m_aux[1], m_aux[5], m_aux[9], m_aux[13], m_aux[2], m_aux[6], m_aux[10], m_aux[14], m_aux[3], m_aux[7], m_aux[11], m_aux[15]); render->SetTransform(m); NxReal radius = shapes[nShapes]->isSphere()->getRadius(); CColor color = physicUserData->GetColor(); render->DrawSphere(radius,MAX_ARISTAS,color); } break; case NX_SHAPE_CAPSULE: { NxF32 m_aux[16]; shapes[nShapes]->getGlobalPose().getColumnMajor44(m_aux); Mat44f m( m_aux[0], m_aux[4], m_aux[8], m_aux[12], m_aux[1], m_aux[5], m_aux[9], m_aux[13], m_aux[2], m_aux[6], m_aux[10], m_aux[14], m_aux[3], m_aux[7], m_aux[11], m_aux[15]); Mat44f translation, total; translation.SetIdentity(); render->SetTransform(m); const NxReal & radius = shapes[nShapes]->isCapsule()->getRadius(); const NxReal & height = shapes[nShapes]->isCapsule()->getHeight(); CColor color = physicUserData->GetColor(); translation.Translate(Vect3f(0.f, (height*0.5f), 0.f)); total = m * translation; render->SetTransform(total); render->DrawSphere(radius,MAX_ARISTAS,color); translation.Translate( Vect3f(0.f, -(height*0.5f), 0.f )); total = m * translation; render->SetTransform(total); render->DrawSphere(radius, MAX_ARISTAS, color); } break; case NX_SHAPE_CONVEX: break; case NX_SHAPE_MESH: { NxShape* mesh = shapes[nShapes]; NxTriangleMeshDesc meshDesc; mesh->isTriangleMesh()->getTriangleMesh().saveToDesc(meshDesc); typedef NxVec3 Point; typedef struct _Triangle { NxU32 p0; NxU32 p1; NxU32 p2; } Triangle; NxU32 nbVerts = meshDesc.numVertices; NxU32 nbTriangles = meshDesc.numTriangles; Point* points = (Point *)meshDesc.points; Triangle* triangles = (Triangle *)meshDesc.triangles; CColor color = physicUserData->GetColor(); NxF32 m_aux[16]; mesh->getGlobalPose().getColumnMajor44(m_aux); Mat44f m( m_aux[0], m_aux[4], m_aux[8], m_aux[12], m_aux[1], m_aux[5], m_aux[9], m_aux[13], m_aux[2], m_aux[6], m_aux[10], m_aux[14], m_aux[3], m_aux[7], m_aux[11], m_aux[15]); render->SetTransform(m); Vect3f a,b,c; while(nbTriangles--) { a = Vect3f(points[triangles->p0].x, points[triangles->p0].y,points[triangles->p0].z); b = Vect3f(points[triangles->p1].x, points[triangles->p1].y,points[triangles->p1].z); c = Vect3f(points[triangles->p2].x, points[triangles->p2].y,points[triangles->p2].z); render->DrawLine(a, b, color); render->DrawLine(b, c, color); render->DrawLine(c, a, color); triangles++; } } break; case NX_SHAPE_WHEEL: { //TODO... } break; default: { //TODO... } break; } } }