// Parse a primitive, apply defaults first, grab any base level // key pairs, then process any sub groups we may contain. //------------------------------------------------------ bool CPrimitiveTemplate::ParsePrimitive( CGPGroup *grp ) { CGPGroup *subGrp; CGPValue *pairs; const char *key; const char *val; // Lets work with the pairs first pairs = grp->GetPairs(); while( pairs ) { // the fields key = pairs->GetName(); val = pairs->GetTopValue(); // Huge stricmp lists suxor if ( !stricmp( key, "count" )) { ParseCount( val ); } else if ( !stricmp( key, "shaders" ) || !stricmp( key, "shader" )) { ParseShaders( pairs ); } else if ( !stricmp( key, "models" ) || !stricmp( key, "model" )) { ParseModels( pairs ); } else if ( !stricmp( key, "sounds" ) || !stricmp( key, "sound" )) { ParseSounds( pairs ); } else if ( !stricmp( key, "impactfx" )) { ParseImpactFxStrings( pairs ); } else if ( !stricmp( key, "deathfx" )) { ParseDeathFxStrings( pairs ); } else if ( !stricmp( key, "emitfx" )) { ParseEmitterFxStrings( pairs ); } else if ( !stricmp( key, "playfx" )) { ParsePlayFxStrings( pairs ); } else if ( !stricmp( key, "life" )) { ParseLife( val ); } else if ( !stricmp( key, "cullrange" )) { mCullRange = atoi( val ); mCullRange *= mCullRange; // Square } else if ( !stricmp( key, "delay" )) { ParseDelay( val ); } else if ( !stricmp( key, "bounce" ) || !stricmp( key, "intensity" )) // me==bad for reusing this...but it shouldn't hurt anything) { ParseElasticity( val ); } else if ( !stricmp( key, "min" )) { ParseMin( val ); } else if ( !stricmp( key, "max" )) { ParseMax( val ); } else if ( !stricmp( key, "angle" ) || !stricmp( key, "angles" )) { ParseAngle( val ); } else if ( !stricmp( key, "angleDelta" )) { ParseAngleDelta( val ); } else if ( !stricmp( key, "velocity" ) || !stricmp( key, "vel" )) { ParseVelocity( val ); } else if ( !stricmp( key, "acceleration" ) || !stricmp( key, "accel" )) { ParseAcceleration( val ); } else if ( !stricmp( key, "gravity" )) { ParseGravity( val ); } else if ( !stricmp( key, "density" )) { ParseDensity( val ); } else if ( !stricmp( key, "variance" )) { ParseVariance( val ); } else if ( !stricmp( key, "origin" )) { ParseOrigin1( val ); } else if ( !stricmp( key, "origin2" )) { ParseOrigin2( val ); } else if ( !stricmp( key, "radius" )) // part of ellipse/cylinder calcs. { ParseRadius( val ); } else if ( !stricmp( key, "height" )) // part of ellipse/cylinder calcs. { ParseHeight( val ); } else if ( !stricmp( key, "rotation" )) { ParseRotation( val ); } else if ( !Q_stricmp( key, "rotationDelta" )) { ParseRotationDelta( val ); } else if ( !stricmp( key, "flags" ) || !stricmp( key, "flag" )) { // these need to get passed on to the primitive ParseFlags( val ); } else if ( !stricmp( key, "spawnFlags" ) || !stricmp( key, "spawnFlag" )) { // these are used to spawn things in cool ways, but don't ever get passed on to prims. ParseSpawnFlags( val ); } else if ( !stricmp( key, "name" )) { if ( val ) { // just stash the descriptive name of the primitive strcpy( mName, val ); } } else { theFxHelper.Print( "Unknown key parsing an effect primitive: %s\n", key ); } pairs = (CGPValue *)pairs->GetNext(); } subGrp = grp->GetSubGroups(); // Lets chomp on the groups now while ( subGrp ) { key = subGrp->GetName(); if ( !stricmp( key, "rgb" )) { ParseRGB( subGrp ); } else if ( !stricmp( key, "alpha" )) { ParseAlpha( subGrp ); } else if ( !stricmp( key, "size" ) || !stricmp( key, "width" )) { ParseSize( subGrp ); } else if ( !stricmp( key, "size2" ) || !stricmp( key, "width2" )) { ParseSize2( subGrp ); } else if ( !stricmp( key, "length" ) || !stricmp( key, "height" )) { ParseLength( subGrp ); } else { theFxHelper.Print( "Unknown group key parsing a particle: %s\n", key ); } subGrp = (CGPGroup *)subGrp->GetNext(); } return true; }
void StructureVisitor::startElement (const char * name, const XMLAttributes &atts) { int i; if (_level == 0) { if (string(name) != (string)"structures-file") { string message = "Root element name is "; message += name; message += "; expected structures-file"; throw xh_io_exception(message, "XML Reader"); } push_state(NULL, "top"); return; } if (_level == 1) { if (string(name) == (string)"coordinates") { const char *type = atts.getValue("type"); const char *value = atts.getValue("value"); m_pSA->m_proj.SetTextDescription(type, value); g_Conv.Setup(m_pSA->m_proj.GetUnits(), DRECT(0,1,1,0)); } else if (string(name) == (string)"structures") { push_state(NULL, "structures"); } else { // Unknown element: ignore push_state(NULL, "dummy"); } return; } const char *attval; if (_level == 2) { vtStructure *pStruct = NULL; if (string(name) == (string)"structure") { // Get the name. attval = atts.getValue("type"); if (attval != NULL) { if (string(attval) == (string)"building") { vtBuilding *bld = m_pSA->NewBuilding(); pStruct = bld; } if (string(attval) == (string)"linear") { vtFence *fen = m_pSA->NewFence(); pStruct = fen; } if (string(attval) == (string)"instance") { vtStructInstance *inst = m_pSA->NewInstance(); pStruct = inst; } } push_state(pStruct, "structure"); } else { // Unknown field, ignore. pStruct = NULL; push_state(pStruct, "dummy"); } return; } State &st = state(); vtStructure *pStruct = st.item; if (!pStruct) return; vtFence *fen = pStruct->GetFence(); vtBuilding *bld = pStruct->GetBuilding(); vtStructInstance *inst = pStruct->GetInstance(); if (_level == 3 && bld != NULL) { if (string(name) == (string)"height") { attval = atts.getValue("stories"); if (attval) { // height in stories ("floors") int stories = atoi(attval); if (bld) bld->SetStories(stories); } } if (string(name) == (string)"walls") { attval = atts.getValue("color"); if (bld && attval) st.wall_color = ParseRGB(attval); } if (string(name) == (string)"shapes") { push_state(pStruct, "shapes"); return; } if (string(name) == (string)"roof") { // hack to postpone setting building color until now bld->SetColor(BLD_BASIC, st.wall_color); const char *type = atts.getValue("type"); if (bld && (string)type == (string)"flat") bld->SetRoofType(ROOF_FLAT); if (bld && (string)type == (string)"shed") bld->SetRoofType(ROOF_SHED); if (bld && (string)type == (string)"gable") bld->SetRoofType(ROOF_GABLE); if (bld && (string)type == (string)"hip") bld->SetRoofType(ROOF_HIP); attval = atts.getValue("color"); if (bld && attval) bld->SetColor(BLD_ROOF, ParseRGB(attval)); } if (string(name) == (string)"points") { attval = atts.getValue("num"); } return; } if (_level == 3 && fen != NULL) { if (string(name) == (string)"points") { int points; const char *num = atts.getValue("num"); points = atoi(num); DLine2 &fencepts = fen->GetFencePoints(); DPoint2 loc; const char *coords = atts.getValue("coords"); const char *cp = coords; for (i = 0; i < points; i++) { sscanf(cp, "%lf %lf", &loc.x, &loc.y); fencepts.Append(loc); cp = strchr(cp, ' '); cp++; cp = strchr(cp, ' '); cp++; } } if (string(name) == (string)"height") { // absolute height in meters const char *abs_str = atts.getValue("abs"); if (abs_str) fen->GetParams().m_fPostHeight = (float)atof(abs_str); } if (string(name) == (string)"posts") { // this linear structure has posts const char *type = atts.getValue("type"); if (0 == strcmp(type, "wood")) fen->ApplyStyle(FS_WOOD_POSTS_WIRE); else if (0 == strcmp(type, "steel")) fen->ApplyStyle(FS_CHAINLINK); else fen->ApplyStyle(FS_METAL_POSTS_WIRE); const char *size = atts.getValue("size"); FPoint3 postsize; postsize.y = fen->GetParams().m_fPostHeight; sscanf(size, "%f, %f", &postsize.x, &postsize.z); fen->GetParams().m_fPostWidth = postsize.x; fen->GetParams().m_fPostDepth = postsize.z; const char *spacing = atts.getValue("spacing"); if (spacing) fen->GetParams().m_fPostSpacing = (float)atof(spacing); } if (string(name) == (string)"connect") { attval = atts.getValue("type"); // not supported here } return; } if (_level == 3 && inst != NULL) { if (string(name) == (string)"placement") { const char *loc = atts.getValue("location"); if (loc) { DPoint2 p; sscanf(loc, "%lf %lf", &p.x, &p.y); inst->SetPoint(p); } const char *rot = atts.getValue("rotation"); if (rot) { float fRot; sscanf(rot, "%f", &fRot); inst->SetRotation(fRot); } } else _data = ""; } if (_level == 4 && bld != NULL) { if (string(name) == (string)"rect") { DPoint2 loc; FPoint2 size2; const char *ref_point = atts.getValue("ref_point"); if (ref_point) { sscanf(ref_point, "%lf %lf", &loc.x, &loc.y); bld->SetRectangle(loc, 10, 10); } float fRotation = 0.0f; const char *rot = atts.getValue("rot"); if (rot) { fRotation = (float)atof(rot); } const char *size = atts.getValue("size"); if (size) { sscanf(size, "%f, %f", &size2.x, &size2.y); bld->SetRectangle(loc, size2.x, size2.y, fRotation); } } if (string(name) == (string)"circle") { DPoint2 loc; const char *ref_point = atts.getValue("ref_point"); if (ref_point) { sscanf(ref_point, "%lf %lf", &loc.x, &loc.y); bld->SetCircle(loc, 10); } const char *radius = atts.getValue("radius"); if (radius) { bld->SetCircle(loc, (float)atof(radius)); } } if (string(name) == (string)"poly") { int points; const char *num = atts.getValue("num"); points = atoi(num); DLine2 foot; DPoint2 loc; const char *coords = atts.getValue("coords"); const char *cp = coords; for (i = 0; i < points; i++) { sscanf(cp, "%lf %lf", &loc.x, &loc.y); foot.Append(loc); cp = strchr(cp, ' '); cp++; cp = strchr(cp, ' '); cp++; } bld->SetFootprint(0, foot); } } }