//.logicking >> void StaticShape::updatePhysics() { SAFE_DELETE(mPhysicsRep); if ( PHYSICSMGR) { mShapeInstance->animate(); // Get the interior collision geometry. ConcretePolyList polylist; if (buildPolyList(PLC_Collision, &polylist, getWorldBox(), getWorldSphere())) { polylist.triangulate(); PhysicsCollision *colShape = PHYSICSMGR->createCollision(); colShape->addTriangleMesh( polylist.mVertexList.address(), polylist.mVertexList.size(), polylist.mIndexList.address(), polylist.mIndexList.size() / 3, MatrixF::Identity ); PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" ); mPhysicsRep = PHYSICSMGR->createBody(); //.hack - set kinematic flag to prevent crash on deleting static shape in character sweep(deleting Doors) mPhysicsRep->init( colShape, 0, PhysicsBody::BF_KINEMATIC, this, world ); } if (isServerObject()) setMaskBits(PhysicsMask); } }
void ForestCell::buildPhysicsRep( Forest *forest ) { AssertFatal( isLeaf(), "ForestCell::buildPhysicsRep() - This shouldn't be called on non-leaf cells!" ); bool isServer = forest->isServerObject(); // Already has a PhysicsBody, if it needed to be rebuilt it would // already be null. if ( mPhysicsRep[ isServer ] ) return; if ( !PHYSICSMGR ) return; PhysicsCollision *colShape = NULL; // If we can steal the collision shape from the server-side cell // then do so as it saves us alot of cpu time and memory. if ( mPhysicsRep[ 1 ] ) { colShape = mPhysicsRep[ 1 ]->getColShape(); } else { // We must pass a sphere to buildPolyList but it is not used. const static SphereF dummySphere( Point3F::Zero, 0 ); // Step thru them and build collision data. ForestItemVector::iterator itemItr = mItems.begin(); ConcretePolyList polyList; for ( ; itemItr != mItems.end(); itemItr++ ) { const ForestItem &item = *itemItr; const ForestItemData *itemData = item.getData(); // If not collidable don't need to build anything. if ( !itemData->mCollidable ) continue; // TODO: When we add breakable tree support this is where // we would need to store their collision data seperately. item.buildPolyList( &polyList, item.getWorldBox(), dummySphere ); // TODO: Need to support multiple collision shapes // for really big forests at some point in the future. } if ( !polyList.isEmpty() ) { colShape = PHYSICSMGR->createCollision(); if ( !colShape->addTriangleMesh( polyList.mVertexList.address(), polyList.mVertexList.size(), polyList.mIndexList.address(), polyList.mIndexList.size() / 3, MatrixF::Identity ) ) { SAFE_DELETE( colShape ); } } } // We might not have any trees. if ( !colShape ) return; PhysicsWorld *world = PHYSICSMGR->getWorld( isServer ? "server" : "client" ); mPhysicsRep[ isServer ] = PHYSICSMGR->createBody(); mPhysicsRep[ isServer ]->init( colShape, 0, 0, forest, world ); }
PhysicsCollision* CollisionComponent::buildColShapes() { PROFILE_SCOPE(CollisionComponent_buildColShapes); PhysicsCollision *colShape = NULL; U32 surfaceKey = 0; TSShape* shape = mOwnerRenderInterface->getShape(); if (mCollisionType == VisibleMesh) { // Here we build triangle collision meshes from the // visible detail levels. // A negative subshape on the detail means we don't have geometry. const TSShape::Detail &detail = shape->details[0]; if (detail.subShapeNum < 0) return NULL; // We don't try to optimize the triangles we're given // and assume the art was created properly for collision. ConcretePolyList polyList; polyList.setTransform(&MatrixF::Identity, mOwner->getScale()); // Create the collision meshes. S32 start = shape->subShapeFirstObject[detail.subShapeNum]; S32 end = start + shape->subShapeNumObjects[detail.subShapeNum]; for (S32 o = start; o < end; o++) { const TSShape::Object &object = shape->objects[o]; if (detail.objectDetailNum >= object.numMeshes) continue; // No mesh or no verts.... nothing to do. TSMesh *mesh = shape->meshes[object.startMeshIndex + detail.objectDetailNum]; if (!mesh || mesh->mNumVerts == 0) continue; // Gather the mesh triangles. polyList.clear(); mesh->buildPolyList(0, &polyList, surfaceKey, NULL); // Create the collision shape if we haven't already. if (!colShape) colShape = PHYSICSMGR->createCollision(); // Get the object space mesh transform. MatrixF localXfm; shape->getNodeWorldTransform(object.nodeIndex, &localXfm); colShape->addTriangleMesh(polyList.mVertexList.address(), polyList.mVertexList.size(), polyList.mIndexList.address(), polyList.mIndexList.size() / 3, localXfm); } // Return what we built... if anything. return colShape; } else if (mCollisionType == CollisionMesh) { // Scan out the collision hulls... // // TODO: We need to support LOS collision for physics. // for (U32 i = 0; i < shape->details.size(); i++) { const TSShape::Detail &detail = shape->details[i]; const String &name = shape->names[detail.nameIndex]; // Is this a valid collision detail. if (!dStrStartsWith(name, colisionMeshPrefix) || detail.subShapeNum < 0) continue; // Now go thru the meshes for this detail. S32 start = shape->subShapeFirstObject[detail.subShapeNum]; S32 end = start + shape->subShapeNumObjects[detail.subShapeNum]; if (start >= end) continue; for (S32 o = start; o < end; o++) { const TSShape::Object &object = shape->objects[o]; const String &meshName = shape->names[object.nameIndex]; if (object.numMeshes <= detail.objectDetailNum) continue; // No mesh, a flat bounds, or no verts.... nothing to do. TSMesh *mesh = shape->meshes[object.startMeshIndex + detail.objectDetailNum]; if (!mesh || mesh->getBounds().isEmpty() || mesh->mNumVerts == 0) continue; // We need the default mesh transform. MatrixF localXfm; shape->getNodeWorldTransform(object.nodeIndex, &localXfm); // We have some sort of collision shape... so allocate it. if (!colShape) colShape = PHYSICSMGR->createCollision(); // Any other mesh name we assume as a generic convex hull. // // Collect the verts using the vertex polylist which will // filter out duplicates. This is importaint as the convex // generators can sometimes fail with duplicate verts. // VertexPolyList polyList; MatrixF meshMat(localXfm); Point3F t = meshMat.getPosition(); t.convolve(mOwner->getScale()); meshMat.setPosition(t); polyList.setTransform(&MatrixF::Identity, mOwner->getScale()); mesh->buildPolyList(0, &polyList, surfaceKey, NULL); colShape->addConvex(polyList.getVertexList().address(), polyList.getVertexList().size(), meshMat); } // objects } // details } return colShape; }