void WebFrameLoaderClient::dispatchDidFirstLayout() { SharedPtr<WebFrameLoadDelegate> frameLoadDelegate = m_webFrame->webView()->webFrameLoadDelegate(); if (frameLoadDelegate) frameLoadDelegate->dispatchDidFirstLayout(m_webFrame); }
CLOCKWORK_EXPORT_API int clockworksharp_initialize() { sContext = new Clockwork::Context(); sApplication = new ClockworkPlayer::ClockworkPlayerApp(sContext); return sApplication->Initialize(); }
bool TextureCube::Load(CubeMapFace face, SharedPtr<Image> image, bool useAlpha) { if (!image) { LOGERROR("Null image, can not load texture"); return false; } unsigned memoryUse = 0; int quality = QUALITY_HIGH; Renderer* renderer = GetSubsystem<Renderer>(); if (renderer) quality = renderer->GetTextureQuality(); if (!image->IsCompressed()) { unsigned char* levelData = image->GetData(); int levelWidth = image->GetWidth(); int levelHeight = image->GetHeight(); unsigned components = image->GetComponents(); unsigned format = 0; if (levelWidth != levelHeight) { LOGERROR("Cube texture width not equal to height"); return false; } // Discard unnecessary mip levels for (unsigned i = 0; i < mipsToSkip_[quality]; ++i) { image = image->GetNextLevel(); levelData = image->GetData(); levelWidth = image->GetWidth(); levelHeight = image->GetHeight(); } switch (components) { case 1: format = useAlpha ? Graphics::GetAlphaFormat() : Graphics::GetLuminanceFormat(); break; case 2: format = Graphics::GetLuminanceAlphaFormat(); break; case 3: format = Graphics::GetRGBFormat(); break; case 4: format = Graphics::GetRGBAFormat(); break; } // Create the texture when face 0 is being loaded, check that rest of the faces are same size & format if (!face) { // If image was previously compressed, reset number of requested levels to avoid error if level count is too high for new size if (IsCompressed() && requestedLevels_ > 1) requestedLevels_ = 0; SetSize(levelWidth, format); } else { if (!object_) { LOGERROR("Cube texture face 0 must be loaded first"); return false; } if (levelWidth != width_ || format != format_) { LOGERROR("Cube texture face does not match size or format of face 0"); return false; } } for (unsigned i = 0; i < levels_; ++i) { SetData(face, i, 0, 0, levelWidth, levelHeight, levelData); memoryUse += levelWidth * levelHeight * components; if (i < levels_ - 1) { image = image->GetNextLevel(); levelData = image->GetData(); levelWidth = image->GetWidth(); levelHeight = image->GetHeight(); } } } else { int width = image->GetWidth(); int height = image->GetHeight(); unsigned levels = image->GetNumCompressedLevels(); unsigned format = graphics_->GetFormat(image->GetCompressedFormat()); bool needDecompress = false; if (width != height) { LOGERROR("Cube texture width not equal to height"); return false; } if (!format) { format = Graphics::GetRGBAFormat(); needDecompress = true; } unsigned mipsToSkip = mipsToSkip_[quality]; if (mipsToSkip >= levels) mipsToSkip = levels - 1; while (mipsToSkip && (width / (1 << mipsToSkip) < 4 || height / (1 << mipsToSkip) < 4)) --mipsToSkip; width /= (1 << mipsToSkip); height /= (1 << mipsToSkip); // Create the texture when face 0 is being loaded, assume rest of the faces are same size & format if (!face) { SetNumLevels(Max((int)(levels - mipsToSkip), 1)); SetSize(width, format); } else { if (!object_) { LOGERROR("Cube texture face 0 must be loaded first"); return false; } if (width != width_ || format != format_) { LOGERROR("Cube texture face does not match size or format of face 0"); return false; } } for (unsigned i = 0; i < levels_ && i < levels - mipsToSkip; ++i) { CompressedLevel level = image->GetCompressedLevel(i + mipsToSkip); if (!needDecompress) { SetData(face, i, 0, 0, level.width_, level.height_, level.data_); memoryUse += level.rows_ * level.rowSize_; } else { unsigned char* rgbaData = new unsigned char[level.width_ * level.height_ * 4]; level.Decompress(rgbaData); SetData(face, i, 0, 0, level.width_, level.height_, rgbaData); memoryUse += level.width_ * level.height_ * 4; delete[] rgbaData; } } } faceMemoryUse_[face] = memoryUse; unsigned totalMemoryUse = sizeof(TextureCube); for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i) totalMemoryUse += faceMemoryUse_[i]; SetMemoryUse(totalMemoryUse); return true; }
Node* buildSimpleMechanicExample() { SharedPtr<Group> group = new Group("G"); MobileRootJoint* mobileRootJoint = new MobileRootJoint("Root Joint"); group->addChild(mobileRootJoint); RigidBody *rigidBody = new RigidBody("Rigid Body"); rigidBody->addLink("link2"); rigidBody->addLink("externalInteractLink"); rigidBody->addLink("internalInteractLink"); rigidBody->addLink("internalInteractLink2"); group->addChild(rigidBody); InertiaMatrix inertia(1, 0, 0, 1, 0, 1); Mass* mass = new Mass("Mass", 1, inertia); group->addChild(mass); RevoluteJoint* revoluteJoint = new RevoluteJoint("Revolute Joint"); revoluteJoint->setEnableExternalForce(true); group->addChild(revoluteJoint); RigidBody *rigidBody2 = new RigidBody("Rigid Body 2"); rigidBody2->addLink("externalInteractLink"); rigidBody2->addLink("internalInteractLink"); rigidBody2->addLink("internalInteractLink2"); group->addChild(rigidBody2); Mass* mass2 = new Mass("Mass 2", 1, inertia); group->addChild(mass2); ExternalInteract* externalInteract = new ExternalInteract("ExternalInteract"); externalInteract->setPosition(mass->getPosition()); externalInteract->setEnableAllOutputs(true); group->addChild(externalInteract); ExternalInteract* externalInteract2 = new ExternalInteract("ExternalInteract 2"); externalInteract2->setPosition(mass2->getPosition()); externalInteract2->setEnableAllOutputs(true); group->addChild(externalInteract2); group->connect(mobileRootJoint->getPort("link"), rigidBody->getPort("link0")); group->connect(rigidBody->getPort("link1"), mass->getPort("link")); group->connect(rigidBody->getPort("link2"), revoluteJoint->getPort("link0")); group->connect(revoluteJoint->getPort("link1"), rigidBody2->getPort("link0")); group->connect(rigidBody2->getPort("link1"), mass2->getPort("link")); group->connect(rigidBody->getPort("externalInteractLink"), externalInteract->getPort("link")); group->connect(rigidBody2->getPort("externalInteractLink"), externalInteract2->getPort("link")); ConstModel* jointForce = new ConstModel("Joint Force", 1); group->addChild(jointForce); group->connect(jointForce->getPort("output"), revoluteJoint->getPort("force")); InternalInteract* internalInteract = new InternalInteract("InternalInteract"); internalInteract->setPosition0(Vector3(0, 0, 1)); internalInteract->setPosition1(Vector3(0, 0, 0.8)); internalInteract->setEnableAllOutputs(true); internalInteract->setEnableForce(true); group->addChild(internalInteract); group->connect(internalInteract->getPort("link0"), rigidBody->getPort("internalInteractLink")); group->connect(internalInteract->getPort("link1"), rigidBody2->getPort("internalInteractLink")); InternalInteract* internalInteract2 = new InternalInteract("InternalInteract2"); internalInteract2->setPosition0(Vector3(0, 0, 0.8)); internalInteract2->setPosition1(Vector3(0, 0, 1)); internalInteract2->setEnableAllOutputs(true); group->addChild(internalInteract2); group->connect(internalInteract2->getPort("link1"), rigidBody->getPort("internalInteractLink2")); group->connect(internalInteract2->getPort("link0"), rigidBody2->getPort("internalInteractLink2")); LinearSpringDamper* damper = new LinearSpringDamper("LinearSpringDamper"); damper->setSpringConstant(0.5); damper->setDamperConstant(1); group->addChild(damper); group->connect(damper->getPort("velocity"), internalInteract->getPort("velocity")); group->connect(damper->getPort("position"), internalInteract->getPort("distance")); group->connect(damper->getPort("force"), internalInteract->getPort("force")); return group.release(); }
bool Shader::ProcessSource(SharedArrayPtr<char>& dest, unsigned& length, const String& fileName) { ResourceCache* cache = GetSubsystem<ResourceCache>(); if (!cache) return false; // Allow to define only a vertex shader or only a pixel shader if (!cache->Exists(fileName)) return true; cache->StoreResourceDependency(this, fileName); Vector<String> glslCode; // Load the shader source code SharedPtr<File> glslFile = cache->GetFile(fileName); if (!glslFile) return false; while (!glslFile->IsEof()) glslCode.Push(glslFile->ReadLine()); // Process the code for includes for (unsigned i = 0; i < glslCode.Size(); ++i) { if (glslCode[i].StartsWith("#include")) { String includeFileName = GetPath(fileName) + glslCode[i].Substring(9).Replaced("\"", "").Trimmed(); SharedPtr<File> glslIncludeFile = cache->GetFile(includeFileName); if (!glslIncludeFile) return false; // Remove the #include line, then include the code glslCode.Erase(i); unsigned pos = i; while (!glslIncludeFile->IsEof()) { glslCode.Insert(pos, glslIncludeFile->ReadLine()); ++pos; } // Finally insert an empty line to mark the space between files glslCode.Insert(pos, ""); } } // Copy the final code into one memory block length = 0; for (unsigned i = 0; i < glslCode.Size(); ++i) length += glslCode[i].Length() + 1; dest = new char[length]; char* destPtr = dest.Get(); for (unsigned i = 0; i < glslCode.Size(); ++i) { memcpy(destPtr, glslCode[i].CString(), glslCode[i].Length()); destPtr += glslCode[i].Length(); *destPtr++ = '\n'; } return true; }
void NetworkModule::Stop () { SharedPtr<NetworkBinding> b = this->variables.cast<NetworkBinding>(); b->Shutdown(); }
void bar(SharedPtr<Foo> ptr) { int i = ptr->Get(); assert(i == 1); }
void TerrySpawner::HandleNodeCollisionStart(StringHash eventType, VariantMap& eventData) { using namespace NodeCollisionStart; SharedPtr<Node> otherNode = SharedPtr<Node>(static_cast<Node*>(eventData[P_OTHERNODE].GetPtr())); RigidBody* rb = static_cast<RigidBody*>(eventData[P_BODY].GetPtr()); Node* noed = rb->GetNode(); if (otherNode->GetName() == "safetyNet") { RespawnTerry(noed); return; } if (!otherNode->HasComponent<Health>()) { return; } if (otherNode->GetVar("npcType").GetInt() == 0)//hero { MoveByTouch* mbt = noed->GetComponent<MoveByTouch>(); mbt->MoveTo(otherNode->GetWorldPosition(), mbt->moveToSpeed_,mbt->speedRamp_,mbt->gravity_,mbt->gravityRamp_,false,true,true); int collisionCount = noed->GetVar("collisionCount").GetInt(); collisionCount++; noed->SetVar("collisionCount", collisionCount); if (collisionCount == 1) { VariantMap vm; vm[AnimateSceneNode::P_NODE] = noed; if (noed->GetVar("sex").GetBool()) { vm[AnimateSceneNode::P_ANIMATION] = "attackF"; } else { vm[AnimateSceneNode::P_ANIMATION] = "attackM"; } vm[AnimateSceneNode::P_LOOP] = false; vm[AnimateSceneNode::P_LAYER] = 0; SendEvent(E_ANIMATESCENENODE, vm); } if (noed->GetComponent<Blind>() || noed->GetComponent<Stunned>()) { return; } int healthMod = noed->GetVar("attack").GetInt(); if (otherNode->HasComponent<Armor>()) { healthMod = noed->GetVar("attack").GetInt() - otherNode->GetComponent<Armor>()->armor_; if (healthMod < 0) { healthMod = 0; } } otherNode->GetComponent<Health>()->ModifyHealth(healthMod, -1, false); if (otherNode->GetComponent<Health>()->health_ <= 0) { if (otherNode->GetName() != "tent") { if (!otherNode->HasComponent<Dead>()) { otherNode->AddComponent(new Dead(context_, main_, -1.0f), 0, LOCAL); } } else { SpriteSheetPlayer* ssp = main_->mySceneNode_->GetComponent<SpriteSheetPlayer>(); for (int x = 0; x < ssp->sprites_.Size(); x++) { if (!ssp->sprites_[x]->noed_->HasComponent<Dead>()) { ssp->sprites_[x]->noed_->AddComponent(new Dead(context_, main_, -1.0f), 0, LOCAL); Node* particleStartNode_ = ssp->sprites_[x]->noed_->GetScene()->CreateChild(0,LOCAL); particleStartNode_->SetPosition(ssp->sprites_[x]->noed_->GetPosition()); particleStartNode_->AddComponent(new TimedRemove(context_, main_, 2.0f), 0, LOCAL); particleStartNode_->AddComponent(new SoundSource3D(context_), 0, LOCAL); particleStartNode_->GetComponent<SoundSource3D>()->SetGain(0.1f); particleStartNode_->GetComponent<SoundSource3D>()->Play(main_->cache_->GetResource<Sound>("Sounds/319071__mishicu__v8.ogg")); } } } //otherNode->GetComponent<Health>()->ModifyHealth(100, 0, false); //otherNode->GetScene()->GetComponent<TerrySpawner>()->RespawnTerry(otherNode); return; } /*if (!noed->HasComponent<Stunned>()) { noed->AddComponent(new Stunned(context_, main_, 2.0f), 0, LOCAL); }*/ } }
void TerrySpawner::HandleNodeCollision(StringHash eventType, VariantMap& eventData) { using namespace NodeCollision; RigidBody* rb = static_cast<RigidBody*>(eventData[P_BODY].GetPtr()); Node* noed = rb->GetNode(); if (!noed->GetVar("canAttack").GetBool()) { return; } if (noed->GetComponent<Blind>()) { return; } noed->SetVar("canAttack", false); SharedPtr<Node> otherNode = SharedPtr<Node>(static_cast<Node*>(eventData[P_OTHERNODE].GetPtr())); if (!otherNode->HasComponent<Health>()) { return; } bool enemy = false; if (otherNode->GetVar("npcType").GetInt() == 0)//hero { enemy = true; } if (enemy || noed->HasComponent<Enchanted>()) { int healthMod = noed->GetVar("attack").GetInt(); if (otherNode->HasComponent<Armor>()) { healthMod = noed->GetVar("attack").GetInt() - otherNode->GetComponent<Armor>()->armor_; if (healthMod < 0) { healthMod = 0; } } otherNode->GetComponent<Health>()->ModifyHealth(healthMod, -1, false); if (otherNode->GetComponent<Health>()->health_ <= 0) { if (!enemy && noed->HasComponent<Enchanted>()) { otherNode->GetComponent<Health>()->ModifyHealth(100, 0, false); otherNode->GetScene()->GetComponent<TerrySpawner>()->RespawnTerry(otherNode); } else if (otherNode->GetName() != "tent") { if (!otherNode->HasComponent<Dead>()) { otherNode->AddComponent(new Dead(context_, main_, -1.0f), 0, LOCAL); } } else { SpriteSheetPlayer* ssp = main_->mySceneNode_->GetComponent<SpriteSheetPlayer>(); for (int x = 0; x < ssp->sprites_.Size(); x++) { if (!ssp->sprites_[x]->noed_->HasComponent<Dead>()) { ssp->sprites_[x]->noed_->AddComponent(new Dead(context_, main_, -1.0f), 0, LOCAL); Node* particleStartNode_ = ssp->sprites_[x]->noed_->GetScene()->CreateChild(0,LOCAL); particleStartNode_->SetPosition(ssp->sprites_[x]->noed_->GetPosition()); particleStartNode_->AddComponent(new TimedRemove(context_, main_, 2.0f), 0, LOCAL); particleStartNode_->AddComponent(new SoundSource3D(context_), 0, LOCAL); particleStartNode_->GetComponent<SoundSource3D>()->SetGain(0.1f); particleStartNode_->GetComponent<SoundSource3D>()->Play(main_->cache_->GetResource<Sound>("Sounds/319071__mishicu__v8.ogg")); } } } return; } /*if (!noed->HasComponent<Stunned>()) { noed->AddComponent(new Stunned(context_, main_, 2.0f), 0, LOCAL); }*/ } }
// // main // int main(int argc, char **argv) { #ifdef __unix__ // Load wxWindows Stub (for pop-up dialogues) (void)dlopen(WXSTUB_DLL_NAME, RTLD_NOW|RTLD_NODELETE); #endif #ifdef LOG char buff[1000]; if (getUserDataDir(buff, sizeof(buff)) != 0) { strcpy(buff, "c:"); } strcat(buff, "/gdbServer.log"); FILE *errorLog = fopen(buff, "wt"); Logging::setLogFileHandle(errorLog); #endif Logging::setLoggingLevel(100); LOGGING; #ifdef LOG Logging::print("Args = "); for (int index=0; index<argc; index++) { Logging::printq("%s ", argv[index]); } Logging::printq("\n"); #endif if (signal(SIGINT, signalHandler) == SIG_IGN) { (void)signal(SIGINT, SIG_IGN); } shared = SharedPtr(new Shared(TARGET_TYPE)); USBDM_ErrorCode rc = doArgs(argc, argv); if (rc != BDM_RC_OK) { Logging::print("Error %s\n", USBDM_GetErrorString(rc)); exit (-1); } Logging::print("After doArgs\n"); rc = shared->initBdm(); if (rc != BDM_RC_OK) { Logging::print("Error %s\n", USBDM_GetErrorString(rc)); exit (-1); } Logging::print("After shared->initBdm()\n"); // setDefaultWindowParent(FindEclipseWindowHwnd()); GdbInOutPipe *gdbInOut = GdbInOutPipe::getGdbInOut(); Logging::print("After GdbInOutPipe::getGdbInOut()\n"); // Redirect stdout to stderr dup2(2,1); if (gdbInOut == NULL) { Logging::print("Error gdbInOut() creation failed\n"); exit (-1); } Logging::print("After gdbInOut()\n"); // Now do the actual processing of GDB messages gdbHandlerInit(gdbInOut, *shared->getCurrentDevice(), callBack); gdbLoop(gdbInOut); gdbInOut->finish(); delete gdbInOut; return 0; }
bool Texture3D::Load(Deserializer& source) { PROFILE(LoadTexture3D); // In headless mode, do not actually load the texture, just return success if (!graphics_) return true; // If device is lost, retry later if (graphics_->IsDeviceLost()) { LOGWARNING("Texture load while device is lost"); dataPending_ = true; return true; } // If over the texture budget, see if materials can be freed to allow textures to be freed CheckTextureBudget(GetTypeStatic()); // Before actually loading the texture, get optional parameters from an XML description file LoadParameters(); String texPath, texName, texExt; SplitPath(GetName(), texPath, texName, texExt); SharedPtr<XMLFile> xml(new XMLFile(context_)); if (!xml->Load(source)) return false; XMLElement textureElem = xml->GetRoot(); XMLElement volumeElem = textureElem.GetChild("volume"); XMLElement colorlutElem = textureElem.GetChild("colorlut"); if (volumeElem) { String name = volumeElem.GetAttribute("name"); String volumeTexPath, volumeTexName, volumeTexExt; SplitPath(name, volumeTexPath, volumeTexName, volumeTexExt); // If path is empty, add the XML file path if (volumeTexPath.Empty()) name = texPath + name; SharedPtr<Image> image(GetSubsystem<ResourceCache>()->GetResource<Image>(name)); return Load(image); } else if (colorlutElem) { String name = colorlutElem.GetAttribute("name"); String colorlutTexPath, colorlutTexName, colorlutTexExt; SplitPath(name, colorlutTexPath, colorlutTexName, colorlutTexExt); // If path is empty, add the XML file path if (colorlutTexPath.Empty()) name = texPath + name; SharedPtr<File> file = GetSubsystem<ResourceCache>()->GetFile(name); SharedPtr<Image> image(new Image(context_)); if (!image->LoadColorLUT(*(file.Get()))) return false; return Load(image); } return false; }
void DotsNetCrits::AttachLogicComponents(SharedPtr<Node> sceneNode) { sceneNode->AddComponent(new ModelPlayer(context_, main_), 0, LOCAL); sceneNode->AddComponent(new TopDownCamera(context_, main_), 0, LOCAL); sceneNode->AddComponent(new ThirdPersonCamera(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Speed(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Gravity(context_, main_), 0, LOCAL); sceneNode->AddComponent(new MoveByTouch(context_, main_), 0, LOCAL); sceneNode->AddComponent(new RotateTo(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Silence(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Teleport(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Sprint(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Snare(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Blind(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Melee(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Health(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Mute(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Armor(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Shield(context_, main_), 0, LOCAL); sceneNode->AddComponent(new DPSHeal(context_, main_), 0, LOCAL); sceneNode->AddComponent(new BlindingFlash(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Crit(context_, main_), 0, LOCAL); sceneNode->AddComponent(new DOT(context_, main_), 0, LOCAL); sceneNode->AddComponent(new DOTHeal(context_, main_), 0, LOCAL); sceneNode->AddComponent(new AOE(context_, main_), 0, LOCAL); sceneNode->AddComponent(new AOEHeal(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Cloak(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Cleanse(context_, main_), 0, LOCAL); sceneNode->AddComponent(new Knockback(context_, main_), 0, LOCAL); sceneNode->AddComponent(new SoundPlayer(context_, main_), 0, LOCAL); }
void WebFrameLoaderClient::setTitle(const String& title, const KURL& url) { #if OS(AMIGAOS4) if (!m_webFrame->parentFrame()) { BalWidget* viewWindow = m_webFrame->webView()->viewWindow(); if (viewWindow && viewWindow->window) { extern char* utf8ToAmiga(const char* utf8); char *titlestr = utf8ToAmiga(title.utf8().data()); if (titlestr && titlestr[0]) snprintf(viewWindow->title, sizeof(viewWindow->title), viewWindow->clickTabNode ? "%s" : "OWB: %s", titlestr); else strcpy(viewWindow->title, "Origyn Web Browser"); free(titlestr); if (amigaConfig.tabs) { IIntuition->SetGadgetAttrs(viewWindow->gad_clicktab, viewWindow->window, NULL, CLICKTAB_Labels, ~0, TAG_DONE); IClickTab->SetClickTabNodeAttrs(viewWindow->clickTabNode, TNA_Text, viewWindow->title, TAG_DONE); IIntuition->RefreshSetGadgetAttrs(viewWindow->gad_clicktab, viewWindow->window, NULL, CLICKTAB_Labels, viewWindow->clickTabList, TAG_DONE); } else IIntuition->SetWindowTitles(viewWindow->window, viewWindow->title, (STRPTR)~0UL); CString urlLatin1 = url.prettyURL().latin1(); const char *urlstr = urlLatin1.data(); if (urlstr && urlstr[0] && viewWindow->gad_url) { snprintf(viewWindow->url, sizeof(viewWindow->url), "%s", urlstr); if (ILayout->SetPageGadgetAttrs(viewWindow->gad_url, viewWindow->page, viewWindow->window, NULL, STRINGA_TextVal, viewWindow->url, TAG_DONE)) ILayout->RefreshPageGadget(viewWindow->gad_url, viewWindow->page, viewWindow->window, NULL); } } } #endif WebView* webView = m_webFrame->webView(); SharedPtr<WebHistoryDelegate> historyDelegate = webView->historyDelegate(); if (historyDelegate) { historyDelegate->updateHistoryTitle(webView, title.utf8().data(), url.string().utf8().data()); return; } bool privateBrowsingEnabled = false; WebPreferences* preferences = m_webFrame->webView()->preferences(); if (preferences) privateBrowsingEnabled = preferences->privateBrowsingEnabled(); if (privateBrowsingEnabled) return; // update title in global history WebHistory* history = webHistory(); if (!history) return; WebHistoryItem* item = history->itemForURL(strdup(url.string().utf8().data())); if (!item) return; item->setTitle(title.utf8().data()); }
void WebFrameLoaderClient::postProgressEstimateChangedNotification() { SharedPtr<WebNotificationDelegate> webNotificationDelegate = m_webFrame->webView()->webNotificationDelegate(); if (webNotificationDelegate) webNotificationDelegate->progressNotification(m_webFrame); }
void AnimatedModel::CloneGeometries() { const Vector<SharedPtr<VertexBuffer> >& originalVertexBuffers = model_->GetVertexBuffers(); HashMap<VertexBuffer*, SharedPtr<VertexBuffer> > clonedVertexBuffers; morphVertexBuffers_.Resize(originalVertexBuffers.Size()); for (unsigned i = 0; i < originalVertexBuffers.Size(); ++i) { VertexBuffer* original = originalVertexBuffers[i]; if (model_->GetMorphRangeCount(i)) { SharedPtr<VertexBuffer> clone(new VertexBuffer(context_)); clone->SetShadowed(true); clone->SetSize(original->GetVertexCount(), morphElementMask_ & original->GetElementMask(), true); void* dest = clone->Lock(0, original->GetVertexCount()); if (dest) { CopyMorphVertices(dest, original->GetShadowData(), original->GetVertexCount(), clone, original); clone->Unlock(); } clonedVertexBuffers[original] = clone; morphVertexBuffers_[i] = clone; } else morphVertexBuffers_[i].Reset(); } // Geometries will always be cloned fully. They contain only references to buffer, so they are relatively light for (unsigned i = 0; i < geometries_.Size(); ++i) { for (unsigned j = 0; j < geometries_[i].Size(); ++j) { SharedPtr<Geometry> original = geometries_[i][j]; SharedPtr<Geometry> clone(new Geometry(context_)); // Add an additional vertex stream into the clone, which supplies only the morphable vertex data, while the static // data comes from the original vertex buffer(s) const Vector<SharedPtr<VertexBuffer> >& originalBuffers = original->GetVertexBuffers(); unsigned totalBuf = originalBuffers.Size(); for (unsigned k = 0; k < originalBuffers.Size(); ++k) { VertexBuffer* originalBuffer = originalBuffers[k]; if (clonedVertexBuffers.Contains(originalBuffer)) ++totalBuf; } clone->SetNumVertexBuffers(totalBuf); unsigned l = 0; for (unsigned k = 0; k < originalBuffers.Size(); ++k) { VertexBuffer* originalBuffer = originalBuffers[k]; if (clonedVertexBuffers.Contains(originalBuffer)) { VertexBuffer* clonedBuffer = clonedVertexBuffers[originalBuffer]; clone->SetVertexBuffer(l++, originalBuffer); // Specify the morph buffer at a greater index to override the model's original positions/normals/tangents clone->SetVertexBuffer(l++, clonedBuffer); } else clone->SetVertexBuffer(l++, originalBuffer); } clone->SetIndexBuffer(original->GetIndexBuffer()); clone->SetDrawRange(original->GetPrimitiveType(), original->GetIndexStart(), original->GetIndexCount()); clone->SetLodDistance(original->GetLodDistance()); geometries_[i][j] = clone; } } // Make sure the rendering batches use the new cloned geometries ResetLodLevels(); MarkMorphsDirty(); }
void FileStream::WriteLine(const ValueList& args, SharedValue result) { if(! this->stream) { throw ValueException::FromString("FileStream must be opened before calling readLine"); } char *text = NULL; int size = 0; if (args.at(0)->IsObject()) { SharedKObject b = args.at(0)->ToObject(); SharedPtr<Blob> blob = b.cast<Blob>(); if (!blob.isNull()) { text = (char*)blob->Get(); size = (int)blob->Length(); } } else if (args.at(0)->IsString()) { text = (char*)args.at(0)->ToString(); } else if (args.at(0)->IsInt()) { std::stringstream ostr; ostr << args.at(0)->ToInt(); text = (char*)ostr.str().c_str(); size = ostr.str().length(); } else if (args.at(0)->IsDouble()) { std::stringstream ostr; ostr << args.at(0)->ToDouble(); text = (char*)ostr.str().c_str(); size = ostr.str().length(); } if (size==0) { size = strlen(text); } if (text == NULL) { result->SetBool(false); return; } if (size <= 0) { result->SetBool(false); return; } std::string astr = text; #ifdef OS_WIN32 astr += "\r\n"; #else astr += "\n"; #endif Write((char*)astr.c_str(),astr.length()); result->SetBool(true); }
void DynamicGeometry::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create the Octree component to the scene so that drawable objects can be rendered. Use default volume // (-1000, -1000, -1000) to (1000, 1000, 1000) scene_->CreateComponent<Octree>(); // Create a Zone for ambient light & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetFogColor(Color(0.2f, 0.2f, 0.2f)); zone->SetFogStart(200.0f); zone->SetFogEnd(300.0f); // Create a directional light Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(-0.6f, -1.0f, -0.8f)); // The direction vector does not need to be normalized Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetColor(Color(0.4f, 1.0f, 0.4f)); light->SetSpecularIntensity(1.5f); // Get the original model and its unmodified vertices, which are used as source data for the animation Model* originalModel = cache->GetResource<Model>("Models/Box.mdl"); if (!originalModel) { ATOMIC_LOGERROR("Model not found, cannot initialize example scene"); return; } // Get the vertex buffer from the first geometry's first LOD level VertexBuffer* buffer = originalModel->GetGeometry(0, 0)->GetVertexBuffer(0); const unsigned char* vertexData = (const unsigned char*)buffer->Lock(0, buffer->GetVertexCount()); if (vertexData) { unsigned numVertices = buffer->GetVertexCount(); unsigned vertexSize = buffer->GetVertexSize(); // Copy the original vertex positions for (unsigned i = 0; i < numVertices; ++i) { const Vector3& src = *reinterpret_cast<const Vector3*>(vertexData + i * vertexSize); originalVertices_.Push(src); } buffer->Unlock(); // Detect duplicate vertices to allow seamless animation vertexDuplicates_.Resize(originalVertices_.Size()); for (unsigned i = 0; i < originalVertices_.Size(); ++i) { vertexDuplicates_[i] = i; // Assume not a duplicate for (unsigned j = 0; j < i; ++j) { if (originalVertices_[i].Equals(originalVertices_[j])) { vertexDuplicates_[i] = j; break; } } } } else { ATOMIC_LOGERROR("Failed to lock the model vertex buffer to get original vertices"); return; } // Create StaticModels in the scene. Clone the model for each so that we can modify the vertex data individually for (int y = -1; y <= 1; ++y) { for (int x = -1; x <= 1; ++x) { Node* node = scene_->CreateChild("Object"); node->SetPosition(Vector3(x * 2.0f, 0.0f, y * 2.0f)); StaticModel* object = node->CreateComponent<StaticModel>(); SharedPtr<Model> cloneModel = originalModel->Clone(); object->SetModel(cloneModel); // Store the cloned vertex buffer that we will modify when animating animatingBuffers_.Push(SharedPtr<VertexBuffer>(cloneModel->GetGeometry(0, 0)->GetVertexBuffer(0))); } } // Finally create one model (pyramid shape) and a StaticModel to display it from scratch // Note: there are duplicated vertices to enable face normals. We will calculate normals programmatically { const unsigned numVertices = 18; float vertexData[] = { // Position Normal 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f }; const unsigned short indexData[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; // Calculate face normals now for (unsigned i = 0; i < numVertices; i += 3) { Vector3& v1 = *(reinterpret_cast<Vector3*>(&vertexData[6 * i])); Vector3& v2 = *(reinterpret_cast<Vector3*>(&vertexData[6 * (i + 1)])); Vector3& v3 = *(reinterpret_cast<Vector3*>(&vertexData[6 * (i + 2)])); Vector3& n1 = *(reinterpret_cast<Vector3*>(&vertexData[6 * i + 3])); Vector3& n2 = *(reinterpret_cast<Vector3*>(&vertexData[6 * (i + 1) + 3])); Vector3& n3 = *(reinterpret_cast<Vector3*>(&vertexData[6 * (i + 2) + 3])); Vector3 edge1 = v1 - v2; Vector3 edge2 = v1 - v3; n1 = n2 = n3 = edge1.CrossProduct(edge2).Normalized(); } SharedPtr<Model> fromScratchModel(new Model(context_)); SharedPtr<VertexBuffer> vb(new VertexBuffer(context_)); SharedPtr<IndexBuffer> ib(new IndexBuffer(context_)); SharedPtr<Geometry> geom(new Geometry(context_)); // Shadowed buffer needed for raycasts to work, and so that data can be automatically restored on device loss vb->SetShadowed(true); // We could use the "legacy" element bitmask to define elements for more compact code, but let's demonstrate // defining the vertex elements explicitly to allow any element types and order PODVector<VertexElement> elements; elements.Push(VertexElement(TYPE_VECTOR3, SEM_POSITION)); elements.Push(VertexElement(TYPE_VECTOR3, SEM_NORMAL)); vb->SetSize(numVertices, elements); vb->SetData(vertexData); ib->SetShadowed(true); ib->SetSize(numVertices, false); ib->SetData(indexData); geom->SetVertexBuffer(0, vb); geom->SetIndexBuffer(ib); geom->SetDrawRange(TRIANGLE_LIST, 0, numVertices); fromScratchModel->SetNumGeometries(1); fromScratchModel->SetGeometry(0, 0, geom); fromScratchModel->SetBoundingBox(BoundingBox(Vector3(-0.5f, -0.5f, -0.5f), Vector3(0.5f, 0.5f, 0.5f))); // Though not necessary to render, the vertex & index buffers must be listed in the model so that it can be saved properly Vector<SharedPtr<VertexBuffer> > vertexBuffers; Vector<SharedPtr<IndexBuffer> > indexBuffers; vertexBuffers.Push(vb); indexBuffers.Push(ib); // Morph ranges could also be not defined. Here we simply define a zero range (no morphing) for the vertex buffer PODVector<unsigned> morphRangeStarts; PODVector<unsigned> morphRangeCounts; morphRangeStarts.Push(0); morphRangeCounts.Push(0); fromScratchModel->SetVertexBuffers(vertexBuffers, morphRangeStarts, morphRangeCounts); fromScratchModel->SetIndexBuffers(indexBuffers); Node* node = scene_->CreateChild("FromScratchObject"); node->SetPosition(Vector3(0.0f, 3.0f, 0.0f)); StaticModel* object = node->CreateComponent<StaticModel>(); object->SetModel(fromScratchModel); } // Create the camera cameraNode_ = new Node(context_); cameraNode_->SetPosition(Vector3(0.0f, 2.0f, -20.0f)); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); }
inline void operator()(Topology &t,const SharedPtr<Peer> &p) { if (p->resetWithinScope(RR,_scope,_now)) peersReset.push_back(p); }
bool Texture3D::BeginLoad(Deserializer& source) { auto* cache = GetSubsystem<ResourceCache>(); // In headless mode, do not actually load the texture, just return success if (!graphics_) return true; // If device is lost, retry later if (graphics_->IsDeviceLost()) { URHO3D_LOGWARNING("Texture load while device is lost"); dataPending_ = true; return true; } String texPath, texName, texExt; SplitPath(GetName(), texPath, texName, texExt); cache->ResetDependencies(this); loadParameters_ = new XMLFile(context_); if (!loadParameters_->Load(source)) { loadParameters_.Reset(); return false; } XMLElement textureElem = loadParameters_->GetRoot(); XMLElement volumeElem = textureElem.GetChild("volume"); XMLElement colorlutElem = textureElem.GetChild("colorlut"); if (volumeElem) { String name = volumeElem.GetAttribute("name"); String volumeTexPath, volumeTexName, volumeTexExt; SplitPath(name, volumeTexPath, volumeTexName, volumeTexExt); // If path is empty, add the XML file path if (volumeTexPath.Empty()) name = texPath + name; loadImage_ = cache->GetTempResource<Image>(name); // Precalculate mip levels if async loading if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING) loadImage_->PrecalculateLevels(); cache->StoreResourceDependency(this, name); return true; } else if (colorlutElem) { String name = colorlutElem.GetAttribute("name"); String colorlutTexPath, colorlutTexName, colorlutTexExt; SplitPath(name, colorlutTexPath, colorlutTexName, colorlutTexExt); // If path is empty, add the XML file path if (colorlutTexPath.Empty()) name = texPath + name; SharedPtr<File> file = GetSubsystem<ResourceCache>()->GetFile(name); loadImage_ = new Image(context_); if (!loadImage_->LoadColorLUT(*(file.Get()))) { loadParameters_.Reset(); loadImage_.Reset(); return false; } // Precalculate mip levels if async loading if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING) loadImage_->PrecalculateLevels(); cache->StoreResourceDependency(this, name); return true; } URHO3D_LOGERROR("Texture3D XML data for " + GetName() + " did not contain either volume or colorlut element"); return false; }
void LoadSkeleton(const String& skeletonFileName) { // Process skeleton first (if found) XMLElement skeletonRoot; File skeletonFileSource(context_); skeletonFileSource.Open(skeletonFileName); if (!skelFile_->Load(skeletonFileSource)) PrintLine("Failed to load skeleton " + skeletonFileName); skeletonRoot = skelFile_->GetRoot(); if (skeletonRoot) { XMLElement bonesRoot = skeletonRoot.GetChild("bones"); XMLElement bone = bonesRoot.GetChild("bone"); while (bone) { unsigned index = bone.GetInt("id"); String name = bone.GetAttribute("name"); if (index >= bones_.Size()) bones_.Resize(index + 1); // Convert from right- to left-handed XMLElement position = bone.GetChild("position"); float x = position.GetFloat("x"); float y = position.GetFloat("y"); float z = position.GetFloat("z"); Vector3 pos(x, y, -z); XMLElement rotation = bone.GetChild("rotation"); XMLElement axis = rotation.GetChild("axis"); float angle = -rotation.GetFloat("angle") * M_RADTODEG; x = axis.GetFloat("x"); y = axis.GetFloat("y"); z = axis.GetFloat("z"); Vector3 axisVec(x, y, -z); Quaternion rot(angle, axisVec); bones_[index].name_ = name; bones_[index].parentIndex_ = index; // Fill in the correct parent later bones_[index].bindPosition_ = pos; bones_[index].bindRotation_ = rot; bones_[index].bindScale_ = Vector3::ONE; bones_[index].collisionMask_ = 0; bones_[index].radius_ = 0.0f; bone = bone.GetNext("bone"); } // Go through the bone hierarchy XMLElement boneHierarchy = skeletonRoot.GetChild("bonehierarchy"); XMLElement boneParent = boneHierarchy.GetChild("boneparent"); while (boneParent) { String bone = boneParent.GetAttribute("bone"); String parent = boneParent.GetAttribute("parent"); unsigned i = 0, j = 0; for (i = 0; i < bones_.Size() && bones_[i].name_ != bone; ++i); for (j = 0; j < bones_.Size() && bones_[j].name_ != parent; ++j); if (i >= bones_.Size() || j >= bones_.Size()) ErrorExit("Found indeterminate parent bone assignment"); bones_[i].parentIndex_ = j; boneParent = boneParent.GetNext("boneparent"); } // Calculate bone derived positions for (unsigned i = 0; i < bones_.Size(); ++i) { Vector3 derivedPosition = bones_[i].bindPosition_; Quaternion derivedRotation = bones_[i].bindRotation_; Vector3 derivedScale = bones_[i].bindScale_; unsigned index = bones_[i].parentIndex_; if (index != i) { for (;;) { derivedPosition = bones_[index].bindPosition_ + (bones_[index].bindRotation_ * (bones_[index].bindScale_ * derivedPosition)); derivedRotation = bones_[index].bindRotation_ * derivedRotation; derivedScale = bones_[index].bindScale_ * derivedScale; if (bones_[index].parentIndex_ != index) index = bones_[index].parentIndex_; else break; } } bones_[i].derivedPosition_ = derivedPosition; bones_[i].derivedRotation_ = derivedRotation; bones_[i].derivedScale_ = derivedScale; bones_[i].worldTransform_ = Matrix3x4(derivedPosition, derivedRotation, derivedScale); bones_[i].inverseWorldTransform_ = bones_[i].worldTransform_.Inverse(); } PrintLine("Processed skeleton"); } }
bool WatcherMgr::RemoveWatcher(SharedPtr<WatcherBase> pWatcher) { if(pWatcher.isNull()) return false; return RemoveWatcher(pWatcher->GetConnID()); }
void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubMeshes, bool exportMorphs) { File meshFileSource(context_); meshFileSource.Open(inputFileName); if (!meshFile_->Load(meshFileSource)) ErrorExit("Could not load input file " + inputFileName); XMLElement root = meshFile_->GetRoot("mesh"); XMLElement subMeshes = root.GetChild("submeshes"); XMLElement skeletonLink = root.GetChild("skeletonlink"); if (root.IsNull()) ErrorExit("Could not load input file " + inputFileName); String skeletonName = skeletonLink.GetAttribute("name"); if (!skeletonName.Empty()) LoadSkeleton(GetPath(inputFileName) + GetFileName(skeletonName) + ".skeleton.xml"); // Check whether there's benefit of avoiding 32bit indices by splitting each submesh into own buffer XMLElement subMesh = subMeshes.GetChild("submesh"); unsigned totalVertices = 0; unsigned maxSubMeshVertices = 0; while (subMesh) { materialNames_.Push(subMesh.GetAttribute("material")); XMLElement geometry = subMesh.GetChild("geometry"); if (geometry) { unsigned vertices = geometry.GetInt("vertexcount"); totalVertices += vertices; if (maxSubMeshVertices < vertices) maxSubMeshVertices = vertices; } ++numSubMeshes_; subMesh = subMesh.GetNext("submesh"); } XMLElement sharedGeometry = root.GetChild("sharedgeometry"); if (sharedGeometry) { unsigned vertices = sharedGeometry.GetInt("vertexcount"); totalVertices += vertices; if (maxSubMeshVertices < vertices) maxSubMeshVertices = vertices; } if (!sharedGeometry && (splitSubMeshes || (totalVertices > 65535 && maxSubMeshVertices <= 65535))) { useOneBuffer_ = false; vertexBuffers_.Resize(numSubMeshes_); indexBuffers_.Resize(numSubMeshes_); } else { vertexBuffers_.Resize(1); indexBuffers_.Resize(1); } subMesh = subMeshes.GetChild("submesh"); unsigned indexStart = 0; unsigned vertexStart = 0; unsigned subMeshIndex = 0; PODVector<unsigned> vertexStarts; vertexStarts.Resize(numSubMeshes_); while (subMesh) { XMLElement geometry = subMesh.GetChild("geometry"); XMLElement faces = subMesh.GetChild("faces"); // If no submesh vertexbuffer, process the shared geometry, but do it only once unsigned vertices = 0; if (!geometry) { vertexStart = 0; if (!subMeshIndex) geometry = root.GetChild("sharedgeometry"); } if (geometry) vertices = geometry.GetInt("vertexcount"); ModelSubGeometryLodLevel subGeometryLodLevel; ModelVertexBuffer* vBuf; ModelIndexBuffer* iBuf; if (useOneBuffer_) { vBuf = &vertexBuffers_[0]; if (vertices) vBuf->vertices_.Resize(vertexStart + vertices); iBuf = &indexBuffers_[0]; subGeometryLodLevel.vertexBuffer_ = 0; subGeometryLodLevel.indexBuffer_ = 0; } else { vertexStart = 0; indexStart = 0; vBuf = &vertexBuffers_[subMeshIndex]; vBuf->vertices_.Resize(vertices); iBuf = &indexBuffers_[subMeshIndex]; subGeometryLodLevel.vertexBuffer_ = subMeshIndex; subGeometryLodLevel.indexBuffer_ = subMeshIndex; } // Store the start vertex for later use vertexStarts[subMeshIndex] = vertexStart; // Ogre may have multiple buffers in one submesh. These will be merged into one XMLElement bufferDef; if (geometry) bufferDef = geometry.GetChild("vertexbuffer"); while (bufferDef) { if (bufferDef.HasAttribute("positions")) vBuf->elementMask_ |= MASK_POSITION; if (bufferDef.HasAttribute("normals")) vBuf->elementMask_ |= MASK_NORMAL; if (bufferDef.HasAttribute("texture_coords")) { vBuf->elementMask_ |= MASK_TEXCOORD1; if (bufferDef.GetInt("texture_coords") > 1) vBuf->elementMask_ |= MASK_TEXCOORD2; } unsigned vertexNum = vertexStart; if (vertices) { XMLElement vertex = bufferDef.GetChild("vertex"); while (vertex) { XMLElement position = vertex.GetChild("position"); if (position) { // Convert from right- to left-handed float x = position.GetFloat("x"); float y = position.GetFloat("y"); float z = position.GetFloat("z"); Vector3 vec(x, y, -z); vBuf->vertices_[vertexNum].position_ = vec; boundingBox_.Merge(vec); } XMLElement normal = vertex.GetChild("normal"); if (normal) { // Convert from right- to left-handed float x = normal.GetFloat("x"); float y = normal.GetFloat("y"); float z = normal.GetFloat("z"); Vector3 vec(x, y, -z); vBuf->vertices_[vertexNum].normal_ = vec; } XMLElement uv = vertex.GetChild("texcoord"); if (uv) { float x = uv.GetFloat("u"); float y = uv.GetFloat("v"); Vector2 vec(x, y); vBuf->vertices_[vertexNum].texCoord1_ = vec; if (vBuf->elementMask_ & MASK_TEXCOORD2) { uv = uv.GetNext("texcoord"); if (uv) { float x = uv.GetFloat("u"); float y = uv.GetFloat("v"); Vector2 vec(x, y); vBuf->vertices_[vertexNum].texCoord2_ = vec; } } } vertexNum++; vertex = vertex.GetNext("vertex"); } } bufferDef = bufferDef.GetNext("vertexbuffer"); } unsigned triangles = faces.GetInt("count"); unsigned indices = triangles * 3; XMLElement triangle = faces.GetChild("face"); while (triangle) { unsigned v1 = triangle.GetInt("v1"); unsigned v2 = triangle.GetInt("v2"); unsigned v3 = triangle.GetInt("v3"); iBuf->indices_.Push(v3 + vertexStart); iBuf->indices_.Push(v2 + vertexStart); iBuf->indices_.Push(v1 + vertexStart); triangle = triangle.GetNext("face"); } subGeometryLodLevel.indexStart_ = indexStart; subGeometryLodLevel.indexCount_ = indices; if (vertexStart + vertices > 65535) iBuf->indexSize_ = sizeof(unsigned); XMLElement boneAssignments = subMesh.GetChild("boneassignments"); if (bones_.Size()) { if (boneAssignments) { XMLElement boneAssignment = boneAssignments.GetChild("vertexboneassignment"); while (boneAssignment) { unsigned vertex = boneAssignment.GetInt("vertexindex") + vertexStart; unsigned bone = boneAssignment.GetInt("boneindex"); float weight = boneAssignment.GetFloat("weight"); BoneWeightAssignment assign; assign.boneIndex_ = bone; assign.weight_ = weight; // Source data might have 0 weights. Disregard these if (assign.weight_ > 0.0f) { subGeometryLodLevel.boneWeights_[vertex].Push(assign); // Require skinning weight to be sufficiently large before vertex contributes to bone hitbox if (assign.weight_ > 0.33f) { // Check distance of vertex from bone to get bone max. radius information Vector3 bonePos = bones_[bone].derivedPosition_; Vector3 vertexPos = vBuf->vertices_[vertex].position_; float distance = (bonePos - vertexPos).Length(); if (distance > bones_[bone].radius_) { bones_[bone].collisionMask_ |= 1; bones_[bone].radius_ = distance; } // Build the hitbox for the bone bones_[bone].boundingBox_.Merge(bones_[bone].inverseWorldTransform_ * (vertexPos)); bones_[bone].collisionMask_ |= 2; } } boneAssignment = boneAssignment.GetNext("vertexboneassignment"); } } if ((subGeometryLodLevel.boneWeights_.Size()) && bones_.Size()) { vBuf->elementMask_ |= MASK_BLENDWEIGHTS | MASK_BLENDINDICES; bool sorted = false; // If amount of bones is larger than supported by HW skinning, must remap per submesh if (bones_.Size() > maxBones_) { HashMap<unsigned, unsigned> usedBoneMap; unsigned remapIndex = 0; for (HashMap<unsigned, PODVector<BoneWeightAssignment> >::Iterator i = subGeometryLodLevel.boneWeights_.Begin(); i != subGeometryLodLevel.boneWeights_.End(); ++i) { // Sort the bone assigns by weight Sort(i->second_.Begin(), i->second_.End(), CompareWeights); // Use only the first 4 weights for (unsigned j = 0; j < i->second_.Size() && j < 4; ++j) { unsigned originalIndex = i->second_[j].boneIndex_; if (!usedBoneMap.Contains(originalIndex)) { usedBoneMap[originalIndex] = remapIndex; remapIndex++; } i->second_[j].boneIndex_ = usedBoneMap[originalIndex]; } } // If still too many bones in one subgeometry, error if (usedBoneMap.Size() > maxBones_) ErrorExit("Too many bones (limit " + String(maxBones_) + ") in submesh " + String(subMeshIndex + 1)); // Write mapping of vertex buffer bone indices to original bone indices subGeometryLodLevel.boneMapping_.Resize(usedBoneMap.Size()); for (HashMap<unsigned, unsigned>::Iterator j = usedBoneMap.Begin(); j != usedBoneMap.End(); ++j) subGeometryLodLevel.boneMapping_[j->second_] = j->first_; sorted = true; } for (HashMap<unsigned, PODVector<BoneWeightAssignment> >::Iterator i = subGeometryLodLevel.boneWeights_.Begin(); i != subGeometryLodLevel.boneWeights_.End(); ++i) { // Sort the bone assigns by weight, if not sorted yet in bone remapping pass if (!sorted) Sort(i->second_.Begin(), i->second_.End(), CompareWeights); float totalWeight = 0.0f; float normalizationFactor = 0.0f; // Calculate normalization factor in case there are more than 4 blend weights, or they do not add up to 1 for (unsigned j = 0; j < i->second_.Size() && j < 4; ++j) totalWeight += i->second_[j].weight_; if (totalWeight > 0.0f) normalizationFactor = 1.0f / totalWeight; for (unsigned j = 0; j < i->second_.Size() && j < 4; ++j) { vBuf->vertices_[i->first_].blendIndices_[j] = i->second_[j].boneIndex_; vBuf->vertices_[i->first_].blendWeights_[j] = i->second_[j].weight_ * normalizationFactor; } // If there are less than 4 blend weights, fill rest with zero for (unsigned j = i->second_.Size(); j < 4; ++j) { vBuf->vertices_[i->first_].blendIndices_[j] = 0; vBuf->vertices_[i->first_].blendWeights_[j] = 0.0f; } vBuf->vertices_[i->first_].hasBlendWeights_ = true; } } } else if (boneAssignments) PrintLine("No skeleton loaded, skipping skinning information"); // Calculate center for the subgeometry Vector3 center = Vector3::ZERO; for (unsigned i = 0; i < iBuf->indices_.Size(); i += 3) { center += vBuf->vertices_[iBuf->indices_[i]].position_; center += vBuf->vertices_[iBuf->indices_[i + 1]].position_; center += vBuf->vertices_[iBuf->indices_[i + 2]].position_; } if (iBuf->indices_.Size()) center /= (float)iBuf->indices_.Size(); subGeometryCenters_.Push(center); indexStart += indices; vertexStart += vertices; OptimizeIndices(&subGeometryLodLevel, vBuf, iBuf); PrintLine("Processed submesh " + String(subMeshIndex + 1) + ": " + String(vertices) + " vertices " + String(triangles) + " triangles"); Vector<ModelSubGeometryLodLevel> thisSubGeometry; thisSubGeometry.Push(subGeometryLodLevel); subGeometries_.Push(thisSubGeometry); subMesh = subMesh.GetNext("submesh"); subMeshIndex++; } // Process LOD levels, if any XMLElement lods = root.GetChild("levelofdetail"); if (lods) { try { // For now, support only generated LODs, where the vertices are the same XMLElement lod = lods.GetChild("lodgenerated"); while (lod) { float distance = M_EPSILON; if (lod.HasAttribute("fromdepthsquared")) distance = sqrtf(lod.GetFloat("fromdepthsquared")); if (lod.HasAttribute("value")) distance = lod.GetFloat("value"); XMLElement lodSubMesh = lod.GetChild("lodfacelist"); while (lodSubMesh) { unsigned subMeshIndex = lodSubMesh.GetInt("submeshindex"); unsigned triangles = lodSubMesh.GetInt("numfaces"); ModelSubGeometryLodLevel newLodLevel; ModelSubGeometryLodLevel& originalLodLevel = subGeometries_[subMeshIndex][0]; // Copy all initial values newLodLevel = originalLodLevel; ModelVertexBuffer* vBuf; ModelIndexBuffer* iBuf; if (useOneBuffer_) { vBuf = &vertexBuffers_[0]; iBuf = &indexBuffers_[0]; } else { vBuf = &vertexBuffers_[subMeshIndex]; iBuf = &indexBuffers_[subMeshIndex]; } unsigned indexStart = iBuf->indices_.Size(); unsigned indexCount = triangles * 3; unsigned vertexStart = vertexStarts[subMeshIndex]; newLodLevel.distance_ = distance; newLodLevel.indexStart_ = indexStart; newLodLevel.indexCount_ = indexCount; // Append indices to the original index buffer XMLElement triangle = lodSubMesh.GetChild("face"); while (triangle) { unsigned v1 = triangle.GetInt("v1"); unsigned v2 = triangle.GetInt("v2"); unsigned v3 = triangle.GetInt("v3"); iBuf->indices_.Push(v3 + vertexStart); iBuf->indices_.Push(v2 + vertexStart); iBuf->indices_.Push(v1 + vertexStart); triangle = triangle.GetNext("face"); } OptimizeIndices(&newLodLevel, vBuf, iBuf); subGeometries_[subMeshIndex].Push(newLodLevel); PrintLine("Processed LOD level for submesh " + String(subMeshIndex + 1) + ": distance " + String(distance)); lodSubMesh = lodSubMesh.GetNext("lodfacelist"); } lod = lod.GetNext("lodgenerated"); } } catch (...) {} } // Process poses/morphs // First find out all pose definitions if (exportMorphs) { try { Vector<XMLElement> poses; XMLElement posesRoot = root.GetChild("poses"); if (posesRoot) { XMLElement pose = posesRoot.GetChild("pose"); while (pose) { poses.Push(pose); pose = pose.GetNext("pose"); } } // Then process animations using the poses XMLElement animsRoot = root.GetChild("animations"); if (animsRoot) { XMLElement anim = animsRoot.GetChild("animation"); while (anim) { String name = anim.GetAttribute("name"); float length = anim.GetFloat("length"); HashSet<unsigned> usedPoses; XMLElement tracks = anim.GetChild("tracks"); if (tracks) { XMLElement track = tracks.GetChild("track"); while (track) { XMLElement keyframes = track.GetChild("keyframes"); if (keyframes) { XMLElement keyframe = keyframes.GetChild("keyframe"); while (keyframe) { float time = keyframe.GetFloat("time"); XMLElement poseref = keyframe.GetChild("poseref"); // Get only the end pose if (poseref && time == length) usedPoses.Insert(poseref.GetInt("poseindex")); keyframe = keyframe.GetNext("keyframe"); } } track = track.GetNext("track"); } } if (usedPoses.Size()) { ModelMorph newMorph; newMorph.name_ = name; if (useOneBuffer_) newMorph.buffers_.Resize(1); else newMorph.buffers_.Resize(usedPoses.Size()); unsigned bufIndex = 0; for (HashSet<unsigned>::Iterator i = usedPoses.Begin(); i != usedPoses.End(); ++i) { XMLElement pose = poses[*i]; unsigned targetSubMesh = pose.GetInt("index"); XMLElement poseOffset = pose.GetChild("poseoffset"); if (useOneBuffer_) newMorph.buffers_[bufIndex].vertexBuffer_ = 0; else newMorph.buffers_[bufIndex].vertexBuffer_ = targetSubMesh; newMorph.buffers_[bufIndex].elementMask_ = MASK_POSITION; ModelVertexBuffer* vBuf = &vertexBuffers_[newMorph.buffers_[bufIndex].vertexBuffer_]; while (poseOffset) { // Convert from right- to left-handed unsigned vertexIndex = poseOffset.GetInt("index") + vertexStarts[targetSubMesh]; float x = poseOffset.GetFloat("x"); float y = poseOffset.GetFloat("y"); float z = poseOffset.GetFloat("z"); Vector3 vec(x, y, -z); if (vBuf->morphCount_ == 0) { vBuf->morphStart_ = vertexIndex; vBuf->morphCount_ = 1; } else { unsigned first = vBuf->morphStart_; unsigned last = first + vBuf->morphCount_ - 1; if (vertexIndex < first) first = vertexIndex; if (vertexIndex > last) last = vertexIndex; vBuf->morphStart_ = first; vBuf->morphCount_ = last - first + 1; } ModelVertex newVertex; newVertex.position_ = vec; newMorph.buffers_[bufIndex].vertices_.Push(MakePair(vertexIndex, newVertex)); poseOffset = poseOffset.GetNext("poseoffset"); } if (!useOneBuffer_) ++bufIndex; } morphs_.Push(newMorph); PrintLine("Processed morph " + name + " with " + String(usedPoses.Size()) + " sub-poses"); } anim = anim.GetNext("animation"); } } } catch (...) {} } // Check any of the buffers for vertices with missing blend weight assignments for (unsigned i = 0; i < vertexBuffers_.Size(); ++i) { if (vertexBuffers_[i].elementMask_ & MASK_BLENDWEIGHTS) { for (unsigned j = 0; j < vertexBuffers_[i].vertices_.Size(); ++j) if (!vertexBuffers_[i].vertices_[j].hasBlendWeights_) ErrorExit("Found a vertex with missing skinning information"); } } // Tangent generation if (generateTangents) { for (unsigned i = 0; i < subGeometries_.Size(); ++i) { for (unsigned j = 0; j < subGeometries_[i].Size(); ++j) { ModelVertexBuffer& vBuf = vertexBuffers_[subGeometries_[i][j].vertexBuffer_]; ModelIndexBuffer& iBuf = indexBuffers_[subGeometries_[i][j].indexBuffer_]; unsigned indexStart = subGeometries_[i][j].indexStart_; unsigned indexCount = subGeometries_[i][j].indexCount_; // If already has tangents, do not regenerate if (vBuf.elementMask_ & MASK_TANGENT || vBuf.vertices_.Empty() || iBuf.indices_.Empty()) continue; vBuf.elementMask_ |= MASK_TANGENT; if ((vBuf.elementMask_ & (MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1)) != (MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1)) ErrorExit("To generate tangents, positions normals and texcoords are required"); GenerateTangents(&vBuf.vertices_[0], sizeof(ModelVertex), &iBuf.indices_[0], sizeof(unsigned), indexStart, indexCount, offsetof(ModelVertex, normal_), offsetof(ModelVertex, texCoord1_), offsetof(ModelVertex, tangent_)); PrintLine("Generated tangents"); } } } }
void SceneHudPanel::UpdatePanel(float frametime, const SharedPtr<Urho3D::UIElement> &widget) { if (!limiter_.ShouldUpdate(frametime)) return; Text *sceneText = dynamic_cast<Text*>(widget.Get()); if (!sceneText || !framework_->Renderer()) return; Scene *scene = framework_->Renderer()->MainCameraScene(); if (!scene) return; String str; SceneInfo info; auto entities = scene->Entities(); info.ents = entities.Size(); for(auto entIter = entities.Begin(); entIter != entities.End(); ++entIter) { const EntityPtr ent = entIter->second_; if (ent->Parent()) info.entsParented++; else info.entsRoot++; if (ent->IsLocal()) info.entsLocal++; if (ent->IsReplicated()) info.entsReplicated++; if (ent->IsTemporary()) info.entsTemporary++; String group = ent->Group().Trimmed(); if (!group.Empty()) { info.entGroups[group]++; InsertAlpha(info.groups, group); if ((int)group.Length() > info.pad) info.pad = group.Length() + 2; } auto components = ent->Components(); info.comps += components.Size(); for(auto compIter = components.Begin(); compIter != components.End(); ++compIter) { auto comp = compIter->second_; String type = comp->TypeName(); info.compTypes[type]++; InsertAlpha(info.types, type); if (comp->IsLocal()) info.compsLocal++; if (comp->IsReplicated()) info.compsReplicated++; if (comp->IsTemporary()) info.compsTemporary++; if ((int)type.Length() > info.pad) info.pad = type.Length() + 2; } if (components.Empty()) info.entsEmpty++; } str.AppendWithFormat("%s %u\n", PadString("Entities", info.pad).CString(), info.ents); str.AppendWithFormat(" %s %u\n", PadString("Root", info.pad).CString(), info.entsRoot); str.AppendWithFormat(" %s %u\n", PadString("Parented", info.pad).CString(), info.entsParented); str.AppendWithFormat(" %s %u\n", PadString("Empty", info.pad).CString(), info.entsEmpty); str.AppendWithFormat(" %s %u\n", PadString("Replicated", info.pad).CString(), info.entsReplicated); str.AppendWithFormat(" %s %u\n", PadString("Local", info.pad).CString(), info.entsLocal); str.AppendWithFormat(" %s %u\n\n", PadString("Temporary", info.pad).CString(), info.entsTemporary); if (!info.groups.Empty()) { str.AppendWithFormat("%s %u\n", PadString("Entity Groups", info.pad).CString(), info.groups.Size()); foreach(auto &group, info.groups) { uint num = info.entGroups[group]; str.AppendWithFormat(" %s %u\n", PadString(group, info.pad).CString(), num); } str.Append("\n"); }
void WriteOutput(const String& outputFileName, bool exportAnimations, bool rotationsOnly, bool saveMaterialList) { // Begin serialization { File dest(context_); if (!dest.Open(outputFileName, FILE_WRITE)) ErrorExit("Could not open output file " + outputFileName); // ID dest.WriteFileID("UMDL"); // Vertexbuffers dest.WriteUInt(vertexBuffers_.Size()); for (unsigned i = 0; i < vertexBuffers_.Size(); ++i) vertexBuffers_[i].WriteData(dest); // Indexbuffers dest.WriteUInt(indexBuffers_.Size()); for (unsigned i = 0; i < indexBuffers_.Size(); ++i) indexBuffers_[i].WriteData(dest); // Subgeometries dest.WriteUInt(subGeometries_.Size()); for (unsigned i = 0; i < subGeometries_.Size(); ++i) { // Write bone mapping info from the first LOD level. It does not change for further LODs dest.WriteUInt(subGeometries_[i][0].boneMapping_.Size()); for (unsigned k = 0; k < subGeometries_[i][0].boneMapping_.Size(); ++k) dest.WriteUInt(subGeometries_[i][0].boneMapping_[k]); // Lod levels for this subgeometry dest.WriteUInt(subGeometries_[i].Size()); for (unsigned j = 0; j < subGeometries_[i].Size(); ++j) { dest.WriteFloat(subGeometries_[i][j].distance_); dest.WriteUInt((unsigned)subGeometries_[i][j].primitiveType_); dest.WriteUInt(subGeometries_[i][j].vertexBuffer_); dest.WriteUInt(subGeometries_[i][j].indexBuffer_); dest.WriteUInt(subGeometries_[i][j].indexStart_); dest.WriteUInt(subGeometries_[i][j].indexCount_); } } // Morphs dest.WriteUInt(morphs_.Size()); for (unsigned i = 0; i < morphs_.Size(); ++i) morphs_[i].WriteData(dest); // Skeleton dest.WriteUInt(bones_.Size()); for (unsigned i = 0; i < bones_.Size(); ++i) { dest.WriteString(bones_[i].name_); dest.WriteUInt(bones_[i].parentIndex_); dest.WriteVector3(bones_[i].bindPosition_); dest.WriteQuaternion(bones_[i].bindRotation_); dest.WriteVector3(bones_[i].bindScale_); Matrix3x4 offsetMatrix(bones_[i].derivedPosition_, bones_[i].derivedRotation_, bones_[i].derivedScale_); offsetMatrix = offsetMatrix.Inverse(); dest.Write(offsetMatrix.Data(), sizeof(Matrix3x4)); dest.WriteUByte(bones_[i].collisionMask_); if (bones_[i].collisionMask_ & 1) dest.WriteFloat(bones_[i].radius_); if (bones_[i].collisionMask_ & 2) dest.WriteBoundingBox(bones_[i].boundingBox_); } // Bounding box dest.WriteBoundingBox(boundingBox_); // Geometry centers for (unsigned i = 0; i < subGeometryCenters_.Size(); ++i) dest.WriteVector3(subGeometryCenters_[i]); } if (saveMaterialList) { String materialListName = ReplaceExtension(outputFileName, ".txt"); File listFile(context_); if (listFile.Open(materialListName, FILE_WRITE)) { for (unsigned i = 0; i < materialNames_.Size(); ++i) { // Assume the materials will be located inside the standard Materials subdirectory listFile.WriteLine("Materials/" + ReplaceExtension(SanitateAssetName(materialNames_[i]), ".xml")); } } else PrintLine("Warning: could not write material list file " + materialListName); } XMLElement skeletonRoot = skelFile_->GetRoot("skeleton"); if (skeletonRoot && exportAnimations) { // Go through animations XMLElement animationsRoot = skeletonRoot.GetChild("animations"); if (animationsRoot) { XMLElement animation = animationsRoot.GetChild("animation"); while (animation) { ModelAnimation newAnimation; newAnimation.name_ = animation.GetAttribute("name"); newAnimation.length_ = animation.GetFloat("length"); XMLElement tracksRoot = animation.GetChild("tracks"); XMLElement track = tracksRoot.GetChild("track"); while (track) { String trackName = track.GetAttribute("bone"); ModelBone* bone = 0; for (unsigned i = 0; i < bones_.Size(); ++i) { if (bones_[i].name_ == trackName) { bone = &bones_[i]; break; } } if (!bone) ErrorExit("Found animation track for unknown bone " + trackName); AnimationTrack newAnimationTrack; newAnimationTrack.name_ = trackName; if (!rotationsOnly) newAnimationTrack.channelMask_ = CHANNEL_POSITION | CHANNEL_ROTATION; else newAnimationTrack.channelMask_ = CHANNEL_ROTATION; XMLElement keyFramesRoot = track.GetChild("keyframes"); XMLElement keyFrame = keyFramesRoot.GetChild("keyframe"); while (keyFrame) { AnimationKeyFrame newKeyFrame; // Convert from right- to left-handed XMLElement position = keyFrame.GetChild("translate"); float x = position.GetFloat("x"); float y = position.GetFloat("y"); float z = position.GetFloat("z"); Vector3 pos(x, y, -z); XMLElement rotation = keyFrame.GetChild("rotate"); XMLElement axis = rotation.GetChild("axis"); float angle = -rotation.GetFloat("angle") * M_RADTODEG; x = axis.GetFloat("x"); y = axis.GetFloat("y"); z = axis.GetFloat("z"); Vector3 axisVec(x, y, -z); Quaternion rot(angle, axisVec); // Transform from bind-pose relative into absolute pos = bone->bindPosition_ + bone->bindRotation_ * pos; rot = bone->bindRotation_ * rot; newKeyFrame.time_ = keyFrame.GetFloat("time"); newKeyFrame.position_ = pos; newKeyFrame.rotation_ = rot; newAnimationTrack.keyFrames_.Push(newKeyFrame); keyFrame = keyFrame.GetNext("keyframe"); } // Make sure keyframes are sorted from beginning to end Sort(newAnimationTrack.keyFrames_.Begin(), newAnimationTrack.keyFrames_.End(), CompareKeyFrames); // Do not add tracks with no keyframes if (newAnimationTrack.keyFrames_.Size()) newAnimation.tracks_.Push(newAnimationTrack); track = track.GetNext("track"); } // Write each animation into a separate file String animationFileName = outputFileName.Replaced(".mdl", ""); animationFileName += "_" + newAnimation.name_ + ".ani"; File dest(context_); if (!dest.Open(animationFileName, FILE_WRITE)) ErrorExit("Could not open output file " + animationFileName); dest.WriteFileID("UANI"); dest.WriteString(newAnimation.name_); dest.WriteFloat(newAnimation.length_); dest.WriteUInt(newAnimation.tracks_.Size()); for (unsigned i = 0; i < newAnimation.tracks_.Size(); ++i) { AnimationTrack& track = newAnimation.tracks_[i]; dest.WriteString(track.name_); dest.WriteUByte(track.channelMask_); dest.WriteUInt(track.keyFrames_.Size()); for (unsigned j = 0; j < track.keyFrames_.Size(); ++j) { AnimationKeyFrame& keyFrame = track.keyFrames_[j]; dest.WriteFloat(keyFrame.time_); if (track.channelMask_ & CHANNEL_POSITION) dest.WriteVector3(keyFrame.position_); if (track.channelMask_ & CHANNEL_ROTATION) dest.WriteQuaternion(keyFrame.rotation_); if (track.channelMask_ & CHANNEL_SCALE) dest.WriteVector3(keyFrame.scale_); } } animation = animation.GetNext("animation"); PrintLine("Processed animation " + newAnimation.name_); } } } }
bool Texture2D::SetData(SharedPtr<Image> image, bool useAlpha) { if (!image) { URHO3D_LOGERROR("Null image, can not set data"); return false; } unsigned memoryUse = sizeof(Texture2D); int quality = QUALITY_HIGH; Renderer* renderer = GetSubsystem<Renderer>(); if (renderer) quality = renderer->GetTextureQuality(); if (!image->IsCompressed()) { // Convert unsuitable formats to RGBA unsigned components = image->GetComponents(); if (Graphics::GetGL3Support() && ((components == 1 && !useAlpha) || components == 2)) { image = image->ConvertToRGBA(); if (!image) return false; components = image->GetComponents(); } unsigned char* levelData = image->GetData(); int levelWidth = image->GetWidth(); int levelHeight = image->GetHeight(); unsigned format = 0; // Discard unnecessary mip levels for (unsigned i = 0; i < mipsToSkip_[quality]; ++i) { image = image->GetNextLevel(); levelData = image->GetData(); levelWidth = image->GetWidth(); levelHeight = image->GetHeight(); } switch (components) { case 1: format = useAlpha ? Graphics::GetAlphaFormat() : Graphics::GetLuminanceFormat(); break; case 2: format = Graphics::GetLuminanceAlphaFormat(); break; case 3: format = Graphics::GetRGBFormat(); break; case 4: format = Graphics::GetRGBAFormat(); break; default: assert(false); // Should not reach here break; } // If image was previously compressed, reset number of requested levels to avoid error if level count is too high for new size if (IsCompressed() && requestedLevels_ > 1) requestedLevels_ = 0; SetSize(levelWidth, levelHeight, format); if (!object_) return false; for (unsigned i = 0; i < levels_; ++i) { SetData(i, 0, 0, levelWidth, levelHeight, levelData); memoryUse += levelWidth * levelHeight * components; if (i < levels_ - 1) { image = image->GetNextLevel(); levelData = image->GetData(); levelWidth = image->GetWidth(); levelHeight = image->GetHeight(); } } } else { int width = image->GetWidth(); int height = image->GetHeight(); unsigned levels = image->GetNumCompressedLevels(); unsigned format = graphics_->GetFormat(image->GetCompressedFormat()); bool needDecompress = false; if (!format) { format = Graphics::GetRGBAFormat(); needDecompress = true; } unsigned mipsToSkip = mipsToSkip_[quality]; if (mipsToSkip >= levels) mipsToSkip = levels - 1; while (mipsToSkip && (width / (1 << mipsToSkip) < 4 || height / (1 << mipsToSkip) < 4)) --mipsToSkip; width /= (1 << mipsToSkip); height /= (1 << mipsToSkip); SetNumLevels((unsigned)Max((int)(levels - mipsToSkip), 1)); SetSize(width, height, format); for (unsigned i = 0; i < levels_ && i < levels - mipsToSkip; ++i) { CompressedLevel level = image->GetCompressedLevel(i + mipsToSkip); if (!needDecompress) { SetData(i, 0, 0, level.width_, level.height_, level.data_); memoryUse += level.rows_ * level.rowSize_; } else { unsigned char* rgbaData = new unsigned char[level.width_ * level.height_ * 4]; level.Decompress(rgbaData); SetData(i, 0, 0, level.width_, level.height_, rgbaData); memoryUse += level.width_ * level.height_ * 4; delete[] rgbaData; } } } SetMemoryUse(memoryUse); return true; }
bool ShaderVariation::LoadByteCode(const String& binaryShaderName) { ResourceCache* cache = owner_->GetSubsystem<ResourceCache>(); if (!cache->Exists(binaryShaderName)) return false; FileSystem* fileSystem = owner_->GetSubsystem<FileSystem>(); unsigned sourceTimeStamp = owner_->GetTimeStamp(); // If source code is loaded from a package, its timestamp will be zero. Else check that binary is not older // than source if (sourceTimeStamp && fileSystem->GetLastModifiedTime(cache->GetResourceFileName(binaryShaderName)) < sourceTimeStamp) return false; SharedPtr<File> file = cache->GetFile(binaryShaderName); if (!file || file->ReadFileID() != "USHD") { ATOMIC_LOGERROR(binaryShaderName + " is not a valid shader bytecode file"); return false; } /// \todo Check that shader type and model match /*unsigned short shaderType = */file->ReadUShort(); /*unsigned short shaderModel = */file->ReadUShort(); unsigned numParameters = file->ReadUInt(); for (unsigned i = 0; i < numParameters; ++i) { String name = file->ReadString(); unsigned reg = file->ReadUByte(); unsigned regCount = file->ReadUByte(); ShaderParameter parameter; parameter.type_ = type_; parameter.name_ = name; parameter.register_ = reg; parameter.regCount_ = regCount; parameters_[StringHash(name)] = parameter; } unsigned numTextureUnits = file->ReadUInt(); for (unsigned i = 0; i < numTextureUnits; ++i) { /*String unitName = */file->ReadString(); unsigned reg = file->ReadUByte(); if (reg < MAX_TEXTURE_UNITS) useTextureUnit_[reg] = true; } unsigned byteCodeSize = file->ReadUInt(); if (byteCodeSize) { byteCode_.Resize(byteCodeSize); file->Read(&byteCode_[0], byteCodeSize); if (type_ == VS) ATOMIC_LOGDEBUG("Loaded cached vertex shader " + GetFullName()); else ATOMIC_LOGDEBUG("Loaded cached pixel shader " + GetFullName()); return true; } else { ATOMIC_LOGERROR(binaryShaderName + " has zero length bytecode"); return false; } }
~BaseEntity(){ manager->releaseEntity(this); }
bool TextureCube::BeginLoad(Deserializer& source) { ResourceCache* cache = context_->resourceCache(); // In headless mode, do not actually load the texture, just return success if (!graphics_) return true; // If device is lost, retry later if (graphics_->IsDeviceLost()) { URHO3D_LOGWARNING("Texture load while device is lost"); dataPending_ = true; return true; } cache->ResetDependencies(this); QString texPath, texName, texExt; SplitPath(GetName(), texPath, texName, texExt); loadParameters_ = (new XMLFile(context_)); if (!loadParameters_->Load(source)) { loadParameters_.Reset(); return false; } loadImages_.clear(); XMLElement textureElem = loadParameters_->GetRoot(); XMLElement imageElem = textureElem.GetChild("image"); // Single image and multiple faces with layout if (imageElem) { QString name = imageElem.GetAttribute("name"); // If path is empty, add the XML file path if (GetPath(name).isEmpty()) name = texPath + name; SharedPtr<Image> image = cache->GetTempResource<Image>(name); if (!image) return false; int faceWidth, faceHeight; loadImages_.resize(MAX_CUBEMAP_FACES); if (image->IsCubemap()) { loadImages_[FACE_POSITIVE_X] = image; loadImages_[FACE_NEGATIVE_X] = loadImages_[FACE_POSITIVE_X]->GetNextSibling(); loadImages_[FACE_POSITIVE_Y] = loadImages_[FACE_NEGATIVE_X]->GetNextSibling(); loadImages_[FACE_NEGATIVE_Y] = loadImages_[FACE_POSITIVE_Y]->GetNextSibling(); loadImages_[FACE_POSITIVE_Z] = loadImages_[FACE_NEGATIVE_Y]->GetNextSibling(); loadImages_[FACE_NEGATIVE_Z] = loadImages_[FACE_POSITIVE_Z]->GetNextSibling(); } else { CubeMapLayout layout = (CubeMapLayout)GetStringListIndex(imageElem.GetAttribute("layout"), cubeMapLayoutNames, CML_HORIZONTAL); switch (layout) { case CML_HORIZONTAL: faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES; faceHeight = image->GetHeight(); loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 0, 0, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 1, 0, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 2, 0, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 3, 0, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 4, 0, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 5, 0, faceWidth, faceHeight); break; case CML_HORIZONTALNVIDIA: faceWidth = image->GetWidth() / MAX_CUBEMAP_FACES; faceHeight = image->GetHeight(); for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i) loadImages_[i] = GetTileImage(image, i, 0, faceWidth, faceHeight); break; case CML_HORIZONTALCROSS: faceWidth = image->GetWidth() / 4; faceHeight = image->GetHeight() / 3; loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 3, 1, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight); break; case CML_VERTICALCROSS: faceWidth = image->GetWidth() / 3; faceHeight = image->GetHeight() / 4; loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 0, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 1, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 1, 1, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 1, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 1, 2, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 3, faceWidth, faceHeight); if (loadImages_[FACE_NEGATIVE_Z]) { loadImages_[FACE_NEGATIVE_Z]->FlipVertical(); loadImages_[FACE_NEGATIVE_Z]->FlipHorizontal(); } break; case CML_BLENDER: faceWidth = image->GetWidth() / 3; faceHeight = image->GetHeight() / 2; loadImages_[FACE_NEGATIVE_X] = GetTileImage(image, 0, 0, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_Z] = GetTileImage(image, 1, 0, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_X] = GetTileImage(image, 2, 0, faceWidth, faceHeight); loadImages_[FACE_NEGATIVE_Y] = GetTileImage(image, 0, 1, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_Y] = GetTileImage(image, 1, 1, faceWidth, faceHeight); loadImages_[FACE_POSITIVE_Z] = GetTileImage(image, 2, 1, faceWidth, faceHeight); break; } } } // Face per image else { XMLElement faceElem = textureElem.GetChild("face"); while (faceElem) { QString name = faceElem.GetAttribute("name"); // If path is empty, add the XML file path if (GetPath(name).isEmpty()) name = texPath + name; loadImages_.push_back(cache->GetTempResource<Image>(name)); cache->StoreResourceDependency(this, name); faceElem = faceElem.GetNext("face"); } } // Precalculate mip levels if async loading if (GetAsyncLoadState() == ASYNC_LOADING) { for (unsigned i = 0; i < loadImages_.size(); ++i) { if (loadImages_[i]) loadImages_[i]->PrecalculateLevels(); } } return true; }
SharedPtr<Model> Model::Clone(const String& cloneName) const { SharedPtr<Model> ret(new Model(context_)); ret->SetName(cloneName); ret->boundingBox_ = boundingBox_; ret->skeleton_ = skeleton_; ret->geometryBoneMappings_ = geometryBoneMappings_; ret->geometryCenters_ = geometryCenters_; ret->morphs_ = morphs_; ret->morphRangeStarts_ = morphRangeStarts_; ret->morphRangeCounts_ = morphRangeCounts_; // Deep copy vertex/index buffers HashMap<VertexBuffer*, VertexBuffer*> vbMapping; for (Vector<SharedPtr<VertexBuffer> >::ConstIterator i = vertexBuffers_.Begin(); i != vertexBuffers_.End(); ++i) { VertexBuffer* origBuffer = *i; SharedPtr<VertexBuffer> cloneBuffer; if (origBuffer) { cloneBuffer = new VertexBuffer(context_); cloneBuffer->SetSize(origBuffer->GetVertexCount(), origBuffer->GetElementMask(), origBuffer->IsDynamic()); cloneBuffer->SetShadowed(origBuffer->IsShadowed()); if (origBuffer->IsShadowed()) cloneBuffer->SetData(origBuffer->GetShadowData()); else { void* origData = origBuffer->Lock(0, origBuffer->GetVertexCount()); if (origData) cloneBuffer->SetData(origData); else URHO3D_LOGERROR("Failed to lock original vertex buffer for copying"); } vbMapping[origBuffer] = cloneBuffer; } ret->vertexBuffers_.Push(cloneBuffer); } HashMap<IndexBuffer*, IndexBuffer*> ibMapping; for (Vector<SharedPtr<IndexBuffer> >::ConstIterator i = indexBuffers_.Begin(); i != indexBuffers_.End(); ++i) { IndexBuffer* origBuffer = *i; SharedPtr<IndexBuffer> cloneBuffer; if (origBuffer) { cloneBuffer = new IndexBuffer(context_); cloneBuffer->SetSize(origBuffer->GetIndexCount(), origBuffer->GetIndexSize() == sizeof(unsigned), origBuffer->IsDynamic()); cloneBuffer->SetShadowed(origBuffer->IsShadowed()); if (origBuffer->IsShadowed()) cloneBuffer->SetData(origBuffer->GetShadowData()); else { void* origData = origBuffer->Lock(0, origBuffer->GetIndexCount()); if (origData) cloneBuffer->SetData(origData); else URHO3D_LOGERROR("Failed to lock original index buffer for copying"); } ibMapping[origBuffer] = cloneBuffer; } ret->indexBuffers_.Push(cloneBuffer); } // Deep copy all the geometry LOD levels and refer to the copied vertex/index buffers ret->geometries_.Resize(geometries_.Size()); for (unsigned i = 0; i < geometries_.Size(); ++i) { ret->geometries_[i].Resize(geometries_[i].Size()); for (unsigned j = 0; j < geometries_[i].Size(); ++j) { SharedPtr<Geometry> cloneGeometry; Geometry* origGeometry = geometries_[i][j]; if (origGeometry) { cloneGeometry = new Geometry(context_); cloneGeometry->SetIndexBuffer(ibMapping[origGeometry->GetIndexBuffer()]); unsigned numVbs = origGeometry->GetNumVertexBuffers(); for (unsigned k = 0; k < numVbs; ++k) { cloneGeometry->SetVertexBuffer(k, vbMapping[origGeometry->GetVertexBuffer(k)]); } cloneGeometry->SetDrawRange(origGeometry->GetPrimitiveType(), origGeometry->GetIndexStart(), origGeometry->GetIndexCount(), origGeometry->GetVertexStart(), origGeometry->GetVertexCount(), false); cloneGeometry->SetLodDistance(origGeometry->GetLodDistance()); } ret->geometries_[i][j] = cloneGeometry; } } // Deep copy the morph data (if any) to allow modifying it for (Vector<ModelMorph>::Iterator i = ret->morphs_.Begin(); i != ret->morphs_.End(); ++i) { ModelMorph& morph = *i; for (HashMap<unsigned, VertexBufferMorph>::Iterator j = morph.buffers_.Begin(); j != morph.buffers_.End(); ++j) { VertexBufferMorph& vbMorph = j->second_; if (vbMorph.dataSize_) { SharedArrayPtr<unsigned char> cloneData(new unsigned char[vbMorph.dataSize_]); memcpy(cloneData.Get(), vbMorph.morphData_.Get(), vbMorph.dataSize_); vbMorph.morphData_ = cloneData; } } } ret->SetMemoryUse(GetMemoryUse()); return ret; }
void WebFrameLoaderClient::dispatchDidFinishLoad() { SharedPtr<WebFrameLoadDelegate> webFrameLoadDelegate = m_webFrame->webView()->webFrameLoadDelegate(); if (webFrameLoadDelegate) webFrameLoadDelegate->didFinishLoad(m_webFrame); }