int plSimulationMgr::GetMaterialIdx(NxScene* scene, float friction, float restitution) { if (friction == 0.5f && restitution == 0.5f) return 0; // Use the nutty PhysX method to search for a matching material #define kNumMatsPerCall 32 NxMaterial* materials[kNumMatsPerCall]; NxU32 iterator = 0; bool getMore = true; while (getMore) { int numMats = scene->getMaterialArray(materials, kNumMatsPerCall, iterator); for (int i = 0; i < numMats; i++) { if (materials[i]->getDynamicFriction() == friction && materials[i]->getRestitution() == restitution) { return materials[i]->getMaterialIndex(); } } getMore = (numMats == kNumMatsPerCall); } // Couldn't find the material, so create it NxMaterialDesc desc; desc.restitution = restitution; desc.dynamicFriction = friction; desc.staticFriction = friction; NxMaterial* mat = scene->createMaterial(desc); return mat->getMaterialIndex(); }
NxActor* CreateGroundPlane() { // Create a plane with default descriptor NxPlaneShapeDesc planeDesc; NxActorDesc actorDesc; NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0); planeDesc.materialIndex = defaultMaterial->getMaterialIndex(); actorDesc.shapes.pushBack(&planeDesc); return gScene->createActor(actorDesc); }
Cutter::Cutter(NxVec3 pos, string fname) { m_cutterHeight = 0.0f; m_cutterRotateAngle = 0.0f; m_cutterON = false; m_cutterParams = new CutterParams; m_attachedTriPod = NULL; CfgLoader cfg(fname, m_cutterParams->getVariableList()); //D3DXMatrixRotationYawPitchRoll(&dimm->matChassisRotation, rotateChassis.y, rotateChassis.x, rotateChassis.z); ObjectParams temp; temp.loadFromFile("Objects\\" + m_cutterParams->chassisModel); m_objChassis = new Surface(temp.meshName, temp.generateMaterial(), Vec3(0, 0, 0)); temp.loadFromFile("Objects\\" + m_cutterParams->cutterModel); m_objCutter = new Surface(temp.meshName, temp.generateMaterial(), Vec3(0, 0, 0)); Vec3 min = m_objChassis->boundingBox.Min; //min.y -= 1.0f; Vec3 max = m_objChassis->boundingBox.Max; //max.y += 0.5f; m_actionBox = new ActionBox(min, max); core.game->getWorld()->addToWorld(m_objChassis, NO_COLLISION, 0, GROUP_NON_COLLIDABLE, NULL, 1); core.game->getWorld()->addToWorld(m_objCutter, NO_COLLISION, 0, GROUP_NON_COLLIDABLE, NULL, 1); m_cutterParams->dimm = Vec3(m_objChassis->boundingBox.getWidth()/2, m_objChassis->boundingBox.getHeight()/6, m_objChassis->boundingBox.getDepth()/2); m_actor = core.dynamics->createBox(pos, NxVec3(m_cutterParams->dimm), m_cutterParams->density); SetActorCollisionGroup(m_actor, GROUP_COLLIDABLE_NON_PUSHABLE); NxMaterial *anisoMaterial = NULL; //if(!anisoMaterial) { //Create an anisotropic material NxMaterialDesc material; //Anisotropic friction material material.restitution = 0.01f; material.staticFriction = 0.01f; material.dynamicFriction = 0.01f; material.dynamicFrictionV = 0.1f; material.staticFrictionV = 0.1f; material.dirOfAnisotropy.set(1,0,0); material.flags = NX_MF_ANISOTROPIC; anisoMaterial = core.dynamics->getScene()->createMaterial(material); } m_actor->getShapes()[0]->setMaterial(anisoMaterial->getMaterialIndex()); }
int DXApp::run(HINSTANCE hInst, HWND hWnd) { MSG msg; HACCEL hAccelTable; hAccelTable = LoadAccelerators(hInst, (LPCTSTR)IDC_TESTDXPROJ); QueryPerformanceFrequency((LARGE_INTEGER*)&Frequency); if(!_p_physdk) return -1; NxSceneDesc sceneDesc; sceneDesc.gravity.set(0, -9800.f, 0); sceneDesc.collisionDetection = true; sceneDesc.groundPlane = true; _p_scene = _p_physdk->createScene(sceneDesc); if(!_p_scene) return -2; _time_step = 1.0f/400.0f; _p_scene->setTiming(_time_step); NxMaterialDesc ParticleMaterialDesc; ParticleMaterialDesc.restitution = 0.80f; //ParticleMaterialDesc.spinFriction = 0.2f; ParticleMaterialDesc.staticFriction = 0.8f; ParticleMaterialDesc.dynamicFriction = 0.5f; NxMaterial* ParticleMaterial = _p_scene->createMaterial(ParticleMaterialDesc); _particle_material = ParticleMaterial->getMaterialIndex(); D3DPRESENT_PARAMETERS D3DParams; D3DParams.Windowed = true; D3DParams.BackBufferWidth = width; D3DParams.BackBufferHeight = height; D3DParams.MultiSampleType = D3DMULTISAMPLE_NONE; D3DParams.MultiSampleQuality = 0; D3DParams.SwapEffect = D3DSWAPEFFECT_DISCARD; D3DParams.Flags = 0; D3DParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; D3DParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; D3DParams.BackBufferFormat = D3DFMT_UNKNOWN; D3DParams.BackBufferCount = 3; D3DParams.hDeviceWindow = hWnd; D3DParams.EnableAutoDepthStencil = true; D3DParams.AutoDepthStencilFormat = D3DFMT_D16; if(FAILED(_p_D3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &D3DParams, &_p_device))) { return -3; } D3DXCreateFont(_p_device, 12, 0, FW_NORMAL, 1, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Arial", &FPSFont); _p_device->SetFVF(particle_fvf); if(FAILED(D3DXCompileShaderFromFile( strPixelShader, NULL, NULL, "ps_main", "ps_2_0", 0, &_p_code, NULL, &_p_constant_able ))) { MessageBox(hWnd, "Error compiling Script", "Pixel Shader Compile Error", MB_ICONERROR); return 1; } _p_device->CreatePixelShader((DWORD*)_p_code->GetBufferPointer(), &_p_shader); _p_code->Release(); _p_code = NULL; //SHADOW Buffer Pixel Shaders if(FAILED(D3DXCompileShaderFromFile( strShadowPS, NULL, NULL, "ps_main", "ps_2_0", 0, &_p_code, NULL, &_p_SB_constant_able ))) { MessageBox(hWnd, "Error compiling Script", "Pixel Shader Compile Error", MB_ICONERROR); return 1; } _p_device->CreatePixelShader((DWORD*)_p_code->GetBufferPointer(), &_p_SB_shader); _p_code->Release(); _p_code = NULL; //SHADOW Buffer Vertex Shaders if(FAILED(D3DXCompileShaderFromFile( strShadowVS, NULL, NULL, "vs_main", "vs_2_0", 0, &_p_code, NULL, &_p_SB_vertex_constant_able ))) { MessageBox(hWnd, "Error compiling Script", "Vertex Shader Compile Error", MB_ICONERROR); return 1; } _p_device->CreateVertexShader((DWORD*)_p_code->GetBufferPointer(), &_p_SB_vshader); _p_code->Release(); _p_code = NULL; if(FAILED(D3DXCompileShaderFromFile( strCombinerShader, NULL, NULL, "ps_main", "ps_2_b", 0, &_p_code, NULL, &_p_constant_able ))) { MessageBox(hWnd, "Error compiling Script", "Pixel Shader Compile Error", MB_ICONERROR); return 1; } _p_device->CreatePixelShader((DWORD*)_p_code->GetBufferPointer(), &_p_combinershader); _p_code->Release(); _p_code = NULL; if(FAILED(D3DXCompileShaderFromFile( strScreenAlignShader, NULL, NULL, "vs_main", "vs_2_0", 0, &_p_code, NULL, &_p_constant_able ))) { MessageBox(hWnd, "Error compiling Script", "Vertex Shader Compile Error", MB_ICONERROR); return 1; } _p_device->CreateVertexShader((DWORD*)_p_code->GetBufferPointer(), &_p_alignshader); _p_code->Release(); _p_code = NULL; _p_device->SetFVF(light_fvf); if(FAILED(D3DXCompileShaderFromFile( strLightShader, NULL, NULL, "ps_main", "ps_2_0", 0, &_p_code, NULL, &_p_constant_able ))) { MessageBox(hWnd, "Error compiling Script", "Pixel Shader Compile Error", MB_ICONERROR); return 1; } _p_device->CreatePixelShader((DWORD*)_p_code->GetBufferPointer(), &_p_lightshader); _p_code->Release(); _p_code = NULL; _p_device->SetFVF(particle_fvf); if(FAILED(D3DXCompileShaderFromFile( strVertexShader, NULL, NULL, "vs_main", "vs_2_0", 0, &_p_code, NULL, &_p_vertex_constant_able ))) { MessageBox(hWnd, "Error compiling Script", "Vertex Shader Compile Error", MB_ICONERROR); return 1; } _p_device->CreateVertexShader((DWORD*)_p_code->GetBufferPointer(), &_p_vshader); _p_code->Release(); _p_code = NULL; hMatProjection = _p_vertex_constant_able->GetConstantByName(NULL, strMatProjection); hMatView = _p_vertex_constant_able->GetConstantByName(NULL, strMatView); hMatTexture = _p_vertex_constant_able->GetConstantByName(NULL, strMatTexture); hMatWorld = _p_vertex_constant_able->GetConstantByName(NULL, strMatWorld); hLightPosition = _p_vertex_constant_able->GetConstantByName(NULL, strLightPosition); hDeltaPos = _p_vertex_constant_able->GetConstantByName(NULL, strDeltaPos); hSBMatProjection = _p_SB_vertex_constant_able->GetConstantByName(NULL, strMatProjection); hSBMatWorld = _p_SB_vertex_constant_able->GetConstantByName(NULL, strMatWorld); //Setup our particle mesh. { LPD3DXMESH _tmp_mesh; if(FAILED(D3DXLoadMeshFromX(strCubeMesh, D3DXMESH_VB_MANAGED, _p_device, NULL, NULL, NULL, NULL, &_tmp_mesh))) { MessageBox(hWnd, "Error Loading Cube Model", "Mesh Load Error", MB_ICONERROR); return 1; } _tmp_mesh->CloneMeshFVF(D3DXMESH_VB_MANAGED, particle_fvf, _p_device, &_particle_Mesh); _tmp_mesh->Release(); } // We now have _p_physdk, _p_scene, _p_D3D, _p_device initialized // Setup the Camera CameraAngleX = (D3DX_PI/4)*3; CameraAngleY = 0; // Light Setup DrawLight.location = NxVec3(500, 500, 50); DrawLight.point_size = _particle_size; DrawLight.diffuse = (((_particle_color & 0xFF000000)>>24))<<24 | (((_particle_color & 0x00FF0000)>>16))<<16 | (((_particle_color & 0x0000FF00)>>8))<<8 | ((_particle_color & 0x000000FF)); D3DCAPS9 DevCaps; _p_device->GetDeviceCaps(&DevCaps); if(FAILED(_p_device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &_screen_buffer, NULL))) { MessageBox(hWnd, "Error Creating Texture", "Texture Error", MB_ICONERROR); return 1; } if(DevCaps.NumSimultaneousRTs > 1) { bMotionBlur = true; if(FAILED(_p_device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &_blur_buffer, NULL))) { MessageBox(hWnd, "Error Creating BLUR Texture", "Texture Error", MB_ICONERROR); return 1; } if(FAILED(_p_device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &_old_blur_buffer, NULL))) { MessageBox(hWnd, "Error Creating BLUR Texture", "Texture Error", MB_ICONERROR); return 1; } //_p_device->CreateRenderTarget(width, height, D3DFMT_D32, D3DMULTISAMPLE_NONE , 0, false, &_blur_buffer, NULL); } else bMotionBlur = false; if(FAILED(_p_device->CreateTexture(ShadowMapSize, ShadowMapSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &ShadowBuffer, NULL))) { MessageBox(hWnd, "Error Creating Shadow Buffer", "Texture Error", MB_ICONERROR); return 1; } while(loop_continue) { Frame(); if(PeekMessage(&msg, NULL, 0, 0, 1)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } return (int) msg.wParam; }
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; }
/// materials ids are set to shape descs virtual int GetMaterialID() { return (int)m_pNxMaterial->getMaterialIndex(); }