void MeshObject::stopAllAnimations( ) { AnimationStateSet* animStates = getEntity()->getAllAnimationStates(); if (animStates != NULL) { AnimationStateIterator iter = animStates->getAnimationStateIterator(); while(iter.hasMoreElements()) { AnimationState* state = iter.getNext(); stopAnimation( state->getAnimationName() ); } } }
/** * Construit la scène animée. */ void AnimApp::buildScene() { Entity * ent = scMgr->createEntity("AnimatedMesh", "Sinbad.mesh"); scMgr->getRootSceneNode()->attachObject(ent); camera->setPosition(0, 2, 12); AnimationStateSet * set = ent->getAllAnimationStates(); AnimationStateIterator iter = set->getAnimationStateIterator(); vector<string> animSetNames; while (iter.hasMoreElements()) { animSetNames.push_back(iter.getNext()->getAnimationName()); } animState = ent->getAnimationState(animSetNames.at(0)); animState->setEnabled(true); animState->setLoop(true); }
void FvXMLAnimationModelSerializerImpl::ReadEntity( FvXMLSectionPtr spSection, Ogre::SceneNode* pkNode, FvAnimationModel* pkDest ) { Ogre::SceneManager *pkSceneManager = Ogre::Root::getSingleton(). _getCurrentSceneManager(); FV_ASSERT(pkSceneManager); FvString kMeshIdentifier = spSection->ReadString("identifier"); FvString kMeshFile = spSection->ReadString("mesh"); Ogre::Entity *pkEntity = pkSceneManager->createEntity( pkNode->getName() + "_" + kMeshIdentifier,kMeshFile); FV_ASSERT(pkEntity); pkEntity->setCastShadows(pkDest->m_bCastShadows); pkNode->attachObject(pkEntity); pkDest->m_akNodes[pkDest->m_u32CurrentLodLevel].m_kEntityList.push_back(pkEntity); pkEntity->setRenderQueueGroup(RENDER_QUEUE_MAX); AnimationStateSet *pkAnimations = pkEntity->getAllAnimationStates(); if(pkAnimations) { AnimationStateIterator kIt = pkAnimations->getAnimationStateIterator(); while (kIt.hasMoreElements()) { AnimationState *pkAnim= kIt.getNext(); if(pkDest->GetAnimation(pkAnim->getAnimationName()) == NULL) pkDest->m_kModelAnimations.insert(std::make_pair(pkAnim->getAnimationName(),pkAnim)); } } std::vector<FvXMLSectionPtr> kSubentities; spSection->OpenSections("subentities/subentity",kSubentities); std::vector<FvXMLSectionPtr>::iterator kSubIt = kSubentities.begin(); for(; kSubIt != kSubentities.end(); ++kSubIt) { int iIndex = (*kSubIt)->ReadInt("index",-1); FvString kMaterialName = (*kSubIt)->ReadString("materialName"); Ogre::SubEntity *pkSubEntity = pkEntity->getSubEntity(iIndex); if(pkSubEntity && !kMaterialName.empty()) pkSubEntity->setMaterialName(kMaterialName); } }
void AnimationBlender::init(const String &animation, bool l, Game::Actor* _owner) { this->Owner = _owner; if (!mEntity->hasSkeleton()) return; AnimationStateSet *set = mEntity->getAllAnimationStates(); AnimationStateIterator it = set->getAnimationStateIterator(); while(it.hasMoreElements()) { AnimationState *anim = it.getNext(); anim->setEnabled(false); anim->setWeight(0); anim->setTimePosition(0); std::string name = anim->getAnimationName(); if (_owner->entity->hasSkeleton()) { Animation* an = _owner->entity->getSkeleton()->getAnimation(name); an->setRotationInterpolationMode(Ogre::Animation::RotationInterpolationMode::RIM_LINEAR); an->setInterpolationMode(Ogre::Animation::InterpolationMode::IM_LINEAR); } //GameFramework::getSingletonPtr()->sceneManager->getAnimation(); } //Ogre::Animation::setDefaultInterpolationMode(InterpolationMode:: //_owner->entity->getAnimationState("")-> mSource = mEntity->getAnimationState( animation ); mSource->setEnabled(true); //////CALLBACK///// this->Owner->onAnimationStarted(mSource->getAnimationName()); mSource->setWeight(1); mTimeleft = 0; mDuration = 1; mTarget = 0; complete = false; loop = l; this->isInitialized = true; this->isBlending = false; }
void AnimationBlender::init(const string& animation, bool looping) { AnimationStateSet* set = mEntity->getAllAnimationStates(); if (set == nullptr) throw string("AnimationBlender::init:That mesh does not have any animations!"); for (auto animPair : set->getAnimationStateIterator()) { animPair.second->setEnabled(false); animPair.second->setWeight(0); animPair.second->setTimePosition(0); } mCurrentAnim = animation; mSource = mEntity->getAnimationState(animation); mSource->setEnabled(true); mSource->setWeight(1); mTimeleft = 0; mDuration = 1; mTarget = nullptr; mComplete = true; mLoop = looping; }
void AnimationBlender2::init(const String &animation, bool loop, Game::Actor* _owner) { this->Owner = _owner; if (!mEntity->hasSkeleton()) return; AnimationStateSet *set = mEntity->getAllAnimationStates(); AnimationStateIterator it = set->getAnimationStateIterator(); while(it.hasMoreElements()) { AnimationState *anim = it.getNext(); std::string name = anim->getAnimationName(); if (_owner->entity->hasSkeleton()) { Animation* an = _owner->entity->getSkeleton()->getAnimation(name); if (an->getRotationInterpolationMode() != Animation::RotationInterpolationMode::RIM_LINEAR) an->setRotationInterpolationMode(Ogre::Animation::RotationInterpolationMode::RIM_LINEAR); if (an->getInterpolationMode() != Ogre::Animation::InterpolationMode::IM_LINEAR) an->setInterpolationMode(Ogre::Animation::InterpolationMode::IM_LINEAR); } } this->currentAnimation = AnimationBlendData(mEntity->getAnimationState( animation )); this->currentAnimation.animationState->setEnabled(true); this->currentAnimation.animationState->setWeight(1); this->currentAnimation.animationState->setTimePosition(0); this->currentAnimation.animationState->setLoop(loop); this->animationFadingIn.exist = false; this->animationsFadingOut->clear(); this->isInitialized = true; }
//--------------------------------------------------------------------- void Skeleton::setAnimationState(const AnimationStateSet& animSet) { /* Algorithm: 1. Reset all bone positions 2. Iterate per AnimationState, if enabled get Animation and call Animation::apply */ // Reset bones reset(); Real weightFactor = 1.0f; if (mBlendState == ANIMBLEND_AVERAGE) { // Derive total weights so we can rebalance if > 1.0f Real totalWeights = 0.0f; ConstEnabledAnimationStateIterator stateIt = animSet.getEnabledAnimationStateIterator(); while (stateIt.hasMoreElements()) { const AnimationState* animState = stateIt.getNext(); // Make sure we have an anim to match implementation const LinkedSkeletonAnimationSource* linked = 0; if (_getAnimationImpl(animState->getAnimationName(), &linked)) { totalWeights += animState->getWeight(); } } // Allow < 1.0f, allows fade out of all anims if required if (totalWeights > 1.0f) { weightFactor = 1.0f / totalWeights; } } // Per enabled animation state ConstEnabledAnimationStateIterator stateIt = animSet.getEnabledAnimationStateIterator(); while (stateIt.hasMoreElements()) { const AnimationState* animState = stateIt.getNext(); const LinkedSkeletonAnimationSource* linked = 0; Animation* anim = _getAnimationImpl(animState->getAnimationName(), &linked); // tolerate state entries for animations we're not aware of if (anim) { if(animState->hasBlendMask()) { anim->apply(this, animState->getTimePosition(), animState->getWeight() * weightFactor, animState->getBlendMask(), linked ? linked->scale : 1.0f); } else { anim->apply(this, animState->getTimePosition(), animState->getWeight() * weightFactor, linked ? linked->scale : 1.0f); } } } }
void Character::Init(Ogre::SceneManager *SceneMgr) { m_pkSceneManager = SceneMgr; m_pkCharacterNode = m_pkSceneManager->getRootSceneNode()->createChildSceneNode(); // Body 생성 m_pkBodyEntity = m_pkSceneManager->createEntity("Sinbad", "Sinbad.mesh"); m_pkBodyEntity->setCastShadows(true); m_pkBodyEntity->getWorldBoundingBox(true); // 이 블랜드 모드를 설정해줘야 상하 애니메이션 가능 m_pkBodyEntity->getSkeleton()->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE); m_pkBodyNode = m_pkCharacterNode->createChildSceneNode(); m_pkBodyNode->attachObject(m_pkBodyEntity); // Sword 생성 m_pkLSwordEntity = m_pkSceneManager->createEntity("LSword", "Sword.mesh"); m_pkRSwordEntity = m_pkSceneManager->createEntity("RSword", "Sword.mesh"); m_pkLSwordNode = m_pkCharacterNode->createChildSceneNode(); m_pkRSwordNode = m_pkCharacterNode->createChildSceneNode(); m_pkLSwordNode->attachObject(m_pkLSwordEntity); m_pkRSwordNode->attachObject(m_pkRSwordEntity); AnimationStateSet *ani = m_pkBodyEntity->getAllAnimationStates(); m_pkTopAniState[0] = ani->getAnimationState("DrawSwords"); m_pkTopAniState[1] = ani->getAnimationState("IdleTop"); m_pkTopAniState[2] = ani->getAnimationState("RunTop"); m_pkTopAniState[3] = ani->getAnimationState("SliceHorizontal"); m_pkTopAniState[4] = ani->getAnimationState("SliceVertical"); m_pkBaseAniState[0] = ani->getAnimationState("IdleBase"); m_pkBaseAniState[1] = ani->getAnimationState("RunBase"); m_pkBaseAniState[2] = ani->getAnimationState("Dance"); m_pkBaseAniState[3] = ani->getAnimationState("JumpStart"); m_pkBaseAniState[4] = ani->getAnimationState("JumpLoop"); m_pkBaseAniState[5] = ani->getAnimationState("JumpEnd"); m_TopAni = TOP_IDLE; m_BaseAni = BASE_IDLE; m_pkTopAniState[m_TopAni]->setEnabled(true); m_pkBaseAniState[m_BaseAni]->setEnabled(true); m_Position = Vector3::ZERO; }
void TerrainObjectManager::loadObject(const Ogre::String &name, const Ogre::Vector3 &pos, const Ogre::Vector3 &rot, Ogre::SceneNode *bakeNode, const Ogre::String &instancename, const Ogre::String &type, bool enable_collisions /* = true */, int scripthandler /* = -1 */, bool uniquifyMaterial /* = false */) { ScopeLog log("object_"+name); if (type == "grid") { // some fast grid object hacks :) for (int x=0; x < 500; x += 50) { for (int z=0; z < 500; z += 50) { const String notype = ""; loadObject(name, pos + Vector3(x, 0.0f, z), rot, bakeNode, name, notype, enable_collisions, scripthandler, uniquifyMaterial); } } return; } // nice idea, but too many random hits //if (abs(rot.x+1) < 0.001) rot.x = Math::RangeRandom(0, 360); //if (abs(rot.y+1) < 0.001) rot.y = Math::RangeRandom(0, 360); //if (abs(rot.z+1) < 0.001) rot.z = Math::RangeRandom(0, 360); if (name.empty()) return; //FILE *fd; //char oname[1024] = {}; char mesh[1024] = {}; char line[1024] = {}; char collmesh[1024] = {}; Vector3 l(Vector3::ZERO); Vector3 h(Vector3::ZERO); Vector3 dr(Vector3::ZERO); Vector3 fc(Vector3::ZERO); Vector3 sc(Vector3::ZERO); Vector3 sr(Vector3::ZERO); bool forcecam=false; bool ismovable=false; int event_filter = EVENT_ALL; Quaternion rotation = Quaternion(Degree(rot.x), Vector3::UNIT_X) * Quaternion(Degree(rot.y), Vector3::UNIT_Y) * Quaternion(Degree(rot.z), Vector3::UNIT_Z); // try to load with UID first! String odefgroup = ""; String odefname = name + ".odef"; bool odefFound = false; bool exists = ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(odefname); if (exists) { odefgroup = ResourceGroupManager::getSingleton().findGroupContainingResource(odefname); odefFound = true; } if (!RoR::Application::GetCacheSystem()->checkResourceLoaded(odefname, odefgroup)) if (!odefFound) { LOG("Error while loading Terrain: could not find required .odef file: " + odefname + ". Ignoring entry."); return; } DataStreamPtr ds=ResourceGroupManager::getSingleton().openResource(odefname, odefgroup); ds->readLine(mesh, 1023); if (String(mesh) == "LOD") { // LOD line is obsolete ds->readLine(mesh, 1023); } //scale ds->readLine(line, 1023); sscanf(line, "%f, %f, %f",&sc.x, &sc.y, &sc.z); String entityName = "object" + TOSTRING(objcounter) + "(" + name + ")"; objcounter++; SceneNode *tenode = gEnv->sceneManager->getRootSceneNode()->createChildSceneNode(); bool background_loading = BSETTING("Background Loading", false); MeshObject *mo = NULL; if (String(mesh) != "none") { mo = new MeshObject(mesh, entityName, tenode, NULL, background_loading); } //mo->setQueryFlags(OBJECTS_MASK); //tenode->attachObject(te); tenode->setScale(sc); tenode->setPosition(pos); tenode->rotate(rotation); tenode->pitch(Degree(-90)); tenode->setVisible(true); // register in map loadedObject_t *obj = &loadedObjects[instancename]; obj->instanceName = instancename; obj->loadType = 0; obj->enabled = true; obj->sceneNode = tenode; obj->collTris.clear(); if (mo && uniquifyMaterial && !instancename.empty()) { for (unsigned int i = 0; i < mo->getEntity()->getNumSubEntities(); i++) { SubEntity *se = mo->getEntity()->getSubEntity(i); String matname = se->getMaterialName(); String newmatname = matname + "/" + instancename; //LOG("subentity " + TOSTRING(i) + ": "+ matname + " -> " + newmatname); se->getMaterial()->clone(newmatname); se->setMaterialName(newmatname); } } //String meshGroup = ResourceGroupManager::getSingleton().findGroupContainingResource(mesh); //MeshPtr mainMesh = mo->getMesh(); //collision box(es) bool virt=false; bool rotating=false; bool classic_ref=true; // everything is of concrete by default ground_model_t *gm = gEnv->collisions->getGroundModelByString("concrete"); char eventname[256] = {}; while (!ds->eof()) { size_t ll=ds->readLine(line, 1023); // little workaround to trim it String lineStr = String(line); Ogre::StringUtil::trim(lineStr); const char* ptline = lineStr.c_str(); if (ll==0 || line[0]=='/' || line[0]==';') continue; if (!strcmp("end",ptline)) break; if (!strcmp("movable", ptline)) {ismovable=true;continue;}; if (!strcmp("localizer-h", ptline)) { localizers[free_localizer].position=Vector3(pos.x,pos.y,pos.z); localizers[free_localizer].rotation=rotation; localizers[free_localizer].type=Autopilot::LOCALIZER_HORIZONTAL; free_localizer++; continue; } if (!strcmp("localizer-v", ptline)) { localizers[free_localizer].position=Vector3(pos.x,pos.y,pos.z); localizers[free_localizer].rotation=rotation; localizers[free_localizer].type=Autopilot::LOCALIZER_VERTICAL; free_localizer++; continue; } if (!strcmp("localizer-ndb", ptline)) { localizers[free_localizer].position=Vector3(pos.x,pos.y,pos.z); localizers[free_localizer].rotation=rotation; localizers[free_localizer].type=Autopilot::LOCALIZER_NDB; free_localizer++; continue; } if (!strcmp("localizer-vor", ptline)) { localizers[free_localizer].position=Vector3(pos.x,pos.y,pos.z); localizers[free_localizer].rotation=rotation; localizers[free_localizer].type=Autopilot::LOCALIZER_VOR; free_localizer++; continue; } if (!strcmp("standard", ptline)) {classic_ref=false;tenode->pitch(Degree(90));continue;}; if (!strncmp("sound", ptline, 5)) { #ifdef USE_OPENAL if (!SoundScriptManager::getSingleton().isDisabled()) { char tmp[255]=""; sscanf(ptline, "sound %s", tmp); SoundScriptInstance *sound = SoundScriptManager::getSingleton().createInstance(tmp, MAX_TRUCKS+1, tenode); sound->setPosition(tenode->getPosition(), Vector3::ZERO); sound->start(); } #endif //USE_OPENAL continue; } if (!strcmp("beginbox", ptline) || !strcmp("beginmesh", ptline)) { dr = Vector3::ZERO; rotating=false; virt=false; forcecam=false; event_filter=EVENT_NONE; eventname[0]=0; collmesh[0]=0; gm = gEnv->collisions->getGroundModelByString("concrete"); continue; }; if (!strncmp("boxcoords", ptline, 9)) { sscanf(ptline, "boxcoords %f, %f, %f, %f, %f, %f",&l.x,&h.x,&l.y,&h.y,&l.z, &h.z); continue; } if (!strncmp("mesh", ptline, 4)) { sscanf(ptline, "mesh %s",collmesh); continue; } if (!strncmp("rotate", ptline, 6)) { sscanf(ptline, "rotate %f, %f, %f",&sr.x, &sr.y, &sr.z); rotating=true; continue; } if (!strncmp("forcecamera", ptline, 11)) { sscanf(ptline, "forcecamera %f, %f, %f",&fc.x, &fc.y, &fc.z); forcecam=true; continue; } if (!strncmp("direction", ptline, 9)) { sscanf(ptline, "direction %f, %f, %f",&dr.x, &dr.y, &dr.z); continue; } if (!strncmp("frictionconfig", ptline, 14) && strlen(ptline) > 15) { // load a custom friction config gEnv->collisions->loadGroundModelsConfigFile(String(ptline + 15)); continue; } if ((!strncmp("stdfriction", ptline, 11) || !strncmp("usefriction", ptline, 11)) && strlen(ptline) > 12) { String modelName = String(ptline + 12); gm = gEnv->collisions->getGroundModelByString(modelName); continue; } if (!strcmp("virtual", ptline)) {virt=true;continue;}; if (!strncmp("event", ptline, 5)) { char ts[256]; ts[0]=0; sscanf(ptline, "event %s %s",eventname, ts); if (!strncmp(ts, "avatar", 6)) event_filter=EVENT_AVATAR; else if (!strncmp(ts, "truck", 5)) event_filter=EVENT_TRUCK; else if (!strncmp(ts, "airplane", 8)) event_filter=EVENT_AIRPLANE; else if (!strncmp(ts, "boat", 8)) event_filter=EVENT_BOAT; else if (!strncmp(ts, "delete", 8)) event_filter=EVENT_DELETE; //if (!strncmp(ts, "shoptruck", 9)) // terrainManager->terrainHasTruckShop=true; // fallback if (strlen(ts) == 0) event_filter=EVENT_ALL; continue; } if (!strcmp("endbox", ptline)) { if (enable_collisions) { const String eventnameStr = eventname; int boxnum = gEnv->collisions->addCollisionBox(tenode, rotating, virt, pos, rot, l, h, sr, eventnameStr, instancename, forcecam, fc, sc, dr, event_filter, scripthandler); obj->collBoxes.push_back((boxnum)); } continue; } if (!strcmp("endmesh", ptline)) { gEnv->collisions->addCollisionMesh(collmesh, Vector3(pos.x,pos.y,pos.z), tenode->getOrientation(), sc, gm, &(obj->collTris)); continue; } if (!strncmp("particleSystem", ptline, 14) && tenode) { float x=0, y=0, z=0, scale=0; char pname[255]="", sname[255]=""; int res = sscanf(ptline, "particleSystem %f, %f, %f, %f, %s %s", &scale, &x, &y, &z, pname, sname); if (res != 6) continue; // hacky: prevent duplicates String paname = String(pname); while(gEnv->sceneManager->hasParticleSystem(paname)) paname += "_"; // create particle system ParticleSystem* pParticleSys = gEnv->sceneManager->createParticleSystem(paname, String(sname)); pParticleSys->setCastShadows(false); pParticleSys->setVisibilityFlags(DEPTHMAP_DISABLED); // disable particles in depthmap // Some affectors may need its instance name (e.g. for script feedback purposes) #ifdef USE_ANGELSCRIPT unsigned short affCount = pParticleSys->getNumAffectors(); ParticleAffector* pAff; for (unsigned short i = 0; i<affCount; ++i) { pAff = pParticleSys->getAffector(i); if (pAff->getType()=="ExtinguishableFire") { ((ExtinguishableFireAffector*)pAff)->setInstanceName(obj->instanceName); } } #endif // USE_ANGELSCRIPT SceneNode *sn = tenode->createChildSceneNode(); sn->attachObject(pParticleSys); sn->pitch(Degree(90)); continue; } if (!strncmp("setMeshMaterial", ptline, 15)) { char mat[256]=""; sscanf(ptline, "setMeshMaterial %s", mat); if (mo->getEntity() && strnlen(mat,250)>0) { mo->getEntity()->setMaterialName(String(mat)); // load it //MaterialManager::getSingleton().load(String(mat), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); } continue; } if (!strncmp("generateMaterialShaders", ptline, 23)) { char mat[256]=""; sscanf(ptline, "generateMaterialShaders %s", mat); if (BSETTING("Use RTShader System", false)) { Ogre::RTShader::ShaderGenerator::getSingleton().createShaderBasedTechnique(String(mat), Ogre::MaterialManager::DEFAULT_SCHEME_NAME, Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); Ogre::RTShader::ShaderGenerator::getSingleton().invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, String(mat)); } continue; } if (!strncmp("playanimation", ptline, 13) && mo) { char animname[256]=""; float speedfactorMin = 0, speedfactorMax = 0; sscanf(ptline, "playanimation %f, %f, %s", &speedfactorMin, &speedfactorMax, animname); if (tenode && mo->getEntity() && strnlen(animname,250)>0) { AnimationStateSet *s = mo->getEntity()->getAllAnimationStates(); if (!s->hasAnimationState(String(animname))) { LOG("ODEF: animation '" + String(animname) + "' for mesh: '" + String(mesh) + "' in odef file '" + name + ".odef' not found!"); continue; } animated_object_t ao; ao.node = tenode; ao.ent = mo->getEntity(); ao.speedfactor = speedfactorMin; if (speedfactorMin != speedfactorMax) ao.speedfactor = Math::RangeRandom(speedfactorMin, speedfactorMax); ao.anim = 0; try { ao.anim = mo->getEntity()->getAnimationState(String(animname)); } catch (...) { ao.anim = 0; } if (!ao.anim) { LOG("ODEF: animation '" + String(animname) + "' for mesh: '" + String(mesh) + "' in odef file '" + name + ".odef' not found!"); continue; } ao.anim->setEnabled(true); animatedObjects.push_back(ao); } continue; } if (!strncmp("drawTextOnMeshTexture", ptline, 21) && mo) { if (!mo->getEntity()) continue; String matName = mo->getEntity()->getSubEntity(0)->getMaterialName(); MaterialPtr m = MaterialManager::getSingleton().getByName(matName); if (m.getPointer() == 0) { LOG("ODEF: problem with drawTextOnMeshTexture command: mesh material not found: "+odefname+" : "+String(ptline)); continue; } String texName = m->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName(); Texture* background = (Texture *)TextureManager::getSingleton().getByName(texName).getPointer(); if (!background) { LOG("ODEF: problem with drawTextOnMeshTexture command: mesh texture not found: "+odefname+" : "+String(ptline)); continue; } static int textureNumber = 0; textureNumber++; char tmpTextName[256]="", tmpMatName[256]=""; sprintf(tmpTextName, "TextOnTexture_%d_Texture", textureNumber); sprintf(tmpMatName, "TextOnTexture_%d_Material", textureNumber); // Make sure the texture is not WRITE_ONLY, we need to read the buffer to do the blending with the font (get the alpha for example) TexturePtr texture = TextureManager::getSingleton().createManual(tmpTextName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (Ogre::uint)background->getWidth(), (Ogre::uint)background->getHeight(), MIP_UNLIMITED , PF_X8R8G8B8, Ogre::TU_STATIC|Ogre::TU_AUTOMIPMAP, new ResourceBuffer()); if (texture.getPointer() == 0) { LOG("ODEF: problem with drawTextOnMeshTexture command: could not create texture: "+odefname+" : "+String(ptline)); continue; } float x=0, y=0, w=0, h=0; float a=0, r=0, g=0, b=0; char fontname[256]=""; char text[256]=""; char option='l'; int res = sscanf(ptline, "drawTextOnMeshTexture %f, %f, %f, %f, %f, %f, %f, %f, %c, %s %s", &x, &y, &w, &h, &r, &g, &b, &a, &option, fontname, text); if (res < 11) { LOG("ODEF: problem with drawTextOnMeshTexture command: "+odefname+" : "+String(ptline)); continue; } // check if we got a template argument if (!strncmp(text, "{{argument1}}", 13)) strncpy(text, instancename.c_str(), 250); // replace '_' with ' ' char *text_pointer = text; while (*text_pointer!=0) {if (*text_pointer=='_') *text_pointer=' ';text_pointer++;}; Font* font = (Font *)FontManager::getSingleton().getByName(String(fontname)).getPointer(); if (!font) { LOG("ODEF: problem with drawTextOnMeshTexture command: font not found: "+odefname+" : "+String(ptline)); continue; } //Draw the background to the new texture texture->getBuffer()->blit(background->getBuffer()); x = background->getWidth() * x; y = background->getHeight() * y; w = background->getWidth() * w; h = background->getHeight() * h; Image::Box box = Image::Box((size_t)x, (size_t)y, (size_t)(x+w), (size_t)(y+h)); WriteToTexture(String(text), texture, box, font, ColourValue(r, g, b, a), option); // we can save it to disc for debug purposes: //SaveImage(texture, "test.png"); m->clone(tmpMatName); MaterialPtr mNew = MaterialManager::getSingleton().getByName(tmpMatName); mNew->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(tmpTextName); mo->getEntity()->setMaterialName(String(tmpMatName)); continue; } LOG("ODEF: unknown command in "+odefname+" : "+String(ptline)); } //add icons if type is set #ifdef USE_MYGUI String typestr = ""; if (!type.empty() && gEnv->surveyMap) { typestr = type; // hack for raceways if (name == "chp-checkpoint") typestr = "checkpoint"; if (name == "chp-start") typestr = "racestart"; if (name == "road", 4) typestr = "road"; if (typestr != "" && typestr != "road" && typestr != "sign") { SurveyMapEntity *e = gEnv->surveyMap->createMapEntity(typestr); if (e) { e->setVisibility(true); e->setPosition(pos); e->setRotation(Radian(rot.y)); if (!name.empty()) e->setDescription(instancename); } } } #endif //USE_MYGUI }