bool plMultistageBehComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { // Create the stage vector plAnimStageVec* animStages = new plAnimStageVec; int numStages = fStages.size(); animStages->reserve(numStages); // Convert the stages and add them to the vector for (int i = 0; i < numStages; i++) { plBaseStage* stage = fStages[i]; plAnimStage* animStage = stage->CreateStage(); animStages->push_back(animStage); } // re-find the mod and attach it plMultistageBehMod* mod = fMods[node]; std::vector<plKey> receivers; IGetReceivers(node, receivers); mod->Init(animStages, fFreezePhys, fSmartSeek, fReverseFBOnRelease, &receivers); node->AddModifier(mod, IGetUniqueName(node)); return true; }
void plAvatarComponent::IAttachModifiers(plMaxNode *node, plErrorMsg *pErrMsg) { plString name = node->GetKey()->GetName(); plMaxNode *meshNode = (plMaxNode *)fCompPB->GetINode(plAvatarComponent::kMeshNode); plKey meshKey = meshNode->GetSceneObject()->GetKey(); plMaxNode *animRootNode = (plMaxNode *)fCompPB->GetINode(plAvatarComponent::kRootNode); plKey animRootKey = animRootNode->GetSceneObject()->GetKey(); plSceneObject * bodySO = node->GetSceneObject(); plArmatureMod* avMod = new plArmatureMod(); avMod->SetRootName(name); avMod->AppendMeshKey(meshKey); int skeletonType = fCompPB->GetInt(ParamID(kSkeleton)); avMod->SetBodyType( skeletonType ); // only make a human brain if we're a human if (skeletonType == plArmatureMod::kBoneBaseCritter) avMod->PushBrain(new plAvBrainCritter()); else avMod->PushBrain(new plAvBrainHuman(skeletonType == plArmatureMod::kBoneBaseActor)); avMod->SetBodyAgeName(node->GetAgeName()); avMod->SetBodyFootstepSoundPage(fCompPB->GetStr(ParamID(kBodyFootstepSoundPage))); avMod->SetAnimationPrefix(plString::FromUtf8(fCompPB->GetStr(ParamID(kAnimationPrefix)))); //AddLinkSound(node, node->GetSceneObject()->GetKey(), pErrMsg ); plKey avKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), avMod, node->GetLocation()); plObjRefMsg *objRefMsg = new plObjRefMsg(bodySO->GetKey(), plRefMsg::kOnCreate,-1, plObjRefMsg::kModifier); hsgResMgr::ResMgr()->AddViaNotify(avKey, objRefMsg, plRefFlags::kActiveRef); fArmMod = avMod; }
bool plGrassComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) { fShader = new plGrassShaderMod(); plLoadMask loadMask; int qual = 1; int cap = plQuality::kPS_1_1; plLoadMask::ComputeRepMasks(1, &qual, &cap, &loadMask); plKey modKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), fShader, node->GetLocation(), loadMask); int i; for (i = 0; i < plGrassShaderMod::kNumWaves; i++) { fShader->fWaves[i].fDistX = fCompPB->GetFloat(ParamID(kDistXTab), 0, i); fShader->fWaves[i].fDistY = fCompPB->GetFloat(ParamID(kDistYTab), 0, i); fShader->fWaves[i].fDistZ = fCompPB->GetFloat(ParamID(kDistZTab), 0, i); fShader->fWaves[i].fDirX = fCompPB->GetFloat(ParamID(kDirXTab), 0, i); fShader->fWaves[i].fDirY = fCompPB->GetFloat(ParamID(kDirYTab), 0, i); fShader->fWaves[i].fSpeed = fCompPB->GetFloat(ParamID(kSpeedTab), 0, i); } // Add a ref to the shader. fShader->GetKey()->RefObject(); return true; }
hsBool plMaintainersMarkerComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { plMaintainersMarkerModifier* pSpawn = new plMaintainersMarkerModifier; pSpawn->SetCalibrated(fCompPB->GetInt(kCalibrated)); node->AddModifier(pSpawn, IGetUniqueName(node)); return true; }
hsBool plResponderComponent::PreConvert(plMaxNode *node,plErrorMsg *pErrMsg) { plSceneObject* rObj = node->GetSceneObject(); plLocation loc = node->GetLocation(); // Create and register the RESPONDER's logic component plResponderModifier *responder = new plResponderModifier; plKey responderKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), responder, loc); hsgResMgr::ResMgr()->AddViaNotify(responderKey, new plObjRefMsg(rObj->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); // Tell all the activators to notify us for (int i = 0; i < fCompPB->Count(kResponderActivators); i++) { plMaxNode *activatorNode = (plMaxNode*)fCompPB->GetINode(kResponderActivators, 0, i); plComponentBase *comp = activatorNode ? activatorNode->ConvertToComponent() : nil; if (comp) { if (fCompPB->GetInt(kResponderLocalDetect)) comp->AddReceiverKey(responderKey, node); else comp->AddReceiverKey(responderKey); } } fModKeys[node] = responderKey; return true; }
void plLODAvatarComponent::IAttachModifiers( plMaxNode *node, plErrorMsg *pErrMsg) { plString avatarName = node->GetKey()->GetName(); plMaxNode *animRoot = (plMaxNode *)fCompPB->GetINode(plLODAvatarComponent::kRootNodeAddBtn); plKey animRootKey = animRoot->GetSceneObject()->GetKey(); plArmatureLODMod* avMod = new plArmatureLODMod(avatarName); int skeletonType = fCompPB->GetInt(ParamID(kSkeleton)); avMod->SetBodyType( skeletonType ); if (skeletonType == plArmatureLODMod::kBoneBaseCritter) avMod->PushBrain(new plAvBrainCritter()); else avMod->PushBrain(new plAvBrainHuman(skeletonType == plArmatureMod::kBoneBaseActor)); avMod->SetBodyAgeName(node->GetAgeName()); avMod->SetBodyFootstepSoundPage(fCompPB->GetStr(ParamID(kBodyFootstepSoundPage))); avMod->SetAnimationPrefix(plString::FromUtf8(fCompPB->GetStr(ParamID(kAnimationPrefix)))); int iLODCount = fCompPB->Count(plLODAvatarComponent::kMeshNodeTab); for (int i = 0; i < iLODCount; i++) { plMaxNode *meshNode = (plMaxNode *)fCompPB->GetINode(plLODAvatarComponent::kMeshNodeTab, 0, i); plKey meshKey = meshNode->GetSceneObject()->GetKey(); avMod->AppendMeshKey(meshKey); } node->AddModifier(avMod, IGetUniqueName(node)); fArmMod = avMod; IAttachShadowCastToLODs(node); }
// // PreConvert done below // bool plMultistageBehComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) { //create the modifier here so that other components can find it plMultistageBehMod *mod = new plMultistageBehMod; hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), mod, node->GetLocation()); fMods[node] = mod; return true; }
// this is a little gross...the armature component shouldn't know that the subclasses // actually exist....it's a hard-to-detect implementation detail that breaks new subclasses.... bool plArmatureComponent::Convert(plMaxNode* node, plErrorMsg *pErrMsg) { // plHKPhysical *physical = plHKPhysical::ConvertToPhysical(node->GetSceneObject()); // physical->SetProperty(plSimulationInterface::kUpright, true); IAttachModifiers(node, pErrMsg); ISetupClothes(node, fArmMod, pErrMsg); // ArmatureEffects plArmatureEffectsMgr *effects = new plArmatureEffectsMgr(); hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), effects, node->GetLocation()); plGenRefMsg *msg = new plGenRefMsg(fArmMod->GetKey(), plRefMsg::kOnCreate, -1, -1); hsgResMgr::ResMgr()->AddViaNotify(effects->GetKey(), msg, plRefFlags::kActiveRef); // Attach effects plSceneObject *obj = node->GetSceneObject(); node->MakeCharacterHierarchy(pErrMsg); const plAGModifier *temp = static_cast<const plAGModifier *>(FindModifierByClass(obj, plAGModifier::Index())); plAGModifier *agMod = const_cast<plAGModifier *>(temp); hsAssert(agMod, "Armature root didn't get a agmod. I'll make one for you."); if( ! agMod) { // MakeCharacterHierarchy will attach agmodifiers to all the bones in the hierarchy; // have to manually add any for non-bone objects... agMod = new plAGModifier("Handle"); // the player root is known as the handle node->AddModifier(agMod, IGetUniqueName(node)); } agMod->SetChannelName("Handle"); // Get the position and radius of the head and torso physicals if (ClassID() == AVATAR_CLASS_ID || ClassID() == LOD_AVATAR_CLASS_ID) { bool isLOD = ((ClassID() == LOD_AVATAR_CLASS_ID) != 0); float height = fCompPB->GetFloat(isLOD ? plLODAvatarComponent::kPhysicsHeight : plAvatarComponent::kPhysicsHeight); float width = fCompPB->GetFloat(isLOD ? plLODAvatarComponent::kPhysicsWidth : plAvatarComponent::kPhysicsWidth); fArmMod->SetPhysicalDims(height, width); } // node->SetupBonesAliasesRecur(node->GetKey()->GetName()); return true; }
hsBool plStrongSpringConstraintComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { plStrongSpringConstraintMod* HMod = new plStrongSpringConstraintMod; HMod->SetDamp(fCompPB->GetFloat(kStrength)); HMod->SetRR(fCompPB->GetFloat(kRebound)); //No MaximumTorque here, might as well use that field for the Pinned state for the Parent... HMod->SetParentPin(fCompPB->GetInt(kParentPinnedBool)); Object *obj = fCompPB->GetINode(kParent)->EvalWorldState(0/*hsConverterUtils::Instance().GetTime(GetInterface())*/).obj; plKey ParentKey = nil; if(fCompPB->GetINode(kParent)) if(((plMaxNode*)fCompPB->GetINode(kParent))->CanConvert() && (obj->ClassID() == Class_ID(DUMMY_CLASS_ID,0) || obj->SuperClassID() == GEOMOBJECT_CLASS_ID )) { plMaxNode* ParentNode = (plMaxNode*)fCompPB->GetINode(kParent); ParentKey = ParentNode->GetKey(); } else { pErrMsg->Set(true, "Ignored Parent Node", "Parent Node %s was set to be Ignored. Bad! Bad!.", (fCompPB->GetINode(kParent)->GetName())); pErrMsg->Set(false); return false; } else { // pErrMsg->Set(true, "Bad Parent Node", " Parent Node %s wasn't selected. Strong Spring Constraint failed.", (fCompPB->GetINode(kParent)->GetName())); // pErrMsg->Set(false); // return false; } //No motor Angle here, might as well use the field for Length Storage... HMod->SetFixedLength(fCompPB->GetFloat(kLength)); node->AddModifier(HMod, IGetUniqueName(node)); hsgResMgr::ResMgr()->AddViaNotify( ParentKey, new plGenRefMsg( HMod->GetKey(), plRefMsg::kOnCreate, plHavokConstraintsMod::kParentIdx, 0 ), plRefFlags::kPassiveRef ); hsgResMgr::ResMgr()->AddViaNotify( node->GetKey(), new plGenRefMsg( HMod->GetKey(), plRefMsg::kOnCreate, plHavokConstraintsMod::kChildIdx, 0 ), plRefFlags::kPassiveRef ); return true; }
// // PreConvert done below // bool plOneShotComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) { if (IsValid()) { plOneShotMod *mod = new plOneShotMod; hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), mod, node->GetLocation()); fMods[node] = mod; } return true; }
hsBool plPhysBridgeComponent::Convert(plMaxNode* node, plErrorMsg* errMsg) { plMaxNode* parent = nil; // Find the parent for this section int count = fCompPB->Count(kSections); for (int i = 0; i < count; i++) { plMaxNode* curNode = (plMaxNode*)fCompPB->GetINode(kSections, 0, i); if (curNode == node) { if (i < count-1) parent = (plMaxNode*)fCompPB->GetINode(kSections, 0, i+1); break; } } // No parent, must be the end anchor for the bridge if (!parent) return false; plHingeConstraintMod* mod = new plHingeConstraintMod; // mod->SetHCFriction(0, 1.f); mod->SetRR(fCompPB->GetFloat(kStrength));//1.f / sqrt(float(count))); mod->SetDamp(fCompPB->GetFloat(kStiffness)); // Grab the pivot point from the child translate hsPoint3 pivot = node->GetLocalToWorld44().GetTranslate(); hsVector3 pivotVec; pivotVec.Set(pivot.fX, pivot.fY, pivot.fZ); mod->SetPP(pivotVec); // Cut'n'Paste enum { kYAxis, kXAxis, kZAxis, }; hsVector3 hingeVector; hingeVector = node->GetLocalToWorld44().GetAxis(hsMatrix44::kRight); // mod->SetHCLimits(kXAxis, 0, -1*fCompPB->GetFloat(kUpperAngle)); // mod->SetHCLimits(kXAxis, 1, -1*fCompPB->GetFloat(kLowerAngle)); mod->SetRotationAxis(-1*hingeVector); node->AddModifier(mod, IGetUniqueName(node)); hsgResMgr::ResMgr()->AddViaNotify(parent->GetKey(), new plGenRefMsg(mod->GetKey(), plRefMsg::kOnCreate, plHavokConstraintsMod::kParentIdx, 0), plRefFlags::kPassiveRef); hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), new plGenRefMsg(mod->GetKey(), plRefMsg::kOnCreate, plHavokConstraintsMod::kChildIdx, 0), plRefFlags::kPassiveRef); return true; }
// CONVERT bool plSeekPointComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { const char *objName = node->GetName(); char *name = new char[strlen(objName) + 1]; strcpy(name, objName); plSeekPointMod* pointMod = new plSeekPointMod(name); node->AddModifier(pointMod, IGetUniqueName(node)); return true; }
bool plMtlEventComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) { if (!fCanExport) return false; plAnimEventModifier* mod = new plAnimEventModifier; plKey modKey = node->AddModifier(mod, IGetUniqueName(node)); fLogicModKeys[node] = modKey; return true; }
hsBool plSpawnComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { const char *templateName = GetPBString(fCompPB, kTemplateName); if (!templateName) return false; plCloneSpawnModifier* mod = new plCloneSpawnModifier; mod->SetExportTime(); mod->SetTemplateName(templateName); node->AddModifier(mod, IGetUniqueName(node)); return true; }
bool plArmatureComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) { // add audio interface and record/playback component pl2WayWinAudible* pAudible = new pl2WayWinAudible; // Add a key for it plKey key = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), pAudible, node->GetLocation() ); plAudioInterface* ai = new plAudioInterface; plKey pAiKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), (hsKeyedObject*)ai,node->GetLocation()); hsgResMgr::ResMgr()->AddViaNotify(pAiKey, new plObjRefMsg(node->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface), plRefFlags::kActiveRef); plIntRefMsg* pMsg = new plIntRefMsg(node->GetKey(), plRefMsg::kOnCreate, 0, plIntRefMsg::kAudible); hsgResMgr::ResMgr()->AddViaNotify(pAudible->GetKey(), pMsg, plRefFlags::kActiveRef ); ISetArmatureSORecurse(node, node->GetSceneObject()); // Uncomment this line to enable a single bone pallete for the entire avatar. node->SetupBoneHierarchyPalette(); return true; }
bool plCompoundCtrlComponent::Convert(plMaxNode* node, plErrorMsg *pErrMsg) { plString name = node->GetKey()->GetName(); node->MakeCharacterHierarchy(pErrMsg); node->SetupBonesAliasesRecur(name.c_str()); // create and register the player modifier plAGMasterMod *agMaster = new plAGMasterMod(); node->AddModifier(agMaster, IGetUniqueName(node)); return true; }
hsBool plVolumeGadgetComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) { plLocation loc = node->GetLocation(); plSceneObject *obj = node->GetSceneObject(); // Create and register the VolumeGadget's logic component if(fCompPB->GetInt(kVolumeGadgetEnter) || fCompPB->GetInt(kVolumeTriggerOnFacing)) { plLogicModifier *logic = new plLogicModifier; plString tmpName = plString::Format("%s_Enter", IGetUniqueName(node).c_str()); plKey logicKey = hsgResMgr::ResMgr()->NewKey(tmpName, logic, node->GetLocation()); hsgResMgr::ResMgr()->AddViaNotify(logicKey, new plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); fLogicModKeys[node] = logicKey; if (fCompPB->GetInt(kVolumeOneShot)) logic->SetFlag(plLogicModBase::kOneShot); logic->SetFlag(plLogicModBase::kMultiTrigger); } if(fCompPB->GetInt(kVolumeGadgetExit)) { plLogicModifier *logic = new plLogicModifier; plString tmpName = plString::Format("%s_Exit", IGetUniqueName(node).c_str()); plKey logicKey = hsgResMgr::ResMgr()->NewKey(tmpName, logic, node->GetLocation()); hsgResMgr::ResMgr()->AddViaNotify(logicKey, new plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); fLogicModOutKeys[node] = logicKey; if (fCompPB->GetInt(kVolumeOneShot)) logic->SetFlag(plLogicModBase::kOneShot); logic->SetFlag(plLogicModBase::kMultiTrigger); } return true; }
bool plActivatorBaseComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) { node->SetForceLocal(true); plLocation loc = node->GetLocation(); plSceneObject *obj = node->GetSceneObject(); // Create and register the VolumeGadget's logic component plLogicModifier *logic = new plLogicModifier; plKey logicKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), logic, node->GetLocation()); hsgResMgr::ResMgr()->AddViaNotify(logicKey, new plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); fLogicModKeys[node] = logicKey; return true; }
void plLODAvatarComponent::IAttachShadowCastToLODs(plMaxNode* rootNode) { plShadowCaster* caster = new plShadowCaster; hsgResMgr::ResMgr()->NewKey(IGetUniqueName(rootNode), caster, rootNode->GetLocation()); caster->SetSelfShadow(true); int iLODCount = fCompPB->Count(plLODAvatarComponent::kMeshNodeTab); for (int i = 0; i < iLODCount; i++) { plMaxNode *meshNode = (plMaxNode *)fCompPB->GetINode(plLODAvatarComponent::kMeshNodeTab, 0, i); if( meshNode ) { plShadowCastComponent::AddShadowCastModifier(meshNode, caster); // The LOD roots are a special case. IAttachShadowCastModifiersRecur(meshNode, caster); } } }
hsBool plVehicleComponent::PreConvert(plMaxNode *pNode, plErrorMsg *pErrMsg) { return false; #if 0 if (!IIsValid()) return false; fMod = new plVehicleModifier; plKey modKey = pNode->AddModifier(fMod, IGetUniqueName(pNode)); plMaxNode* detectorNode = (plMaxNode*)fCompPB->GetINode(kVehicleDriveDet); plComponentBase* comp = detectorNode ? detectorNode->ConvertToComponent() : nil; if (comp) comp->AddReceiverKey(modKey); return true; #endif }
bool plObjectFlockerComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) { if (fFlocker) delete fFlocker; fFlocker = new pfObjectFlocker; hsgResMgr::ResMgr()->NewKey( IGetUniqueName(node), fFlocker, node->GetLocation(), node->GetLoadMask()); fFlocker->SetGoalWeight(fCompPB->GetFloat(ParamID(kGoalStrength))); fFlocker->SetWanderWeight(fCompPB->GetFloat(ParamID(kWanderStrength))); fFlocker->SetSeparationWeight(fCompPB->GetFloat(ParamID(kSepStrength))); fFlocker->SetSeparationRadius(fCompPB->GetFloat(ParamID(kSepRadius))); fFlocker->SetCohesionWeight(fCompPB->GetFloat(ParamID(kCohStrength))); fFlocker->SetCohesionRadius(fCompPB->GetFloat(ParamID(kCohRadius))); fFlocker->SetMaxForce(fCompPB->GetFloat(ParamID(kMaxForce))); fFlocker->SetMaxSpeed(fCompPB->GetFloat(ParamID(kMaxSpeed))); fFlocker->SetMinSpeed(fCompPB->GetFloat(ParamID(kMinSpeed))); fFlocker->SetUseTargetRotation(fCompPB->GetInt(ParamID(kUseTargetRotation)) != 0); fFlocker->SetRandomizeAnimStart(fCompPB->GetInt(ParamID(kRandomAnimStart)) != 0); fFlocker->SetNumBoids(fCompPB->GetInt(ParamID(kNumBoids))); plKey boidKey = nil; plMaxNode* targNode = (plMaxNode*)fCompPB->GetINode(kBoidObject); if( targNode->CanConvert() ) { plSceneObject* targObj = targNode->GetSceneObject(); if( targObj ) { boidKey = targObj->GetKey(); } } fFlocker->SetBoidKey(boidKey); // Add a ref to the flocker. fFlocker->GetKey()->RefObject(); return true; }
// // Convert Done below // bool plOneShotComponent::Convert(plMaxNode* node, plErrorMsg *pErrMsg) { if (fMods.find(node) != fMods.end()) { const char *animName = fCompPB->GetStr(kAnimName); bool drivable = fCompPB->GetInt(kControlSpeedBool); bool reversable = fCompPB->GetInt(kPlayBackwardsBool); float seekDuration = fCompPB->GetFloat(kSeekTimeFloat); bool smartSeek = fCompPB->GetInt(kSmartSeekBool); bool noSeek = fCompPB->GetInt(kNoSeekBool); plOneShotMod *mod = fMods[node]; mod->Init(animName, drivable, reversable, seekDuration, smartSeek, noSeek); node->AddModifier(mod, IGetUniqueName(node)); return true; } return false; }
hsBool plGameMarkerComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { plGameMarkerModifier* markerMod = new plGameMarkerModifier; plKey greenKey = IGetMtlAnimKey(kMarkerGreenAnim, node); plKey redKey = IGetMtlAnimKey(kMarkerRedAnim, node); plKey openKey = IGetMtlAnimKey(kMarkerOpenAnim, node); plKey bounceKey = IGetAnimKey(kMarkerBounceNode, kMarkerBounceComp); plMaxNode* sndPlaceComp = (plMaxNode*)fCompPB->GetINode(kMarkerSndPlace); int sndPlaceIdx = plAudioComp::GetSoundModIdx(sndPlaceComp->ConvertToComponent(), node); plMaxNode* sndHitComp = (plMaxNode*)fCompPB->GetINode(kMarkerSndHit); int sndHitIdx = plAudioComp::GetSoundModIdx(sndHitComp->ConvertToComponent(), node); markerMod->ExportInit(greenKey, redKey, openKey, bounceKey, sndPlaceIdx, sndHitIdx); node->AddModifier(markerMod, IGetUniqueName(node)); return true; }
hsBool plAvBehaviorSittingComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg) { plMaxNode *detectNode = (plMaxNode*)fCompPB->GetINode(kDetector); plComponentBase *detectComp = detectNode ? detectNode->ConvertToComponent() : nil; if (detectComp) { bool hasFrontApproach = fCompPB->GetInt(ParamID(kApproachFront)) ? true : false; bool hasLeftApproach = fCompPB->GetInt(ParamID(kApproachLeft)) ? true : false; bool hasRightApproach = fCompPB->GetInt(ParamID(kApproachRight)) ? true : false; // Create our key here and give it to the detector so it will notify us plSittingModifier *sitMod = new plSittingModifier(hasFrontApproach, hasLeftApproach, hasRightApproach); if (fCompPB->GetInt(ParamID(kDisableForward))) sitMod->fMiscFlags |= plSittingModifier::kDisableForward; plKey key = node->AddModifier(sitMod, IGetUniqueName(node)); detectComp->AddReceiverKey(key); fLogicModKeys[node] = key; } return true; }
bool plClickDragComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) { plActivatorBaseComponent::PreConvert(node, pErrMsg); plLogicModifier *logic = plLogicModifier::ConvertNoRef(fLogicModKeys[node]->GetObjectPtr()); if (fCompPB->GetInt(kClickDragOneShot)) logic->SetFlag(plLogicModBase::kOneShot); plLocation loc = node->GetLocation(); plSceneObject *obj = node->GetSceneObject(); // do the same thing for axis animation controllers. plAxisAnimModifier* pAxis = new plAxisAnimModifier; plKey axisKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), pAxis, loc); hsgResMgr::ResMgr()->AddViaNotify(axisKey, new plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); logic->AddNotifyReceiver(axisKey); fAxisKeys[node] = axisKey; return true; }
bool plAnimGroupedComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) { bool needSetMaster = fNeedReset; if (fNeedReset) { fForward = new plMsgForwarder; plKey forwardKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), fForward, node->GetLocation()); plNodeRefMsg *refMsg = new plNodeRefMsg(node->GetRoomKey(), plRefMsg::kOnCreate, -1, plNodeRefMsg::kGeneric); hsgResMgr::ResMgr()->AddViaNotify(forwardKey, refMsg, plRefFlags::kActiveRef); } bool ret = plAnimComponentBase::PreConvert(node, pErrMsg); plAGMasterMod *mod = fMods[node]; if (needSetMaster) mod->SetIsGroupMaster(true, fForward); mod->SetIsGrouped(true); fForward->AddForwardKey(mod->GetKey()); return ret; }
bool plAnimComponentBase::IConvertNodeSegmentBranch(plMaxNode *node, plAGAnim *anim, plErrorMsg *pErrMsg) { bool madeAnim = false; int i; if (IAddTMToAnim(node, anim, pErrMsg)) madeAnim = true; if (IAddLightToAnim(node, anim, pErrMsg)) madeAnim = true; for (i = 0; i < node->NumAttachedComponents(); i++) { if (node->GetAttachedComponent(i)->AddToAnim(anim, node)) madeAnim = true; } if (madeAnim) { // It has an animation, we're going to need a plAGMod when loading the anim if (!node->HasAGMod()) { node->AddModifier(new plAGModifier(ST::string::from_utf8(node->GetName())), IGetUniqueName(node)); } madeAnim = true; } /* // let's see if the children have any segments specified... int childCount = node->NumberOfChildren(); for (int i = 0; i < childCount; i++) { if (IConvertNodeSegmentBranch((plMaxNode *)(node->GetChildNode(i)), anim, pErrMsg)) madeAnim = true; } */ return madeAnim; }
hsBool plPhysHingeConstraintComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { plHingeConstraintMod* HMod = new plHingeConstraintMod; plMaxNode* ParentNode = (plMaxNode*)fCompPB->GetINode(kParent); if(ParentNode) { if(!ParentNode->GetPhysicalProps()->IsUsed()) { pErrMsg->Set(true, "Need a Physical Component", "Object %s has a Physical Constraint but no Physical Component. No Constraint was used.", (node->GetName())).Show(); pErrMsg->Set(false); } } if(!node->GetPhysicalProps()->IsUsed()) { pErrMsg->Set(true, "Need a Physical Component", "Object %s has a Physical Constraint but no Physical Component. No Constraint was used.", (node->GetName())).Show(); pErrMsg->Set(false); } // Using the MotorTorque field, just to keep from creating yet another field in our bloated base class. if(fCompPB->GetInt(kParentPinnedBool)) HMod->SetParentPin(true); if(fCompPB->GetInt(kChildPinnedBool)) HMod->SetChildPin(true); if(fCompPB->GetFloat(kFriction)) HMod->SetHCFriction(0,fCompPB->GetFloat(kFriction)); //Grab the pivot point from the child translate hsPoint3 PP = node->GetLocalToWorld44().GetTranslate(); hsVector3 PPVector; PPVector.Set(PP.fX, PP.fY, PP.fZ); HMod->SetPP(PPVector); plKey ParentKey = nil; if(fCompPB->GetINode(kParent) && fCompPB->GetInt(kUseParentBool)) if(((plMaxNode*)fCompPB->GetINode(kParent))->CanConvert()) { plMaxNode* ParentNode = (plMaxNode*)fCompPB->GetINode(kParent); ParentKey = ParentNode->GetKey(); } else { pErrMsg->Set(true, "Ignored Position Value", "Position %s was set to be Ignored. No Physical Proxy selected.", (fCompPB->GetINode(kPositionPtr)->GetName())); pErrMsg->Set(false); return false; } hsVector3 HingeVector; if(fCompPB->GetInt(kPositionPtr) == kZAxis) { HingeVector = node->GetLocalToWorld44().GetAxis(hsMatrix44::kUp); HMod->SetHCLimits(kZAxis, 1, fCompPB->GetFloat(kUpperAngle)); HMod->SetHCLimits(kZAxis, 0, fCompPB->GetFloat(kLowerAngle)); } else if(fCompPB->GetInt(kPositionPtr) == kYAxis) { HingeVector = node->GetLocalToWorld44().GetAxis(hsMatrix44::kView); HMod->SetHCLimits(kYAxis, 0, -1*fCompPB->GetFloat(kUpperAngle)); HMod->SetHCLimits(kYAxis, 1, -1*fCompPB->GetFloat(kLowerAngle)); } else { HingeVector = node->GetLocalToWorld44().GetAxis(hsMatrix44::kRight); HMod->SetHCLimits(kXAxis, 0, -1*fCompPB->GetFloat(kUpperAngle)); HMod->SetHCLimits(kXAxis, 1, -1*fCompPB->GetFloat(kLowerAngle)); } HMod->SetRotationAxis(-1*HingeVector); HMod->SetRR(fCompPB->GetFloat(kRebound)); HMod->SetDamp(fCompPB->GetFloat(kStrength)); node->AddModifier(HMod, IGetUniqueName(node)); if(ParentKey) hsgResMgr::ResMgr()->AddViaNotify( ParentKey, new plGenRefMsg( HMod->GetKey(), plRefMsg::kOnCreate, plHavokConstraintsMod::kParentIdx, 0 ), plRefFlags::kPassiveRef ); hsgResMgr::ResMgr()->AddViaNotify( node->GetKey(), new plGenRefMsg( HMod->GetKey(), plRefMsg::kOnCreate, plHavokConstraintsMod::kChildIdx, 0 ), plRefFlags::kPassiveRef ); return true; }
bool plClickDragComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { plLocation loc = node->GetLocation(); plSceneObject *obj = node->GetSceneObject(); plKey logicKey = fLogicModKeys[node]; plLogicModifier *logic = plLogicModifier::ConvertNoRef(logicKey->GetObjectPtr()); logic->fMyCursor = plCursorChangeMsg::kCursorOpen; // Create the detector plDetectorModifier *detector = nil; detector = new plPickingDetector; // Register the detector plKey detectorKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), detector, loc); hsgResMgr::ResMgr()->AddViaNotify(detectorKey, new plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); // set up the axis anim controller plKey axisKey = fAxisKeys[node]; plAxisAnimModifier* pAxis = plAxisAnimModifier::ConvertNoRef(axisKey->GetObjectPtr()); // attach the animation controller to the animation objects: // find an animation controller: hsTArray<plKey> receivers; IGetReceivers(node, receivers); int i; for (i = 0; i < receivers.Count(); i++) pAxis->GetNotify()->AddReceiver(receivers[i]); pAxis->SetNotificationKey(logicKey); uint32_t count = node->NumAttachedComponents(); bool bHasAnim = false; plAnimComponentBase* pAnim = nil; for (i = 0; i < count; i++) { plComponentBase *comp = node->GetAttachedComponent(i); if (comp->ClassID() == ANIM_COMP_CID || comp->ClassID() == ANIM_GROUP_COMP_CID) { pAnim = (plAnimComponentBase*)comp; break; } } if (!pAnim) { pErrMsg->Set(true, "WARNING", "Object %s has click-drag component attached but NO animation component!", ((INode*)node)->GetName()).Show(); pErrMsg->Set(false); } else { if (fCompPB->GetInt(kClickDragUseX)) { pAxis->SetXAnim( pAnim->GetModKey(node) ); } else // take out this else when we support multiple channels if (fCompPB->GetInt(kClickDragUseY)) { pAxis->SetYAnim( pAnim->GetModKey(node) ); } pAxis->SetAllOrNothing(fCompPB->GetInt(kClickDragAllOrNothing)); // add callbacks for beginning and end of animation plEventCallbackMsg* pCall1 = new plEventCallbackMsg; pCall1->fEvent = kBegin; pCall1->fRepeats = -1; pCall1->AddReceiver(axisKey); plEventCallbackMsg* pCall2 = new plEventCallbackMsg; pCall2->fEvent = kEnd; pCall2->fRepeats = -1; pCall2->AddReceiver(axisKey); plAnimCmdMsg* pMsg = new plAnimCmdMsg; plString tempAnimName = pAnim->GetAnimName(); if (tempAnimName.IsNull()) { //pMsg->SetAnimName(ENTIRE_ANIMATION_NAME); pMsg->SetAnimName(pAnim->GetModKey(node)->GetName()); pAxis->SetAnimLabel(ENTIRE_ANIMATION_NAME); } else { //pMsg->SetAnimName(tempAnimName); pMsg->SetAnimName(pAnim->GetModKey(node)->GetName()); pAxis->SetAnimLabel(tempAnimName); } pMsg->SetCmd(plAnimCmdMsg::kAddCallbacks); pMsg->AddCallback(pCall1); pMsg->AddCallback(pCall2); hsRefCnt_SafeUnRef( pCall1 ); hsRefCnt_SafeUnRef( pCall2 ); pMsg->AddReceiver( pAnim->GetModKey(node) ); plgDispatch::MsgSend(pMsg); } // is this a using a proxy primitive? plPickingDetector* det2 = nil; plKey det2Key = nil; plMaxNode* pProxyNode = (plMaxNode*)fCompPB->GetINode(kClickDragProxy); if (pProxyNode && fCompPB->GetInt(kClickDragUseProxy)) { // verify that there is a physical proxy attached to this scene object: uint32_t count = ((plMaxNodeBase*)pProxyNode)->NumAttachedComponents(); bool bHasPhys = false; // for (uint32_t i = 0; i < count; i++) // { // plComponentBase *comp = ((plMaxNodeBase*)pProxyNode)->GetAttachedComponent(i); // if (comp->ClassID() == Class_ID(0x11e81ee4, 0x36b81450)) // { // bHasPhys = true; // break; // } // } // if (!bHasPhys) // { // pErrMsg->Set(true, "WARNING", "Object %s listed as draggable component proxy physical for %s but has NO physical component.\n Please attach a proxyTerrain componet!\n Export will continue but this gadget will not function",pProxyNode->GetName(), ((INode*)node)->GetName()).Show(); // pErrMsg->Set(false); // } if(pProxyNode->CanConvert()) { det2 = new plPickingDetector; // Register the detector det2Key = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), det2, loc); hsgResMgr::ResMgr()->AddViaNotify(det2Key, new plObjRefMsg(((plMaxNode*)pProxyNode)->GetSceneObject()->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); hsgResMgr::ResMgr()->AddViaNotify(logicKey, new plObjRefMsg( det2Key, plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); det2->SetProxyKey(node->GetSceneObject()->GetKey()); } else { pErrMsg->Set(true, "Unknown Error", "Invalid proxy physical detector set for draggable %s.", ((INode*)pProxyNode)->GetName()).Show(); pErrMsg->Set(false); return false; } } // create and register the CONDITIONS for the DETECTOR's Logic Modifier plActivatorConditionalObject* activatorCond = new plActivatorConditionalObject; plKey activatorKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), activatorCond, loc); // do we have a required region? plMaxNode* pProxyRegNode = (plMaxNode*)fCompPB->GetINode(kClickDragProxyRegion); if (pProxyRegNode) { // verify that there is a physical detector attached to this scene object: uint32_t count = ((plMaxNodeBase*)pProxyRegNode)->NumAttachedComponents(); bool bHasPhys = false; // for (uint32_t i = 0; i < count; i++) // { // plComponentBase *comp = ((plMaxNodeBase*)pProxyRegNode)->GetAttachedComponent(i); // if (comp->ClassID() == Class_ID(0x33b60376, 0x7e5163e0)) // { // bHasPhys = true; // break; // } // } // if (!bHasPhys) // { // pErrMsg->Set(true, "WARNING", "Object %s listed as draggable component detector region for %s but has NO physical detector component!\n Please attach a detector componet.\n Export will continue but this gadget will not function",((INode*)pProxyRegNode)->GetName(), ((INode*)node)->GetName()).Show(); // pErrMsg->Set(false); // } if(pProxyRegNode->CanConvert()) { // need a player in box condition here... // first a detector-any for the box plObjectInVolumeDetector* pCDet = new plObjectInVolumeDetector(plCollisionDetector::kTypeAny); plKey cDetKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), pCDet, loc); hsgResMgr::ResMgr()->AddViaNotify(cDetKey, new plObjRefMsg(((plMaxNode*)pProxyRegNode)->GetSceneObject()->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); pCDet->AddLogicObj(logicKey); // then an object-in-box condition for the logic mod plObjectInBoxConditionalObject* boxCond = new plObjectInBoxConditionalObject; plKey boxCondKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), boxCond, loc); logic->AddCondition(boxCond); } else { pErrMsg->Set(true, "Problem with region", "Can't convert region component on %s. This component will not be exported.\n", ((INode*)pProxyRegNode)->GetName()).Show(); pErrMsg->Set(false); return false; } } else { pErrMsg->Set(true, "Must specify trigger region", "No required trigger region specified for click-drag component on %s. This component will not be exported.\n", ((INode*)node)->GetName()).Show(); pErrMsg->Set(false); return false; } // How do we feel about player facing plFacingConditionalObject* facingCond = new plFacingConditionalObject; facingCond->SetDirectional(fCompPB->GetInt(kClickDragDirectional)); int deg = fCompPB->GetInt(kClickDragDegrees); if (deg > 180) deg = 180; float rad = hsDegreesToRadians(deg); facingCond->SetTolerance(cos(rad)); plKey facingKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), facingCond, loc); // link everything up: if (det2) // set up the remote detector (if any) { activatorCond->SetActivatorKey(det2Key); det2->AddLogicObj(logicKey); } else { detector->AddLogicObj(logicKey); // send messages to this logic component activatorCond->SetActivatorKey(detectorKey); // Tells the activator condition to look for stimulus from the detector } logic->AddCondition(activatorCond); // add this activator condition logic->AddCondition(facingCond); logic->SetDisabled(fCompPB->GetInt(kClikDragEnabled) == 0); // If this is for the SceneViewer, set the local only flag since the read function will never be called if (plConvert::Instance().IsForSceneViewer()) logic->SetLocalOnly(true); return true; }
void plVolumeGadgetComponent::ICreateConditions(plMaxNode* node, plErrorMsg* errMsg, bool enter) { bool disabled = (fCompPB->GetInt(kVolumeEnabled) == 0); plLocation loc = node->GetLocation(); plSceneObject *obj = node->GetSceneObject(); plKey logicKey; if (enter) logicKey = fLogicModKeys[node]; else logicKey = fLogicModOutKeys[node]; plLogicModifier *logic = plLogicModifier::ConvertNoRef(logicKey->GetObjectPtr()); hsTArray<plKey> receivers; IGetReceivers(node, receivers); for (int i = 0; i < receivers.Count(); i++) logic->AddNotifyReceiver(receivers[i]); // Create the detector plDetectorModifier* detector = nil; if (enter && fCompPB->GetInt(kVolumeTriggerOnFacing)) { plObjectInVolumeAndFacingDetector* newDetector = new plObjectInVolumeAndFacingDetector; int deg = fCompPB->GetInt(kVolumeDegrees); if (deg > 180) deg = 180; newDetector->SetFacingTolerance(deg); bool walkingForward = (fCompPB->GetInt(kVolumeWalkingForward) != 0); newDetector->SetNeedWalkingForward(walkingForward); detector = newDetector; } else detector = new plObjectInVolumeDetector; const char* prefix = "Exit"; if (enter) prefix = "Enter"; // Register the detector plString tmpName = plString::Format("%s_%s", IGetUniqueName(node).c_str(), prefix); plKey detectorKey = hsgResMgr::ResMgr()->NewKey(tmpName, detector, loc); hsgResMgr::ResMgr()->AddViaNotify(detectorKey, new plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef); plVolumeSensorConditionalObject* boxCond=nil; if((fCompPB->GetInt(kSkipServerArbitration)==0)) {//we want server arbitration boxCond = new plVolumeSensorConditionalObject; } else { boxCond = new plVolumeSensorConditionalObjectNoArbitration; } tmpName = plString::Format("%s_%s", IGetUniqueName(node).c_str(), prefix); plKey boxKey = hsgResMgr::ResMgr()->NewKey(tmpName, boxCond, loc); if (enter) boxCond->SetType(plVolumeSensorConditionalObject::kTypeEnter); else boxCond->SetType(plVolumeSensorConditionalObject::kTypeExit); if (enter && !fCompPB->GetInt(kVolumeTriggerOnFacing)) { int trigType = fCompPB->GetInt(kVolumeEnterType); switch (trigType) { case kEnterTypeEach: break; case kEnterTypeCount: { int count = fCompPB->GetInt(kVolumeEnterNum); boxCond->SetTrigNum(count); break; } } } else if (!enter) { int trigType = fCompPB->GetInt(kVolumeExitType); switch (trigType) { case kExitTypeEach: break; case kExitTypeFirst: boxCond->SetFirst(true); break; case kExitTypeCount: { int count = fCompPB->GetInt(kVolumeExitNum); boxCond->SetTrigNum(count); break; } } } // link everything up: detector->AddLogicObj(boxKey); // This MUST be first!! detector->AddLogicObj(logicKey); // send messages to this logic component logic->AddCondition(boxCond); logic->SetDisabled(disabled); // If this is for the SceneViewer, set the local only flag since the read function will never be called if (plConvert::Instance().IsForSceneViewer()) logic->SetLocalOnly(true); }