ColumnScoringMethod ColumnScorer::GetMethodForScorer(unsigned int scorerIndex) const { ColumnScoringMethod method = eInvalidColumnScorerMethod; if (scorerIndex == 0 && !IsCompound()) { method = GetMethod(); } else if (IsCompound() && scorerIndex < m_scorers.size()) { method = m_scorers[scorerIndex]->GetMethod(); } return method; }
/* 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); }
BOOL NodeRenderableInk::FactorOutCommonChildAttrHelper(BOOL Global, AttrTypeSet* pAffectedAttrTypes) { // This function should only ever get called on a compound object ENSURE(IsCompound(), "FactorOutCommonChildAttributes called on a non compound object"); CommonAttrSet CommonAttributeSet; // A list of CommonAttributeItems if (!FindCommonAttributesToFactorOut(&CommonAttributeSet)) // Ignores attr discard nodes { return FALSE; } NodeAttribute* pFactoredOutAttr; // Ok let's add the common attributes to the first child of the group CommonAttributeItem* pCommonAttr; for (pCommonAttr = (CommonAttributeItem*)CommonAttributeSet.GetHead(); pCommonAttr != NULL; pCommonAttr = (CommonAttributeItem*)CommonAttributeSet.GetNext(pCommonAttr)) { // Is the common attribute an attribute which should be factored out ? if (!pAffectedAttrTypes || (pAffectedAttrTypes->InSet(pCommonAttr->pAttr->GetAttributeType())) ) { //pCommonAttr->pAttr->MoveNode(this, FIRSTCHILD); // Take a copy of the node and insert it as a first child pFactoredOutAttr = (NodeAttribute*)(pCommonAttr->pAttr->SimpleCopy()); if (!pFactoredOutAttr) return FALSE; pFactoredOutAttr->AttachNode(this, FIRSTCHILD, TRUE, FALSE); } } // The CommonAttributeSet is no longer required CommonAttributeSet.DeleteAll(); // Do we need to factor out the parents attributes ? if (Global) { Node* pParent = FindParent(); if (pParent && (pParent->IsCompound())) { // We need to localise the parent's attributes first (Recursive bit) if (!(((NodeRenderableInk*)pParent)->FactorOutCommonChildAttrHelper(TRUE, pAffectedAttrTypes))) { return FALSE; // Failed } } } return TRUE; // Success }
BOOL NodeRenderableInk::FactorOutCommonChildAttributes(BOOL Global, AttrTypeSet* pAffectedAttrTypes) { // This function should only ever get called on a compound object ENSURE(IsCompound(), "FactorOutCommonChildAttributes called on a non compound object"); // Try to factor out the neccessary attributes if (!FactorOutCommonChildAttrHelper(Global, pAffectedAttrTypes)) { // Tidyup then return FAIL DeleteLocalisedAttributes(Global, pAffectedAttrTypes); // tidyup return FALSE; // Failed } else { // The only thing that remains now is to delete all remaining factored out attributes DeleteFactoredOutAttribs(Global, pAffectedAttrTypes); } return TRUE; // Success }
BOOL NodeRenderableInk::LocaliseCommonAttributes(BOOL CheckForDuplicates, BOOL Global, AttrTypeSet* pAffectedAttrTypes, BOOL RecursiveForChildren) { // This function should only ever get called on a compound object ENSURE(IsCompound(), "LocaliseCommonAttributes called on a non compound object"); // First of all let's try and localise the attributes. This is the bit that can fail if (!LocaliseCommonAttrHelper(CheckForDuplicates, Global, pAffectedAttrTypes, RecursiveForChildren)) { // We ran out of memory so we must, delete all attributes which were localised DeleteFactoredOutAttribs(Global, pAffectedAttrTypes); return FALSE; } else { // We managed to localise all the attributes so it is now safe to delete // them from the compounds. DeleteLocalisedAttributes(Global, pAffectedAttrTypes); return TRUE; } }
/* 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); }