/*===================================*/ void CFragment::DiscreteInit( void ) { NxVec3 Dimensions[CBreakWall::FragmentType] = { NxVec3( 0.60f , 0.30f , 1.15f ) , NxVec3( 0.25f , 0.15f , 1.65f ) , NxVec3( 0.60f , 0.30f , 1.65f ) }; NxBodyDesc bodyDesc; bodyDesc.setToDefault(); NxActorDesc actorDesc; actorDesc.setToDefault(); NxBoxShapeDesc boxDesc; boxDesc.setToDefault(); boxDesc.skinWidth = 0.0f; actorDesc.density = 1000000.0f; actorDesc.body = &bodyDesc; actorDesc.globalPose.t = NxVec3( m_vPos.x , m_vPos.y , m_vPos.z ); NxMat33 Mat; CRandomize Rand; D3DXVECTOR3 Rot( (float)Rand.GetRandomize( 0.0 , 359.0 ) , (float)Rand.GetRandomize( 0.0 , 359.0 ) , (float)Rand.GetRandomize( 0.0 , 359.0 ) ); CDPConverter::SetRot( &Mat , &Rot ); actorDesc.globalPose.M = Mat; bodyDesc.angularDamping = 0.0f; boxDesc.dimensions = Dimensions[m_Type-1]*m_Scale; if( m_MaterialIndex == -1 ) { // アクターのマテリアルを設定する NxMaterialDesc materialDesc; materialDesc.restitution = 0.4f; materialDesc.dynamicFriction = 3.8f; materialDesc.staticFriction = 3.5f; m_MaterialIndex = m_pPhysX->GetScene()->createMaterial( materialDesc )->getMaterialIndex(); boxDesc.materialIndex = m_MaterialIndex; } else { boxDesc.materialIndex = m_MaterialIndex; } actorDesc.shapes.pushBack( &boxDesc ); m_Actor = m_pPhysX->GetScene()->createActor( actorDesc ); m_Actor->putToSleep(); m_Material = m_lpXFile->GetMaterial(); }
/** * CreateSphere(float r, float xInit, float yInit, float zInit) * @float r: radius of the sphere * @float xInit: Initial Position on X * @float yInit: Initial Position on Y * @float zInit: Initial Position on Z * @return */ void CreateSphere(float r, float xInit, float yInit, float zInit){ NxActorDesc actorDesc; NxBodyDesc bodyDesc; NxSphereShapeDesc sphereDesc; //デフォルト値で初期化 (クリア) actorDesc.setToDefault(); bodyDesc.setToDefault(); sphereDesc.setToDefault(); bodyDesc.angularDamping = 0.5f; //転がり摩擦係数 sphereDesc.radius = r; //球の半径を指定 sphereDesc.userData = (void *)size_t(sphereDesc.radius); actorDesc.shapes.pushBack(&sphereDesc); //球をアクターに追加 actorDesc.body = &bodyDesc; //動的情報を指定 actorDesc.density = 100.0f; //質量密度 (kg/m^3) actorDesc.globalPose.t = NxVec3(xInit, yInit, zInit); //Scene上の位置 //Set userData to NULL if you are not doing anyting with it. NxActor*pActor = pScene->createActor( actorDesc ); pActor->userData = (void *)size_t((int)r); }
void PhysXCapsule::createCapsule(const CapsuleInfo& info) { NxCapsuleShapeDesc capsuleDesc; capsuleDesc.setToDefault(); capsuleDesc.height = info.mHeight; capsuleDesc.radius = info.mRadius; NxMat33 rot0, rot1,rot2; rot0.rotX(info.mLocalPose.x); rot1.rotY(info.mLocalPose.y); rot2.rotZ(info.mLocalPose.z); rot0 = rot0 * rot1 * rot2; capsuleDesc.localPose.M = rot0; NxActorDesc actorDesc; actorDesc.setToDefault(); actorDesc.shapes.pushBack(&capsuleDesc); actorDesc.density = 1.0; actorDesc.globalPose.t = info.mGlobalPose; mCapsule = mScene->createActor(actorDesc); mCapsule->userData = (void*) &mInvisible; }
pRigidBody*pFactory::createBox(CK3dEntity *referenceObject,CK3dEntity *worldReferenceObject,pObjectDescr*descr,int creationFlags) { pWorld *world=getManager()->getWorld(worldReferenceObject,referenceObject); pRigidBody*result = world->getBody(referenceObject); if(result) { result->destroy(); delete result; result = NULL; } // we create our final body in the given world : result = createBody(referenceObject,worldReferenceObject); if (result) { result->setWorld(world); using namespace vtTools::AttributeTools; result->setFlags(descr->flags); result->setHullType(descr->hullType); result->setDataFlags(0x000); result->checkDataFlags(); if (result->getSkinWidth()==-1.0f) { result->setSkinWidth(0.01f); } VxMatrix v_matrix ; VxVector position,scale; VxQuaternion quat; v_matrix = referenceObject->GetWorldMatrix(); Vx3DDecomposeMatrix(v_matrix,quat,position,scale); VxVector box_s= BoxGetZero(referenceObject); NxVec3 pos = pMath::getFrom(position); NxQuat rot = pMath::getFrom(quat); float density = result->getDensity(); float radius = referenceObject->GetRadius(); if (referenceObject->GetRadius() < 0.001f ) { radius = 1.0f; } ////////////////////////////////////////////////////////////////////////// //create actors description NxActorDesc actorDesc;actorDesc.setToDefault(); NxBodyDesc bodyDesc;bodyDesc.setToDefault(); ////////////////////////////////////////////////////////////////////////// NxMaterialDesc *materialDescr = NULL; NxMaterial *material = NULL; if (isFlagOn(result->getDataFlags(),EDF_MATERIAL_PARAMETER)) { NxMaterialDesc entMatNull;entMatNull.setToDefault(); NxMaterialDesc *entMat = createMaterialFromEntity(referenceObject); material = world->getScene()->createMaterial(entMatNull); material->loadFromDesc(*entMat); result->setMaterial(material); }else{ if (world->getDefaultMaterial()) { result->setMaterial(world->getDefaultMaterial()); } } ////////////////////////////////////////////////////////////////////////// NxBoxShapeDesc boxShape; if (creationFlags & E_OFC_DIMENSION ) { boxShape.dimensions = pMath::getFrom(box_s)*0.5f; } boxShape.density = descr->density; boxShape.materialIndex = result->getMaterial()->getMaterialIndex(); if (result->getSkinWidth()!=-1.0f) boxShape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&boxShape); ////////////////////////////////////////////////////////////////////////// //dynamic object ? if (result->getFlags() & BF_Moving){ actorDesc.body = &bodyDesc; } else actorDesc.body = NULL; ////////////////////////////////////////////////////////////////////////// //set transformations actorDesc.density = descr->density; if (creationFlags & E_OFC_POSITION) { actorDesc.globalPose.t = pos; } if (creationFlags & E_OFC_POSITION) { actorDesc.globalPose.M = rot; } ////////////////////////////////////////////////////////////////////////// //create the actor int v = actorDesc.isValid(); NxActor *actor = world->getScene()->createActor(actorDesc); if (!actor) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't create actor"); delete result; return NULL; } ////////////////////////////////////////////////////////////////////////// //set additional settings : result->setActor(actor); actor->setName(referenceObject->GetName()); actor->userData= result; if (result->getFlags() & BF_Moving) { VxVector massOffsetOut;referenceObject->Transform(&massOffsetOut,&result->getMassOffset()); actor->setCMassOffsetGlobalPosition(pMath::getFrom(massOffsetOut)); } if (result->getFlags() & BF_Kinematic) { actor->raiseBodyFlag(NX_BF_KINEMATIC); } result->enableCollision((result->getFlags() & BF_Collision)); if (result->getFlags() & BF_Moving) { if (!(result->getFlags() & BF_Gravity)) { actor->raiseBodyFlag(NX_BF_DISABLE_GRAVITY); } } NxShape *shape = result->getShapeByIndex(); if (shape) { pSubMeshInfo *sInfo = new pSubMeshInfo(); sInfo->entID = referenceObject->GetID(); sInfo->refObject = (CKBeObject*)referenceObject; shape->userData = (void*)sInfo; result->setMainShape(shape); shape->setName(referenceObject->GetName()); } } return result; }
pRigidBody*pFactory::createRigidBody(CK3dEntity *referenceObject,pObjectDescr& oDescr) { CK3dEntity *worldReferenceObject = (CK3dEntity*)GetPMan()->GetContext()->GetObject(oDescr.worlReference); pWorld *world=getManager()->getWorld(worldReferenceObject,referenceObject); if (!world) { xLogger::xLog(XL_START,ELOGWARNING,E_LI_MANAGER,"world object invalid, setting to default world"); world = GetPMan()->getDefaultWorld(); } pRigidBody*result = world->getBody(referenceObject); // create minimum object result = createBody(referenceObject,worldReferenceObject); if (!result) { xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"failed"); return NULL; } result->setWorld(world); result->setFlags(oDescr.flags); result->setHullType(oDescr.hullType); if (oDescr.density <= 0.001f) oDescr.density = 1.0f; if (oDescr.skinWidth <= 0.001f) oDescr.skinWidth = 0.025f; result->setDensity(oDescr.density); bool hierarchy = (oDescr.flags & BF_Hierarchy); bool isDeformable = oDescr.flags & BF_Deformable; bool trigger = oDescr.flags & BF_TriggerShape; //################################################################ // // Deformable ? // pCloth *cloth = NULL; pClothDesc cDescr; if (isDeformable) { xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"deformable feature disabled in this release"); return NULL; cDescr.setToDefault(); cDescr.worldReference = worldReferenceObject->GetID(); if ( result->getFlags() & BF_Gravity ) { cDescr.flags |= PCF_Gravity; } if ( result->getFlags() & BF_Collision ) { } if (!cloth) { cloth = pFactory::Instance()->createCloth(referenceObject,cDescr); if (!cloth) { xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"Cannot create cloth : factory object failed !"); } } } float density = oDescr.density; VxVector box_s= BoxGetZero(referenceObject); VxMatrix v_matrix ; VxVector position,scale; VxQuaternion quat; v_matrix = referenceObject->GetWorldMatrix(); Vx3DDecomposeMatrix(v_matrix,quat,position,scale); NxVec3 pos = pMath::getFrom(position); NxQuat rot = pMath::getFrom(quat); //---------------------------------------------------------------- // // Fill NxActorDescr // NxActorDesc actorDesc;actorDesc.setToDefault(); NxBodyDesc bodyDesc;bodyDesc.setToDefault(); // // Fix parameters to default values actorDesc.density = oDescr.density; //skin width if (oDescr.skinWidth<=0.0001f) oDescr.skinWidth=0.025f; float radius = result->GetVT3DObject()->GetRadius(); //---------------------------------------------------------------- // // Create the physic mesh. Externalizing this procedure will corrupt the // actor description object. // switch(oDescr.hullType) { ////////////////////////////////////////////////////////////////////////// case HT_Box: { NxBoxShapeDesc shape; if (! (oDescr.flags & BF_Deformable) ) { shape.dimensions = pMath::getFrom(box_s)*0.5f; } shape.density = density; shape.skinWidth = oDescr.skinWidth; actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Sphere: { NxSphereShapeDesc shape; if (! (oDescr.flags & BF_Deformable) ) { shape.radius = radius; } shape.density = density; shape.skinWidth = oDescr.skinWidth; actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Mesh: { NxTriangleMeshDesc myMesh; myMesh.setToDefault(); pFactory::Instance()->createMesh(result->getWorld()->getScene(),result->GetVT3DObject()->GetCurrentMesh(),myMesh); NxTriangleMeshShapeDesc shape; bool status = InitCooking(); if (!status) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!"); return false; } MemoryWriteBuffer buf; status = CookTriangleMesh(myMesh, buf); if (!status) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't cook mesh!"); return false; } shape.meshData = GetPMan()->getPhysicsSDK()->createTriangleMesh(MemoryReadBuffer(buf.data)); shape.density = density; shape.group = oDescr.collisionGroup; actorDesc.shapes.pushBack(&shape); shape.skinWidth = oDescr.skinWidth; CloseCooking(); if (myMesh.points) { delete [] myMesh.points; } if (myMesh.triangles) { delete []myMesh.triangles; } break; } ////////////////////////////////////////////////////////////////////////// case HT_ConvexMesh: { if (result->GetVT3DObject()->GetCurrentMesh()) { if (result->GetVT3DObject()->GetCurrentMesh()->GetVertexCount()>=256 ) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Only 256 vertices for convex meshes allowed, by Ageia!"); return false; } }else { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Object has no mesh!"); return false; } NxConvexMeshDesc myMesh; myMesh.setToDefault(); pFactory::Instance()->createConvexMesh(result->getWorld()->getScene(),result->GetVT3DObject()->GetCurrentMesh(),myMesh); NxConvexShapeDesc shape; bool status = InitCooking(); if (!status) { xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!"); return false; } MemoryWriteBuffer buf; status = CookConvexMesh(myMesh, buf); if (!status) { xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't cook convex mesh!"); return false; } shape.meshData = GetPMan()->getPhysicsSDK()->createConvexMesh(MemoryReadBuffer(buf.data)); shape.density = density; actorDesc.shapes.pushBack(&shape); if (oDescr.skinWidth!=-1.0f) shape.skinWidth = oDescr.skinWidth; int h = shape.isValid(); CloseCooking(); if (myMesh.points) { delete [] myMesh.points; } if (myMesh.triangles) { delete []myMesh.triangles; } break; } ////////////////////////////////////////////////////////////////////////// case HT_ConvexCylinder: { NxConvexShapeDesc shape; pConvexCylinderSettings &cSettings = oDescr.convexCylinder; iAssertW( (oDescr.mask & OD_ConvexCylinder),pFactory::Instance()->findSettings(cSettings,result->GetVT3DObject()), "Hull type has been set to convex cylinder but there is no descriptions passed or activated in the pObjectDescr::mask.Trying object attributes...."); if (cSettings.radius.reference) cSettings.radius.evaluate(cSettings.radius.reference); if (cSettings.height.reference) cSettings.height.evaluate(cSettings.height.reference); iAssertW( cSettings.isValid() , cSettings.setToDefault(),""); cSettings.radius.value = cSettings.radius.value > 0.0f ? (cSettings.radius.value*0.5) : (box_s.v[cSettings.radius.referenceAxis] * 0.5f); cSettings.height.value = cSettings.height.value > 0.0f ? cSettings.height.value : (box_s.v[cSettings.height.referenceAxis] * 0.5f); bool resultAssert = true; iAssertWR( pFactory::Instance()->_createConvexCylinderMesh(&shape,cSettings,result->GetVT3DObject()),"",resultAssert); shape.density = density; shape.skinWidth = oDescr.skinWidth; actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Capsule: { NxCapsuleShapeDesc shape; pCapsuleSettingsEx &cSettings = oDescr.capsule; if (!( oDescr.mask & OD_Capsule) ) { // try over attribute : pFactory::Instance()->findSettings(cSettings,result->GetVT3DObject()); } bool resultAssert = true; if (cSettings.radius.reference) cSettings.radius.evaluate(cSettings.radius.reference); if (cSettings.height.reference) cSettings.height.evaluate(cSettings.height.reference); iAssertWR(cSettings.isValid(),cSettings.setToDefault(),resultAssert); shape.radius = cSettings.radius.value > 0.0f ? (cSettings.radius.value*0.5) : (box_s.v[cSettings.radius.referenceAxis] * 0.5f); shape.height = cSettings.height.value > 0.0f ? (cSettings.height.value-( 2*shape.radius)) : (box_s.v[cSettings.height.referenceAxis] - ( 2*shape.radius)) ; shape.density = density; shape.skinWidth = oDescr.skinWidth; actorDesc.shapes.pushBack(&shape); break; } case HT_Wheel: { xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Wheel shape can be sub shape only!"); return false; } } if ( !isDeformable) { actorDesc.globalPose.t = pos; actorDesc.globalPose.M = rot; } //---------------------------------------------------------------- // // Create the final NxActor // if (oDescr.flags & BF_Moving) actorDesc.body = &bodyDesc; NxActor *actor = world->getScene()->createActor(actorDesc); if (!actor) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't create actor"); delete result; return NULL; } //---------------------------------------------------------------- // // // result->setActor(actor); actor->setName(referenceObject->GetName()); result->SetVT3DObject(referenceObject); actor->userData= result; ////////////////////////////////////////////////////////////////////////// //Deformable : if (isDeformable && cloth) { pDeformableSettings dSettings; dSettings.ImpulsThresold = 50.0f; dSettings.PenetrationDepth= 0.1f ; dSettings.MaxDeform = 2.0f; CKParameterOut *poutDS = referenceObject->GetAttributeParameter(GetPMan()->att_deformable); if (poutDS) { pFactory::Instance()->copyTo(dSettings,poutDS); } cloth->attachToCore(referenceObject,dSettings.ImpulsThresold,dSettings.PenetrationDepth,dSettings.MaxDeform); result->setCloth(cloth); } ////////////////////////////////////////////////////////////////////////// // // Extra settings : // if (result->getFlags() & BF_Moving) { VxVector massOffsetOut;referenceObject->Transform(&massOffsetOut,&oDescr.massOffsetLinear); actor->setCMassOffsetGlobalPosition(pMath::getFrom(massOffsetOut)); } if (result->getFlags() & BF_Kinematic) { result->setKinematic(true); } if (result->getFlags() & BF_Moving ) { result->enableGravity(result->getFlags() & BF_Gravity); } if (result->getFlags() & BF_Sleep ) { result->setSleeping(true); } if (oDescr.worlReference == 0) { if (GetPMan()->getDefaultWorld()) { oDescr.worlReference = GetPMan()->getDefaultWorld()->getReference()->GetID(); } } //---------------------------------------------------------------- // // store mesh meta info in the first main mesh // NxShape *shape = result->getShapeByIndex(); if (shape) { pSubMeshInfo *sInfo = new pSubMeshInfo(); sInfo->entID = referenceObject->GetID(); sInfo->refObject = (CKBeObject*)referenceObject; shape->userData = (void*)sInfo; result->setMainShape(shape); shape->setName(referenceObject->GetName()); } result->enableCollision( (result->getFlags() & BF_Collision), referenceObject ); //---------------------------------------------------------------- // // Adjust pivot // if ( (oDescr.mask & OD_Pivot) ) { iAssertW1( oDescr.pivot.isValid(),oDescr.pivot.setToDefault()); result->updatePivotSettings(oDescr.pivot,referenceObject); }else if(pFactory::Instance()->findSettings(oDescr.collision,referenceObject)) result->updatePivotSettings(oDescr.pivot,referenceObject); //---------------------------------------------------------------- // // Optimization // if ((oDescr.mask & OD_Optimization )) { iAssertW1( oDescr.optimization.isValid(),oDescr.optimization.setToDefault()); result->updateOptimizationSettings(oDescr.optimization); } else{ if(pFactory::Instance()->findSettings(oDescr.optimization,referenceObject)) { iAssertW1( oDescr.optimization.isValid(),oDescr.optimization.setToDefault()); result->updateOptimizationSettings(oDescr.optimization); } } //---------------------------------------------------------------- // // Collision // if ((oDescr.mask & OD_Collision)) result->updateCollisionSettings(oDescr.collision,referenceObject); else if(pFactory::Instance()->findSettings(oDescr.collision,referenceObject)) result->updateCollisionSettings(oDescr.collision,referenceObject); //---------------------------------------------------------------- // // Material // NxMaterialDesc *materialDescr = NULL; NxMaterial *material = NULL; pMaterial &bMaterial = oDescr.material; if (oDescr.mask & OD_Material) { result->updateMaterialSettings(bMaterial,referenceObject); }else { bool hasMaterial = pFactory::Instance()->findSettings(bMaterial,referenceObject); if (!hasMaterial) { if (world->getDefaultMaterial()) { int z = (int)world->getDefaultMaterial()->userData; shape->setMaterial(world->getDefaultMaterial()->getMaterialIndex()); } }else{ iAssertW( bMaterial.isValid(),bMaterial.setToDefault(), "Material settings were still invalid : "); NxMaterialDesc nxMatDescr; pFactory::Instance()->copyTo(nxMatDescr,bMaterial); NxMaterial *nxMaterial = world->getScene()->createMaterial(nxMatDescr); if (nxMaterial) { shape->setMaterial(nxMaterial->getMaterialIndex()); } } } xLogger::xLog(ELOGINFO,E_LI_MANAGER,"Rigid body creation successful : %s",referenceObject->GetName()); result->setInitialDescription(&oDescr); //---------------------------------------------------------------- // // Hierarchy mode fix : // if ( (oDescr.flags & BF_Hierarchy) ) oDescr.hirarchy = true; if ( oDescr.hirarchy ) oDescr.flags << BF_Hierarchy; if ( (!oDescr.hirarchy) || !(oDescr.flags & BF_Hierarchy) ) return result; //---------------------------------------------------------------- // // Parse hirarchy // CK3dEntity* subEntity = NULL; while (subEntity= referenceObject->HierarchyParser(subEntity) ) { pObjectDescr *subDescr = NULL; int attTypePBSetup = GetPMan()->getAttributeTypeByGuid(VTS_PHYSIC_ACTOR); if (subEntity->HasAttribute(attTypePBSetup)) { subDescr = new pObjectDescr(); CKParameterOut *par = subEntity->GetAttributeParameter(attTypePBSetup); IParameter::Instance()->copyTo(subDescr,par); subDescr->version = pObjectDescr::E_OD_VERSION::OD_DECR_V1; } if (!subDescr) continue; if (subDescr->flags & BF_SubShape) { ////////////////////////////////////////////////////////////////////////// // // Regular Mesh : // if (subDescr->hullType != HT_Cloth) { //result->addSubShape(NULL,*subDescr,subEntity); VxQuaternion refQuad;subEntity->GetQuaternion(&refQuad,referenceObject); VxVector relPos;subEntity->GetPosition(&relPos,referenceObject); shape = pFactory::Instance()->createShape(referenceObject,*subDescr,subEntity,subEntity->GetCurrentMesh(),relPos,refQuad); //NxShape *shape = result->getSubShape(subEntity); if (shape) { //---------------------------------------------------------------- // // check for collision setup // //try to get get from child attributes first /* if(pFactory::Instance()->findSettings(subDescr->collision,subEntity)) { result->updateCollisionSettings(subDescr->collision,subEntity); continue; } if ( (subDescr->mask & OD_Optimization) ) { //if (pFactory::Instance()->findSettings(subDescr->collision,subEntity)) result->updateCollisionSettings(subDescr->collision,subEntity); } else if ( (oDescr.mask & OD_Optimization) ) { result->updateCollisionSettings(oDescr.collision,subEntity); }else if(pFactory::Instance()->findSettings(subDescr->collision,subEntity)) { result->updateCollisionSettings(subDescr->collision,subEntity); } */ } } ////////////////////////////////////////////////////////////////////////// // // Cloth Mesh : // if (subDescr->hullType == HT_Cloth) { //pClothDesc *cloth = pFactory::Instance()->createPObjectDescrFromParameter(subEntity->GetAttributeParameter(GetPMan()->GetPAttribute())); } } } //---------------------------------------------------------------- // // Adjust mass // //---------------------------------------------------------------- // // Collision // if ((oDescr.mask & OD_Mass)) result->updateMassSettings(oDescr.mass); else if(pFactory::Instance()->findSettings(oDescr.mass,referenceObject)) result->updateMassSettings(oDescr.mass); return result; nothing: return result; }
pRigidBody*pFactory::createRigidBodyFull(CK3dEntity *referenceObject, CK3dEntity *worldReferenceObject) { //################################################################ // // Sanity checks // pWorld *world=getManager()->getWorld(worldReferenceObject,referenceObject); pRigidBody*result = world->getBody(referenceObject); if(result) { result->destroy(); delete result; result = NULL; } //################################################################ // // Construct the result // result = createBody(referenceObject,worldReferenceObject); if (result) { result->setWorld(world); //---------------------------------------------------------------- // // Handle different attribute types (Object or pBSetup) // int attTypeOld = GetPMan()->GetPAttribute(); int attTypeNew = GetPMan()->getAttributeTypeByGuid(VTS_PHYSIC_ACTOR); pObjectDescr *oDescr = NULL; //---------------------------------------------------------------- // // the old way : // if (referenceObject->HasAttribute(attTypeOld)) { result->retrieveSettingsFromAttribute(); oDescr = pFactory::Instance()->createPObjectDescrFromParameter(referenceObject->GetAttributeParameter(GetPMan()->GetPAttribute())); } bool hierarchy = result->getFlags() & BF_Hierarchy; bool isDeformable = result->getFlags() & BF_Deformable; bool trigger = (result->getFlags() & BF_TriggerShape); //---------------------------------------------------------------- // // the new way // if (referenceObject->HasAttribute(attTypeNew)) { oDescr = new pObjectDescr(); } result->checkDataFlags(); /* pObjectDescr *oDescr = if (!oDescr) return result; */ //################################################################ // // Older versions have the hierarchy mode settings not the body flags // We migrate it : // if (oDescr->hirarchy) { result->setFlags( (result->getFlags() | BF_Hierarchy )); } if (hierarchy) { oDescr->hirarchy = hierarchy; } //################################################################ // // Deformable ? // pCloth *cloth = NULL; pClothDesc cDescr; if (isDeformable) { cDescr.setToDefault(); cDescr.worldReference = worldReferenceObject->GetID(); if ( result->getFlags() & BF_Gravity ) { cDescr.flags |= PCF_Gravity; } if ( result->getFlags() & BF_Collision ) { } if (!cloth) { cloth = pFactory::Instance()->createCloth(referenceObject,cDescr); if (!cloth) { xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"Cannot create cloth : factory object failed !"); } } } //################################################################ // // Some settings // if (result->getSkinWidth()==-1.0f) { result->setSkinWidth(0.01f); } float radius = referenceObject->GetRadius(); if (referenceObject->GetRadius() < 0.001f ) { radius = 1.0f; } float density = result->getDensity(); VxVector box_s= BoxGetZero(referenceObject); //################################################################ // // Calculate destination matrix // VxMatrix v_matrix ; VxVector position,scale; VxQuaternion quat; v_matrix = referenceObject->GetWorldMatrix(); Vx3DDecomposeMatrix(v_matrix,quat,position,scale); NxVec3 pos = pMath::getFrom(position); NxQuat rot = pMath::getFrom(quat); ////////////////////////////////////////////////////////////////////////// //create actors description NxActorDesc actorDesc;actorDesc.setToDefault(); NxBodyDesc bodyDesc;bodyDesc.setToDefault(); NxMaterialDesc *materialDescr = NULL; NxMaterial *material = NULL; switch(result->getHullType()) { ////////////////////////////////////////////////////////////////////////// case HT_Box: { NxBoxShapeDesc shape; if (! isDeformable ) { shape.dimensions = pMath::getFrom(box_s)*0.5f; } shape.density = density; //shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Sphere: { NxSphereShapeDesc shape; if (! isDeformable ) { shape.radius = radius; } shape.density = density; //shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Mesh: { if (! (result->getFlags() & BF_Deformable) ) { //xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Can not use a mesh as de"); //return NULL; } NxTriangleMeshDesc myMesh; myMesh.setToDefault(); createMesh(world->getScene(),referenceObject->GetCurrentMesh(),myMesh); NxTriangleMeshShapeDesc shape; bool status = InitCooking(); if (!status) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!"); return NULL; } MemoryWriteBuffer buf; status = CookTriangleMesh(myMesh, buf); if (!status) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't cook mesh!"); return NULL; } shape.meshData = getManager()->getPhysicsSDK()->createTriangleMesh(MemoryReadBuffer(buf.data)); shape.density = density; // shape.materialIndex = result->getMaterial()->getMaterialIndex(); actorDesc.shapes.pushBack(&shape); //shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); CloseCooking(); if (myMesh.points) { delete [] myMesh.points; } if (myMesh.triangles) { delete []myMesh.triangles; } break; } ////////////////////////////////////////////////////////////////////////// case HT_ConvexMesh: { if (referenceObject->GetCurrentMesh()) { if (referenceObject->GetCurrentMesh()->GetVertexCount()>=256 ) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Only 256 vertices for convex meshs allowed, by Ageia!"); goto nothing; } }else { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Object has no mesh!"); goto nothing; } NxConvexMeshDesc myMesh; myMesh.setToDefault(); createConvexMesh(world->getScene(),referenceObject->GetCurrentMesh(),myMesh); NxConvexShapeDesc shape; bool status = InitCooking(); if (!status) { xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!"); goto nothing; } MemoryWriteBuffer buf; status = CookConvexMesh(myMesh, buf); if (!status) { xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't cook convex mesh!"); goto nothing; } shape.meshData = getManager()->getPhysicsSDK()->createConvexMesh(MemoryReadBuffer(buf.data)); shape.density = density; // shape.materialIndex = result->getMaterial()->getMaterialIndex(); actorDesc.shapes.pushBack(&shape); //shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); int h = shape.isValid(); CloseCooking(); if (myMesh.points) { delete [] myMesh.points; } if (myMesh.triangles) { delete []myMesh.triangles; } break; } ////////////////////////////////////////////////////////////////////////// case HT_ConvexCylinder: { NxConvexShapeDesc shape; if (!_createConvexCylinder(&shape,referenceObject)) xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't create convex cylinder mesh"); shape.density = density; if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Capsule: { NxCapsuleShapeDesc shape; if ( !isDeformable ) { pCapsuleSettings cSettings; pFactory::Instance()->findSettings(cSettings,referenceObject); shape.radius = cSettings.radius > 0.0f ? cSettings.radius : box_s.v[cSettings.localRadiusAxis] * 0.5f; shape.height = cSettings.height > 0.0f ? cSettings.height : box_s.v[cSettings.localLengthAxis] - ( 2*shape.radius) ; } shape.density = density; // shape.materialIndex = result->getMaterial()->getMaterialIndex(); // shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&shape); break; } case HT_Wheel: { // xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't create convex cylinder mesh"); /* NxWheelShapeDesc shape; shape.radius = box_s.z*0.5f; shape.density = density; if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); if (referenceObject && referenceObject->HasAttribute(GetPMan()->att_wheelDescr )) { CKParameter *par = referenceObject->GetAttributeParameter(GetPMan()->att_wheelDescr ); if (par) { pWheelDescr *wheelDescr = pFactory::Instance()->copyTo(par); if (wheelDescr) { float heightModifier = (wheelDescr->wheelSuspension + radius ) / wheelDescr->wheelSuspension; shape.suspension.damper = wheelDescr->springDamping * heightModifier; shape.suspension.targetValue = wheelDescr->springBias * heightModifier; shape.suspensionTravel = wheelDescr->wheelSuspension; shape.lateralTireForceFunction.stiffnessFactor *= wheelDescr->frictionToSide; shape.longitudalTireForceFunction.stiffnessFactor*=wheelDescr->frictionToFront; shape.inverseWheelMass = 0.1; int isValid = shape.isValid(); actorDesc.shapes.pushBack(&shape); } }else { XString name = result->GetVT3DObject()->GetName(); name << " needs to have an additional wheel attribute attached ! "; xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,name.CStr()); } } */ break; } } ////////////////////////////////////////////////////////////////////////// //dynamic object ? if (result->getFlags() & BF_Moving){ actorDesc.body = &bodyDesc; } else actorDesc.body = NULL; ////////////////////////////////////////////////////////////////////////// //set transformations actorDesc.density = result->getDensity(); if ( !isDeformable) { actorDesc.globalPose.t = pos; actorDesc.globalPose.M = rot; } ////////////////////////////////////////////////////////////////////////// //create the actor int v = actorDesc.isValid(); NxActor *actor = world->getScene()->createActor(actorDesc); if (!actor) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't create actor"); delete result; return NULL; } ////////////////////////////////////////////////////////////////////////// //set additional settings : result->setActor(actor); actor->setName(referenceObject->GetName()); actor->userData= result; ////////////////////////////////////////////////////////////////////////// //Deformable : if (isDeformable && cloth) { pDeformableSettings dSettings; dSettings.ImpulsThresold = 50.0f; dSettings.PenetrationDepth= 0.1f ; dSettings.MaxDeform = 2.0f; CKParameterOut *poutDS = referenceObject->GetAttributeParameter(GetPMan()->att_deformable); if (poutDS) { pFactory::Instance()->copyTo(dSettings,poutDS); } cloth->attachToCore(referenceObject,dSettings.ImpulsThresold,dSettings.PenetrationDepth,dSettings.MaxDeform); result->setCloth(cloth); } ////////////////////////////////////////////////////////////////////////// // // Extra settings : // if (result->getFlags() & BF_Moving) { VxVector massOffsetOut;referenceObject->Transform(&massOffsetOut,&result->getMassOffset()); actor->setCMassOffsetGlobalPosition(pMath::getFrom(massOffsetOut)); } if (result->getFlags() & BF_Kinematic) { result->setKinematic(true); } if (result->getFlags() & BF_Moving ) { result->enableGravity(result->getFlags() & BF_Gravity); } //---------------------------------------------------------------- // // Special Parameters // //- look for optimization attribute : result->checkForOptimization(); //---------------------------------------------------------------- // // store mesh meta info in the first main mesh // NxShape *shape = result->getShapeByIndex(); if (shape) { pSubMeshInfo *sInfo = new pSubMeshInfo(); sInfo->entID = referenceObject->GetID(); sInfo->refObject = (CKBeObject*)referenceObject; shape->userData = (void*)sInfo; result->setMainShape(shape); shape->setName(referenceObject->GetName()); pMaterial bMaterial; bool hasMaterial = pFactory::Instance()->findSettings(bMaterial,referenceObject); if (!hasMaterial) { if (world->getDefaultMaterial()) { int z = (int)world->getDefaultMaterial()->userData; shape->setMaterial(world->getDefaultMaterial()->getMaterialIndex()); //pFactory::Instance()->copyTo(bMaterial,world->getDefaultMaterial()); } }else{ NxMaterialDesc nxMatDescr; pFactory::Instance()->copyTo(nxMatDescr,bMaterial); NxMaterial *nxMaterial = world->getScene()->createMaterial(nxMatDescr); if (nxMaterial) { shape->setMaterial(nxMaterial->getMaterialIndex()); } } } result->enableCollision( (result->getFlags() & BF_Collision), referenceObject ); //- handle collisions setup if (oDescr->version == pObjectDescr::E_OD_VERSION::OD_DECR_V1) result->updateCollisionSettings(*oDescr,referenceObject); xLogger::xLog(ELOGINFO,E_LI_MANAGER,"Rigid body creation successful : %s",referenceObject->GetName()); //---------------------------------------------------------------- // // Parse hierarchy // if (!oDescr->hirarchy) return result; CK3dEntity* subEntity = NULL; while (subEntity= referenceObject->HierarchyParser(subEntity) ) { if (subEntity->HasAttribute(GetPMan()->GetPAttribute())) { pObjectDescr *subDescr = pFactory::Instance()->createPObjectDescrFromParameter(subEntity->GetAttributeParameter(GetPMan()->GetPAttribute())); if (subDescr->flags & BF_SubShape) { ////////////////////////////////////////////////////////////////////////// // // Regular Mesh : // if (subDescr->hullType != HT_Cloth) { result->addSubShape(NULL,*oDescr,subEntity); } ////////////////////////////////////////////////////////////////////////// // // Cloth Mesh : // if (subDescr->hullType == HT_Cloth) { //pClothDesc *cloth = pFactory::Instance()->createPObjectDescrFromParameter(subEntity->GetAttributeParameter(GetPMan()->GetPAttribute())); } } } } if (oDescr->hirarchy) { if (oDescr->newDensity!=0.0f || oDescr->totalMass!=0.0f ) { result->updateMassFromShapes(oDescr->newDensity,oDescr->totalMass); } } return result; } nothing: return result; }
//----------------------------------------------------------------------- PhysicsActor* PhysXActorExtern::createPhysicsActor(PhysicsActorDesc* physicsActorDesc, PhysicsShapeDesc* physicsShapeDesc) { if (!PhysXBridge::getSingletonPtr()->getScene() || !physicsActorDesc || !physicsShapeDesc) return 0; NxBodyDesc bodyDesc; bodyDesc.setToDefault(); NxReal angularDamping = bodyDesc.angularDamping; NxVec3 angularVelocity = bodyDesc.angularVelocity; NxVec3 linearVelocity = bodyDesc.linearVelocity; bodyDesc.angularDamping = physicsShapeDesc->mAngularDamping; bodyDesc.angularVelocity = PhysXMath::convert(physicsShapeDesc->mAngularVelocity); bodyDesc.linearVelocity = PhysXMath::convert(physicsActorDesc->direction); NxActorDesc actorDesc; NxActorDesc defaultActorDesc; actorDesc.setToDefault(); defaultActorDesc.setToDefault(); switch (physicsShapeDesc->mPhysicsShapeType) { case ST_BOX: { PhysicsBoxDesc* physicsBoxDesc = static_cast<PhysicsBoxDesc*>(physicsShapeDesc); NxBoxShapeDesc boxDesc; boxDesc.setToDefault(); boxDesc.dimensions = PhysXMath::convert(physicsBoxDesc->mDimensions); boxDesc.group = physicsBoxDesc->mCollisionGroup; boxDesc.groupsMask = PhysXMath::convert(physicsBoxDesc->mGroupMask); boxDesc.materialIndex = physicsBoxDesc->mMaterialIndex; actorDesc.density = NxComputeBoxDensity(2 * boxDesc.dimensions, physicsActorDesc->mass); actorDesc.shapes.pushBack(&boxDesc); } break; case ST_SPHERE: { PhysicsSphereDesc* physicsSphereDesc = static_cast<PhysicsSphereDesc*>(physicsShapeDesc); NxSphereShapeDesc sphereDec; sphereDec.setToDefault(); sphereDec.radius = physicsSphereDesc->mRadius; sphereDec.group = physicsSphereDesc->mCollisionGroup; sphereDec.groupsMask = PhysXMath::convert(physicsSphereDesc->mGroupMask); sphereDec.materialIndex = physicsSphereDesc->mMaterialIndex; actorDesc.density = NxComputeSphereDensity(sphereDec.radius, physicsActorDesc->mass); actorDesc.shapes.pushBack(&sphereDec); } break; case ST_CAPSULE: { PhysicsCapsuleDesc* physicsCapsuleDesc = static_cast<PhysicsCapsuleDesc*>(physicsShapeDesc); NxCapsuleShapeDesc capsuleDec; capsuleDec.setToDefault(); capsuleDec.radius = physicsCapsuleDesc->mRadius; capsuleDec.height = physicsCapsuleDesc->mHeight; capsuleDec.group = physicsCapsuleDesc->mCollisionGroup; capsuleDec.groupsMask = PhysXMath::convert(physicsCapsuleDesc->mGroupMask); capsuleDec.materialIndex = physicsCapsuleDesc->mMaterialIndex; actorDesc.density = NxComputeCylinderDensity(capsuleDec.radius, capsuleDec.height, physicsActorDesc->mass); actorDesc.shapes.pushBack(&capsuleDec); } break; } actorDesc.globalPose.t = PhysXMath::convert(physicsActorDesc->position); actorDesc.body = &bodyDesc; actorDesc.group = physicsActorDesc->collisionGroup; PhysXActor* physXActor = 0; if (!actorDesc.isValid()) { actorDesc = defaultActorDesc; Ogre::LogManager::getSingleton().logMessage("ParticleUniverse PhysXActor: Cannot create actor; use default attributes."); } NxActor* nxActor = PhysXBridge::getSingletonPtr()->getScene()->createActor(actorDesc); if (nxActor) { physXActor = OGRE_NEW_T(PhysXActor, Ogre::MEMCATEGORY_SCENE_OBJECTS)(); physXActor->position = PhysXMath::convert(nxActor->getGlobalPosition()); physXActor->direction = PhysXMath::convert(nxActor->getLinearVelocity()); nxActor->setGlobalOrientationQuat(PhysXMath::convert(physicsActorDesc->orientation)); physXActor->orientation = physicsActorDesc->orientation; physXActor->mass = nxActor->getMass(); physXActor->collisionGroup = nxActor->getGroup(); physXActor->nxActor = nxActor; } return physXActor; }
static bool InitNx() { if (!gAllocator) gAllocator = new UserAllocator; // Initialize PhysicsSDK NxPhysicsSDKDesc desc; NxSDKCreateError errorCode = NXCE_NO_ERROR; gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, gAllocator, &gErrorStream, desc, &errorCode); if(gPhysicsSDK == NULL) { printf("\nSDK create error (%d - %s).\nUnable to initialize the PhysX SDK, exiting the sample.\n\n", errorCode, getNxSDKCreateError(errorCode)); return false; } #if SAMPLES_USE_VRD // The settings for the VRD host and port are found in SampleCommonCode/SamplesVRDSettings.h if (gPhysicsSDK->getFoundationSDK().getRemoteDebugger() && !gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->isConnected()) gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect(SAMPLES_VRD_HOST, SAMPLES_VRD_PORT, SAMPLES_VRD_EVENTMASK); #endif gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.025f); //enable visualisation gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1.0f); gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 1.0f); // Create a scene NxSceneDesc sceneDesc; sceneDesc.gravity = gDefaultGravity; gScene = gPhysicsSDK->createScene(sceneDesc); if(gScene == NULL) { printf("\nError: Unable to create a PhysX scene, exiting the sample.\n\n"); return false; } //create some materials -- note that we reuse the same NxMaterialDesc every time, //as it gets copied to the SDK with every call, not just referenced. NxMaterialDesc material; //default material material.restitution = 0.0f; material.staticFriction = 0.5f; material.dynamicFriction = 0.5f; defaultMaterialIndex = 0; gScene->getMaterialFromIndex(defaultMaterialIndex)->loadFromDesc(material);//we redefine the default material in slot 0 //somewhat bouncy material material.restitution = 0.75f; material.staticFriction = 0.5f; material.dynamicFriction = 0.5f; somewhatBouncyMaterialIndex = gScene->createMaterial(material)->getMaterialIndex(); //very bouncy material material.restitution = 1.0f; material.staticFriction = 0.5f; material.dynamicFriction = 0.5f; veryBouncyMaterialIndex = gScene->createMaterial(material)->getMaterialIndex(); //almost frictionless material material.restitution = 0.0f; material.staticFriction = 0.01f; material.dynamicFriction = 0.01f; frictionlessMaterialIndex = gScene->createMaterial(material)->getMaterialIndex(); //really high friction material material.restitution = 0.0f; material.staticFriction = 20.0f;//static friction can be higher than 1. material.dynamicFriction = 1.0f; //dynamic friction should not be higher than 1. highFrictionMaterialIndex = gScene->createMaterial(material)->getMaterialIndex(); //anisotropic friction material material.restitution = 0.0f; material.staticFriction = 0.1f; material.dynamicFriction = 0.1f; material.dynamicFrictionV = 0.8f; material.staticFrictionV = 1.0f; material.dirOfAnisotropy.set(1.5,0,1); //this will be used on one of the ramps so that boxes slide off at an angle material.dirOfAnisotropy.normalize(); material.flags = NX_MF_ANISOTROPIC; anisoMaterialIndex = gScene->createMaterial(material)->getMaterialIndex(); material.setToDefault(); //turn off aniso on our material object in case we want to use it again. // Create ground plane NxPlaneShapeDesc planeDesc; planeDesc.materialIndex = frictionlessMaterialIndex; NxActorDesc actorDesc; actorDesc.shapes.pushBack(&planeDesc); gScene->createActor(actorDesc); //create some ramps NxBoxShapeDesc anisoBoxDesc; anisoBoxDesc.dimensions = NxVec3(float(20), float(2), float(30)); anisoBoxDesc.materialIndex = anisoMaterialIndex; actorDesc.setToDefault(); actorDesc.shapes.pushBack(&anisoBoxDesc); actorDesc.globalPose.t.set(0,20.0f,0); float angle = NxMath::degToRad(30.0f); actorDesc.globalPose.M(0,0) = 1; actorDesc.globalPose.M(0,1) = 0; actorDesc.globalPose.M(0,2) = 0; actorDesc.globalPose.M(1,0) = 0; actorDesc.globalPose.M(1,1) = cos(angle); actorDesc.globalPose.M(1,2) = -sin(angle); actorDesc.globalPose.M(2,0) = 0; actorDesc.globalPose.M(2,1) = sin(angle); actorDesc.globalPose.M(2,2) = cos(angle); gScene->createActor(actorDesc); NxBoxShapeDesc frictlessBoxDesc; frictlessBoxDesc.dimensions = NxVec3(float(20), float(2), float(30)); frictlessBoxDesc.materialIndex = frictionlessMaterialIndex; actorDesc.setToDefault(); actorDesc.shapes.clear(); actorDesc.shapes.pushBack(&frictlessBoxDesc); actorDesc.globalPose.t.set(-40,20.0f,0); actorDesc.globalPose.M(0,0) = 1; actorDesc.globalPose.M(0,1) = 0; actorDesc.globalPose.M(0,2) = 0; actorDesc.globalPose.M(1,0) = 0; actorDesc.globalPose.M(1,1) = cos(angle); actorDesc.globalPose.M(1,2) = -sin(angle); actorDesc.globalPose.M(2,0) = 0; actorDesc.globalPose.M(2,1) = sin(angle); actorDesc.globalPose.M(2,2) = cos(angle); gScene->createActor(actorDesc); NxBoxShapeDesc hiFrictBoxDesc; hiFrictBoxDesc.dimensions = NxVec3(float(20), float(2), float(30)); hiFrictBoxDesc.materialIndex = highFrictionMaterialIndex; actorDesc.setToDefault(); actorDesc.shapes.clear(); actorDesc.shapes.pushBack(&hiFrictBoxDesc); actorDesc.globalPose.t.set(40,20.0f,0); actorDesc.globalPose.M(0,0) = 1; actorDesc.globalPose.M(0,1) = 0; actorDesc.globalPose.M(0,2) = 0; actorDesc.globalPose.M(1,0) = 0; actorDesc.globalPose.M(1,1) = cos(angle); actorDesc.globalPose.M(1,2) = -sin(angle); actorDesc.globalPose.M(2,0) = 0; actorDesc.globalPose.M(2,1) = sin(angle); actorDesc.globalPose.M(2,2) = cos(angle); gScene->createActor(actorDesc); return true; }