// 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 CPhysicsActor::SetScale( Vec3& scale ) { // do not scale if scale is currently 1:1 or if the scale // has not changed if( scale.x == 1 && scale.y == 1 && scale.z == 1 || scale == m_CurrentScale ) { return; } // make sure the scale is valid // No 0 scales or negative scales! if( scale.x <= 0 && scale.y <= 0 && scale.z <= 0 ) { m_ToolBox->Log( LOGWARNING, _T("CPhysicsActor::SetScale() Invalid scale!\n" ) ); return; } NxVec3 newScale( scale.x, scale.y, scale.z ); // unscale the old scale // Loop through shapes in the actor unsigned int numShapes = m_Actor->getNbShapes(); NxShape*const* shapes = m_Actor->getShapes(); NxShape* currentShape; NxVec3 shapeLocalPosition; // for each shape type scale its dimensions while( numShapes-- >= 1 ) { currentShape = shapes[numShapes]; // get the shape's type NxShapeType type = currentShape->getType(); switch( type ) { case NX_SHAPE_BOX: { // do something NxBoxShape* shape = (NxBoxShape*)currentShape; // rescale box dimensions NxVec3 dimensions = shape->getDimensions(); Vec3 newDimensions(dimensions.x, dimensions.y, dimensions.z); RescaleVector( newDimensions, scale ); // set the shape data with the newly rescaled dimensions shape->setDimensions( NxVec3(newDimensions.x, newDimensions.y, newDimensions.z) ); break; } case NX_SHAPE_SPHERE: { // do something NxSphereShape* shape = (NxSphereShape*)currentShape; float radius = shape->getRadius(); radius /= m_CurrentScale.x; radius *= newScale.x; // set the shape data with the newly rescaled dimensions shape->setRadius( radius ); break; } case NX_SHAPE_CAPSULE: { // do something NxCapsuleShape* shape; shape = (NxCapsuleShape*)currentShape; // rescale radius float radius = shape->getRadius(); radius /= m_CurrentScale.x; radius *= newScale.x; // rescale height float height = shape->getHeight(); height /= m_CurrentScale.z; height *= newScale.z; // set the shape data with the newly rescaled dimensions shape->setRadius( radius ); shape->setHeight( height ); break; } default: m_ToolBox->Log( LOGWARNING, _T("CPhysicsObject::SetScale() Attempting to scale on unsupported shape!\n" ) ); return; } // get the shape's local position and rescale it shapeLocalPosition = currentShape->getLocalPosition(); Vec3 newShapeLocalPosition(shapeLocalPosition.x, shapeLocalPosition.y, shapeLocalPosition.z); RescaleVector( newShapeLocalPosition, scale ); currentShape->setLocalPosition( NxVec3(newShapeLocalPosition.x, newShapeLocalPosition.y, newShapeLocalPosition.z) ); } // Set the current scale to the new scale so we can unscale the scale m_CurrentScale = scale; }
void drawActor( NxActor *inActor ) { GFXDrawUtil *drawer = GFX->getDrawUtil(); //drawer->setZRead( false ); // Determine alpha we render shapes with. const U8 enabledAlpha = 255; const U8 disabledAlpha = 100; U8 renderAlpha = inActor->readActorFlag( NX_AF_DISABLE_COLLISION ) ? disabledAlpha : enabledAlpha; // Determine color we render actors and shapes with. ColorI actorColor( 0, 0, 255, 200 ); ColorI shapeColor = ( inActor->isSleeping() ? ColorI( 0, 0, 255, renderAlpha ) : ColorI( 255, 0, 255, renderAlpha ) ); MatrixF actorMat(true); inActor->getGlobalPose().getRowMajor44( actorMat ); GFXStateBlockDesc desc; desc.setBlend( true ); desc.setZReadWrite( true, false ); desc.setCullMode( GFXCullNone ); // Draw an xfm gizmo for the actor's globalPose... //drawer->drawTransform( desc, actorMat, Point3F::One, actorColor ); // Loop through and render all the actor's shapes.... NxShape *const*pShapeArray = inActor->getShapes(); U32 numShapes = inActor->getNbShapes(); for ( U32 i = 0; i < numShapes; i++ ) { const NxShape *shape = pShapeArray[i]; Point3F shapePos = pxCast<Point3F>( shape->getGlobalPosition() ); MatrixF shapeMat(true); shape->getGlobalPose().getRowMajor44(shapeMat); shapeMat.setPosition( Point3F::Zero ); switch ( shape->getType() ) { case NX_SHAPE_SPHERE: { NxSphereShape *sphere = (NxSphereShape*)shape; drawer->drawSphere( desc, sphere->getRadius(), shapePos, shapeColor ); break; } case NX_SHAPE_BOX: { NxBoxShape *box = (NxBoxShape*)shape; Point3F size = pxCast<Point3F>( box->getDimensions() ); drawer->drawCube( desc, size*2, shapePos, shapeColor, &shapeMat ); break; } case NX_SHAPE_CAPSULE: { shapeMat.mul( MatrixF( EulerF( mDegToRad(90.0f), mDegToRad(90.0f), 0 ) ) ); NxCapsuleShape *capsule = (NxCapsuleShape*)shape; drawer->drawCapsule( desc, shapePos, capsule->getRadius(), capsule->getHeight(), shapeColor, &shapeMat ); break; } default: { break; } } } //drawer->clearZDefined(); }
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 } } }
/*********************************************************** Render actors ***********************************************************/ void PhysXEngine::RenderActors() { glEnable(GL_BLEND); glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glLineWidth(2.0f); // Render all the actors in the scene NxU32 nbActors = gScene->getNbActors(); NxActor** actors = gScene->getActors(); while (nbActors--) { NxActor* actor = *actors++; glPushMatrix(); glScalef(1, 0.5f, 1); NxMat34 pose = actor->getShapes()[0]->getGlobalPose(); //glTranslated(pose.t.x, pose.t.y/2. + 0.5, pose.t.z); float glmat[16]; //4x4 column major matrix for OpenGL. pose.M.getColumnMajorStride4(&(glmat[0])); pose.t.get(&(glmat[12])); //clear the elements we don't need: glmat[3] = glmat[7] = glmat[11] = 0.0f; glmat[15] = 1.0f; glMultMatrixf(&(glmat[0])); NxBoxShape* boxshap = actor->getShapes()[0]->isBox(); if(boxshap) { glColor4f(0.0f,0.0f,1.0f, 1.f); NxVec3 boxDim = boxshap->getDimensions(); glScalef(boxDim.x, boxDim.y, boxDim.z); float _sizeX = 1, _sizeY = 1, _sizeZ = 1; glBegin(GL_LINES); glVertex3f(-_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,_sizeZ); glVertex3f(_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,-_sizeZ); glVertex3f(-_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,_sizeY,_sizeZ); glVertex3f(_sizeX,_sizeY,_sizeZ); glVertex3f(-_sizeX,_sizeY,_sizeZ); glVertex3f(-_sizeX,_sizeY,_sizeZ); glVertex3f(-_sizeX,_sizeY,-_sizeZ); glVertex3f(-_sizeX,-_sizeY,-_sizeZ); glVertex3f(-_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,_sizeZ); glVertex3f(_sizeX,_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,_sizeY,_sizeZ); glEnd(); } else { for(int i=1; i<100; ++i) { glColor4f(1.0f,0.0f,0.0f, 1.f); float _sizeX = (float)i, _sizeY = 0, _sizeZ = (float)i; glBegin(GL_LINES); glVertex3f(-_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,_sizeZ); glVertex3f(_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,-_sizeZ); glEnd(); } } glPopMatrix(); } for(unsigned int i=0; i<gManager->getNbControllers(); ++i) { NxController* ctrl = gManager->getController(i); NxExtendedVec3 vec = ctrl->getPosition(); glPushMatrix(); glTranslated(vec.x, vec.y, vec.z); glColor4f(1.0f,1.0f,0.0f, 1.f); float _sizeX = 1, _sizeY = 3, _sizeZ = 1; glBegin(GL_LINES); glVertex3f(-_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,_sizeZ); glVertex3f(_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,-_sizeZ); glVertex3f(-_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,_sizeY,_sizeZ); glVertex3f(_sizeX,_sizeY,_sizeZ); glVertex3f(-_sizeX,_sizeY,_sizeZ); glVertex3f(-_sizeX,_sizeY,_sizeZ); glVertex3f(-_sizeX,_sizeY,-_sizeZ); glVertex3f(-_sizeX,-_sizeY,-_sizeZ); glVertex3f(-_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,-_sizeZ); glVertex3f(_sizeX,_sizeY,-_sizeZ); glVertex3f(_sizeX,-_sizeY,_sizeZ); glVertex3f(_sizeX,_sizeY,_sizeZ); glVertex3f(-_sizeX,-_sizeY,_sizeZ); glVertex3f(-_sizeX,_sizeY,_sizeZ); glEnd(); glPopMatrix(); } glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); }