// If a callback is specified, the included files will be loaded asynchronously and the callback will be called // when all of the files have finished loading. // If no callback is specified, the included files will be loaded synchronously and will block execution until // all of the files have finished loading. void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callback) { if (_stoppingAllScripts) { qCDebug(scriptengine) << "Script.include() while shutting down is ignored..." << "includeFiles:" << includeFiles << "parent script:" << getFilename(); return; // bail early } QList<QUrl> urls; for (QString file : includeFiles) { urls.append(resolvePath(file)); } BatchLoader* loader = new BatchLoader(urls); auto evaluateScripts = [=](const QMap<QUrl, QString>& data) { for (QUrl url : urls) { QString contents = data[url]; if (contents.isNull()) { qCDebug(scriptengine) << "Error loading file: " << url << "line:" << __LINE__; } else { QScriptValue result = evaluate(contents, url.toString()); } } if (callback.isFunction()) { QScriptValue(callback).call(); } loader->deleteLater(); }; connect(loader, &BatchLoader::finished, this, evaluateScripts); // If we are destroyed before the loader completes, make sure to clean it up connect(this, &QObject::destroyed, loader, &QObject::deleteLater); loader->start(); if (!callback.isFunction() && !loader->isFinished()) { QEventLoop loop; QObject::connect(loader, &BatchLoader::finished, &loop, &QEventLoop::quit); loop.exec(); } }
void MenuLoad::loadAssets() { BatchLoader* batchLoader = new BatchLoader(assetManager); batchLoader->addEventListener(loadListener); //LOAD MENU ASSETS HERE: //TODO: Assets need to be loaded in a non-linear fashion. Maybe an array of strings containing // all of the asset paths could be loaded so that they could be called when needed (ie. @ // application launch or upon error. Right now, when an asset isn't loaded and is needed, // the application will crash / break upon calling. This seems very inefficient... batchLoader->addTexture("backgrounds/loading.png"); batchLoader->addTexture("backgrounds/error.png"); batchLoader->addTexture("backgrounds/main.png"); batchLoader->addTexture("buttons/back.png"); batchLoader->addTexture("buttons/main/group.png"); batchLoader->addTexture("buttons/main/solo.png"); batchLoader->addTexture("buttons/group/rules.png"); batchLoader->addTexture("buttons/group/smash.png"); batchLoader->addTexture("buttons/solo/training.png"); batchLoader->addTexture("characterselect/chip_cpu.png"); batchLoader->addTexture("characterselect/chip_p1.png"); batchLoader->addTexture("characterselect/chip_p2.png"); batchLoader->addTexture("characterselect/chip_p3.png"); batchLoader->addTexture("characterselect/chip_p4.png"); batchLoader->addTexture("characterselect/icon_frame.png"); batchLoader->addTexture("characterselect/panel_background_p1.png"); batchLoader->addTexture("characterselect/panel_background_p2.png"); batchLoader->addTexture("characterselect/panel_background_p3.png"); batchLoader->addTexture("characterselect/panel_background_p4.png"); batchLoader->addTexture("characterselect/panel_background_cpu.png"); batchLoader->addTexture("characterselect/panel_background_na.png"); batchLoader->addTexture("characterselect/panel_background_blank.png"); batchLoader->addTexture("characterselect/panel_overlay_p1.png"); batchLoader->addTexture("characterselect/panel_overlay_p2.png"); batchLoader->addTexture("characterselect/panel_overlay_p3.png"); batchLoader->addTexture("characterselect/panel_overlay_p4.png"); batchLoader->addTexture("characterselect/panel_overlay_cpu.png"); batchLoader->addTexture("characterselect/panel_overlay_na.png"); batchLoader->addTexture("characterselect/panel_overlay_blank.png"); batchLoader->addTexture("characterselect/readytofight_banner.png"); batchLoader->addTexture("elements/button_arrow_down.png"); batchLoader->addTexture("elements/button_arrow_left.png"); batchLoader->addTexture("elements/button_arrow_right.png"); batchLoader->addTexture("elements/button_arrow_up.png"); batchLoader->addTexture("elements/headerbar_full.png"); batchLoader->addTexture("elements/headerbar_small.png"); batchLoader->addTexture("elements/menu_bar.png"); batchLoader->addTexture("elements/rules_bar.png"); batchLoader->addFont("fonts/default.ttf"); //batchLoader->addFont("fonts/"BorisBlackBloxx.ttf"); batchLoader->addTexture("stageselect/icon_frame.png"); batchLoader->addTexture("titlescreen/logo.png"); batchLoader->addTexture("titlescreen/background.png"); batchLoader->loadAll(); delete batchLoader; }
// ------------------------------------------------------------------------------------------------ // Recursively build the scenegraph void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<AttachmentInfo>& attach, BatchLoader& batch, aiCamera**& camOut, aiLight**& lightOut, std::vector<aiNodeAnim*>& animOut) { // Setup a very cryptic name for the node, we want the user to be happy SetupNodeName(nd,src); // If this is an object from an external file - get the scene and setup proper attachment tags aiScene* obj = NULL; if (src.type == LWS::NodeDesc::OBJECT && src.path.length() ) { obj = batch.GetImport(src.id); if (!obj) { DefaultLogger::get()->error("LWS: Failed to read external file " + src.path); } else { attach.push_back(AttachmentInfo(obj,nd)); } } // If object is a light source - setup a corresponding ai structure else if (src.type == LWS::NodeDesc::LIGHT) { aiLight* lit = *lightOut++ = new aiLight(); // compute final light color lit->mColorDiffuse = lit->mColorSpecular = src.lightColor*src.lightIntensity; // name to attach light to node -> unique due to LWs indexing system lit->mName = nd->mName; // detemine light type and setup additional members if (src.lightType == 2) { /* spot light */ lit->mType = aiLightSource_SPOT; lit->mAngleInnerCone = (float)AI_DEG_TO_RAD( src.lightConeAngle ); lit->mAngleOuterCone = lit->mAngleInnerCone+(float)AI_DEG_TO_RAD( src.lightEdgeAngle ); } else if (src.lightType == 1) { /* directional light source */ lit->mType = aiLightSource_DIRECTIONAL; } else lit->mType = aiLightSource_POINT; // fixme: no proper handling of light falloffs yet if (src.lightFalloffType == 1) lit->mAttenuationConstant = 1.f; else if (src.lightFalloffType == 1) lit->mAttenuationLinear = 1.f; else lit->mAttenuationQuadratic = 1.f; } // If object is a camera - setup a corresponding ai structure else if (src.type == LWS::NodeDesc::CAMERA) { aiCamera* cam = *camOut++ = new aiCamera(); // name to attach cam to node -> unique due to LWs indexing system cam->mName = nd->mName; } // Get the node transformation from the LWO key LWO::AnimResolver resolver(src.channels,fps); resolver.ExtractBindPose(nd->mTransformation); // .. and construct animation channels aiNodeAnim* anim = NULL; if (first != last) { resolver.SetAnimationRange(first,last); resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO); if (anim) { anim->mNodeName = nd->mName; animOut.push_back(anim); } } // process pivot point, if any if (src.pivotPos != aiVector3D()) { aiMatrix4x4 tmp; aiMatrix4x4::Translation(-src.pivotPos,tmp); if (anim) { // We have an animation channel for this node. Problem: to combine the pivot // point with the node anims, we'd need to interpolate *all* keys, get // transformation matrices from them, apply the translation and decompose // the resulting matrices again in order to reconstruct the keys. This // solution here is *much* easier ... we're just inserting an extra node // in the hierarchy. // Maybe the final optimization here will be done during postprocessing. aiNode* pivot = new aiNode(); pivot->mName.length = sprintf( pivot->mName.data, "$Pivot_%s",nd->mName.data); pivot->mTransformation = tmp; pivot->mChildren = new aiNode*[pivot->mNumChildren = 1]; pivot->mChildren[0] = nd; pivot->mParent = nd->mParent; nd->mParent = pivot; // swap children and hope the parents wont see a huge difference pivot->mParent->mChildren[pivot->mParent->mNumChildren-1] = pivot; } else { nd->mTransformation = tmp*nd->mTransformation; } } // Add children if (src.children.size()) { nd->mChildren = new aiNode*[src.children.size()]; for (std::list<LWS::NodeDesc*>::iterator it = src.children.begin(); it != src.children.end(); ++it) { aiNode* ndd = nd->mChildren[nd->mNumChildren++] = new aiNode(); ndd->mParent = nd; BuildGraph(ndd,**it,attach,batch,camOut,lightOut,animOut); } } }
// ------------------------------------------------------------------------------------------------ // Recursively build the scenegraph void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<AttachmentInfo>& attach, BatchLoader& batch, aiCamera**& camOut, aiLight**& lightOut, std::vector<aiNodeAnim*>& animOut) { // Setup a very cryptic name for the node, we want the user to be happy SetupNodeName(nd,src); aiNode* ndAnim = nd; // If the node is an object if (src.type == LWS::NodeDesc::OBJECT) { // If the object is from an external file, get it aiScene* obj = NULL; if (src.path.length() ) { obj = batch.GetImport(src.id); if (!obj) { DefaultLogger::get()->error("LWS: Failed to read external file " + src.path); } else { if (obj->mRootNode->mNumChildren == 1) { //If the pivot is not set for this layer, get it from the external object if (!src.isPivotSet) { src.pivotPos.x = +obj->mRootNode->mTransformation.a4; src.pivotPos.y = +obj->mRootNode->mTransformation.b4; src.pivotPos.z = -obj->mRootNode->mTransformation.c4; //The sign is the RH to LH back conversion } //Remove first node from obj (the old pivot), reset transform of second node (the mesh node) aiNode* newRootNode = obj->mRootNode->mChildren[0]; obj->mRootNode->mChildren[0] = NULL; delete obj->mRootNode; obj->mRootNode = newRootNode; obj->mRootNode->mTransformation.a4 = 0.0; obj->mRootNode->mTransformation.b4 = 0.0; obj->mRootNode->mTransformation.c4 = 0.0; } } } //Setup the pivot node (also the animation node), the one we received nd->mName = std::string("Pivot:") + nd->mName.data; ndAnim = nd; //Add the attachment node to it nd->mNumChildren = 1; nd->mChildren = new aiNode*[1]; nd->mChildren[0] = new aiNode(); nd->mChildren[0]->mParent = nd; nd->mChildren[0]->mTransformation.a4 = -src.pivotPos.x; nd->mChildren[0]->mTransformation.b4 = -src.pivotPos.y; nd->mChildren[0]->mTransformation.c4 = -src.pivotPos.z; SetupNodeName(nd->mChildren[0], src); //Update the attachment node nd = nd->mChildren[0]; //Push attachment, if the object came from an external file if (obj) { attach.push_back(AttachmentInfo(obj,nd)); } } // If object is a light source - setup a corresponding ai structure else if (src.type == LWS::NodeDesc::LIGHT) { aiLight* lit = *lightOut++ = new aiLight(); // compute final light color lit->mColorDiffuse = lit->mColorSpecular = src.lightColor*src.lightIntensity; // name to attach light to node -> unique due to LWs indexing system lit->mName = nd->mName; // detemine light type and setup additional members if (src.lightType == 2) { /* spot light */ lit->mType = aiLightSource_SPOT; lit->mAngleInnerCone = (float)AI_DEG_TO_RAD( src.lightConeAngle ); lit->mAngleOuterCone = lit->mAngleInnerCone+(float)AI_DEG_TO_RAD( src.lightEdgeAngle ); } else if (src.lightType == 1) { /* directional light source */ lit->mType = aiLightSource_DIRECTIONAL; } else lit->mType = aiLightSource_POINT; // fixme: no proper handling of light falloffs yet if (src.lightFalloffType == 1) lit->mAttenuationConstant = 1.f; else if (src.lightFalloffType == 1) lit->mAttenuationLinear = 1.f; else lit->mAttenuationQuadratic = 1.f; } // If object is a camera - setup a corresponding ai structure else if (src.type == LWS::NodeDesc::CAMERA) { aiCamera* cam = *camOut++ = new aiCamera(); // name to attach cam to node -> unique due to LWs indexing system cam->mName = nd->mName; } // Get the node transformation from the LWO key LWO::AnimResolver resolver(src.channels,fps); resolver.ExtractBindPose(ndAnim->mTransformation); // .. and construct animation channels aiNodeAnim* anim = NULL; if (first != last) { resolver.SetAnimationRange(first,last); resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO); if (anim) { anim->mNodeName = ndAnim->mName; animOut.push_back(anim); } } // Add children if (src.children.size()) { nd->mChildren = new aiNode*[src.children.size()]; for (std::list<LWS::NodeDesc*>::iterator it = src.children.begin(); it != src.children.end(); ++it) { aiNode* ndd = nd->mChildren[nd->mNumChildren++] = new aiNode(); ndd->mParent = nd; BuildGraph(ndd,**it,attach,batch,camOut,lightOut,animOut); } } }