bool KX_SoftBodyDeformer::Apply(class RAS_IPolyMaterial *polymat) { KX_BulletPhysicsController* ctrl = (KX_BulletPhysicsController*) m_gameobj->GetPhysicsController(); if (!ctrl) return false; btSoftBody* softBody= ctrl->GetSoftBody(); if (!softBody) return false; //printf("apply\n"); RAS_MeshSlot::iterator it; RAS_MeshMaterial *mmat; RAS_MeshSlot *slot; size_t i; // update the vertex in m_transverts Update(); // The vertex cache can only be updated for this deformer: // Duplicated objects with more than one ploymaterial (=multiple mesh slot per object) // share the same mesh (=the same cache). As the rendering is done per polymaterial // cycling through the objects, the entire mesh cache cannot be updated in one shot. mmat = m_pMeshObject->GetMeshMaterial(polymat); if(!mmat->m_slots[(void*)m_gameobj]) return true; slot = *mmat->m_slots[(void*)m_gameobj]; // for each array for(slot->begin(it); !slot->end(it); slot->next(it)) { btSoftBody::tNodeArray& nodes(softBody->m_nodes); int index = 0; for(i=it.startvertex; i<it.endvertex; i++,index++) { RAS_TexVert& v = it.vertex[i]; btAssert(v.getSoftBodyIndex() >= 0); MT_Point3 pt ( nodes[v.getSoftBodyIndex()].m_x.getX(), nodes[v.getSoftBodyIndex()].m_x.getY(), nodes[v.getSoftBodyIndex()].m_x.getZ()); v.SetXYZ(pt); MT_Vector3 normal ( nodes[v.getSoftBodyIndex()].m_n.getX(), nodes[v.getSoftBodyIndex()].m_n.getY(), nodes[v.getSoftBodyIndex()].m_n.getZ()); v.SetNormal(normal); } } return true; }
/* Reverse function of the above, it will remove a shape from a compound shape * provided that the former was added to the later using AddCompoundChild() */ void KX_BulletPhysicsController::RemoveCompoundChild(KX_IPhysicsController* child) { if (child == NULL || !IsCompound()) return; // other controller must be a bullet controller too // verify that body and shape exist and match KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child); btRigidBody* rootBody = GetRigidBody(); btRigidBody* childBody = childCtrl->GetRigidBody(); if (!rootBody || !childBody) return; const btCollisionShape* rootShape = rootBody->getCollisionShape(); if (!rootShape || rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE) return; btCompoundShape* compoundShape = (btCompoundShape*)rootShape; // retrieve the shapeInfo CcdShapeConstructionInfo* childShapeInfo = childCtrl->GetShapeInfo(); CcdShapeConstructionInfo* rootShapeInfo = GetShapeInfo(); // and verify that the child is part of the parent int i = rootShapeInfo->FindChildShape(childShapeInfo, childCtrl); if (i < 0) return; rootShapeInfo->RemoveChildShape(i); if (childCtrl->m_bulletChildShape) { int numChildren = compoundShape->getNumChildShapes(); for (i=0; i<numChildren; i++) { if (compoundShape->getChildShape(i) == childCtrl->m_bulletChildShape) { compoundShape->removeChildShapeByIndex(i); compoundShape->recalculateLocalAabb(); break; } } delete childCtrl->m_bulletChildShape; childCtrl->m_bulletChildShape = NULL; } // recompute inertia of parent if (!rootBody->isStaticOrKinematicObject()) { btVector3 localInertia; float mass = 1.f/rootBody->getInvMass(); compoundShape->calculateLocalInertia(mass,localInertia); rootBody->setMassProps(mass,localInertia); } // must update the broadphase cache, GetPhysicsEnvironment()->refreshCcdPhysicsController(this); // reactivate the children GetPhysicsEnvironment()->enableCcdPhysicsController(childCtrl); }
SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode) { PHY_IMotionState* motionstate = new KX_MotionState(destnode); KX_BulletPhysicsController* physicsreplica = new KX_BulletPhysicsController(*this); //parentcontroller is here be able to avoid collisions between parent/child PHY_IPhysicsController* parentctrl = NULL; KX_BulletPhysicsController* parentKxCtrl = NULL; CcdPhysicsController* ccdParent = NULL; if (destnode != destnode->GetRootSGParent()) { KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject(); if (clientgameobj) { parentctrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController(); } else { // it could be a false node, try the children NodeList::const_iterator childit; for ( childit = destnode->GetSGChildren().begin(); childit!= destnode->GetSGChildren().end(); ++childit ) { KX_GameObject *clientgameobj_child = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject()); if (clientgameobj_child) { parentKxCtrl = (KX_BulletPhysicsController*)clientgameobj_child->GetPhysicsController(); parentctrl = parentKxCtrl; ccdParent = parentKxCtrl; } } } } physicsreplica->setParentCtrl(ccdParent); physicsreplica->PostProcessReplica(motionstate,parentctrl); physicsreplica->m_userdata = (PHY_IPhysicsController*)physicsreplica; physicsreplica->m_bulletChildShape = NULL; return physicsreplica; }
/* This function dynamically adds the collision shape of another controller to * the current controller shape provided it is a compound shape. * The idea is that dynamic parenting on a compound object will dynamically extend the shape */ void KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* child) { if (child == NULL || !IsCompound()) return; // other controller must be a bullet controller too // verify that body and shape exist and match KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child); btRigidBody* rootBody = GetRigidBody(); btRigidBody* childBody = childCtrl->GetRigidBody(); if (!rootBody || !childBody) return; const btCollisionShape* rootShape = rootBody->getCollisionShape(); const btCollisionShape* childShape = childBody->getCollisionShape(); if (!rootShape || !childShape || rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE || childShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) return; btCompoundShape* compoundShape = (btCompoundShape*)rootShape; // compute relative transformation between parent and child btTransform rootTrans; btTransform childTrans; rootBody->getMotionState()->getWorldTransform(rootTrans); childBody->getMotionState()->getWorldTransform(childTrans); btVector3 rootScale = rootShape->getLocalScaling(); rootScale[0] = 1.0/rootScale[0]; rootScale[1] = 1.0/rootScale[1]; rootScale[2] = 1.0/rootScale[2]; // relative scale = child_scale/parent_scale btVector3 relativeScale = childShape->getLocalScaling()*rootScale; btMatrix3x3 rootRotInverse = rootTrans.getBasis().transpose(); // relative pos = parent_rot^-1 * ((parent_pos-child_pos)/parent_scale) btVector3 relativePos = rootRotInverse*((childTrans.getOrigin()-rootTrans.getOrigin())*rootScale); // relative rot = parent_rot^-1 * child_rot btMatrix3x3 relativeRot = rootRotInverse*childTrans.getBasis(); // create a proxy shape info to store the transformation CcdShapeConstructionInfo* proxyShapeInfo = new CcdShapeConstructionInfo(); // store the transformation to this object shapeinfo proxyShapeInfo->m_childTrans.setOrigin(relativePos); proxyShapeInfo->m_childTrans.setBasis(relativeRot); proxyShapeInfo->m_childScale.setValue(relativeScale[0], relativeScale[1], relativeScale[2]); // we will need this to make sure that we remove the right proxy later when unparenting proxyShapeInfo->m_userData = childCtrl; proxyShapeInfo->SetProxy(childCtrl->GetShapeInfo()->AddRef()); // add to parent compound shapeinfo (increments ref count) GetShapeInfo()->AddShape(proxyShapeInfo); // create new bullet collision shape from the object shapeinfo and set scaling btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(childCtrl->GetMargin(), childCtrl->getConstructionInfo().m_bGimpact, true); newChildShape->setLocalScaling(relativeScale); // add bullet collision shape to parent compound collision shape compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape); // proxyShapeInfo is not needed anymore, release it proxyShapeInfo->Release(); // remember we created this shape childCtrl->m_bulletChildShape = newChildShape; // recompute inertia of parent if (!rootBody->isStaticOrKinematicObject()) { btVector3 localInertia; float mass = 1.f/rootBody->getInvMass(); compoundShape->calculateLocalInertia(mass,localInertia); rootBody->setMassProps(mass,localInertia); } // must update the broadphase cache, GetPhysicsEnvironment()->refreshCcdPhysicsController(this); // remove the children GetPhysicsEnvironment()->disableCcdPhysicsController(childCtrl); }
void KX_ConvertBulletObject( class KX_GameObject* gameobj, class RAS_MeshObject* meshobj, struct DerivedMesh* dm, class KX_Scene* kxscene, struct PHY_ShapeProps* shapeprops, struct PHY_MaterialProps* smmaterial, struct KX_ObjectProperties* objprop) { CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); assert(env); bool isbulletdyna = false; bool isbulletsensor = false; bool isbulletchar = false; bool useGimpact = false; CcdConstructionInfo ci; class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo(); if (!objprop->m_dyna) { ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; } if (objprop->m_ghost) { ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE; } ci.m_MotionState = motionstate; ci.m_gravity = btVector3(0,0,0); ci.m_linearFactor = btVector3(objprop->m_lockXaxis? 0 : 1, objprop->m_lockYaxis? 0 : 1, objprop->m_lockZaxis? 0 : 1); ci.m_angularFactor = btVector3(objprop->m_lockXRotaxis? 0 : 1, objprop->m_lockYRotaxis? 0 : 1, objprop->m_lockZRotaxis? 0 : 1); ci.m_localInertiaTensor =btVector3(0,0,0); ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f; ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min; ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max; ci.m_margin = objprop->m_margin; ci.m_stepHeight = objprop->m_character ? shapeprops->m_step_height : 0.f; ci.m_jumpSpeed = objprop->m_character ? shapeprops->m_jump_speed : 0.f; ci.m_fallSpeed = objprop->m_character ? shapeprops->m_fall_speed : 0.f; shapeInfo->m_radius = objprop->m_radius; isbulletdyna = objprop->m_dyna; isbulletsensor = objprop->m_sensor; isbulletchar = objprop->m_character; useGimpact = ((isbulletdyna || isbulletsensor) && !objprop->m_softbody); ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f); btCollisionShape* bm = 0; switch (objprop->m_boundclass) { case KX_BOUNDSPHERE: { //float radius = objprop->m_radius; //btVector3 inertiaHalfExtents ( // radius, // radius, // radius); //blender doesn't support multisphere, but for testing: //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1); shapeInfo->m_shapeType = PHY_SHAPE_SPHERE; bm = shapeInfo->CreateBulletShape(ci.m_margin); break; }; case KX_BOUNDBOX: { shapeInfo->m_halfExtend.setValue( objprop->m_boundobject.box.m_extends[0], objprop->m_boundobject.box.m_extends[1], objprop->m_boundobject.box.m_extends[2]); shapeInfo->m_halfExtend /= 2.0; shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute(); shapeInfo->m_shapeType = PHY_SHAPE_BOX; bm = shapeInfo->CreateBulletShape(ci.m_margin); break; }; case KX_BOUNDCYLINDER: { shapeInfo->m_halfExtend.setValue( objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height * 0.5f ); shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER; bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDCONE: { shapeInfo->m_radius = objprop->m_boundobject.c.m_radius; shapeInfo->m_height = objprop->m_boundobject.c.m_height; shapeInfo->m_shapeType = PHY_SHAPE_CONE; bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDPOLYTOPE: { shapeInfo->SetMesh(meshobj, dm,true); bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDCAPSULE: { shapeInfo->m_radius = objprop->m_boundobject.c.m_radius; shapeInfo->m_height = objprop->m_boundobject.c.m_height; shapeInfo->m_shapeType = PHY_SHAPE_CAPSULE; bm = shapeInfo->CreateBulletShape(ci.m_margin); break; } case KX_BOUNDMESH: { // mesh shapes can be shared, check first if we already have a shape on that mesh class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false); if (sharedShapeInfo != NULL) { shapeInfo->Release(); shapeInfo = sharedShapeInfo; shapeInfo->AddRef(); } else { shapeInfo->SetMesh(meshobj, dm, false); } // Soft bodies can benefit from welding, don't do it on non-soft bodies if (objprop->m_softbody) { shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI } bm = shapeInfo->CreateBulletShape(ci.m_margin, useGimpact, !objprop->m_softbody); //should we compute inertia for dynamic shape? //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor); break; } case KX_BOUND_DYN_MESH: /* do nothing */ break; } // ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f); if (!bm) { delete motionstate; shapeInfo->Release(); return; } //bm->setMargin(ci.m_margin); if (objprop->m_isCompoundChild) { //find parent, compound shape and add to it //take relative transform into account! KX_BulletPhysicsController* parentCtrl = (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController(); assert(parentCtrl); CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo(); btRigidBody* rigidbody = parentCtrl->GetRigidBody(); btCollisionShape* colShape = rigidbody->getCollisionShape(); assert(colShape->isCompound()); btCompoundShape* compoundShape = (btCompoundShape*)colShape; // compute the local transform from parent, this may include several node in the chain SG_Node* gameNode = gameobj->GetSGNode(); SG_Node* parentNode = objprop->m_dynamic_parent->GetSGNode(); // relative transform MT_Vector3 parentScale = parentNode->GetWorldScaling(); parentScale[0] = MT_Scalar(1.0)/parentScale[0]; parentScale[1] = MT_Scalar(1.0)/parentScale[1]; parentScale[2] = MT_Scalar(1.0)/parentScale[2]; MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale; MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed(); MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale); MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation(); shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]); bm->setLocalScaling(shapeInfo->m_childScale); shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]); float rot[12]; relativeRot.getValue(rot); shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot); parentShapeInfo->AddShape(shapeInfo); compoundShape->addChildShape(shapeInfo->m_childTrans,bm); //do some recalc? //recalc inertia for rigidbody if (!rigidbody->isStaticOrKinematicObject()) { btVector3 localInertia; float mass = 1.f/rigidbody->getInvMass(); compoundShape->calculateLocalInertia(mass,localInertia); rigidbody->setMassProps(mass,localInertia); } shapeInfo->Release(); // delete motionstate as it's not used delete motionstate; return; } if (objprop->m_hasCompoundChildren) { // create a compound shape info CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo(); compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND; compoundShapeInfo->AddShape(shapeInfo); // create the compound shape manually as we already have the child shape btCompoundShape* compoundShape = new btCompoundShape(); compoundShape->addChildShape(shapeInfo->m_childTrans,bm); // now replace the shape bm = compoundShape; shapeInfo->Release(); shapeInfo = compoundShapeInfo; } #ifdef TEST_SIMD_HULL if (bm->IsPolyhedral()) { PolyhedralConvexShape* polyhedron = static_cast<PolyhedralConvexShape*>(bm); if (!polyhedron->m_optionalHull) { //first convert vertices in 'Point3' format int numPoints = polyhedron->GetNumVertices(); Point3* points = new Point3[numPoints+1]; //first 4 points should not be co-planar, so add central point to satisfy MakeHull points[0] = Point3(0.f,0.f,0.f); btVector3 vertex; for (int p=0;p<numPoints;p++) { polyhedron->GetVertex(p,vertex); points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ()); } Hull* hull = Hull::MakeHull(numPoints+1,points); polyhedron->m_optionalHull = hull; } } #endif //TEST_SIMD_HULL ci.m_collisionShape = bm; ci.m_shapeInfo = shapeInfo; ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice ci.m_restitution = smmaterial->m_restitution; ci.m_physicsEnv = env; // drag / damping is inverted ci.m_linearDamping = 1.f - shapeprops->m_lin_drag; ci.m_angularDamping = 1.f - shapeprops->m_ang_drag; //need a bit of damping, else system doesn't behave well ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behavior ci.m_do_anisotropic = shapeprops->m_do_anisotropic; ci.m_anisotropicFriction.setValue(shapeprops->m_friction_scaling[0],shapeprops->m_friction_scaling[1],shapeprops->m_friction_scaling[2]); ////////// //do Fh, do Rot Fh ci.m_do_fh = shapeprops->m_do_fh; ci.m_do_rot_fh = shapeprops->m_do_rot_fh; ci.m_fh_damping = smmaterial->m_fh_damping; ci.m_fh_distance = smmaterial->m_fh_distance; ci.m_fh_normal = smmaterial->m_fh_normal; ci.m_fh_spring = smmaterial->m_fh_spring; ci.m_radius = objprop->m_radius; /////////////////// ci.m_gamesoftFlag = objprop->m_gamesoftFlag; ci.m_soft_linStiff = objprop->m_soft_linStiff; ci.m_soft_angStiff = objprop->m_soft_angStiff; /* angular stiffness 0..1 */ ci.m_soft_volume= objprop->m_soft_volume; /* volume preservation 0..1 */ ci.m_soft_viterations= objprop->m_soft_viterations; /* Velocities solver iterations */ ci.m_soft_piterations= objprop->m_soft_piterations; /* Positions solver iterations */ ci.m_soft_diterations= objprop->m_soft_diterations; /* Drift solver iterations */ ci.m_soft_citerations= objprop->m_soft_citerations; /* Cluster solver iterations */ ci.m_soft_kSRHR_CL= objprop->m_soft_kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */ ci.m_soft_kSKHR_CL= objprop->m_soft_kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */ ci.m_soft_kSSHR_CL= objprop->m_soft_kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */ ci.m_soft_kSR_SPLT_CL= objprop->m_soft_kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ ci.m_soft_kSK_SPLT_CL= objprop->m_soft_kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ ci.m_soft_kSS_SPLT_CL= objprop->m_soft_kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ ci.m_soft_kVCF= objprop->m_soft_kVCF; /* Velocities correction factor (Baumgarte) */ ci.m_soft_kDP= objprop->m_soft_kDP; /* Damping coefficient [0,1] */ ci.m_soft_kDG= objprop->m_soft_kDG; /* Drag coefficient [0,+inf] */ ci.m_soft_kLF= objprop->m_soft_kLF; /* Lift coefficient [0,+inf] */ ci.m_soft_kPR= objprop->m_soft_kPR; /* Pressure coefficient [-inf,+inf] */ ci.m_soft_kVC= objprop->m_soft_kVC; /* Volume conversation coefficient [0,+inf] */ ci.m_soft_kDF= objprop->m_soft_kDF; /* Dynamic friction coefficient [0,1] */ ci.m_soft_kMT= objprop->m_soft_kMT; /* Pose matching coefficient [0,1] */ ci.m_soft_kCHR= objprop->m_soft_kCHR; /* Rigid contacts hardness [0,1] */ ci.m_soft_kKHR= objprop->m_soft_kKHR; /* Kinetic contacts hardness [0,1] */ ci.m_soft_kSHR= objprop->m_soft_kSHR; /* Soft contacts hardness [0,1] */ ci.m_soft_kAHR= objprop->m_soft_kAHR; /* Anchors hardness [0,1] */ ci.m_soft_collisionflags= objprop->m_soft_collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ ci.m_soft_numclusteriterations= objprop->m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/ //////////////////// ci.m_collisionFilterGroup = (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) : (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : (isbulletchar) ? short(CcdConstructionInfo::CharacterFilter) : short(CcdConstructionInfo::StaticFilter); ci.m_collisionFilterMask = (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) : (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : (isbulletchar) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody; ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so ci.m_bSoft = objprop->m_softbody; ci.m_bSensor = isbulletsensor; ci.m_bCharacter = isbulletchar; ci.m_bGimpact = useGimpact; MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]); KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,isbulletchar,objprop->m_hasCompoundChildren); // shapeInfo is reference counted, decrement now as we don't use it anymore if (shapeInfo) shapeInfo->Release(); gameobj->SetPhysicsController(physicscontroller,isbulletdyna); // don't add automatically sensor object, they are added when a collision sensor is registered if (!isbulletsensor && objprop->m_in_active_layer) { env->addCcdPhysicsController( physicscontroller); } physicscontroller->setNewClientInfo(gameobj->getClientInfo()); { btRigidBody* rbody = physicscontroller->GetRigidBody(); if (rbody) { if (objprop->m_angular_rigidbody) { rbody->setLinearFactor(ci.m_linearFactor); rbody->setAngularFactor(ci.m_angularFactor); } if (rbody && objprop->m_disableSleeping) { rbody->setActivationState(DISABLE_DEACTIVATION); } } } CcdPhysicsController* parentCtrl = objprop->m_dynamic_parent ? (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController() : 0; physicscontroller->setParentCtrl(parentCtrl); //Now done directly in ci.m_collisionFlags so that it propagates to replica //if (objprop->m_ghost) //{ // rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); //} if (objprop->m_dyna && !objprop->m_angular_rigidbody) { #if 0 //setting the inertia could achieve similar results to constraint the up //but it is prone to instability, so use special 'Angular' constraint btVector3 inertia = physicscontroller->GetRigidBody()->getInvInertiaDiagLocal(); inertia.setX(0.f); inertia.setZ(0.f); physicscontroller->GetRigidBody()->setInvInertiaDiagLocal(inertia); physicscontroller->GetRigidBody()->updateInertiaTensor(); #endif //env->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1); //Now done directly in ci.m_bRigid so that it propagates to replica //physicscontroller->GetRigidBody()->setAngularFactor(0.f); ; } bool isActor = objprop->m_isactor; gameobj->getClientInfo()->m_type = (isbulletsensor) ? ((isActor) ? KX_ClientObjectInfo::OBACTORSENSOR : KX_ClientObjectInfo::OBSENSOR) : (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC; // store materialname in auxinfo, needed for touchsensors if (meshobj) { const STR_String& matname=meshobj->GetMaterialName(0); gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL); } else { gameobj->getClientInfo()->m_auxilary_info = 0; } gameobj->GetSGNode()->AddSGController(physicscontroller); STR_String materialname; if (meshobj) materialname = meshobj->GetMaterialName(0); physicscontroller->SetObject(gameobj->GetSGNode()); #if 0 ///test for soft bodies if (objprop->m_softbody && physicscontroller) { btSoftBody* softBody = physicscontroller->GetSoftBody(); if (softBody && gameobj->GetMesh(0))//only the first mesh, if any { //should be a mesh then, so add a soft body deformer KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj); gameobj->SetDeformer(softbodyDeformer); } } #endif }