void DumpSkeleton(IDefaultSkeleton &rIDefaultSkeleton) { for (int i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i) { const char* name = rIDefaultSkeleton.GetJointNameByID(i); int parentid = rIDefaultSkeleton.GetJointParentIDByID(i); if (parentid != -1) CryLog("joint %i: %s (parent %i)", i, name, parentid); else CryLog("joint %i: %s", i, name); } }
bool CLookAtSimple::ValidateJointId(IDefaultSkeleton& rIDefaultSkeleton) { if (m_stateExecute.jointId < 0) return false; return m_stateExecute.jointId < rIDefaultSkeleton.GetJointCount(); }
//------------------------------------------------------------------------ void CVehiclePartAnimated::FlagSkeleton(ISkeletonPose* pSkeletonPose,IDefaultSkeleton &rIDefaultSkeleton) { if (!pSkeletonPose) return; IPhysicalEntity* pPhysics = GetEntity()->GetPhysics(); if (!pPhysics) return; string name; int idWater = rIDefaultSkeleton.GetJointIDByName("proxy_water"); uint32 buoyancyParts = (idWater != -1) ? 1 : 0; uint32 jointCount = rIDefaultSkeleton.GetJointCount(); for (uint32 i = 0; i < jointCount; ++i) { int physId = pSkeletonPose->GetPhysIdOnJoint(i); if (physId >= 0) { CheckColltypeHeavy(physId); name = rIDefaultSkeleton.GetJointNameByID(i); // when water proxy available, remove float from all others // if no water proxy, we leave only "proxy" parts floating if (idWater != -1) { if (i == idWater) { SetFlags(physId, geom_collides, false); SetFlagsCollider(physId, 0); } else SetFlags(physId, geom_floats, false); } else { if (name.find("proxy") != string::npos) ++buoyancyParts; else SetFlags(physId, geom_floats, false); } // all objects which have a corresponding *_proxy on the skeleton // are set to ray collision only if (name.find("_proxy") == string::npos) { name.append("_proxy"); int proxyId = rIDefaultSkeleton.GetJointIDByName(name.c_str()); if (proxyId != -1) { // remove ray collision from hull proxy(s) SetFlags(pSkeletonPose->GetPhysIdOnJoint(proxyId), geom_colltype_ray | geom_colltype13, false); // get StatObj from main part, to connect proxies foreignData with it IStatObj* pStatObj = pSkeletonPose->GetStatObjOnJoint(i); if (pStatObj) { pe_params_part params; params.partid = proxyId; if (pPhysics->GetParams(¶ms)) { if (params.pPhysGeom && params.pPhysGeom->pGeom) params.pPhysGeom->pGeom->SetForeignData(pStatObj, 0); } } for (int p = 2; p < 6; ++p) { // check additional proxies, by naming convention _02, .. _05 char buf[64]; cry_sprintf(buf, "%s_%02i", name.c_str(), p); proxyId = rIDefaultSkeleton.GetJointIDByName(buf); if (proxyId == -1) break; int proxyPhysId = pSkeletonPose->GetPhysIdOnJoint(proxyId); if (proxyPhysId == -1) continue; SetFlags(proxyPhysId, geom_colltype_ray | geom_colltype13, false); // connect proxies to main StatObj (needed for bullet tests, decals) if (pStatObj) { pe_params_part params; params.partid = proxyPhysId; if (pPhysics->GetParams(¶ms)) { if (params.pPhysGeom && params.pPhysGeom->pGeom) params.pPhysGeom->pGeom->SetForeignData(pStatObj, 0); } } } // set ray-collision only on the part SetFlags(physId, geom_collides | geom_floats, false); SetFlags(physId, geom_colltype_ray | geom_colltype13, true); SetFlagsCollider(physId, 0); } } } } if (buoyancyParts == 0) { // as fallback, use part with largest volume for buoyancy int partId = -1; float maxV = 0.f; pe_status_nparts nparts; int numParts = pPhysics->GetStatus(&nparts); for (int i = 0; i < numParts; ++i) { pe_params_part params; params.ipart = i; if (pPhysics->GetParams(¶ms)) { float v = (params.pPhysGeomProxy) ? params.pPhysGeomProxy->V : params.pPhysGeom->V; if (v > maxV) { partId = params.partid; maxV = v; } } } if (partId != -1) SetFlags(partId, geom_floats, true); else GameWarning("[CVehiclePartAnimated]: <%s> has no buoyancy parts! (Check material for correct physicalization setup properties)",GetEntity()->GetName()); } int jointId, physId; if ((jointId = rIDefaultSkeleton.GetJointIDByName("proxy_skirt")) != -1) { if ((physId = pSkeletonPose->GetPhysIdOnJoint(jointId)) != -1) { SetFlags(physId, geom_collides | geom_floats, false); SetFlags(physId, geom_colltype_ray | geom_colltype13 | geom_colltype_player | geom_colltype_foliage, true); SetFlagsCollider(physId, 0); } } // remove collision flags from all _proxy geoms by debug cvar // useful for seeing through, testing ray proxies etc if (VehicleCVars().v_disable_hull > 0) { for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i) { if (strstr(rIDefaultSkeleton.GetJointNameByID(i), "_proxy")) { SetFlags(pSkeletonPose->GetPhysIdOnJoint(i), geom_collides | geom_floats, false); SetFlagsCollider(pSkeletonPose->GetPhysIdOnJoint(i), 0); } } } }
//------------------------------------------------------------------------ bool CVehiclePartAnimated::ChangeState(EVehiclePartState state, int flags) { if ((state == eVGS_Default) && m_initialiseOnChangeState) { // Initialise! // Having to do this because of the way the glass code // swaps a cstatobj. The way the vehicle code stores its // statobj in m_intactStatObjs is going to need reviewing if (m_pCharInstance) { ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); ISkeletonPose* pSkeletonPoseDestroyed = m_pCharInstanceDestroyed ? m_pCharInstanceDestroyed->GetISkeletonPose() : NULL; IDefaultSkeleton* pICharacterModelSkeletonDestroyed = m_pCharInstanceDestroyed ? &m_pCharInstanceDestroyed->GetIDefaultSkeleton() : NULL; if (pSkeletonPose) { const bool bDestroyedSkelExists = pSkeletonPoseDestroyed && pICharacterModelSkeletonDestroyed; for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); i++) { if (IStatObj* pStatObjIntact = pSkeletonPose->GetStatObjOnJoint(i)) { const char* jointName = rIDefaultSkeleton.GetJointNameByID(i); if (m_intactStatObjs.find(CONST_TEMP_STRING(jointName)) == m_intactStatObjs.end()) { m_intactStatObjs.insert(TStringStatObjMap::value_type(jointName, pStatObjIntact)); } // tell the streaming engine to stream destroyed version together with non destroyed if (bDestroyedSkelExists && i < pICharacterModelSkeletonDestroyed->GetJointCount()) { if (IStatObj* pStatObjIntactDestroyed = pSkeletonPoseDestroyed->GetStatObjOnJoint(i)) { pStatObjIntact->SetStreamingDependencyFilePath(pStatObjIntactDestroyed->GetFilePath()); } } } } } } m_initialiseOnChangeState = false; } bool change = CVehiclePartBase::ChangeState(state, flags); if (state == eVGS_Default && !change) { // need to restore state if one of the children is in higher state EVehiclePartState maxState = GetMaxState(); if (maxState > m_state) change = true; } if (!change) { return false; } if (state == eVGS_Destroyed) { if (m_ignoreDestroyedState) return false; if (m_pCharInstance && m_pCharInstanceDestroyed) { ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); if (pSkeletonPose) { IMaterial* pDestroyedMaterial = m_pVehicle->GetDestroyedMaterial(); for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); i++) { if (IStatObj* pStatObjIntact = pSkeletonPose->GetStatObjOnJoint(i)) { const char* jointName = rIDefaultSkeleton.GetJointNameByID(i); IStatObj* pStatObj = GetDestroyedGeometry(jointName); // sets new StatObj to joint, if null, removes it. // object whose name includes "proxy" are not removed. if (pStatObj || !strstr(jointName, "proxy")) { SetCGASlot(i, pStatObj); if (pStatObj && !pDestroyedMaterial) { if (IMaterial* pMaterial = pStatObj->GetMaterial()) SetMaterial(pMaterial); } #if ENABLE_VEHICLE_DEBUG if (IsDebugParts()) { CryLog("swapping StatObj on joint %u (%s) -> %s", i, jointName, pStatObj ? pStatObj->GetGeoName() : "<NULL>"); } #endif } } } FlagSkeleton(pSkeletonPose, rIDefaultSkeleton); for (TStringVehiclePartMap::iterator ite = m_jointParts.begin(); ite != m_jointParts.end(); ++ite) { IVehiclePart* pPart = ite->second; pPart->ChangeState(state, flags | eVPSF_Physicalize); } CryCharAnimationParams animParams; animParams.m_nFlags |= CA_LOOP_ANIMATION; // pSkeleton->SetRedirectToLayer0(1); // pSkeleton->StartAnimation("Default",0, 0,0, animParams); // [MR: commented out on Ivos request] if (pDestroyedMaterial) { SetMaterial(pDestroyedMaterial); } } } } else if (state == eVGS_Default) { if (m_pCharInstance && m_pCharInstanceDestroyed) { // reset material (in case we replaced it with the destroyed material) IMaterial* pMaterial = m_pVehicle->GetPaintMaterial(); if (!pMaterial) { // no paint, so revert to the material already set on the character pMaterial = m_pCharInstance->GetIMaterial(); } if (pMaterial) { SetMaterial(pMaterial); } IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); { for (TStringStatObjMap::iterator ite = m_intactStatObjs.begin(); ite != m_intactStatObjs.end(); ++ite) { const string &jointName = ite->first; IStatObj* pStatObj = ite->second; int16 jointId = rIDefaultSkeleton.GetJointIDByName(jointName.c_str()); if (jointId > -1) { // if compound StatObj (from deformation), use first SubObj for restoring if (pStatObj != NULL) { if (!pStatObj->GetRenderMesh() && pStatObj->GetSubObjectCount() > 0) { pStatObj = pStatObj->GetSubObject(0)->pStatObj; } SetCGASlot(jointId, pStatObj); #if ENABLE_VEHICLE_DEBUG if (IsDebugParts()) CryLog("restoring StatObj on joint %i (%s) -> %s", jointId, jointName.c_str(), pStatObj ? pStatObj->GetGeoName() : "<NULL>"); #endif } TStringVehiclePartMap::iterator it = m_jointParts.find(jointName); if (it != m_jointParts.end()) { it->second->ChangeState(state, flags & ~eVPSF_Physicalize | eVPSF_Force); } } } flags |= eVPSF_Physicalize; } } } m_state = state; // physicalize after all parts have been restored if (flags & eVPSF_Physicalize && GetEntity()->GetPhysics()) { Physicalize(); for (TStringVehiclePartMap::iterator it = m_jointParts.begin(); it != m_jointParts.end(); ++it) { it->second->Physicalize(); } } return true; }