void ResourceOps::HandleCreateModule(const String& resourcePath, const String& resourceName,
                                        bool navigateToResource, bool reportError)
{
    Editor* editor = GetSubsystem<Editor>();

    if (!CheckCreateModule(resourcePath, resourceName, reportError))
        return;

    ResourceCache* cache = GetSubsystem<ResourceCache>();

    SharedPtr<File> srcFile = cache->GetFile("ClockworkEditor/templates/template_module.js");
    if (srcFile.Null() || !srcFile->IsOpen())
    {
        editor->PostModalError("Create Script Error", "Could not open module template");
        return;
    }

    String fullpath = resourcePath + resourceName;
    if (!resourceName.EndsWith(".js"))
        fullpath += ".js";

    if (!CopyFile(srcFile, fullpath))
    {
        String errorMsg;
        errorMsg.AppendWithFormat("Error copying template:\n\n%s\n\nto:\n\n%s",
                                  "ClockworkEditor/template_module.js", fullpath.CString());
        editor->PostModalError("Create Module Error", errorMsg);
        return;
    }

    if (navigateToResource)
    {
        ResourceFrame* rframe = GetSubsystem<MainFrame>()->GetResourceFrame();
        rframe->EditResource(fullpath);
    }

    GetSubsystem<MainFrame>()->GetProjectFrame()->Refresh();

}
Example #2
0
void Cursor::DefineShape(CursorShape shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot)
{
    if (shape < CS_NORMAL || shape >= CS_MAX_SHAPES)
    {
        LOGERROR("Shape index out of bounds, can not define cursor shape");
        return;
    }

    if (!image)
        return;

    ResourceCache* cache = GetSubsystem<ResourceCache>();
    CursorShapeInfo& info = shapeInfos_[shape];

    // Prefer to get the texture with same name from cache to prevent creating several copies of the texture
    if (cache->Exists(image->GetName()))
        info.texture_ = cache->GetResource<Texture2D>(image->GetName());
    else
    {
        Texture2D* texture = new Texture2D(context_);
        texture->Load(SharedPtr<Image>(image));
        info.texture_ = texture;
    }

    info.image_ = image;
    info.imageRect_ = imageRect;
    info.hotSpot_ = hotSpot;

    // Remove existing SDL cursor
    if (info.osCursor_)
    {
        SDL_FreeCursor(info.osCursor_);
        info.osCursor_ = 0;
    }

    // Reset current shape if it was edited
    if (shape == shape_)
        ApplyShape();
}
Example #3
0
void Engine::DumpResources()
{
    #ifdef ENABLE_LOGGING
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    const HashMap<ShortStringHash, ResourceGroup>& resourceGroups = cache->GetAllResources();
    LOGRAW("\n");
    
    for (HashMap<ShortStringHash, ResourceGroup>::ConstIterator i = resourceGroups.Begin();
        i != resourceGroups.End(); ++i)
    {
        unsigned num = i->second_.resources_.Size();
        unsigned memoryUse = i->second_.memoryUse_;
        
        if (num)
        {
            LOGRAW("Resource type " + i->second_.resources_.Begin()->second_->GetTypeName() +
                ": count " + String(num) + " memory use " + String(memoryUse) + "\n");
        }
    }
    
    LOGRAW("Total memory use of all resources " + String(cache->GetTotalMemoryUse()) + "\n\n");
    #endif
}
FrItem SceneItem::msgCreate(FrMsg m, FrMsgLength l)
{
  SceneItem *si = new SceneItem();

  CborParser parser; CborValue it;
  cbor_parser_init(m, l, 0, &parser, &it);
  cbd::Scene scene;
  cbd::readScene(&it, &scene);
  Graphics3DSystem *g3ds = Graphics3DSystem::getG3DS();
  ResourceCache* cache = si->node->GetSubsystem<ResourceCache>();
  SharedPtr<File> file;

  if (scene.selector == cbd::XmlScene) {
    file = cache->GetFile(scene.data.XmlScene.value0.c_str());
    si->node = g3ds->scene->InstantiateXML(*file, Vector3::ZERO, Quaternion::IDENTITY);
  }

  if (scene.selector == cbd::BinaryScene) {
    file = cache->GetFile(scene.data.BinaryScene.value0.c_str());
    si->node = g3ds->scene->Instantiate(*file, Vector3::ZERO, Quaternion::IDENTITY);
  }

  return (FrItem)si;
}
Example #5
0
void Light::SetShapeTextureAttr(ResourceRef value)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    shapeTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.id_));
}
Example #6
0
bool Animation::Load(Deserializer& source)
{
    PROFILE(LoadAnimation);
    
    unsigned memoryUse = sizeof(Animation);
    
    // Check ID
    if (source.ReadFileID() != "UANI")
    {
        LOGERROR(source.GetName() + " is not a valid animation file");
        return false;
    }
    
    // Read name and length
    animationName_ = source.ReadString();
    animationNameHash_ = animationName_;
    length_ = source.ReadFloat();
    tracks_.Clear();
    
    unsigned tracks = source.ReadUInt();
    tracks_.Resize(tracks);
    memoryUse += tracks * sizeof(AnimationTrack);
    
    // Read tracks
    for (unsigned i = 0; i < tracks; ++i)
    {
        AnimationTrack& newTrack = tracks_[i];
        newTrack.name_ = source.ReadString();
        newTrack.nameHash_ = newTrack.name_;
        newTrack.channelMask_ = source.ReadUByte();
        
        unsigned keyFrames = source.ReadUInt();
        newTrack.keyFrames_.Resize(keyFrames);
        memoryUse += keyFrames * sizeof(AnimationKeyFrame);
        
        // Read keyframes of the track
        for (unsigned j = 0; j < keyFrames; ++j)
        {
            AnimationKeyFrame& newKeyFrame = newTrack.keyFrames_[j];
            newKeyFrame.time_ = source.ReadFloat();
            if (newTrack.channelMask_ & CHANNEL_POSITION)
                newKeyFrame.position_ = source.ReadVector3();
            if (newTrack.channelMask_ & CHANNEL_ROTATION)
                newKeyFrame.rotation_ = source.ReadQuaternion();
            if (newTrack.channelMask_ & CHANNEL_SCALE)
                newKeyFrame.scale_ = source.ReadVector3();
        }
    }
    
    // Optionally read triggers from an XML file
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    String xmlName = ReplaceExtension(GetName(), ".xml");
    
    if (cache->Exists(xmlName))
    {
        XMLFile* file = cache->GetResource<XMLFile>(xmlName);
        if (file)
        {
            XMLElement rootElem = file->GetRoot();
            XMLElement triggerElem = rootElem.GetChild("trigger");
            while (triggerElem)
            {
                if (triggerElem.HasAttribute("normalizedtime"))
                    AddTrigger(triggerElem.GetFloat("normalizedtime"), true, triggerElem.GetVariant());
                else if (triggerElem.HasAttribute("time"))
                    AddTrigger(triggerElem.GetFloat("time"), false, triggerElem.GetVariant());
                
                triggerElem = triggerElem.GetNext("trigger");
            }
            
            memoryUse += triggers_.Size() * sizeof(AnimationTriggerPoint);
        }
    }
    
    SetMemoryUse(memoryUse);
    return true;
}
Example #7
0
bool Texture3D::BeginLoad(Deserializer& source)
{
    ResourceCache* 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;
}
Example #8
0
Script::Script(Context* context) :
    Object(context),
    scriptEngine_(0),
    immediateContext_(0),
    scriptNestingLevel_(0),
    executeConsoleCommands_(false)
{
    scriptEngine_ = asCreateScriptEngine(ANGELSCRIPT_VERSION);
    if (!scriptEngine_)
    {
        URHO3D_LOGERROR("Could not create AngelScript engine");
        return;
    }

    scriptEngine_->SetUserData(this);
    scriptEngine_->SetEngineProperty(asEP_USE_CHARACTER_LITERALS, (asPWORD)true);
    scriptEngine_->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCES, (asPWORD)true);
    scriptEngine_->SetEngineProperty(asEP_ALLOW_IMPLICIT_HANDLE_TYPES, (asPWORD)true);
    scriptEngine_->SetEngineProperty(asEP_BUILD_WITHOUT_LINE_CUES, (asPWORD)true);
    scriptEngine_->SetMessageCallback(asMETHOD(Script, MessageCallback), this, asCALL_THISCALL);

    // Create the context for immediate execution
    immediateContext_ = scriptEngine_->CreateContext();
    immediateContext_->SetExceptionCallback(asMETHOD(Script, ExceptionCallback), this, asCALL_THISCALL);

    // Register Script library object factories
    RegisterScriptLibrary(context_);

    // Register the Array, String & Dictionary API
    RegisterArray(scriptEngine_);
    RegisterString(scriptEngine_);
    RegisterDictionary(scriptEngine_);
    RegisterScriptInterfaceAPI(scriptEngine_);

    // Register the rest of the script API
    RegisterMathAPI(scriptEngine_);
    RegisterCoreAPI(scriptEngine_);
    RegisterIOAPI(scriptEngine_);
    RegisterResourceAPI(scriptEngine_);
    RegisterSceneAPI(scriptEngine_);
    RegisterGraphicsAPI(scriptEngine_);
    RegisterInputAPI(scriptEngine_);
    RegisterAudioAPI(scriptEngine_);
    RegisterUIAPI(scriptEngine_);
#ifdef URHO3D_NETWORK
    RegisterNetworkAPI(scriptEngine_);
#endif
#ifdef URHO3D_DATABASE
    RegisterDatabaseAPI(scriptEngine_);
#endif
#ifdef URHO3D_PHYSICS
    RegisterPhysicsAPI(scriptEngine_);
#endif
#ifdef URHO3D_NAVIGATION
    RegisterNavigationAPI(scriptEngine_);
#endif
#ifdef URHO3D_URHO2D
    RegisterUrho2DAPI(scriptEngine_);
#endif
    RegisterScriptAPI(scriptEngine_);
    RegisterEngineAPI(scriptEngine_);

    // Subscribe to console commands
    SetExecuteConsoleCommands(true);

    // Create and register resource router for checking for compiled AngelScript files
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    if (cache)
    {
        router_ = new ScriptResourceRouter(context_);
        cache->AddResourceRouter(router_);
    }
}
    // see http://duktape.org/guide.html#modules   
    static int js_module_search(duk_context* ctx)
    {       
        JSVM* vm = JSVM::GetJSVM(ctx);
        FileSystem* fs = vm->GetSubsystem<FileSystem>();
        ResourceCache* cache = vm->GetSubsystem<ResourceCache>();

        int top = duk_get_top(ctx);

        assert(top ==  4);

        String moduleID = duk_to_string(ctx, 0);

        if (top > 1)
        {
            // require function
            assert(duk_is_function(ctx, 1));
        }
        
        if (top > 2)
        {
            // exports
            assert(duk_is_object(ctx, 2));
        }

        if (top > 3)        
        {
            // module (module.id == a resolved absolute identifier for the module being loaded)
            assert(duk_is_object(ctx, 3));
        }

        String pathName, fileName, extension;
        SplitPath(moduleID, pathName, fileName, extension);
        String path = moduleID;

        // Do we really want this?  It is nice to not have to specify the Atomic path
        if (fileName.StartsWith("Atomic"))
        {
            path = "AtomicModules/" + path + ".js";
        }
        else
        {
            path += ".js";

            if (!cache->Exists(path))
            {
                const Vector<String>& searchPaths = vm->GetModuleSearchPaths();
                for (unsigned i = 0; i < searchPaths.Size(); i++)
                {
                    String search = searchPaths[i] + path;
                    if (cache->Exists(search))
                    {
                        path = search;
                        break;
                    }
                }
            }
        }

        if (cache->Exists(path))
        {
            SharedPtr<File> jsfile(cache->GetFile(path, false));
            vm->SetLastModuleSearchFile(jsfile->GetFullPath());
            String source;
            jsfile->ReadText(source);
            source.Append('\n');
            duk_push_string(ctx, source.CString());
            return 1;
        }
        else
        {
            // we're not a JS file, so check if we're a native module
            const Vector<String>& resourceDirs = cache->GetResourceDirs();

            for (unsigned i = 0; i < resourceDirs.Size(); i++)
            {

             String pluginLibrary;

             // TODO: proper platform folder detection
#ifdef ATOMIC_PLATFORM_WINDOWS              
              pluginLibrary = resourceDirs.At(i) + "Plugins/Windows/x64/" + moduleID + ".dll";
#elif ATOMIC_PLATFORM_OSX
             pluginLibrary = resourceDirs.At(i) + "Plugins/Mac/x64/lib" + moduleID + ".dylib";
#endif

               if (pluginLibrary.Length() && fs->FileExists(pluginLibrary))
                {
                    // let duktape know we loaded a native module
                    if (jsplugin_load(vm, pluginLibrary))
                    {
                        duk_push_undefined(ctx);
                        return 1;
                    }
                    else
                    {
                        duk_push_sprintf(ctx, "Failed loading native plugins: %s", pluginLibrary.CString());
                        duk_throw(ctx);
                    }
                }
            }

        }

        duk_push_sprintf(ctx, "Failed loading module: %s", path.CString());
        duk_throw(ctx);

    }
void PrefabImporter::HandlePrefabSave(StringHash eventType, VariantMap& eventData)
{
    using namespace PrefabSave;

    PrefabComponent* component = static_cast<PrefabComponent*>(eventData[P_PREFABCOMPONENT].GetPtr());

    if (component->GetPrefabGUID() != asset_->GetGUID())
        return;

    Node* node = component->GetNode();

    if (!node)
        return;

    // flip temporary root children and components to not be temporary for save
    const Vector<SharedPtr<Component>>& rootComponents = node->GetComponents();
    const Vector<SharedPtr<Node> >& children = node->GetChildren();

    PODVector<Component*> tempComponents;
    PODVector<Node*> tempChildren;
    PODVector<Node*> filterNodes;

    for (unsigned i = 0; i < rootComponents.Size(); i++)
    {
        if (rootComponents[i]->IsTemporary())
        {
            rootComponents[i]->SetTemporary(false);
            tempComponents.Push(rootComponents[i]);

            // Animated sprites contain a temporary node we don't want to save in the prefab
            // it would be nice if this was general purpose because have to test this when
            // breaking node as well
            if (rootComponents[i]->GetType() == AnimatedSprite2D::GetTypeStatic())
            {
                AnimatedSprite2D* asprite = (AnimatedSprite2D*) rootComponents[i].Get();
                if (asprite->GetRootNode())
                    filterNodes.Push(asprite->GetRootNode());
            }

        }
    }

    for (unsigned i = 0; i < children.Size(); i++)
    {
        if (filterNodes.Contains(children[i].Get()))
            continue;

        if (children[i]->IsTemporary())
        {
            children[i]->SetTemporary(false);
            tempChildren.Push(children[i]);
        }
    }

    // store original transform
    Vector3 pos = node->GetPosition();
    Quaternion rot = node->GetRotation();
    Vector3 scale = node->GetScale();

    node->SetPosition(Vector3::ZERO);
    node->SetRotation(Quaternion::IDENTITY);
    node->SetScale(Vector3::ONE);

    component->SetTemporary(true);

    SharedPtr<File> file(new File(context_, asset_->GetPath(), FILE_WRITE));
    node->SaveXML(*file);
    file->Close();

    component->SetTemporary(false);

    // restore
    node->SetPosition(pos);
    node->SetRotation(rot);
    node->SetScale(scale);

    for (unsigned i = 0; i < tempComponents.Size(); i++)
    {
        tempComponents[i]->SetTemporary(true);
    }

    for (unsigned i = 0; i < tempChildren.Size(); i++)
    {
        tempChildren[i]->SetTemporary(true);
    }


    FileSystem* fs = GetSubsystem<FileSystem>();
    fs->Copy(asset_->GetPath(), asset_->GetCachePath());

    // reload it immediately so it is ready for use
    // TODO: The resource cache is reloading after this reload due to catching the file cache
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    XMLFile* xmlfile = cache->GetResource<XMLFile>(asset_->GetGUID());
    cache->ReloadResource(xmlfile);

    VariantMap changedData;
    changedData[PrefabChanged::P_GUID] = asset_->GetGUID();
    SendEvent(E_PREFABCHANGED, changedData);

}
Example #11
0
void Zone::SetZoneTextureAttr(const ResourceRef& value)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    zoneTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
}
Example #12
0
void DebugHud::Update()
{
    Graphics* graphics = GetSubsystem<Graphics>();
    Renderer* renderer = GetSubsystem<Renderer>();
    if (!renderer || !graphics)
        return;

    // Ensure UI-elements are not detached
    if (!statsText_->GetParent())
    {
        UI* ui = GetSubsystem<UI>();
        UIElement* uiRoot = ui->GetRoot();
        uiRoot->AddChild(statsText_);
        uiRoot->AddChild(modeText_);
        uiRoot->AddChild(profilerText_);
    }

    if (statsText_->IsVisible())
    {
        unsigned primitives, batches;
        if (!useRendererStats_)
        {
            primitives = graphics->GetNumPrimitives();
            batches = graphics->GetNumBatches();
        }
        else
        {
            primitives = renderer->GetNumPrimitives();
            batches = renderer->GetNumBatches();
        }

        String stats;
        stats.AppendWithFormat("Triangles %u\nBatches %u\nViews %u\nLights %u\nShadowmaps %u\nOccluders %u",
                               primitives,
                               batches,
                               renderer->GetNumViews(),
                               renderer->GetNumLights(true),
                               renderer->GetNumShadowMaps(true),
                               renderer->GetNumOccluders(true));

        if (!appStats_.Empty())
        {
            stats.Append("\n");
            for (HashMap<String, String>::ConstIterator i = appStats_.Begin(); i != appStats_.End(); ++i)
                stats.AppendWithFormat("\n%s %s", i->first_.CString(), i->second_.CString());
        }

        statsText_->SetText(stats);
    }

    if (modeText_->IsVisible())
    {
        String mode;
        mode.AppendWithFormat("Tex:%s Mat:%s Spec:%s Shadows:%s Size:%i Quality:%s Occlusion:%s Instancing:%s API:%s",
                              qualityTexts[renderer->GetTextureQuality()],
                              qualityTexts[renderer->GetMaterialQuality()],
                              renderer->GetSpecularLighting() ? "On" : "Off",
                              renderer->GetDrawShadows() ? "On" : "Off",
                              renderer->GetShadowMapSize(),
                              shadowQualityTexts[renderer->GetShadowQuality()],
                              renderer->GetMaxOccluderTriangles() > 0 ? "On" : "Off",
                              renderer->GetDynamicInstancing() ? "On" : "Off",
                              graphics->GetApiName().CString());

        modeText_->SetText(mode);
    }

    Profiler* profiler = GetSubsystem<Profiler>();
    if (profiler)
    {
        if (profilerTimer_.GetMSec(false) >= profilerInterval_)
        {
            profilerTimer_.Reset();

            if (profilerText_->IsVisible())
            {
                String profilerOutput = profiler->PrintData(false, false, profilerMaxDepth_);
                profilerText_->SetText(profilerOutput);
            }

            profiler->BeginInterval();
        }
    }

    if (memoryText_->IsVisible())
    {
        ResourceCache* cache = GetSubsystem<ResourceCache>();
        memoryText_->SetText(cache->PrintMemoryUsage());
    }
}
Example #13
0
int main(int argc, char** argv)
{
    #ifdef WIN32
    const Vector<String>& arguments = ParseArguments(GetCommandLineW());
    #else
    const Vector<String>& arguments = ParseArguments(argc, argv);
    #endif
    
    bool dumpApiMode = false;
    String outputFile;
    
    if (arguments.Size() < 1)
        ErrorExit("Usage: ScriptCompiler <input file> [resource path for includes]\n"
                  "       ScriptCompiler -dumpapi [output file]");
    else
    {
        if (arguments[0] != "-dumpapi")
            outputFile = arguments[0];
        else
        {
            dumpApiMode = true;
            if (arguments.Size() > 1)
                outputFile = arguments[1];
        }
    }
    
    SharedPtr<Context> context(new Context());
    
    // Note: creating the Engine registers most subsystems which don't require engine initialization
    SharedPtr<Engine> engine(new Engine(context));
    context->RegisterSubsystem(new Script(context));
    
    Log* log = context->GetSubsystem<Log>();
    // Register Log subsystem manually if compiled without logging support
    if (!log)
    {
        context->RegisterSubsystem(new Log(context));
        log = context->GetSubsystem<Log>();
    }
    
    log->SetLevel(LOG_WARNING);
    log->SetTimeStamp(false);
    
    if (!dumpApiMode)
    {
        String path, file, extension;
        SplitPath(outputFile, path, file, extension);
        
        ResourceCache* cache = context->GetSubsystem<ResourceCache>();
        
        // Add resource path to be able to resolve includes
        if (arguments.Size() > 1)
            cache->AddResourceDir(arguments[1]);
        else
            cache->AddResourceDir(cache->GetPreferredResourceDir(path));
        
        if (!file.StartsWith("*"))
            CompileScript(context, outputFile);
        else
        {
            Vector<String> scriptFiles;
            context->GetSubsystem<FileSystem>()->ScanDir(scriptFiles, path, file + extension, SCAN_FILES, false);
            for (unsigned i = 0; i < scriptFiles.Size(); ++i)
                CompileScript(context, path + scriptFiles[i]);
        }
    }
    else
    {
        if (!outputFile.Empty())
        {
            log->SetQuiet(true);
            log->Open(outputFile);
        }
        // If without output file, dump to stdout instead
        context->GetSubsystem<Script>()->DumpAPI();
    }
    
    return EXIT_SUCCESS;
}
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;
    }
}
Example #15
0
static shared_ptr<Tree> load_tree_fromCache(const string& name)
{
   static ResourceCache<Tree> cache(load_tree_xml, "trees");
   return cache.load_copy(name);
}
Example #16
0
void Scene::PreloadResourcesXML(const XMLElement& element)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    // Node or Scene attributes do not include any resources; therefore skip to the components
    XMLElement compElem = element.GetChild("component");
    while (compElem)
    {
        String typeName = compElem.GetAttribute("type");
        const Vector<AttributeInfo>* attributes = context_->GetAttributes(StringHash(typeName));
        if (attributes)
        {
            XMLElement attrElem = compElem.GetChild("attribute");
            unsigned startIndex = 0;

            while (attrElem)
            {
                String name = attrElem.GetAttribute("name");
                unsigned i = startIndex;
                unsigned attempts = attributes->Size();

                while (attempts)
                {
                    const AttributeInfo& attr = attributes->At(i);
                    if ((attr.mode_ & AM_FILE) && !attr.name_.Compare(name, true))
                    {
                        if (attr.type_ == VAR_RESOURCEREF)
                        {
                            ResourceRef ref = attrElem.GetVariantValue(attr.type_).GetResourceRef();
                            String name = cache->SanitateResourceName(ref.name_);
                            bool success = cache->BackgroundLoadResource(ref.type_, name);
                            if (success)
                            {
                                ++asyncProgress_.totalResources_;
                                asyncProgress_.resources_.Insert(StringHash(name));
                            }
                        }
                        else if (attr.type_ == VAR_RESOURCEREFLIST)
                        {
                            ResourceRefList refList = attrElem.GetVariantValue(attr.type_).GetResourceRefList();
                            for (unsigned k = 0; k < refList.names_.Size(); ++k)
                            {
                                String name = cache->SanitateResourceName(refList.names_[k]);
                                bool success = cache->BackgroundLoadResource(refList.type_, name);
                                if (success)
                                {
                                    ++asyncProgress_.totalResources_;
                                    asyncProgress_.resources_.Insert(StringHash(name));
                                }
                            }
                        }

                        startIndex = (i + 1) % attributes->Size();
                        break;
                    }
                    else
                    {
                        i = (i + 1) % attributes->Size();
                        --attempts;
                    }
                }

                attrElem = attrElem.GetNext("attribute");
            }
        }

        compElem = compElem.GetNext("component");
    }

    XMLElement childElem = element.GetChild("node");
    while (childElem)
    {
        PreloadResourcesXML(childElem);
        childElem = childElem.GetNext("node");
    }
}
Example #17
0
void Scene::PreloadResources(File* file, bool isSceneFile)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    // Read node ID (not needed)
    /*unsigned nodeID = */file->ReadUInt();

    // Read Node or Scene attributes; these do not include any resources
    const Vector<AttributeInfo>* attributes = context_->GetAttributes(isSceneFile ? Scene::GetTypeStatic() : Node::GetTypeStatic());
    assert(attributes);

    for (unsigned i = 0; i < attributes->Size(); ++i)
    {
        const AttributeInfo& attr = attributes->At(i);
        if (!(attr.mode_ & AM_FILE))
            continue;
        Variant varValue = file->ReadVariant(attr.type_);
    }

    // Read component attributes
    unsigned numComponents = file->ReadVLE();
    for (unsigned i = 0; i < numComponents; ++i)
    {
        VectorBuffer compBuffer(*file, file->ReadVLE());
        StringHash compType = compBuffer.ReadStringHash();
        // Read component ID (not needed)
        /*unsigned compID = */compBuffer.ReadUInt();

        attributes = context_->GetAttributes(compType);
        if (attributes)
        {
            for (unsigned j = 0; j < attributes->Size(); ++j)
            {
                const AttributeInfo& attr = attributes->At(j);
                if (!(attr.mode_ & AM_FILE))
                    continue;
                Variant varValue = compBuffer.ReadVariant(attr.type_);
                if (attr.type_ == VAR_RESOURCEREF)
                {
                    const ResourceRef& ref = varValue.GetResourceRef();
                    // Sanitate resource name beforehand so that when we get the background load event, the name matches exactly
                    String name = cache->SanitateResourceName(ref.name_);
                    bool success = cache->BackgroundLoadResource(ref.type_, name);
                    if (success)
                    {
                        ++asyncProgress_.totalResources_;
                        asyncProgress_.resources_.Insert(StringHash(name));
                    }
                }
                else if (attr.type_ == VAR_RESOURCEREFLIST)
                {
                    const ResourceRefList& refList = varValue.GetResourceRefList();
                    for (unsigned k = 0; k < refList.names_.Size(); ++k)
                    {
                        String name = cache->SanitateResourceName(refList.names_[k]);
                        bool success = cache->BackgroundLoadResource(refList.type_, name);
                        if (success)
                        {
                            ++asyncProgress_.totalResources_;
                            asyncProgress_.resources_.Insert(StringHash(name));
                        }
                    }
                }
             }
        }
    }

    // Read child nodes
    unsigned numChildren = file->ReadVLE();
    for (unsigned i = 0; i < numChildren; ++i)
        PreloadResources(file, false);
}
Example #18
0
bool Engine::Initialize(const VariantMap& parameters)
{
    if (initialized_)
        return true;
    
    PROFILE(InitEngine);
    
    // Set headless mode
    headless_ = GetParameter(parameters, "Headless", false).GetBool();
    
    // Register the rest of the subsystems
    if (!headless_)
    {
        context_->RegisterSubsystem(new Graphics(context_));
        context_->RegisterSubsystem(new Renderer(context_));
    }
    else
    {
        // Register graphics library objects explicitly in headless mode to allow them to work without using actual GPU resources
        RegisterGraphicsLibrary(context_);
    }
    
    // In debug mode, check now that all factory created objects can be created without crashing
    #ifdef _DEBUG
    const HashMap<ShortStringHash, SharedPtr<ObjectFactory> >& factories = context_->GetObjectFactories();
    for (HashMap<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories.Begin(); i != factories.End(); ++i)
        SharedPtr<Object> object = i->second_->CreateObject();
    #endif
    
    // Start logging
    Log* log = GetSubsystem<Log>();
    if (log)
    {
        if (HasParameter(parameters, "LogLevel"))
            log->SetLevel(GetParameter(parameters, "LogLevel").GetInt());
        log->SetQuiet(GetParameter(parameters, "LogQuiet", false).GetBool());
        log->Open(GetParameter(parameters, "LogName", "Urho3D.log").GetString());
    }
    
    // Set maximally accurate low res timer
    GetSubsystem<Time>()->SetTimerPeriod(1);
    
    // Configure max FPS
    if (GetParameter(parameters, "FrameLimiter", true) == false)
        SetMaxFps(0);
    
    // Set amount of worker threads according to the available physical CPU cores. Using also hyperthreaded cores results in
    // unpredictable extra synchronization overhead. Also reserve one core for the main thread
    unsigned numThreads = GetParameter(parameters, "WorkerThreads", true).GetBool() ? GetNumPhysicalCPUs() - 1 : 0;
    if (numThreads)
    {
        GetSubsystem<WorkQueue>()->CreateThreads(numThreads);
        
        LOGINFO(ToString("Created %u worker thread%s", numThreads, numThreads > 1 ? "s" : ""));
    }
    
    // Add resource paths
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    String exePath = fileSystem->GetProgramDir();
    
    Vector<String> resourcePaths = GetParameter(parameters, "ResourcePaths", "CoreData;Data").GetString().Split(';');
    Vector<String> resourcePackages = GetParameter(parameters, "ResourcePackages").GetString().Split(';');
    
    for (unsigned i = 0; i < resourcePaths.Size(); ++i)
    {
        bool success = false;
        
        // If path is not absolute, prefer to add it as a package if possible
        if (!IsAbsolutePath(resourcePaths[i]))
        {
            String packageName = exePath + resourcePaths[i] + ".pak";
            if (fileSystem->FileExists(packageName))
            {
                SharedPtr<PackageFile> package(new PackageFile(context_));
                if (package->Open(packageName))
                {
                    cache->AddPackageFile(package);
                    success = true;
                }
            }
            
            if (!success)
            {
                String pathName = exePath + resourcePaths[i];
                if (fileSystem->DirExists(pathName))
                    success = cache->AddResourceDir(pathName);
            }
        }
        else
        {
            String pathName = resourcePaths[i];
            if (fileSystem->DirExists(pathName))
                success = cache->AddResourceDir(pathName);
        }
        
        if (!success)
        {
            LOGERROR("Failed to add resource path " + resourcePaths[i]);
            return false;
        }
    }
    
    // Then add specified packages
    for (unsigned i = 0; i < resourcePackages.Size(); ++i)
    {
        bool success = false;
        
        String packageName = exePath + resourcePackages[i];
        if (fileSystem->FileExists(packageName))
        {
            SharedPtr<PackageFile> package(new PackageFile(context_));
            if (package->Open(packageName))
            {
                cache->AddPackageFile(package);
                success = true;
            }
        }
        
        if (!success)
        {
            LOGERROR("Failed to add resource package " + resourcePackages[i]);
            return false;
        }
    }
    

    // Initialize graphics & audio output
    if (!headless_)
    {
        Graphics* graphics = GetSubsystem<Graphics>();
        Renderer* renderer = GetSubsystem<Renderer>();
        
        if (HasParameter(parameters, "ExternalWindow"))
            graphics->SetExternalWindow(GetParameter(parameters, "ExternalWindow").GetPtr());
        graphics->SetForceSM2(GetParameter(parameters, "ForceSM2", false).GetBool());
        graphics->SetWindowTitle(GetParameter(parameters, "WindowTitle", "Urho3D").GetString());
        if (!graphics->SetMode(
            GetParameter(parameters, "WindowWidth", 0).GetInt(),
            GetParameter(parameters, "WindowHeight", 0).GetInt(),
            GetParameter(parameters, "FullScreen", true).GetBool(),
            GetParameter(parameters, "WindowResizable", false).GetBool(),
            GetParameter(parameters, "VSync", false).GetBool(),
            GetParameter(parameters, "TripleBuffer", false).GetBool(),
            GetParameter(parameters, "MultiSample", 1).GetInt()
        ))
            return false;
        
        if (HasParameter(parameters, "RenderPath"))
            renderer->SetDefaultRenderPath(cache->GetResource<XMLFile>(GetParameter(parameters, "RenderPath").GetString()));
        renderer->SetDrawShadows(GetParameter(parameters, "Shadows", true).GetBool());
        if (renderer->GetDrawShadows() && GetParameter(parameters, "LowQualityShadows", false).GetBool())
            renderer->SetShadowQuality(SHADOWQUALITY_LOW_16BIT);
        
        if (GetParameter(parameters, "Sound", true).GetBool())
        {
            GetSubsystem<Audio>()->SetMode(
                GetParameter(parameters, "SoundBuffer", 100).GetInt(),
                GetParameter(parameters, "SoundMixRate", 44100).GetInt(),
                GetParameter(parameters, "SoundStereo", true).GetBool(),
                GetParameter(parameters, "SoundInterpolation", true).GetBool()
            );
        }
    }
    
    // Init FPU state of main thread
    InitFPU();
    
    frameTimer_.Reset();
    
    initialized_ = true;
    return true;
}
Example #19
0
Shader::~Shader()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    if (cache)
        cache->ResetDependencies(this);
}
Example #20
0
void Slice::Draw(Ray ray, Vector pos, Vector dir, const Level& level, const ResourceCache& res)
{
   const int wall_height = std::abs(int(mSurface->h / ray.GetDistance()));

   int wall_start = (mSurface->h / 2) - (wall_height / 2);
   int wall_end = (mSurface->h / 2) + (wall_height / 2);

   if (wall_start < 0) {
      wall_start = 0;
   }

   if (wall_end >= mSurface->h) {
      wall_end = mSurface->h - 1;
   }

   // Get the texture that matches the cell type.
   const auto cell_id = level.mGrid[ray.GetMapIntersectionX()][ray.GetMapIntersectionY()] - 1;
   //const auto cell_id = level.mGrid[ray.GetMapIntersectionX()][ray.GetMapIntersectionY()] - 1;
   const auto wall_tex = res.GetWall(cell_id);

   // Where exactly the wall was hit.
   double wall_x = ray.GetIntersection().GetY();
   wall_x -= std::floor(wall_x);

   // X-coordinate on the texture.
   int tex_x = wall_x * wall_tex->w;

   if (( ray.VerticalSideHit() && dir.GetY() < 0) ||
       (!ray.VerticalSideHit() && dir.GetX() > 0))
   {
      tex_x = wall_tex->w - tex_x - 1;
   }

   for (int y = wall_start; y < wall_end; y++)
   {
      const int tex_y = (y * 2 - mSurface->h + wall_height) *
                        (wall_tex->h / 2) / wall_height;

      const auto tex_offset = (wall_tex->pitch * tex_y) + (tex_x * 4);
      const auto tex_ptr = static_cast<Uint8*>(wall_tex->pixels) + tex_offset;

      SDL_Color color = { tex_ptr[0], tex_ptr[1], tex_ptr[2] };

      if (ray.VerticalSideHit())
      {
         // Give X and Y-sides different brightness.
         color.r /= 2;
         color.g /= 2;
         color.b /= 2;
      }

      const auto scr_offset = (mSurface->pitch * y) + (mXCoordinate * 4);
      const auto scr_ptr = static_cast<Uint8*>(mSurface->pixels) + scr_offset;
      memcpy(scr_ptr, &color, sizeof(color));
   }

   // Get the texture for the ceiling and floor.
//   const auto ceiling_tex = res.GetCeiling(0);
   const auto floor_tex = res.GetWall(2);

   // Position of the floor at the bottom of the wall.
   double floor_x_wall;
   double floor_y_wall;

   if (!ray.VerticalSideHit() && (dir.GetX() > 0)) {
      floor_x_wall = ray.GetMapIntersectionX();
      floor_y_wall = ray.GetMapIntersectionY() + wall_x;
   }
   else if (!ray.VerticalSideHit() && (dir.GetX() < 0)) {
      floor_x_wall = ray.GetMapIntersectionX() + 1.;
      floor_y_wall = ray.GetMapIntersectionY() + wall_x;
   }
   else if (ray.VerticalSideHit() && (dir.GetY() > 0)) {
      floor_x_wall = ray.GetMapIntersectionX() + wall_x;
      floor_y_wall = ray.GetMapIntersectionY();
   }
   else {
      floor_x_wall = ray.GetMapIntersectionX() + wall_x;
      floor_y_wall = ray.GetMapIntersectionY() + 1.;
   }

   const double dist_wall = ray.GetDistance();
   const double dist_player = .0;

   // Draw the floor from below the wall to the bottom of the screen.
   for (int y = wall_end; y < mSurface->h; y++)
   {
      const double cur_dist = mSurface->h / (2. * y - mSurface->h);
      const double weight = (cur_dist - dist_player) / (dist_wall - dist_player);

      double cur_floor_x = weight * floor_x_wall + (1.0 - weight) * pos.GetX();
      double cur_floor_y = weight * floor_y_wall + (1.0 - weight) * pos.GetY();
      if (cur_floor_x < 0.) { cur_floor_x = 0.; }
      if (cur_floor_y < 0.) { cur_floor_y = 0.; }

      const int floor_tex_x = int(cur_floor_x * floor_tex->w / 4) % floor_tex->w;
      const int floor_tex_y = int(cur_floor_y * floor_tex->h / 4) % floor_tex->h;

//      const auto ceiling_tex_offset = (ceiling_tex->pitch * floor_tex_y) + (floor_tex_x * 4);
//      const auto ceiling_tex_ptr = static_cast<Uint8*>(ceiling_tex->pixels) + ceiling_tex_offset;

      const auto floor_tex_offset = (floor_tex->pitch * floor_tex_y) + (floor_tex_x * 4);
      const auto floor_tex_ptr = static_cast<Uint8*>(floor_tex->pixels) + floor_tex_offset;

//      const SDL_Color ceiling_color = { ceiling_tex_ptr[0], ceiling_tex_ptr[1], ceiling_tex_ptr[2] };
      SDL_Color floor_color = { floor_tex_ptr[0], floor_tex_ptr[1], floor_tex_ptr[2] };

      // Make the floor darker.
      floor_color.r /= 2;
      floor_color.g /= 2;
      floor_color.b /= 2;

//      const auto ceiling_offset = (mSurface->pitch * (mSurface->h - y - 1)) + (mXCoordinate * 4);
//      const auto ceiling_ptr = static_cast<Uint8*>(mSurface->pixels) + ceiling_offset;
//      memcpy(ceiling_ptr, &ceiling_color, sizeof(ceiling_color));

      const auto floor_offset = (mSurface->pitch * y) + (mXCoordinate * 4);
      const auto floor_ptr = static_cast<Uint8*>(mSurface->pixels) + floor_offset;
      memcpy(floor_ptr, &floor_color, sizeof(floor_color));
   }
}
Example #21
0
void Scene::PreloadResourcesJSON(const JSONValue& value)
{
    // If not threaded, can not background load resources, so rather load synchronously later when needed
#ifdef URHO3D_THREADING
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    // Node or Scene attributes do not include any resources; therefore skip to the components
    JSONArray componentArray = value.Get("components").GetArray();

    for (unsigned i = 0; i < componentArray.Size(); i++)
    {
        const JSONValue& compValue = componentArray.At(i);
        String typeName = compValue.Get("type").GetString();

        const Vector<AttributeInfo>* attributes = context_->GetAttributes(StringHash(typeName));
        if (attributes)
        {
            JSONArray attributesArray = compValue.Get("attributes").GetArray();

            unsigned startIndex = 0;

            for (unsigned j = 0; j < attributesArray.Size(); j++)
            {
                const JSONValue& attrVal = attributesArray.At(j);
                String name = attrVal.Get("name").GetString();
                unsigned i = startIndex;
                unsigned attempts = attributes->Size();

                while (attempts)
                {
                    const AttributeInfo& attr = attributes->At(i);
                    if ((attr.mode_ & AM_FILE) && !attr.name_.Compare(name, true))
                    {
                        if (attr.type_ == VAR_RESOURCEREF)
                        {
                            ResourceRef ref = attrVal.Get("value").GetVariantValue(attr.type_).GetResourceRef();
                            String name = cache->SanitateResourceName(ref.name_);
                            bool success = cache->BackgroundLoadResource(ref.type_, name);
                            if (success)
                            {
                                ++asyncProgress_.totalResources_;
                                asyncProgress_.resources_.Insert(StringHash(name));
                            }
                        }
                        else if (attr.type_ == VAR_RESOURCEREFLIST)
                        {
                            ResourceRefList refList = attrVal.Get("value").GetVariantValue(attr.type_).GetResourceRefList();
                            for (unsigned k = 0; k < refList.names_.Size(); ++k)
                            {
                                String name = cache->SanitateResourceName(refList.names_[k]);
                                bool success = cache->BackgroundLoadResource(refList.type_, name);
                                if (success)
                                {
                                    ++asyncProgress_.totalResources_;
                                    asyncProgress_.resources_.Insert(StringHash(name));
                                }
                            }
                        }

                        startIndex = (i + 1) % attributes->Size();
                        break;
                    }
                    else
                    {
                        i = (i + 1) % attributes->Size();
                        --attempts;
                    }
                }

            }
        }

    }

    JSONArray childrenArray = value.Get("children").GetArray();
    for (unsigned i = 0; i < childrenArray.Size(); i++)
    {
        const JSONValue& childVal = childrenArray.At(i);
        PreloadResourcesJSON(childVal);
    }
#endif
}
Example #22
0
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;
}
Example #23
0
SceneEditor3D ::SceneEditor3D(Context* context, const String &fullpath, TBTabContainer *container) :
    ResourceEditor(context, fullpath, container)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    scene_ = new Scene(context_);
    SharedPtr<File> xmlFile = cache->GetFile(fullpath);

    if (GetExtension(fullpath) == ".scene")
        scene_->LoadXML(*xmlFile);
    else
        scene_->Load(*xmlFile);

    scene_->SetUpdateEnabled(false);

    sceneView_ = new SceneView3D(context_, this);

    // EARLY ACCESS
    if (fullpath.Find(String("ToonTown")) != String::NPOS)
    {
          sceneView_->GetCameraNode()->SetWorldPosition(Vector3(-119.073, 76.1121, 16.47763));
          Quaternion q(0.55, 0.14,  0.8, -0.2);
          sceneView_->SetYaw(q.YawAngle());
          sceneView_->SetPitch(q.PitchAngle());
          sceneView_->GetCameraNode()->SetWorldRotation(q);
    }
    else
    {
        Node* playerSpawn = scene_->GetChild("PlayerInfoStart", true);
        if (playerSpawn)
        {
            sceneView_->GetCameraNode()->SetPosition(playerSpawn->GetPosition());
            sceneView_->SetYaw(playerSpawn->GetRotation().EulerAngles().y_);
        }

    }

    TBWidgetDelegate* delegate = sceneView_->GetWidgetDelegate();
    delegate->SetGravity(WIDGET_GRAVITY_ALL);

    rootContentWidget_->AddChild(delegate);

    gizmo3D_ = new Gizmo3D(context_);
    gizmo3D_->SetView(sceneView_);
    gizmo3D_->Show();

    SubscribeToEvent(E_UPDATE, HANDLER(SceneEditor3D, HandleUpdate));
    SubscribeToEvent(E_EDITORACTIVENODECHANGE, HANDLER(SceneEditor3D, HandleEditorActiveNodeChange));

    // FIXME: Set the size at the end of setup, so all children are updated accordingly
    // future size changes will be handled automatically
    TBRect rect = container_->GetContentRoot()->GetRect();
    rootContentWidget_->SetSize(rect.w, rect.h);

    // TODO: generate this event properly
    VariantMap eventData;
    eventData[EditorActiveSceneChange::P_SCENE] = scene_;
    SendEvent(E_EDITORACTIVESCENECHANGE, eventData);

    SubscribeToEvent(E_EDITORPLAYSTARTED, HANDLER(SceneEditor3D, HandlePlayStarted));
    SubscribeToEvent(E_EDITORPLAYSTOPPED, HANDLER(SceneEditor3D, HandlePlayStopped));

}
Example #24
0
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;
}
Example #25
0
int JSVM::GetRealLineNumber(const String& fileName, const int lineNumber) {

    int realLineNumber = lineNumber;

    String mapPath = fileName;

    if (!mapPath.EndsWith(".js.map"))
        mapPath += ".js.map";

    if (mapPath.EndsWith(".js")) {
        return realLineNumber;
    }

    ResourceCache* cache = GetSubsystem<ResourceCache>();

    String path;
    const Vector<String>& searchPaths = GetModuleSearchPaths();
    for (unsigned i = 0; i < searchPaths.Size(); i++)
    {
        String checkPath = searchPaths[i] + mapPath;

        if (cache->Exists(checkPath))
        {
            path = checkPath;
            break;
        }

    }

    if (!path.Length())
        return realLineNumber;


    SharedPtr<File> mapFile(GetSubsystem<ResourceCache>()->GetFile(path));

    //if there's no source map file, maybe you use a pure js, so give an error, or maybe forgot to generate source-maps :(
    if (mapFile.Null())
    {
        return realLineNumber;
    }

    String map;
    mapFile->ReadText(map);
    int top = duk_get_top(ctx_);
    duk_get_global_string(ctx_, "require");
    duk_push_string(ctx_, "AtomicEditor/EditorScripts/Lib/jsutils");
    if (duk_pcall(ctx_, 1))
    {
        printf("Error: %s\n", duk_safe_to_string(ctx_, -1));
        duk_set_top(ctx_, top);
        return false;
    }

    duk_get_prop_string(ctx_, -1, "getRealLineNumber");
    duk_push_string(ctx_, map.CString());
    duk_push_int(ctx_, lineNumber);
    bool ok = true;
    if (duk_pcall(ctx_, 2))
    {
        ok = false;
        printf("Error: %s\n", duk_safe_to_string(ctx_, -1));
    }
    else
    {
        realLineNumber = duk_to_int(ctx_, -1);
    }
    duk_set_top(ctx_, top);

    return realLineNumber;
}
Example #26
0
SceneEditor3D ::SceneEditor3D(Context* context, const String &fullpath, UITabContainer *container) :
    ResourceEditor(context, fullpath, container)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    scene_ = new Scene(context_);
    SharedPtr<File> xmlFile = cache->GetFile(fullpath);

    if (GetExtension(fullpath) == ".scene")
        scene_->LoadXML(*xmlFile);
    else
        scene_->Load(*xmlFile);

    scene_->SetUpdateEnabled(false);

    sceneView_ = new SceneView3D(context_, this);

    // EARLY ACCESS
    if (fullpath.Find(String("ToonTown")) != String::NPOS)
    {
          sceneView_->GetCameraNode()->SetWorldPosition(Vector3(-119.073f, 76.1121f, 16.47763f));
          Quaternion q(0.55f, 0.14f,  0.8f, -0.2f);
          sceneView_->SetYaw(q.YawAngle());
          sceneView_->SetPitch(q.PitchAngle());
          sceneView_->GetCameraNode()->SetWorldRotation(q);
    }
    else
    {
        Node* playerSpawn = scene_->GetChild("PlayerInfoStart", true);
        if (playerSpawn)
        {
            sceneView_->GetCameraNode()->SetPosition(playerSpawn->GetPosition());
            sceneView_->SetYaw(playerSpawn->GetRotation().EulerAngles().y_);
        }

    }

    sceneView_->SetGravity(UI_GRAVITY_ALL);

    rootContentWidget_->AddChild(sceneView_);

    gizmo3D_ = new Gizmo3D(context_);
    gizmo3D_->SetView(sceneView_);
    gizmo3D_->Show();

    SubscribeToEvent(E_UPDATE, HANDLER(SceneEditor3D, HandleUpdate));
    SubscribeToEvent(E_EDITORACTIVENODECHANGE, HANDLER(SceneEditor3D, HandleEditorActiveNodeChange));

    SubscribeToEvent(E_GIZMOEDITMODECHANGED, HANDLER(SceneEditor3D, HandleGizmoEditModeChanged));

    // FIXME: Set the size at the end of setup, so all children are updated accordingly
    // future size changes will be handled automatically
    IntRect rect = container_->GetContentRoot()->GetRect();
    rootContentWidget_->SetSize(rect.Width(), rect.Height());

    SubscribeToEvent(E_EDITORPLAYSTARTED, HANDLER(SceneEditor3D, HandlePlayStarted));
    SubscribeToEvent(E_EDITORPLAYSTOPPED, HANDLER(SceneEditor3D, HandlePlayStopped));

    SubscribeToEvent(scene_, E_NODEREMOVED, HANDLER(SceneEditor3D, HandleNodeRemoved));

}
bool ModelImporter::Import()
{

    String ext = asset_->GetExtension();
    String modelAssetFilename = asset_->GetPath();

    importNode_ = new Node(context_);

    if (ext == ".mdl")
    {
        FileSystem* fs = GetSubsystem<FileSystem>();
        ResourceCache* cache = GetSubsystem<ResourceCache>();

        // mdl files are native file format that doesn't need to be converted
        // doesn't allow scale, animations legacy primarily for ToonTown

        if (!fs->Copy(asset_->GetPath(), asset_->GetCachePath() + ".mdl"))
        {
            importNode_= 0;
            return false;
        }

        Model* mdl = cache->GetResource<Model>( asset_->GetCachePath() + ".mdl");

        if (!mdl)
        {
            importNode_= 0;
            return false;
        }

        // Force a reload, though file watchers will catch this delayed and load again
        cache->ReloadResource(mdl);

        importNode_->CreateComponent<StaticModel>()->SetModel(mdl);
    }
    else
    {
        // skip external animations, they will be brought in when importing their
        // corresponding model

        if (!modelAssetFilename.Contains("@"))
        {
            ImportModel();

            if (importAnimations_)
            {
                ImportAnimations();
            }

            AnimatedModel* animatedModel = importNode_->GetComponent<AnimatedModel>();
            if (animatedModel)
            {
                Model* model = animatedModel->GetModel();
                if (model && model->GetAnimationCount())
                {
                    // resave with animation info

                    File mdlFile(context_);
                    if (!mdlFile.Open(asset_->GetCachePath() + ".mdl", FILE_WRITE))
                    {
                        ErrorExit("Could not open output file " + asset_->GetCachePath() + ".mdl");
                        return false;
                    }

                    model->Save(mdlFile);
                }
            }
        }
    }


    File outFile(context_);

    if (!outFile.Open(asset_->GetCachePath(), FILE_WRITE))
        ErrorExit("Could not open output file " + asset_->GetCachePath());

    importNode_->SaveXML(outFile);

    importNode_ = 0;

    return true;
}
Example #28
0
bool ScriptFile::AddScriptSection(asIScriptEngine* engine, Deserializer& source)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    
    unsigned dataSize = source.GetSize();
    SharedArrayPtr<char> buffer(new char[dataSize]);
    source.Read((void*)buffer.Get(), dataSize);
    
    // Pre-parse for includes
    // Adapted from Angelscript's scriptbuilder add-on
    Vector<String> includeFiles;
    unsigned pos = 0;
    while(pos < dataSize)
    {
        int len;
        asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len);
        if (t == asTC_COMMENT || t == asTC_WHITESPACE)
        {
            pos += len;
            continue;
        }
        // Is this a preprocessor directive?
        if (buffer[pos] == '#')
        {
            int start = pos++;
            asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len);
            if (t == asTC_IDENTIFIER)
            {
                String token(&buffer[pos], len);
                if (token == "include")
                {
                    pos += len;
                    t = engine->ParseToken(&buffer[pos], dataSize - pos, &len);
                    if (t == asTC_WHITESPACE)
                    {
                        pos += len;
                        t = engine->ParseToken(&buffer[pos], dataSize - pos, &len);
                    }
                    
                    if (t == asTC_VALUE && len > 2 && buffer[pos] == '"')
                    {
                        // Get the include file
                        String includeFile(&buffer[pos+1], len - 2);
                        pos += len;
                        
                        // If the file is not found as it is, add the path of current file but only if it is found there
                        if (!cache->Exists(includeFile))
                        {
                            String prefixedIncludeFile = GetPath(GetName()) + includeFile;
                            if (cache->Exists(prefixedIncludeFile))
                                includeFile = prefixedIncludeFile;
                        }
                        
                        String includeFileLower = includeFile.ToLower();
                        
                        // If not included yet, store it for later processing
                        if (!includeFiles_.Contains(includeFileLower))
                        {
                            includeFiles_.Insert(includeFileLower);
                            includeFiles.Push(includeFile);
                        }
                        
                        // Overwrite the include directive with space characters to avoid compiler error
                        memset(&buffer[start], ' ', pos - start);
                    }
                }
            }
        }
        // Don't search includes within statement blocks or between tokens in statements
        else
        {
            int len;
            // Skip until ; or { whichever comes first
            while (pos < dataSize && buffer[pos] != ';' && buffer[pos] != '{')
            {
                engine->ParseToken(&buffer[pos], 0, &len);
                pos += len;
            }
            // Skip entire statement block
            if (pos < dataSize && buffer[pos] == '{')
            {
                ++pos;
                // Find the end of the statement block
                int level = 1;
                while (level > 0 && pos < dataSize)
                {
                    asETokenClass t = engine->ParseToken(&buffer[pos], 0, &len);
                    if (t == asTC_KEYWORD)
                    {
                        if (buffer[pos] == '{')
                            ++level;
                        else if(buffer[pos] == '}')
                            --level;
                    }
                    pos += len;
                }
            }
            else
                ++pos;
        }
    }
    
    // Process includes first
    for (unsigned i = 0; i < includeFiles.Size(); ++i)
    {
        cache->StoreResourceDependency(this, includeFiles[i]);
        SharedPtr<File> file = cache->GetFile(includeFiles[i]);
        if (file)
        {
            if (!AddScriptSection(engine, *file))
                return false;
        }
        else
        {
            LOGERROR("Could not process all the include directives in " + GetName() + ": missing " + includeFiles[i]);
            return false;
        }
    }
    
    // Then add this section
    if (scriptModule_->AddScriptSection(source.GetName().CString(), (const char*)buffer.Get(), dataSize) < 0)
    {
        LOGERROR("Failed to add script section " + source.GetName());
        return false;
    }
    
    SetMemoryUse(GetMemoryUse() + dataSize);
    return true;
}
Example #29
0
bool AnimationSet2D::LoadFolders(const XMLElement& rootElem)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    bool async = GetAsyncLoadState() == ASYNC_LOADING;

    String parentPath = GetParentPath(GetName());
    String spriteSheetFilePath = parentPath + GetFileName(GetName()) + ".xml";
    SpriteSheet2D* spriteSheet = 0;
    bool hasSpriteSheet = false;

    // When async loading, request the sprite sheet for background loading but do not actually get it
    if (!async)
        spriteSheet = cache->GetResource<SpriteSheet2D>(spriteSheetFilePath, false);
    else
    {
        hasSpriteSheet = cache->Exists(spriteSheetFilePath);
        if (hasSpriteSheet)
            cache->BackgroundLoadResource<SpriteSheet2D>(spriteSheetFilePath, false, this);
    }

    for (XMLElement folderElem = rootElem.GetChild("folder"); folderElem; folderElem = folderElem.GetNext("folder"))
    {
        unsigned folderId = folderElem.GetUInt("id");

        for (XMLElement fileElem = folderElem.GetChild("file"); fileElem; fileElem = fileElem.GetNext("file"))
        {
            unsigned fileId = fileElem.GetUInt("id");
            String fileName = fileElem.GetAttribute("name");

            // When async loading, request the sprites for background loading but do not actually get them
            if (!async)
            {
                SharedPtr<Sprite2D> sprite;
                
                if (spriteSheet)
                    sprite = spriteSheet->GetSprite(GetFileName(fileName));
                else
                    sprite = (cache->GetResource<Sprite2D>(parentPath + fileName));

                if (!sprite)
                {
                    LOGERROR("Could not load sprite " + fileName);
                    return false;
                }

                Vector2 hotSpot(0.0f, 1.0f);
                if (fileElem.HasAttribute("pivot_x"))
                    hotSpot.x_ = fileElem.GetFloat("pivot_x");
                if (fileElem.HasAttribute("pivot_y"))
                    hotSpot.y_ = fileElem.GetFloat("pivot_y");

                // If sprite is trimmed, recalculate hot spot
                const IntVector2& offset = sprite->GetOffset();
                if (offset != IntVector2::ZERO)
                {
                    int width = fileElem.GetInt("width");
                    int height = fileElem.GetInt("height");

                    float pivotX = width * hotSpot.x_;
                    float pivotY = height * (1.0f - hotSpot.y_);

                    const IntRect& rectangle = sprite->GetRectangle();
                    hotSpot.x_ = (offset.x_ + pivotX) / rectangle.Width();
                    hotSpot.y_ = 1.0f - (offset.y_ + pivotY) / rectangle.Height();
                }

                sprite->SetHotSpot(hotSpot);

                sprites_[(folderId << 16) + fileId] = sprite;
            }
            else if (!hasSpriteSheet)
                cache->BackgroundLoadResource<Sprite2D>(parentPath + fileName, true, this);
        }
    }

    return true;
}