static void GetObjectPoints( plSceneObject *so, hsTArray<hsPoint3> &outPoints ) { const plDrawInterface* di = so->GetDrawInterface(); if( !di ) return; // The following uses mf's spiffy plAccessGeometry/Spans stuff, which, in // one uint16_t, kicksAss. hsTArray<plAccessSpan> spans; plAccessGeometry::Instance()->OpenRO( di, spans ); int i; outPoints.Reset(); for( i = 0; i < spans.GetCount(); i++ ) { plAccessVtxSpan& vtxSrc = spans[ i ].AccessVtx(); plAccPositionIterator iterSrc( &vtxSrc ); for( iterSrc.Begin(); iterSrc.More(); iterSrc.Advance() ) outPoints.Append( *iterSrc.Position() ); } if (plAccessGeometry::Instance()) plAccessGeometry::Instance()->Close( spans ); }
virtual bool DeInit(plMaxNode *node, plErrorMsg *pErrMsg) { fModKeys.clear(); fOthersKeys.Reset(); return plComponent::DeInit(node, pErrMsg); }
bool plPythonFileComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) { IParamBlock2 *pb = (IParamBlock2*)fCompPB->GetReferenceTarget(kPythonFilePB); plAutoUIBlock *block = FindAutoUI(pb); if (!block) return false; plKey modKey = fModKeys[node]; plPythonFileMod *mod = plPythonFileMod::ConvertNoRef(modKey->GetObjectPtr()); // add in all the receivers that want to be notified from the Python coded script int j; for (j = 0; j < fOthersKeys.Count(); j++) { mod->AddToNotifyList(fOthersKeys[j]); } // remove all the Keys we know about to be re-built on the next convert fOthersKeys.Reset(); // set the name of the source file mod->SetSourceFile(block->GetName()); int nParams = block->NumParams(); for (int i = 0; i < nParams; i++) { plAutoUIParam *param = block->GetParam(i); plPythonParameter pyParam; pyParam.fID = param->GetID(); // Get the data for the param switch (param->GetParamType()) { case plAutoUIParam::kTypeBool: pyParam.SetTobool(param->GetBool(pb)); mod->AddParameter(pyParam); break; case plAutoUIParam::kTypeInt: pyParam.SetToInt(param->GetInt(pb)); mod->AddParameter(pyParam); break; case plAutoUIParam::kTypeFloat: pyParam.SetToFloat(param->GetFloat(pb)); mod->AddParameter(pyParam); break; case plAutoUIParam::kTypeString: pyParam.SetToString(param->GetString(pb)); mod->AddParameter(pyParam); break; case plAutoUIParam::kTypeSceneObj: { int numKeys = param->GetCount(pb); bool found_atleast_one_good_one = false; for (int i = 0; i < numKeys; i++) { plKey skey = param->GetKey(pb, i); if ( skey != nil ) { pyParam.SetToSceneObject(skey, true); // make sure that there really was a sceneobject mod->AddParameter(pyParam); found_atleast_one_good_one = true; } } if ( !found_atleast_one_good_one ) { char buf[512]; sprintf(buf,"The sceneobject attribute (ID=%d) that was selected in %s PythonFile, somehow does not exist!?", pyParam.fID,this->GetINode()->GetName()); pErrMsg->Set(true, "PythonFile Warning", buf).Show(); pErrMsg->Set(false); } } break; case plAutoUIParam::kTypeComponent: { int count = param->GetCount(pb); bool found_atleast_one_good_one = false; for (int i = 0; i < count; i++) { plComponentBase *comp = param->GetComponent(pb, i); if (comp) { for (int j = 0; j < comp->NumTargets(); j++) { plKey responderKey = Responder::GetKey(comp, comp->GetTarget(j)); if ( responderKey != nil ) { pyParam.SetToResponder(responderKey); mod->AddParameter(pyParam); found_atleast_one_good_one = true; } } if ( !found_atleast_one_good_one ) { char buf[512]; sprintf(buf,"The responder attribute %s that was selected in %s PythonFile, somehow does not exist!?", comp->GetINode()->GetName(),this->GetINode()->GetName()); pErrMsg->Set(true, "PythonFile Warning", buf).Show(); pErrMsg->Set(false); } } } } break; case plAutoUIParam::kTypeActivator: { int count = param->GetCount(pb); for (int i = 0; i < count; i++) { plComponentBase *comp = param->GetComponent(pb, i); // make sure we found a comp and then see if it is an activator type if (comp && comp->CanConvertToType(ACTIVATOR_BASE_CID)) { plActivatorBaseComponent *activator = (plActivatorBaseComponent*)comp; const plActivatorBaseComponent::LogicKeys& logicKeys = activator->GetLogicKeys(); plActivatorBaseComponent::LogicKeys::const_iterator it; for (it = logicKeys.begin(); it != logicKeys.end(); it++) { pyParam.SetToActivator(it->second); mod->AddParameter(pyParam); } // do special stuff for Volume sensors because they are stupid turds if (comp->ClassID() == VOLUMEGADGET_CID) { plVolumeGadgetComponent* pClick = (plVolumeGadgetComponent*)comp; const plVolumeGadgetComponent::LogicKeys &logicKeys2 = pClick->GetLogicOutKeys(); plVolumeGadgetComponent::LogicKeys::const_iterator VGit; for (VGit = logicKeys2.begin(); VGit != logicKeys2.end(); VGit++) { pyParam.SetToActivator(VGit->second); mod->AddParameter(pyParam); } } } // now see if it is a PythonFile kinda activator thingy else if (comp && comp->ClassID() == PYTHON_FILE_CID) { plPythonFileComponent *pyfact = (plPythonFileComponent*)comp; const plPythonFileComponent::PythonKeys& pythonKeys = pyfact->GetKeys(); plPythonFileComponent::PythonKeys::const_iterator it; for (it = pythonKeys.begin(); it != pythonKeys.end(); it++) { pyParam.SetToActivator(it->second); mod->AddParameter(pyParam); } } } } break; case plAutoUIParam::kTypeDynamicText: { int numKeys = param->GetCount(pb); for (int i = 0; i < numKeys; i++) { plKey key = param->GetKey(pb, i); // make sure we got a key and that it is a DynamicTextMap if (key && plDynamicTextMap::ConvertNoRef(key->GetObjectPtr()) ) { pyParam.SetToDynamicText(key); mod->AddParameter(pyParam); } } } break; case plAutoUIParam::kTypeGUIDialog: { int count = param->GetCount(pb); for (int i = 0; i < count; i++) { plComponentBase *comp = param->GetComponent(pb, i); if (comp) { if (comp && comp->ClassID() == GUI_DIALOG_COMP_CLASS_ID ) { // convert the comp to a GUIDialog component, so we can talk to it plGUIDialogComponent *dialog_comp = (plGUIDialogComponent*)comp; plKey dialogKey = dialog_comp->GetModifierKey(); pyParam.SetToGUIDialog(dialogKey); if ( pyParam.fObjectKey == nil ) { char buf[512]; sprintf(buf,"The GUIDialog attribute %s that was selected in %s PythonFile, somehow does not exist!?", comp->GetINode()->GetName(),this->GetINode()->GetName()); pErrMsg->Set(true, "PythonFile Warning", buf).Show(); pErrMsg->Set(false); } else mod->AddParameter(pyParam); } } } } break; case plAutoUIParam::kTypeGUIPopUpMenu: { int count = param->GetCount(pb); for (int i = 0; i < count; i++) { plComponentBase *comp = param->GetComponent(pb, i); if (comp) { if (comp && comp->ClassID() == GUI_MENUANCHOR_CLASSID ) { // convert the comp to a GUIPopUpMenu component, so we can talk to it plGUIMenuComponent *guiComp = (plGUIMenuComponent*)comp; plKey key = guiComp->GetConvertedMenuKey(); pyParam.SetToGUIPopUpMenu( key ); if ( pyParam.fObjectKey == nil ) { char buf[512]; sprintf(buf,"The GUIPopUpMenu attribute %s that was selected in %s PythonFile, somehow does not exist!?", comp->GetINode()->GetName(),this->GetINode()->GetName()); pErrMsg->Set(true, "PythonFile Warning", buf).Show(); pErrMsg->Set(false); } else mod->AddParameter(pyParam); } } } } break; case plAutoUIParam::kTypeGUISkin: { int count = param->GetCount(pb); for (int i = 0; i < count; i++) { plComponentBase *comp = param->GetComponent(pb, i); if (comp) { if (comp && comp->ClassID() == GUI_SKIN_CLASSID ) { // convert the comp to a GUISkin component, so we can talk to it plGUISkinComp *guiComp = (plGUISkinComp *)comp; plKey key = guiComp->GetConvertedSkinKey(); pyParam.SetToGUISkin( key ); if ( pyParam.fObjectKey == nil ) { char buf[512]; sprintf(buf,"The GUISkin attribute %s that was selected in %s PythonFile, somehow does not exist!?", comp->GetINode()->GetName(),this->GetINode()->GetName()); pErrMsg->Set(true, "PythonFile Warning", buf).Show(); pErrMsg->Set(false); } else mod->AddParameter(pyParam); } } } } break; case plAutoUIParam::kTypeExcludeRegion: { int count = param->GetCount(pb); int number_of_real_targets_found = 0; for (int i = 0; i < count; i++) { plComponentBase *comp = param->GetComponent(pb, i); if (comp && comp->ClassID() == XREGION_CID ) { for (int j = 0; j < comp->NumTargets(); j++) { plExcludeRegionComponent *excomp = (plExcludeRegionComponent*)comp; plKey exKey = excomp->GetKey((plMaxNode*)(comp->GetTarget(j))); if ( exKey != nil ) { // only get one real target, just count the rest if ( number_of_real_targets_found == 0 ) { pyParam.SetToExcludeRegion(exKey); mod->AddParameter(pyParam); } number_of_real_targets_found += 1; } } if ( number_of_real_targets_found != 1 ) { // there is zero or more than one node attached to this exclude region char buf[512]; if ( number_of_real_targets_found == 0 ) sprintf(buf,"The ExcludeRegion %s that was selected as an attribute in %s PythonFile, has no scene nodes attached.", comp->GetINode()->GetName(),this->GetINode()->GetName()); else sprintf(buf,"The ExcludeRegion %s that was selected as an attribute in %s PythonFile, has more than one scene node attached (using first one found).", comp->GetINode()->GetName(),this->GetINode()->GetName()); pErrMsg->Set(true, "PythonFile Warning", buf).Show(); pErrMsg->Set(false); } } } } break; case plAutoUIParam::kTypeWaterComponent: { plComponentBase* comp = param->GetComponent(pb, 0); plWaveSetBase* wsb = nil; if (comp) { wsb = plWaterComponent::GetWaveSet(comp->GetINode()); if (wsb != nil) { plKey waterKey = wsb->GetKey(); if ( waterKey != nil ) { pyParam.SetToWaterComponent(waterKey); mod->AddParameter(pyParam); } } } } break; case plAutoUIParam::kTypeSwimCurrentInterface: { plComponentBase* comp = param->GetComponent(pb, 0); plSwimRegionInterface* sri = nil; if (comp && comp->ClassID() == PHYS_SWIMSURFACE_CID) { plSwim2DComponent* swimcomp = (plSwim2DComponent*)comp; std::map<plMaxNode*, plSwimRegionInterface*>::const_iterator containsNode; plMaxNode* mnode = nil; for (int i = 0; i < swimcomp->NumTargets(); i++) { mnode = (plMaxNode*)swimcomp->GetTarget(i); containsNode = swimcomp->fSwimRegions.find(mnode); if ( containsNode != swimcomp->fSwimRegions.end() ) { sri = swimcomp->fSwimRegions[mnode]; break; } } if (sri != nil) { plKey swimKey = sri->GetKey(); if ( swimKey != nil ) { pyParam.SetToSwimCurrentInterface(swimKey); mod->AddParameter(pyParam); } } } } break; case plAutoUIParam::kTypeClusterComponent: { plComponentBase* comp = param->GetComponent(pb, 0); plClusterGroup* clusterGroup = nil; if (comp && comp->ClassID() == CLUSTER_COMP_CID) { plClusterComponent* clusterComp = (plClusterComponent*)comp; int numGroups = clusterComp->GetNumGroups(); int i; for (i=0; i<numGroups; i++) { plClusterGroup* group = clusterComp->GetGroup(i); plKey groupKey = group->GetKey(); if (groupKey != nil) { pyParam.SetToClusterComponent(groupKey); mod->AddParameter(pyParam); } } } } break; case plAutoUIParam::kTypeAnimation: { int count = param->GetCount(pb); for (int i = 0; i < count; i++) { plComponentBase *comp = param->GetComponent(pb, i); if (comp && ( comp->ClassID() == ANIM_COMP_CID || comp->ClassID() == ANIM_GROUP_COMP_CID ) ) { plAnimComponentBase *animcomp = (plAnimComponentBase*)comp; // save out the animation name first plString tempAnimName = animcomp->GetAnimName(); if (tempAnimName.IsNull()) pyParam.SetToAnimationName(ENTIRE_ANIMATION_NAME); else pyParam.SetToAnimationName(tempAnimName); mod->AddParameter(pyParam); // gather up all the modkeys for all the targets attached to this animation component int j; for ( j=0; j<comp->NumTargets(); j++ ) { pyParam.SetToAnimation(animcomp->GetModKey((plMaxNode*)(comp->GetTarget(j)))); mod->AddParameter(pyParam); } } } } break; case plAutoUIParam::kTypeBehavior: { // The Behavior attribute is One-Shots and Multi-stage behaviors // For Python usage: we will only allow using behaviors that are // attached to one position node. In other words, Python will only // be used for special cases. int count = param->GetCount(pb); int number_of_real_targets_found = 0; for (int i = 0; i < count; i++) { plComponentBase *comp = param->GetComponent(pb, i); if (comp && comp->ClassID() == ONESHOTCLASS_ID ) { // gather up all the modkeys for all the targets attached to this animation component int j; for ( j=0; j<comp->NumTargets(); j++ ) { plKey behKey = OneShotComp::GetOneShotKey(comp,(plMaxNode*)(comp->GetTarget(j))); if ( behKey != nil ) { // only get one real target, just count the rest if ( number_of_real_targets_found == 0 ) { pyParam.SetToBehavior(behKey); mod->AddParameter(pyParam); } number_of_real_targets_found += 1; } } } else if (comp && comp->ClassID() == MULTISTAGE_BEH_CID ) { // gather up all the modkeys for all the targets attached to this animation component int j; for ( j=0; j<comp->NumTargets(); j++ ) { plKey behKey = MultiStageBeh::GetMultiStageBehKey(comp,(plMaxNode*)(comp->GetTarget(j))); if ( behKey != nil ) { // only get one real target, just count the rest if ( number_of_real_targets_found == 0 ) { pyParam.SetToBehavior(behKey); mod->AddParameter(pyParam); } number_of_real_targets_found += 1; } } } if ( number_of_real_targets_found != 1 ) { // there is zero or more than one node attached to this exclude region char buf[512]; if ( number_of_real_targets_found == 0 ) sprintf(buf,"The Behavior component %s that was selected as an attribute in %s PythonFile, has no scene nodes attached.", comp->GetINode()->GetName(),this->GetINode()->GetName()); else sprintf(buf,"The Behavior component %s that was selected as an attribute in %s PythonFile, has more than one scene node attached (using first one found).", comp->GetINode()->GetName(),this->GetINode()->GetName()); pErrMsg->Set(true, "PythonFile Warning", buf).Show(); pErrMsg->Set(false); } } } break; case plAutoUIParam::kTypeMaterial: { int numKeys = param->GetCount(pb); for (int i = 0; i < numKeys; i++) { plKey key = param->GetKey(pb, i); // make sure we got a key and that it is a plMipmap if (key && plMipmap::ConvertNoRef(key->GetObjectPtr()) ) { pyParam.SetToMaterial(key); mod->AddParameter(pyParam); } } } break; case plAutoUIParam::kTypeMaterialAnimation: { plPickMaterialAnimationButtonParam* matAnim = (plPickMaterialAnimationButtonParam*)param; matAnim->CreateKeyArray(pb); int numKeys = param->GetCount(pb); for (int i = 0; i < numKeys; i++) { plKey key = param->GetKey(pb, i); if ( key ) { pyParam.SetToMaterialAnimation(key); mod->AddParameter(pyParam); } } matAnim->DestroyKeyArray(); } break; case plAutoUIParam::kTypeDropDownList: pyParam.SetToString(param->GetString(pb)); mod->AddParameter(pyParam); break; case plAutoUIParam::kTypeGrassComponent: { plComponentBase* comp = param->GetComponent(pb, 0); plGrassShaderMod* shader = nil; if (comp) { shader = plGrassComponent::GetShader(comp->GetINode()); if (shader != nil) { plKey shaderKey = shader->GetKey(); if ( shaderKey != nil ) { pyParam.SetToGrassShaderComponent(shaderKey); mod->AddParameter(pyParam); } } } } break; } } return true; }