コード例 #1
0
ファイル: EditorIconCache.cpp プロジェクト: rokups/Urho3D
EditorIconCache::EditorIconCache(Context* context)
    : Object(context)
{
    ResourceCache* cache = ui::GetSystemUI()->GetSubsystem<ResourceCache>();
    auto* icons = cache->GetResource<XMLFile>("UI/EditorIcons.xml");
    if (icons == nullptr)
        return;

    XMLElement root = icons->GetRoot();
    for (XMLElement element = root.GetChild("element"); element.NotNull(); element = element.GetNext("element"))
    {
        ea::string type = element.GetAttribute("type");
        if (type.empty())
        {
            URHO3D_LOGERROR("EditorIconCache.xml contains icon entry without a \"type\" attribute.");
            continue;
        }

        XPathResultSet texture = element.SelectPrepared(XPathQuery("attribute[@name=\"Texture\"]"));
        if (texture.Empty())
        {
            URHO3D_LOGERROR("EditorIconCache.xml contains icon entry without a \"Texture\".");
            continue;
        }

        XPathResultSet rect = element.SelectPrepared(XPathQuery("attribute[@name=\"Image Rect\"]"));
        if (rect.Empty())
        {
            URHO3D_LOGERROR("EditorIconCache.xml contains icon entry without a \"Image Rect\".");
            continue;
        }

        IconData data;
        data.textureRef_ = texture.FirstResult().GetVariantValue(VAR_RESOURCEREF).GetResourceRef();
        data.rect_ = rect.FirstResult().GetVariantValue(VAR_INTRECT).GetIntRect();
        iconCache_[type] = data;
    }
}
コード例 #2
0
ファイル: Sound.cpp プロジェクト: 1vanK/Urho3D
void Sound::LoadParameters()
{
    auto* cache = GetSubsystem<ResourceCache>();
    String xmlName = ReplaceExtension(GetName(), ".xml");

    SharedPtr<XMLFile> file(cache->GetTempResource<XMLFile>(xmlName, false));
    if (!file)
        return;

    XMLElement rootElem = file->GetRoot();
    LoadMetadataFromXML(rootElem);

    for (XMLElement paramElem = rootElem.GetChild(); paramElem; paramElem = paramElem.GetNext())
    {
        String name = paramElem.GetName();

        if (name == "format" && !compressed_)
        {
            if (paramElem.HasAttribute("frequency"))
                frequency_ = (unsigned)paramElem.GetInt("frequency");
            if (paramElem.HasAttribute("sixteenbit"))
                sixteenBit_ = paramElem.GetBool("sixteenbit");
            if (paramElem.HasAttribute("16bit"))
                sixteenBit_ = paramElem.GetBool("16bit");
            if (paramElem.HasAttribute("stereo"))
                stereo_ = paramElem.GetBool("stereo");
        }

        if (name == "loop")
        {
            if (paramElem.HasAttribute("enable"))
                SetLooped(paramElem.GetBool("enable"));
            if (paramElem.HasAttribute("start") && paramElem.HasAttribute("end"))
                SetLoop((unsigned)paramElem.GetInt("start"), (unsigned)paramElem.GetInt("end"));
        }
    }
}
コード例 #3
0
ファイル: PListFile.cpp プロジェクト: 03050903/Urho3D
bool PListFile::LoadDict(PListValueMap& dict, const XMLElement& dictElem)
{
    if (!dictElem)
        return false;

    XMLElement keyElem = dictElem.GetChild("key");
    XMLElement valueElem = keyElem.GetNext();
    while (keyElem && valueElem)
    {
        String key = keyElem.GetValue();
        valueElem = keyElem.GetNext();

        PListValue value;
        if (!LoadValue(value, valueElem))
            return false;

        dict[key] = value;

        keyElem = valueElem.GetNext("key");
        valueElem = keyElem.GetNext();
    }

    return true;
}
コード例 #4
0
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_);
            }
        }
    }
}
コード例 #5
0
ファイル: TextureCube.cpp プロジェクト: nemerle/lutefisk3d
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;
}
コード例 #6
0
ファイル: SpriteSheet2D.cpp プロジェクト: AGreatFish/Urho3D
bool SpriteSheet2D::Load(Deserializer& source)
{
    spriteMapping_.Clear();

    SharedPtr<XMLFile> xmlFile(new XMLFile(context_));
    if(!xmlFile->Load(source))
    {
        LOGERROR("Could not load sprite sheet");
        return false;
    }

    SetMemoryUse(source.GetSize());

    XMLElement rootElem = xmlFile->GetRoot();
    if (!rootElem)
    {
        LOGERROR("Invalid sprite sheet");
        return false;
    }

    if (rootElem.GetName() == "spritesheet")
    {
        ResourceCache* cache = GetSubsystem<ResourceCache>();
        String textureFileName = rootElem.GetAttribute("texture");
        texture_ = cache->GetResource<Texture2D>(textureFileName, false);
        // If texture not found, try get in current directory
        if (!texture_)
            texture_ = cache->GetResource<Texture2D>(GetParentPath(GetName()) + textureFileName);

        if (!texture_)
        {
            LOGERROR("Cound not load texture");
            return false;
        }

        XMLElement spriteElem = rootElem.GetChild("sprite");
        while (spriteElem)
        {
            String name = spriteElem.GetAttribute("name");
            IntRect rectangle = spriteElem.GetIntRect("rectangle");

            Vector2 hotSpot(0.5f, 0.5f);
            if (spriteElem.HasAttribute("hotspot"))
                hotSpot = spriteElem.GetVector2("hotspot");

            DefineSprite(name, rectangle, hotSpot);

            spriteElem = spriteElem.GetNext("sprite");
        }
    }
    // Sparrow Starling texture atlas
    else if (rootElem.GetName() == "TextureAtlas")
    {    
        String textureFileName = rootElem.GetAttribute("imagePath");
        ResourceCache* cache = GetSubsystem<ResourceCache>();
        texture_ = cache->GetResource<Texture2D>(textureFileName, false);
        // If texture not found, try get in current directory
        if (!texture_)
            texture_ = cache->GetResource<Texture2D>(GetParentPath(GetName()) + textureFileName);

        if (!texture_)
        {
            LOGERROR("Cound not load texture");
            return false;
        }

        XMLElement subTextureElem = rootElem.GetChild("SubTexture");
        while (subTextureElem)
        {
            String name = subTextureElem.GetAttribute("name");

            int x = subTextureElem.GetInt("x");
            int y = subTextureElem.GetInt("y");
            int width = subTextureElem.GetInt("width");
            int height = subTextureElem.GetInt("height");
            IntRect rectangle(x, y, x + width, y + height);

            Vector2 hotSpot(0.5f, 0.5f);
            if (subTextureElem.HasAttribute("frameWidth") && subTextureElem.HasAttribute("frameHeight"))
            {
                int frameX = subTextureElem.GetInt("frameX");
                int frameY = subTextureElem.GetInt("frameY");
                int frameWidth = subTextureElem.GetInt("frameWidth");
                int frameHeight = subTextureElem.GetInt("frameHeight");
                hotSpot.x_ = ((float)frameX + frameWidth / 2) / width;
                hotSpot.y_ = 1.0f - ((float)frameY + frameHeight / 2) / height;
            }

            DefineSprite(name, rectangle, hotSpot);

            subTextureElem = subTextureElem.GetNext("SubTexture");
        }
    }
    else
    {
        LOGERROR("Invalid sprite sheet file");
        return false;
    }

    return true;
}
コード例 #7
0
ファイル: Scene.cpp プロジェクト: zhzhxtrrk/Urho3D
bool Scene::LoadAsyncXML(File* file, LoadMode mode)
{
    if (!file)
    {
        LOGERROR("Null file for async loading");
        return false;
    }

    StopAsyncLoading();

    SharedPtr<XMLFile> xml(new XMLFile(context_));
    if (!xml->Load(*file))
        return false;

    if (mode > LOAD_RESOURCES_ONLY)
    {
        LOGINFO("Loading scene from " + file->GetName());
        Clear();
    }

    asyncLoading_ = true;
    asyncProgress_.xmlFile_ = xml;
    asyncProgress_.file_ = file;
    asyncProgress_.mode_ = mode;
    asyncProgress_.loadedNodes_ = asyncProgress_.totalNodes_ = asyncProgress_.loadedResources_ = asyncProgress_.totalResources_ = 0;
    asyncProgress_.resources_.Clear();

    if (mode > LOAD_RESOURCES_ONLY)
    {
        XMLElement rootElement = xml->GetRoot();

        // Preload resources if appropriate
        if (mode != LOAD_SCENE)
        {
            PROFILE(FindResourcesToPreload);

            PreloadResourcesXML(rootElement);
        }

        // Store own old ID for resolving possible root node references
        unsigned nodeID = rootElement.GetInt("id");
        resolver_.AddNode(nodeID, this);

        // Load the root level components first
        if (!Node::LoadXML(rootElement, resolver_, false))
            return false;

        // Then prepare for loading all root level child nodes in the async update
        XMLElement childNodeElement = rootElement.GetChild("node");
        asyncProgress_.xmlElement_ = childNodeElement;

        // Count the amount of child nodes
        while (childNodeElement)
        {
            ++asyncProgress_.totalNodes_;
            childNodeElement = childNodeElement.GetNext("node");
        }
    }
    else
    {
        PROFILE(FindResourcesToPreload);

        LOGINFO("Preloading resources from " + file->GetName());
        PreloadResourcesXML(xml->GetRoot());
    }

    return true;
}
コード例 #8
0
ファイル: Technique.cpp プロジェクト: rokups/Urho3D
bool Technique::BeginLoad(Deserializer& source)
{
    passes_.clear();
    cloneTechniques_.clear();

    SetMemoryUse(sizeof(Technique));

    ea::shared_ptr<XMLFile> xml(context_->CreateObject<XMLFile>());
    if (!xml->Load(source))
        return false;

    XMLElement rootElem = xml->GetRoot();
    if (rootElem.HasAttribute("desktop"))
        isDesktop_ = rootElem.GetBool("desktop");

    ea::string globalVS = rootElem.GetAttribute("vs");
    ea::string globalPS = rootElem.GetAttribute("ps");
    ea::string globalVSDefines = rootElem.GetAttribute("vsdefines");
    ea::string globalPSDefines = rootElem.GetAttribute("psdefines");
    // End with space so that the pass-specific defines can be appended
    if (!globalVSDefines.empty())
        globalVSDefines += ' ';
    if (!globalPSDefines.empty())
        globalPSDefines += ' ';

    XMLElement passElem = rootElem.GetChild("pass");
    while (passElem)
    {
        if (passElem.HasAttribute("name"))
        {
            Pass* newPass = CreatePass(passElem.GetAttribute("name"));

            if (passElem.HasAttribute("desktop"))
                newPass->SetIsDesktop(passElem.GetBool("desktop"));

            // Append global defines only when pass does not redefine the shader
            if (passElem.HasAttribute("vs"))
            {
                newPass->SetVertexShader(passElem.GetAttribute("vs"));
                newPass->SetVertexShaderDefines(passElem.GetAttribute("vsdefines"));
            }
            else
            {
                newPass->SetVertexShader(globalVS);
                newPass->SetVertexShaderDefines(globalVSDefines + passElem.GetAttribute("vsdefines"));
            }
            if (passElem.HasAttribute("ps"))
            {
                newPass->SetPixelShader(passElem.GetAttribute("ps"));
                newPass->SetPixelShaderDefines(passElem.GetAttribute("psdefines"));
            }
            else
            {
                newPass->SetPixelShader(globalPS);
                newPass->SetPixelShaderDefines(globalPSDefines + passElem.GetAttribute("psdefines"));
            }

            newPass->SetVertexShaderDefineExcludes(passElem.GetAttribute("vsexcludes"));
            newPass->SetPixelShaderDefineExcludes(passElem.GetAttribute("psexcludes"));

            if (passElem.HasAttribute("lighting"))
            {
                ea::string lighting = passElem.GetAttributeLower("lighting");
                newPass->SetLightingMode((PassLightingMode)GetStringListIndex(lighting.c_str(), lightingModeNames,
                    LIGHTING_UNLIT));
            }

            if (passElem.HasAttribute("blend"))
            {
                ea::string blend = passElem.GetAttributeLower("blend");
                newPass->SetBlendMode((BlendMode)GetStringListIndex(blend.c_str(), blendModeNames, BLEND_REPLACE));
            }

            if (passElem.HasAttribute("cull"))
            {
                ea::string cull = passElem.GetAttributeLower("cull");
                newPass->SetCullMode((CullMode)GetStringListIndex(cull.c_str(), cullModeNames, MAX_CULLMODES));
            }

            if (passElem.HasAttribute("depthtest"))
            {
                ea::string depthTest = passElem.GetAttributeLower("depthtest");
                if (depthTest == "false")
                    newPass->SetDepthTestMode(CMP_ALWAYS);
                else
                    newPass->SetDepthTestMode((CompareMode)GetStringListIndex(depthTest.c_str(), compareModeNames, CMP_LESS));
            }

            if (passElem.HasAttribute("depthwrite"))
                newPass->SetDepthWrite(passElem.GetBool("depthwrite"));

            if (passElem.HasAttribute("alphatocoverage"))
                newPass->SetAlphaToCoverage(passElem.GetBool("alphatocoverage"));
        }
        else
            URHO3D_LOGERROR("Missing pass name");

        passElem = passElem.GetNext("pass");
    }

    return true;
}
コード例 #9
0
ファイル: Technique.cpp プロジェクト: aster2013/Urho3D
bool Technique::BeginLoad(Deserializer& source)
{
    passes_.Clear();
    SetMemoryUse(sizeof(Technique));
    
    SharedPtr<XMLFile> xml(new XMLFile(context_));
    if (!xml->Load(source))
        return false;
    
    XMLElement rootElem = xml->GetRoot();
    if (rootElem.HasAttribute("sm3"))
        isSM3_ = rootElem.GetBool("sm3");
    
    String globalVS = rootElem.GetAttribute("vs");
    String globalPS = rootElem.GetAttribute("ps");
    String globalVSDefines = rootElem.GetAttribute("vsdefines");
    String globalPSDefines = rootElem.GetAttribute("psdefines");
    // End with space so that the pass-specific defines can be appended
    if (!globalVSDefines.Empty())
        globalVSDefines += ' ';
    if (!globalPSDefines.Empty())
        globalPSDefines += ' ';
    bool globalAlphaMask = false;
    if (rootElem.HasAttribute("alphamask"))
        globalAlphaMask = rootElem.GetBool("alphamask");
    
    unsigned numPasses = 0;
    
    XMLElement passElem = rootElem.GetChild("pass");
    while (passElem)
    {
        if (passElem.HasAttribute("name"))
        {
            StringHash nameHash(passElem.GetAttribute("name"));
            
            Pass* newPass = CreatePass(nameHash);
            ++numPasses;
            
            if (passElem.HasAttribute("sm3"))
                newPass->SetIsSM3(passElem.GetBool("sm3"));
            
            // Append global defines only when pass does not redefine the shader
            if (passElem.HasAttribute("vs"))
            {
                newPass->SetVertexShader(passElem.GetAttribute("vs"));
                newPass->SetVertexShaderDefines(passElem.GetAttribute("vsdefines"));
            }
            else
            {
                newPass->SetVertexShader(globalVS);
                newPass->SetVertexShaderDefines(globalVSDefines + passElem.GetAttribute("vsdefines"));
            }
            if (passElem.HasAttribute("ps"))
            {
                newPass->SetPixelShader(passElem.GetAttribute("ps"));
                newPass->SetPixelShaderDefines(passElem.GetAttribute("psdefines"));
            }
            else
            {
                newPass->SetPixelShader(globalPS);
                newPass->SetPixelShaderDefines(globalPSDefines + passElem.GetAttribute("psdefines"));
            }
            
            if (passElem.HasAttribute("lighting"))
            {
                String lighting = passElem.GetAttributeLower("lighting");
                newPass->SetLightingMode((PassLightingMode)GetStringListIndex(lighting.CString(), lightingModeNames,
                    LIGHTING_UNLIT));
            }
            
            if (passElem.HasAttribute("blend"))
            {
                String blend = passElem.GetAttributeLower("blend");
                newPass->SetBlendMode((BlendMode)GetStringListIndex(blend.CString(), blendModeNames, BLEND_REPLACE));
            }
            
            if (passElem.HasAttribute("depthtest"))
            {
                String depthTest = passElem.GetAttributeLower("depthtest");
                if (depthTest == "false")
                    newPass->SetDepthTestMode(CMP_ALWAYS);
                else
                    newPass->SetDepthTestMode((CompareMode)GetStringListIndex(depthTest.CString(), compareModeNames, CMP_LESS));
            }
            
            if (passElem.HasAttribute("depthwrite"))
                newPass->SetDepthWrite(passElem.GetBool("depthwrite"));
            
            if (passElem.HasAttribute("alphamask"))
                newPass->SetAlphaMask(passElem.GetBool("alphamask"));
            else
                newPass->SetAlphaMask(globalAlphaMask);
        }
        else
            LOGERROR("Missing pass name");
        
        passElem = passElem.GetNext("pass");
    }
    
    // Calculate memory use now
    SetMemoryUse(sizeof(Technique) + numPasses * sizeof(Pass));
    return true;
}
コード例 #10
0
bool ParticleEmitter::Load(XMLFile* file)
{
    if (!file)
    {
        LOGERROR("Null particle emitter parameter file");
        return false;
    }
    
    XMLElement rootElem = file->GetRoot();
    if (!rootElem)
    {
        LOGERROR("Particle emitter parameter file does not have a valid root element");
        return false;
    }
    
    if (rootElem.HasChild("material"))
        SetMaterial(GetSubsystem<ResourceCache>()->GetResource<Material>(rootElem.GetChild("material").GetAttribute("name")));
    
    if (rootElem.HasChild("numparticles"))
        SetNumParticles(rootElem.GetChild("numparticles").GetInt("value"));
    
    if (rootElem.HasChild("updateinvisible"))
        updateInvisible_ = rootElem.GetChild("updateinvisible").GetBool("enable");
    
    if (rootElem.HasChild("relative"))
        relative_ = rootElem.GetChild("relative").GetBool("enable");
    
    if (rootElem.HasChild("scaled"))
        scaled_ = rootElem.GetChild("scaled").GetBool("enable");
    
    if (rootElem.HasChild("sorted"))
        sorted_ = rootElem.GetChild("sorted").GetBool("enable");
    
    if (rootElem.HasChild("animlodbias"))
        SetAnimationLodBias(rootElem.GetChild("relative").GetFloat("value"));
    
    if (rootElem.HasChild("emittertype"))
    {
        String type = rootElem.GetChild("emittertype").GetAttributeLower("value");
        if (type == "point")
        {
            // Point emitter type is deprecated, handled as zero sized sphere
            emitterType_ = EMITTER_SPHERE;
            emitterSize_ = Vector3::ZERO;
        }
        else if (type == "box")
            emitterType_ = EMITTER_BOX;
        else if (type == "sphere")
            emitterType_ = EMITTER_SPHERE;
        else
            LOGERROR("Unknown particle emitter type " + type);
    }
    
    if (rootElem.HasChild("emittersize"))
        emitterSize_ = rootElem.GetChild("emittersize").GetVector3("value");
    
    if (rootElem.HasChild("emitterradius"))
        emitterSize_.x_ = emitterSize_.y_ = emitterSize_.z_ = rootElem.GetChild("emitterradius").GetFloat("value");
    
    if (rootElem.HasChild("direction"))
        GetVector3MinMax(rootElem.GetChild("direction"), directionMin_, directionMax_);
    
    if (rootElem.HasChild("constantforce"))
        constantForce_ = rootElem.GetChild("constantforce").GetVector3("value");
    
    if (rootElem.HasChild("dampingforce"))
        dampingForce_ = rootElem.GetChild("dampingforce").GetFloat("value");
    
    if (rootElem.HasChild("activetime"))
        activeTime_ = rootElem.GetChild("activetime").GetFloat("value");
    if (activeTime_ < 0.0f)
        activeTime_ = M_INFINITY;
    
    if (rootElem.HasChild("inactivetime"))
        inactiveTime_ = rootElem.GetChild("inactivetime").GetFloat("value");
    if (inactiveTime_ < 0.0f)
        inactiveTime_ = M_INFINITY;
    
    if (rootElem.HasChild("emissionrate"))
        GetFloatMinMax(rootElem.GetChild("emissionrate"), emissionRateMin_, emissionRateMax_);
    
    if (rootElem.HasChild("interval"))
    {
        float intervalMin = 0.0f;
        float intervalMax = 0.0f;
        GetFloatMinMax(rootElem.GetChild("interval"), intervalMin, intervalMax);
        emissionRateMax_ = 1.0f / intervalMin;
        emissionRateMin_ = 1.0f / intervalMax;
    }
    
    if (rootElem.HasChild("particlesize"))
        GetVector2MinMax(rootElem.GetChild("particlesize"), sizeMin_, sizeMax_);
    
    if (rootElem.HasChild("timetolive"))
        GetFloatMinMax(rootElem.GetChild("timetolive"), timeToLiveMin_, timeToLiveMax_);
    
    if (rootElem.HasChild("velocity"))
        GetFloatMinMax(rootElem.GetChild("velocity"), velocityMin_, velocityMax_);
    
    if (rootElem.HasChild("rotation"))
        GetFloatMinMax(rootElem.GetChild("rotation"), rotationMin_, rotationMax_);
    
    if (rootElem.HasChild("rotationspeed"))
        GetFloatMinMax(rootElem.GetChild("rotationspeed"), rotationSpeedMin_, rotationSpeedMax_);
    
    if (rootElem.HasChild("sizedelta"))
    {
        XMLElement deltaElem = rootElem.GetChild("sizedelta");
        if (deltaElem.HasAttribute("add"))
            sizeAdd_ = deltaElem.GetFloat("add");
        if (deltaElem.HasAttribute("mul"))
            sizeMul_ = deltaElem.GetFloat("mul");
    }
    
    if (rootElem.HasChild("color"))
        SetColor(rootElem.GetChild("color").GetColor("value"));
    
    if (rootElem.HasChild("colorfade"))
    {
        Vector<ColorFrame> fades;
        XMLElement colorFadeElem = rootElem.GetChild("colorfade");
        while (colorFadeElem)
        {
            fades.Push(ColorFrame(colorFadeElem.GetColor("color"), colorFadeElem.GetFloat("time")));
            
            colorFadeElem = colorFadeElem.GetNext("colorfade");
        }
        SetColors(fades);
    }
    
    if (rootElem.HasChild("texanim"))
    {
        Vector<TextureFrame> animations;
        XMLElement animElem = rootElem.GetChild("texanim");
        while (animElem)
        {
            TextureFrame animation;
            animation.uv_ = animElem.GetRect("uv");
            animation.time_ = animElem.GetFloat("time");
            animations.Push(animation);
            animElem = animElem.GetNext("texanim");
        }
        textureFrames_ = animations;
    }
    
    MarkNetworkUpdate();
    return true;
}
コード例 #11
0
/// Load Communication Logs
bool GameEconomicGameClient::LoadCommunicationLogs(LogFormatType LogType, Vector<CommunicationLog> * TargetLogs)
{
    /// Grab resources
    FileSystem * fileSystem = GetSubsystem<FileSystem>();

    bool success=false;

    /// Create String
    String configFileName;

    /// Set directory and path for network file
    configFileName.Append(fileSystem->GetProgramDir().CString());
    configFileName.Append("CommunicationLogs/DefaultLogs.xml");

    /// If file does not exist exit function with null structure
    if (!fileSystem->FileExists(configFileName))
    {
        cout << "No file found communication log" << endl;
        return false;
    }

    /// Flag file for loading and load
    File loadFile(context_, configFileName, FILE_READ);

    XMLFile * communicationXML = new XMLFile(context_);

    communicationXML -> Load(loadFile);

    XMLElement communicationRootElement =  communicationXML->GetRoot();

    /// If no configuration is set or no root
    if (communicationRootElement.IsNull())
    {
        return false;
    }

    /// Setupload data
    XMLElement TempLogElement;
    String FormatText;

    /// Log log format Personal
    if(LogType == LogFormat_Personal)
    {
        FormatText.Append(String("PersonalLog"));

        TempLogElement = communicationRootElement.GetChild(FormatText);
    }
    else
    {
        return false;
    }

    /// If no network server element return false;
    while(!TempLogElement.IsNull())
    {
        /// Create a temporary log
        CommunicationLog TempLog;

        if (TempLogElement.HasAttribute("LogCreation")) TempLog.Creation= TempLogElement.GetInt("LogCreation");
        if (TempLogElement.HasAttribute("LogTitle")) TempLog.Title = TempLogElement.GetAttribute("LogTitle");
        if (TempLogElement.HasAttribute("LogText")) TempLog.Text = TempLogElement.GetAttribute("LogText");

        TargetLogs->Push(TempLog);

        cout << "Adding" << TempLog.Title.CString()<<endl;

        /// Get next
        TempLogElement=communicationRootElement.GetNext(FormatText);
    }

    return success;
}
コード例 #12
0
ファイル: OGLTexture3D.cpp プロジェクト: codeman001/Urho3D
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;
}
コード例 #13
0
ファイル: TerrySpawner.cpp プロジェクト: practicing01/Terries
Node* TerrySpawner::LoadSprite(String name)
{
	//Vector3 startPos = terrySpawns_->GetChild(Random(0,terrySpawns_->GetNumChildren()))->GetPosition();
	Vector3 startPos = spawnPoint_;

	XMLFile* xmlFile = main_->cache_->GetResource<XMLFile>("Objects/terriesNode.xml");
	Node* spriteNode = scene_->InstantiateXML(xmlFile->GetRoot(),
			startPos, Quaternion::IDENTITY, LOCAL);

	spriteNode->RemoveChild(spriteNode->GetChild("camera"));

	spriteNode->SetName(name);
	spriteNode->AddComponent(new Gravity(context_, main_), 0, LOCAL);
	spriteNode->AddComponent(new Speed(context_, main_), 0, LOCAL);
	//spriteNode->AddComponent(new RotateTo(context_, main_), 0, LOCAL);
	spriteNode->AddComponent(new MoveByTouch(context_, main_), 0, LOCAL);
	spriteNode->AddComponent(new Health(context_, main_), 0, LOCAL);

	spriteNode->GetComponent<MoveByTouch>()->UnsubscribeFromEvent(E_HUDBUTT);

	StaticSprite2D* sprite = spriteNode->CreateComponent<StaticSprite2D>();

	sprite->SetCustomMaterial(SharedPtr<Material>(main_->cache_->GetResource<Material>("Materials/" + name + "Mat.xml")));

	AnimatedSpriteSheet* animatedSpriteSheet = new AnimatedSpriteSheet();
	animatedSpriteSheet->sheet_ = main_->cache_->GetResource<SpriteSheet2D>("Urho2D/" + name + "/" + name + "Sheet.xml");
	animatedSpriteSheet->staticSprite_ = sprite;
	animatedSpriteSheet->playing_ = false;
	animatedSpriteSheet->spriteID_ = spriteIDCount_;
	animatedSpriteSheet->noed_ = spriteNode;
	animatedSpriteSheet->flipX_ = false;

	sprites_.Push(animatedSpriteSheet);

	spriteIDCount_++;

	Vector<String> files;
	files.Push("attackF.xml");
	files.Push("attackM.xml");
	files.Push("dieF.xml");
	files.Push("dieM.xml");
	files.Push("gestureF.xml");
	files.Push("gestureM.xml");
	files.Push("idleF.xml");
	files.Push("idleM.xml");
	files.Push("runF.xml");
	files.Push("runM.xml");

	/*main_->filesystem_->ScanDir(files,
			main_->filesystem_->GetProgramDir() + "Data/Urho2D/" + name + "/animations/",
			"*.xml", SCAN_FILES, false);*/

	for (int x = 0; x < files.Size(); x++)
	{
		XMLElement ani = main_->cache_->GetResource<XMLFile>("Urho2D/" + name + "/animations/" + files[x])->GetRoot();

		SpriteSheetAnimation* spriteSheetAni = new SpriteSheetAnimation();
		animatedSpriteSheet->animations_.Push(spriteSheetAni);

		spriteSheetAni->name_ = ani.GetChild("Name").GetAttribute("name");
		spriteSheetAni->loop_ = ani.GetChild("Loop").GetBool("loop");

		int frameCount = ani.GetChild("FrameCount").GetInt("frameCount");

		for (int x = 0; x < frameCount; x++)
		{
			SpriteSheetAnimationFrame* frame = new SpriteSheetAnimationFrame();
			spriteSheetAni->frames_.Push(frame);

			String child = "Frame" + String(x);

			frame->duration_ = ani.GetChild(child).GetFloat("duration");
			frame->sprite_ = ani.GetChild(child).GetAttribute("sprite");
		}
	}

	bool sex = Random(0,2);
	animatedSpriteSheet->noed_->SetVar("sex",sex);

	VariantMap vm;
	vm[AnimateSpriteSheet::P_NODE] = node_;
	vm[AnimateSpriteSheet::P_SPRITEID] = animatedSpriteSheet->spriteID_;

	if (sex)
	{
		vm[AnimateSpriteSheet::P_ANIMATION] = "idleF";
	}
	else
	{
		vm[AnimateSpriteSheet::P_ANIMATION] = "idleM";
	}

	vm[AnimateSpriteSheet::P_FLIPX] = 0;
	SendEvent(E_ANIMATESPRITESHEET, vm);

	animatedSpriteSheet->noed_->SetVar("collisionCount",0);

	animatedSpriteSheet->noed_->SetVar("attack",1);
	animatedSpriteSheet->noed_->SetVar("attackInterval",1.0f);
	animatedSpriteSheet->noed_->SetVar("attackElapsedTime",0.0f);
	animatedSpriteSheet->noed_->SetVar("canAttack",false);

	animatedSpriteSheet->noed_->SetVar("npcType",1);//0 = hero, 1 = terry

	return spriteNode;
}
コード例 #14
0
ファイル: Material.cpp プロジェクト: Boshin/Urho3D
bool Material::Load(const XMLElement& source)
{
    ResetToDefaults();

    if (source.IsNull())
    {
        LOGERROR("Can not load material from null XML element");
        return false;
    }

    ResourceCache* cache = GetSubsystem<ResourceCache>();

    XMLElement techniqueElem = source.GetChild("technique");
    techniques_.Clear();
    
    while (techniqueElem)
    {
        Technique* tech = cache->GetResource<Technique>(techniqueElem.GetAttribute("name"));
        if (tech)
        {
            TechniqueEntry newTechnique;
            newTechnique.technique_ = tech;
            if (techniqueElem.HasAttribute("quality"))
                newTechnique.qualityLevel_ = techniqueElem.GetInt("quality");
            if (techniqueElem.HasAttribute("loddistance"))
                newTechnique.lodDistance_ = techniqueElem.GetFloat("loddistance");
            techniques_.Push(newTechnique);
        }

        techniqueElem = techniqueElem.GetNext("technique");
    }

    SortTechniques();

    XMLElement textureElem = source.GetChild("texture");
    while (textureElem)
    {
        TextureUnit unit = TU_DIFFUSE;
        if (textureElem.HasAttribute("unit"))
            unit = ParseTextureUnitName(textureElem.GetAttribute("unit"));
        if (unit < MAX_TEXTURE_UNITS)
        {
            String name = textureElem.GetAttribute("name");
            // Detect cube maps by file extension: they are defined by an XML file
            /// \todo Differentiate with 3D textures by actually reading the XML content
            if (GetExtension(name) == ".xml")
            {
                #ifdef DESKTOP_GRAPHICS
                if (unit == TU_VOLUMEMAP)
                    SetTexture(unit, cache->GetResource<Texture3D>(name));
                else
                #endif
                    SetTexture(unit, cache->GetResource<TextureCube>(name));
            }
            else
                SetTexture(unit, cache->GetResource<Texture2D>(name));
        }
        textureElem = textureElem.GetNext("texture");
    }

    batchedParameterUpdate_ = true;
    XMLElement parameterElem = source.GetChild("parameter");
    while (parameterElem)
    {
        String name = parameterElem.GetAttribute("name");
        SetShaderParameter(name, ParseShaderParameterValue(parameterElem.GetAttribute("value")));
        parameterElem = parameterElem.GetNext("parameter");
    }
    batchedParameterUpdate_ = false;

    XMLElement parameterAnimationElem = source.GetChild("parameteranimation");
    while (parameterAnimationElem)
    {
        String name = parameterAnimationElem.GetAttribute("name");
        SharedPtr<ValueAnimation> animation(new ValueAnimation(context_));
        if (!animation->LoadXML(parameterAnimationElem))
        {
            LOGERROR("Could not load parameter animation");
            return false;
        }

        String wrapModeString = parameterAnimationElem.GetAttribute("wrapmode");
        WrapMode wrapMode = WM_LOOP;
        for (int i = 0; i <= WM_CLAMP; ++i)
        {
            if (wrapModeString == wrapModeNames[i])
            {
                wrapMode = (WrapMode)i;
                break;
            }
        }

        float speed = parameterAnimationElem.GetFloat("speed");
        SetShaderParameterAnimation(name, animation, wrapMode, speed);

        parameterAnimationElem = parameterAnimationElem.GetNext("parameteranimation");
    }

    XMLElement cullElem = source.GetChild("cull");
    if (cullElem)
        SetCullMode((CullMode)GetStringListIndex(cullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW));

    XMLElement shadowCullElem = source.GetChild("shadowcull");
    if (shadowCullElem)
        SetShadowCullMode((CullMode)GetStringListIndex(shadowCullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW));

    XMLElement fillElem = source.GetChild("fill");
    if (fillElem)
        SetFillMode((FillMode)GetStringListIndex(fillElem.GetAttribute("value").CString(), fillModeNames, FILL_SOLID));

    XMLElement depthBiasElem = source.GetChild("depthbias");
    if (depthBiasElem)
        SetDepthBias(BiasParameters(depthBiasElem.GetFloat("constant"), depthBiasElem.GetFloat("slopescaled")));

    RefreshShaderParameterHash();
    RefreshMemoryUse();
    CheckOcclusion();
    return true;
}
コード例 #15
0
ファイル: Animation2D.cpp プロジェクト: nexagames/Urho3D
bool Animation2D::Load(Deserializer& source)
{
    frameEndTimes_.Clear();
    frameSprites_.Clear();

    SharedPtr<XMLFile> xmlFile(new XMLFile(context_));
    if(!xmlFile->Load(source))
    {
        LOGERROR("Could not load animation");
        return false;
    }

    SetMemoryUse(source.GetSize());

    XMLElement rootElem = xmlFile->GetRoot("Animation");
    if (!rootElem)
    {
        LOGERROR("Invalid animation");
        return false;
    }

    ResourceCache* cache = GetSubsystem<ResourceCache>();

    XMLElement keyFrameElem = rootElem.GetChild("Frame");
    if (!keyFrameElem)
    {
        LOGERROR("Could not found key frame");
        return false;
    }

    float endTime = 0.0f;

    while (keyFrameElem)
    {
        endTime += keyFrameElem.GetFloat("duration");
        frameEndTimes_.Push(endTime);

        SharedPtr<Sprite2D> sprite;
        Vector<String> names = keyFrameElem.GetAttribute("sprite").Split('@');
        if (names.Size() == 1)
            sprite = cache->GetResource<Sprite2D>(names[0]);
        else if (names.Size() == 2)
        {
            SpriteSheet2D* spriteSheet = cache->GetResource<SpriteSheet2D>(names[0]);
            if (!spriteSheet)
            {
                LOGERROR("Could not get sprite speet");
                return false;
            }

            sprite = spriteSheet->GetSprite(names[1]);
        }

        if (!sprite)
        {
            LOGERROR("Could not get sprite");
            return false;
        }

        frameSprites_.Push(sprite);
        keyFrameElem = keyFrameElem.GetNext("Frame");
    }

    return true;
}
コード例 #16
0
void GameEconomicGameClient::LoadConfiguration(Configuration &configuration)
{
    /// Grab resources
    FileSystem * fileSystem = GetSubsystem<FileSystem>();

    /// Set all defaults
    bool success=false;

    configuration.GameModeForceTablet=false;

    configuration.VideoBloomParam1=0.9f;
    configuration.VideoBloomParam2=0.6f;

    /// Create String
    String configFileName;

    /// Set directory and path for network file
    configFileName.Append(fileSystem->GetProgramDir().CString());
    configFileName.Append("");
    configFileName.Append("Configuration.xml");

    /// If file does not exist exit function with null structure
    if (!fileSystem->FileExists(configFileName))
    {
        cout << "Configuration file not found.. Using defaults.. " << endl;

        return;
    }

    /// Flag file for loading and load
    File loadFile(context_, configFileName, FILE_READ);

    XMLFile * configurationXML = new XMLFile(context_);

    configurationXML -> Load(loadFile);

    XMLElement configElem = configurationXML->GetRoot();

    /// If no configuration is set or no root
    if (configElem.IsNull())
    {
        cout << "Configuration file not found.. Using defaults.. " << endl;

        return;
    }

    /// Basic Config
    XMLElement GameModeConfigurationElem = configElem.GetChild("GameModeConfiguration");

    /// If no network server element return false;
    if (!GameModeConfigurationElem.IsNull())
    {
        if (GameModeConfigurationElem.HasAttribute("GameModeForceTablet")) configuration.GameModeForceTablet = GameModeConfigurationElem.GetBool("GameModeForceTablet");
    }

    /// Basic Config
    XMLElement VideoConfigurationElem = configElem.GetChild("VideoConfiguration");

    /// If no network server element return false;
    if (!VideoConfigurationElem.IsNull())
    {
        if (VideoConfigurationElem.HasAttribute("BloomParam1")) configuration.VideoBloomParam1= VideoConfigurationElem.GetFloat("BloomParam1");
        if (VideoConfigurationElem.HasAttribute("BloomParam2")) configuration.VideoBloomParam2= VideoConfigurationElem.GetFloat("BloomParam2");
    }


    return;
}
コード例 #17
0
ファイル: RenderPath.cpp プロジェクト: ArtemKulyk/Urho3D
void RenderPathCommand::Load(const XMLElement& element)
{
    type_ = (RenderCommandType)GetStringListIndex(element.GetAttributeLower("type").CString(), commandTypeNames, CMD_NONE);
    tag_ = element.GetAttribute("tag");
    if (element.HasAttribute("enabled"))
        enabled_ = element.GetBool("enabled");
    if (element.HasAttribute("metadata"))
        metadata_ = element.GetAttribute("metadata");

    switch (type_)
    {
    case CMD_CLEAR:
        if (element.HasAttribute("color"))
        {
            clearFlags_ |= CLEAR_COLOR;
            if (element.GetAttributeLower("color") == "fog")
                useFogColor_ = true;
            else
                clearColor_ = element.GetColor("color");
        }
        if (element.HasAttribute("depth"))
        {
            clearFlags_ |= CLEAR_DEPTH;
            clearDepth_ = element.GetFloat("depth");
        }
        if (element.HasAttribute("stencil"))
        {
            clearFlags_ |= CLEAR_STENCIL;
            clearStencil_ = (unsigned)element.GetInt("stencil");
        }
        break;

    case CMD_SCENEPASS:
        pass_ = element.GetAttribute("pass");
        sortMode_ =
            (RenderCommandSortMode)GetStringListIndex(element.GetAttributeLower("sort").CString(), sortModeNames, SORT_FRONTTOBACK);
        if (element.HasAttribute("marktostencil"))
            markToStencil_ = element.GetBool("marktostencil");
        if (element.HasAttribute("vertexlights"))
            vertexLights_ = element.GetBool("vertexlights");
        break;

    case CMD_FORWARDLIGHTS:
        pass_ = element.GetAttribute("pass");
        if (element.HasAttribute("uselitbase"))
            useLitBase_ = element.GetBool("uselitbase");
        break;

    case CMD_LIGHTVOLUMES:
    case CMD_QUAD:
        vertexShaderName_ = element.GetAttribute("vs");
        pixelShaderName_ = element.GetAttribute("ps");
        vertexShaderDefines_ = element.GetAttribute("vsdefines");
        pixelShaderDefines_ = element.GetAttribute("psdefines");

        if (type_ == CMD_QUAD)
        {
            if (element.HasAttribute("blend"))
            {
                String blend = element.GetAttributeLower("blend");
                blendMode_ = ((BlendMode)GetStringListIndex(blend.CString(), blendModeNames, BLEND_REPLACE));
            }

            XMLElement parameterElem = element.GetChild("parameter");
            while (parameterElem)
            {
                String name = parameterElem.GetAttribute("name");
                shaderParameters_[name] = Material::ParseShaderParameterValue(parameterElem.GetAttribute("value"));
                parameterElem = parameterElem.GetNext("parameter");
            }
        }
        break;

    default:
        break;
    }

    // By default use 1 output, which is the viewport
    outputs_.Resize(1);
    outputs_[0] = MakePair(String("viewport"), FACE_POSITIVE_X);
    if (element.HasAttribute("output"))
        outputs_[0].first_ = element.GetAttribute("output");
    if (element.HasAttribute("face"))
        outputs_[0].second_ = (CubeMapFace)element.GetInt("face");
    if (element.HasAttribute("depthstencil"))
        depthStencilName_ = element.GetAttribute("depthstencil");
    // Check for defining multiple outputs
    XMLElement outputElem = element.GetChild("output");
    while (outputElem)
    {
        unsigned index = (unsigned)outputElem.GetInt("index");
        if (index < MAX_RENDERTARGETS)
        {
            if (index >= outputs_.Size())
                outputs_.Resize(index + 1);
            outputs_[index].first_ = outputElem.GetAttribute("name");
            outputs_[index].second_ = outputElem.HasAttribute("face") ? (CubeMapFace)outputElem.GetInt("face") : FACE_POSITIVE_X;
        }
        outputElem = outputElem.GetNext("output");
    }

    XMLElement textureElem = element.GetChild("texture");
    while (textureElem)
    {
        TextureUnit unit = TU_DIFFUSE;
        if (textureElem.HasAttribute("unit"))
            unit = ParseTextureUnitName(textureElem.GetAttribute("unit"));
        if (unit < MAX_TEXTURE_UNITS)
        {
            String name = textureElem.GetAttribute("name");
            textureNames_[unit] = name;
        }

        textureElem = textureElem.GetNext("texture");
    }
}
コード例 #18
0
ファイル: Texture3D.cpp プロジェクト: BlueMagnificent/Urho3D
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;
}
コード例 #19
0
void RenderPathCommand::Load(const XMLElement& element)
{
    type_ = (RenderCommandType)GetStringListIndex(element.GetAttributeLower("type").CString(), commandTypeNames, CMD_NONE);
    tag_ = element.GetAttribute("tag");
    if (element.HasAttribute("enabled"))
        enabled_ = element.GetBool("enabled");
    if (element.HasAttribute("metadata"))
        metadata_ = element.GetAttribute("metadata");
    
    switch (type_)
    {
    case CMD_CLEAR:
        if (element.HasAttribute("color"))
        {
            clearFlags_ |= CLEAR_COLOR;
            // Mark fog color with negative values
            if (element.GetAttributeLower("color") == "fog")
                useFogColor_ = true;
            else
                clearColor_ = element.GetColor("color");
        }
        if (element.HasAttribute("depth"))
        {
            clearFlags_ |= CLEAR_DEPTH;
            clearDepth_ = element.GetFloat("depth");
        }
        if (element.HasAttribute("stencil"))
        {
            clearFlags_ |= CLEAR_STENCIL;
            clearStencil_ = element.GetInt("stencil");
        }
        break;
        
    case CMD_SCENEPASS:
        pass_ = element.GetAttribute("pass");
        sortMode_ = (RenderCommandSortMode)GetStringListIndex(element.GetAttributeLower("sort").CString(), sortModeNames, SORT_FRONTTOBACK);
        if (element.HasAttribute("marktostencil"))
            markToStencil_ = element.GetBool("marktostencil");
        if (element.HasAttribute("vertexlights"))
            vertexLights_ = element.GetBool("vertexlights");
        if (element.HasAttribute("usescissor"))
            useScissor_ = element.GetBool("usescissor");
        break;
        
    case CMD_FORWARDLIGHTS:
        pass_ = element.GetAttribute("pass");
        if (element.HasAttribute("uselitbase"))
            useLitBase_ = element.GetBool("uselitbase");
        break;
        
    case CMD_LIGHTVOLUMES:
    case CMD_QUAD:
        vertexShaderName_ = element.GetAttribute("vs");
        pixelShaderName_ = element.GetAttribute("ps");
        if (type_ == CMD_QUAD)
        {
            XMLElement parameterElem = element.GetChild("parameter");
            while (parameterElem)
            {
                String name = parameterElem.GetAttribute("name");
                Variant value = parameterElem.GetVectorVariant("value");
                shaderParameters_[name] = value;
                
                parameterElem = parameterElem.GetNext("parameter");
            }
        }
        break;
    
    default:
        break;
    }
    
    // By default use 1 output, which is the viewport
    outputNames_.Push("viewport");
    if (element.HasAttribute("output"))
        outputNames_[0] = element.GetAttribute("output");
    // Check for defining multiple outputs
    XMLElement outputElem = element.GetChild("output");
    while (outputElem)
    {
        unsigned index = outputElem.GetInt("index");
        if (index < MAX_RENDERTARGETS)
        {
            if (index >= outputNames_.Size())
                outputNames_.Resize(index + 1);
            outputNames_[index] = outputElem.GetAttribute("name");
        }
        outputElem = outputElem.GetNext("output");
    }
    
    XMLElement textureElem = element.GetChild("texture");
    while (textureElem)
    {
        TextureUnit unit = TU_DIFFUSE;
        if (textureElem.HasAttribute("unit"))
        {
            String unitName = textureElem.GetAttributeLower("unit");
            if (unitName.Length() > 1)
                unit = ParseTextureUnitName(unitName);
            else
                unit = (TextureUnit)Clamp(ToInt(unitName), 0, MAX_TEXTURE_UNITS - 1);
        }
        if (unit < MAX_TEXTURE_UNITS)
        {
            String name = textureElem.GetAttribute("name");
            textureNames_[unit] = name;
        }
        
        textureElem = textureElem.GetNext("texture");
    }
}
コード例 #20
0
ファイル: Menu.cpp プロジェクト: 03050903/Urho3D
bool Menu::LoadXML(const XMLElement& source, XMLFile* styleFile, bool setInstanceDefault)
{
    // Get style override if defined
    String styleName = source.GetAttribute("style");

    // Apply the style first, if the style file is available
    if (styleFile)
    {
        // If not defined, use type name
        if (styleName.Empty())
            styleName = GetTypeName();

        SetStyle(styleName, styleFile);
    }
    // The 'style' attribute value in the style file cannot be equals to original's applied style to prevent infinite loop
    else if (!styleName.Empty() && styleName != appliedStyle_)
    {
        // Attempt to use the default style file
        styleFile = GetDefaultStyle();

        if (styleFile)
        {
            // Remember the original applied style
            String appliedStyle(appliedStyle_);
            SetStyle(styleName, styleFile);
            appliedStyle_ = appliedStyle;
        }
    }

    // Then load rest of the attributes from the source
    if (!Serializable::LoadXML(source, setInstanceDefault))
        return false;

    unsigned nextInternalChild = 0;

    // Load child elements. Internal elements are not to be created as they already exist
    XMLElement childElem = source.GetChild("element");
    while (childElem)
    {
        bool internalElem = childElem.GetBool("internal");
        bool popupElem = childElem.GetBool("popup");
        String typeName = childElem.GetAttribute("type");
        if (typeName.Empty())
            typeName = "UIElement";
        unsigned index = childElem.HasAttribute("index") ? childElem.GetUInt("index") : M_MAX_UNSIGNED;
        UIElement* child = 0;

        if (!internalElem)
        {
            if (!popupElem)
                child = CreateChild(typeName, String::EMPTY, index);
            else
            {
                // Do not add the popup element as a child even temporarily, as that can break layouts
                SharedPtr<UIElement> popup = DynamicCast<UIElement>(context_->CreateObject(typeName));
                if (!popup)
                    URHO3D_LOGERROR("Could not create popup element type " + typeName);
                else
                {
                    child = popup;
                    SetPopup(popup);
                }
            }
        }
        else
        {
            // An internal popup element should already exist
            if (popupElem)
                child = popup_;
            else
            {
                for (unsigned i = nextInternalChild; i < children_.Size(); ++i)
                {
                    if (children_[i]->IsInternal() && children_[i]->GetTypeName() == typeName)
                    {
                        child = children_[i];
                        nextInternalChild = i + 1;
                        break;
                    }
                }

                if (!child)
                    URHO3D_LOGWARNING("Could not find matching internal child element of type " + typeName + " in " + GetTypeName());
            }
        }

        if (child)
        {
            if (!styleFile)
                styleFile = GetDefaultStyle();

            // As popup is not a child element in itself, the parental chain to acquire the default style file is broken for popup's child elements
            // To recover from this, popup needs to have the default style set in its own instance so the popup's child elements can find it later
            if (popupElem)
                child->SetDefaultStyle(styleFile);

            if (!child->LoadXML(childElem, styleFile, setInstanceDefault))
                return false;
        }

        childElem = childElem.GetNext("element");
    }

    ApplyAttributes();

    return true;
}
コード例 #21
0
ファイル: Menu.cpp プロジェクト: acremean/urho3d
bool Menu::LoadXML(const XMLElement& source, XMLFile* styleFile)
{
    // Apply the style first, but only for non-internal elements
    if (!internal_ && styleFile)
    {
        // Use style override if defined, otherwise type name
        String styleName = source.GetAttribute("style");
        if (styleName.Empty())
            styleName = GetTypeName();
        
        SetStyle(styleFile, styleName);
    }
    
    // Then load rest of the attributes from the source
    if (!Serializable::LoadXML(source))
        return false;
    
    unsigned nextInternalChild = 0;
    
    // Load child elements. Internal elements are not to be created as they already exist
    XMLElement childElem = source.GetChild("element");
    while (childElem)
    {
        bool internalElem = childElem.GetBool("internal");
        bool popupElem = childElem.GetBool("popup");
        String typeName = childElem.GetAttribute("type");
        if (typeName.Empty())
            typeName = "UIElement";
        UIElement* child = 0;
        
        if (!internalElem)
        {
            if (!popupElem)
                child = CreateChild(ShortStringHash(typeName));
            else
            {
                // Do not add the popup element as a child even temporarily, as that can break layouts
                SharedPtr<UIElement> popup = DynamicCast<UIElement>(context_->CreateObject(ShortStringHash(typeName)));
                if (!popup)
                    LOGERROR("Could not create popup element type " + ShortStringHash(typeName).ToString());
                else
                {
                    child = popup;
                    SetPopup(popup);
                }
            }
        }
        else
        {
            // An internal popup element should already exist
            if (popupElem)
                child = popup_;
            else
            {
                for (unsigned i = nextInternalChild; i < children_.Size(); ++i)
                {
                    if (children_[i]->IsInternal() && children_[i]->GetTypeName() == typeName)
                    {
                        child = children_[i];
                        nextInternalChild = i + 1;
                        break;
                    }
                }
                
                if (!child)
                    LOGWARNING("Could not find matching internal child element of type " + typeName + " in " + GetTypeName());
            }
        }
        
        if (child)
        {
            if (!child->LoadXML(childElem, styleFile))
                return false;
        }
        
        childElem = childElem.GetNext("element");
    }
    
    ApplyAttributes();
    
    return true;
}
コード例 #22
0
ファイル: Technique.cpp プロジェクト: SkunkWorks99/Urho3D
bool Technique::Load(Deserializer& source)
{
    PROFILE(LoadTechnique);
    
    SharedPtr<XMLFile> xml(new XMLFile(context_));
    if (!xml->Load(source))
        return false;
    
    XMLElement rootElem = xml->GetRoot();
    if (rootElem.HasAttribute("sm3"))
        isSM3_ = rootElem.GetBool("sm3");
    
    unsigned numPasses = 0;
    
    XMLElement passElem = rootElem.GetChild("pass");
    while (passElem)
    {
        if (passElem.HasAttribute("name"))
        {
            StringHash nameHash(passElem.GetAttribute("name"));
            Pass* newPass = CreatePass(nameHash);
            ++numPasses;
            
            if (passElem.HasAttribute("vs"))
                newPass->SetVertexShader(passElem.GetAttribute("vs"));
            
            if (passElem.HasAttribute("ps"))
                newPass->SetPixelShader(passElem.GetAttribute("ps"));
            
            if (passElem.HasAttribute("lighting"))
            {
                String lighting = passElem.GetAttributeLower("lighting");
                newPass->SetLightingMode((PassLightingMode)GetStringListIndex(lighting.CString(), lightingModeNames,
                    LIGHTING_UNLIT));
            }
            
            if (passElem.HasAttribute("blend"))
            {
                String blend = passElem.GetAttributeLower("blend");
                newPass->SetBlendMode((BlendMode)GetStringListIndex(blend.CString(), blendModeNames, BLEND_REPLACE));
            }
            
            if (passElem.HasAttribute("depthtest"))
            {
                String depthTest = passElem.GetAttributeLower("depthtest");
                if (depthTest == "false")
                    newPass->SetDepthTestMode(CMP_ALWAYS);
                else
                    newPass->SetDepthTestMode((CompareMode)GetStringListIndex(depthTest.CString(), compareModeNames, CMP_LESS));
            }
            
            if (passElem.HasAttribute("depthwrite"))
                newPass->SetDepthWrite(passElem.GetBool("depthwrite"));
            
            if (passElem.HasAttribute("alphamask"))
                newPass->SetAlphaMask(passElem.GetBool("alphamask"));
        }
        else
            LOGERROR("Missing pass name");
        
        passElem = passElem.GetNext("pass");
    }
    
    // Calculate memory use
    unsigned memoryUse = sizeof(Technique) + numPasses * sizeof(Pass);
    SetMemoryUse(memoryUse);
    return true;
}
コード例 #23
0
ファイル: TileMapDefs2D.cpp プロジェクト: dreamsxin/Urho3D
void PropertySet2D::Load(const XMLElement& element)
{
    assert(element.GetName() == "properties");
    for (XMLElement propertyElem = element.GetChild("property"); propertyElem; propertyElem = propertyElem.GetNext("property"))
        nameToValueMapping_[propertyElem.GetAttribute("name")] = propertyElem.GetAttribute("value");
}
コード例 #24
0
ファイル: Animation.cpp プロジェクト: CarloMaker/Urho3D
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;
}
コード例 #25
0
ファイル: Animation.cpp プロジェクト: dreamsxin/Urho3D
bool Animation::BeginLoad(Deserializer& source)
{
    unsigned memoryUse = sizeof(Animation);

    // Check ID
    if (source.ReadFileID() != "UANI")
    {
        URHO3D_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();
    memoryUse += tracks * sizeof(AnimationTrack);

    // Read tracks
    for (unsigned i = 0; i < tracks; ++i)
    {
        AnimationTrack* newTrack = CreateTrack(source.ReadString());
        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");

    SharedPtr<XMLFile> file(cache->GetTempResource<XMLFile>(xmlName, false));
    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;
    }

    // Optionally read triggers from a JSON file
    String jsonName = ReplaceExtension(GetName(), ".json");

    SharedPtr<JSONFile> jsonFile(cache->GetTempResource<JSONFile>(jsonName, false));
    if (jsonFile)
    {
        const JSONValue& rootVal = jsonFile->GetRoot();
        JSONArray triggerArray = rootVal.Get("triggers").GetArray();

        for (unsigned i = 0; i < triggerArray.Size(); i++)
        {
            const JSONValue& triggerValue = triggerArray.At(i);
            JSONValue normalizedTimeValue = triggerValue.Get("normalizedTime");
            if (!normalizedTimeValue.IsNull())
                AddTrigger(normalizedTimeValue.GetFloat(), true, triggerValue.GetVariant());
            else
            {
                JSONValue timeVal = triggerValue.Get("time");
                if (!timeVal.IsNull())
                    AddTrigger(timeVal.GetFloat(), false, triggerValue.GetVariant());
            }
        }

        memoryUse += triggers_.Size() * sizeof(AnimationTriggerPoint);
        SetMemoryUse(memoryUse);
        return true;
    }

    SetMemoryUse(memoryUse);
    return true;
}
コード例 #26
0
ファイル: Material.cpp プロジェクト: SkunkWorks99/Urho3D
bool Material::Load(const XMLElement& source)
{
    ResetToDefaults();
    
    if (source.IsNull())
    {
        LOGERROR("Can not load material from null XML element");
        return false;
    }
    
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    
    XMLElement techniqueElem = source.GetChild("technique");
    techniques_.Clear();
    while (techniqueElem)
    {
        Technique* tech = cache->GetResource<Technique>(techniqueElem.GetAttribute("name"));
        if (tech)
        {
            TechniqueEntry newTechnique;
            newTechnique.technique_ = tech;
            if (techniqueElem.HasAttribute("quality"))
                newTechnique.qualityLevel_ = techniqueElem.GetInt("quality");
            if (techniqueElem.HasAttribute("loddistance"))
                newTechnique.lodDistance_ = techniqueElem.GetFloat("loddistance");
            techniques_.Push(newTechnique);
        }
        techniqueElem = techniqueElem.GetNext("technique");
    }
    
    SortTechniques();
    
    XMLElement textureElem = source.GetChild("texture");
    while (textureElem)
    {
        TextureUnit unit = TU_DIFFUSE;
        if (textureElem.HasAttribute("unit"))
        {
            String unitName = textureElem.GetAttributeLower("unit");
            if (unitName.Length() > 1)
            {
                unit = ParseTextureUnitName(unitName);
                if (unit >= MAX_MATERIAL_TEXTURE_UNITS)
                    LOGERROR("Unknown or illegal texture unit " + unitName);
            }
            else
                unit = (TextureUnit)Clamp(ToInt(unitName), 0, MAX_MATERIAL_TEXTURE_UNITS - 1);
        }
        if (unit != MAX_MATERIAL_TEXTURE_UNITS)
        {
            String name = textureElem.GetAttribute("name");
            // Detect cube maps by file extension: they are defined by an XML file
            if (GetExtension(name) == ".xml")
                SetTexture(unit, cache->GetResource<TextureCube>(name));
            else
                SetTexture(unit, cache->GetResource<Texture2D>(name));
        }
        textureElem = textureElem.GetNext("texture");
    }
    
    XMLElement parameterElem = source.GetChild("parameter");
    while (parameterElem)
    {
        String name = parameterElem.GetAttribute("name");
        SetShaderParameter(name, ParseShaderParameterValue(parameterElem.GetAttribute("value")));
        parameterElem = parameterElem.GetNext("parameter");
    }
    
    XMLElement cullElem = source.GetChild("cull");
    if (cullElem)
        SetCullMode((CullMode)GetStringListIndex(cullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW));
    
    XMLElement shadowCullElem = source.GetChild("shadowcull");
    if (shadowCullElem)
        SetShadowCullMode((CullMode)GetStringListIndex(shadowCullElem.GetAttribute("value").CString(), cullModeNames, CULL_CCW));
    
    XMLElement depthBiasElem = source.GetChild("depthbias");
    if (depthBiasElem)
        SetDepthBias(BiasParameters(depthBiasElem.GetFloat("constant"), depthBiasElem.GetFloat("slopescaled")));
    
    // Calculate memory use
    unsigned memoryUse = sizeof(Material);
    
    memoryUse += techniques_.Size() * sizeof(TechniqueEntry);
    memoryUse += MAX_MATERIAL_TEXTURE_UNITS * sizeof(SharedPtr<Texture>);
    memoryUse += shaderParameters_.Size() * sizeof(MaterialShaderParameter);
    
    SetMemoryUse(memoryUse);
    CheckOcclusion();
    return true;
}
コード例 #27
0
bool ParticleEffect::Load(const XMLElement& source)
{
    // Reset to defaults first so that missing parameters in case of a live reload behave as expected
    material_.Reset();
    numParticles_ = DEFAULT_NUM_PARTICLES;
    updateInvisible_ = false;
    relative_ = true;
    scaled_ = true;
    sorted_ = false;
    fixedScreenSize_ = false;
    animationLodBias_ = 0.0f;
    emitterType_ = EMITTER_SPHERE;
    emitterSize_ = Vector3::ZERO;
    directionMin_ = DEFAULT_DIRECTION_MIN;
    directionMax_ = DEFAULT_DIRECTION_MAX;
    constantForce_ = Vector3::ZERO;
    dampingForce_ = 0.0f;
    activeTime_ = 0.0f;
    inactiveTime_ = 0.0;
    emissionRateMin_ = DEFAULT_EMISSION_RATE;
    emissionRateMax_ = DEFAULT_EMISSION_RATE;
    sizeMin_ = DEFAULT_PARTICLE_SIZE;
    sizeMax_ = DEFAULT_PARTICLE_SIZE;
    timeToLiveMin_ = DEFAULT_TIME_TO_LIVE;
    timeToLiveMax_ = DEFAULT_TIME_TO_LIVE;
    velocityMin_ = DEFAULT_VELOCITY;
    velocityMax_ = DEFAULT_VELOCITY;
    rotationMin_ = 0.0f;
    rotationMax_ = 0.0f;
    rotationSpeedMin_ = 0.0f;
    rotationSpeedMax_ = 0.0f;
    sizeAdd_ = 0.0f;
    sizeMul_ = 1.0f;
    colorFrames_.Clear();
    textureFrames_.Clear();
    faceCameraMode_ = FC_ROTATE_XYZ;

    if (source.IsNull())
    {
        URHO3D_LOGERROR("Can not load particle effect from null XML element");
        return false;
    }

    if (source.HasChild("material"))
    {
        loadMaterialName_ = source.GetChild("material").GetAttribute("name");
        // If async loading, can not GetResource() the material. But can do a background request for it
        if (GetAsyncLoadState() == ASYNC_LOADING)
            GetSubsystem<ResourceCache>()->BackgroundLoadResource<Material>(loadMaterialName_, true, this);
    }

    if (source.HasChild("numparticles"))
        SetNumParticles((unsigned)source.GetChild("numparticles").GetInt("value"));

    if (source.HasChild("updateinvisible"))
        updateInvisible_ = source.GetChild("updateinvisible").GetBool("enable");

    if (source.HasChild("relative"))
        relative_ = source.GetChild("relative").GetBool("enable");

    if (source.HasChild("scaled"))
        scaled_ = source.GetChild("scaled").GetBool("enable");

    if (source.HasChild("sorted"))
        sorted_ = source.GetChild("sorted").GetBool("enable");

    if (source.HasChild("fixedscreensize"))
        fixedScreenSize_ = source.GetChild("fixedscreensize").GetBool("enable");

    if (source.HasChild("animlodbias"))
        SetAnimationLodBias(source.GetChild("animlodbias").GetFloat("value"));

    if (source.HasChild("emittertype"))
    {
        String type = source.GetChild("emittertype").GetAttributeLower("value");
        if (type == "point")
        {
            // Point emitter type is deprecated, handled as zero sized sphere
            emitterType_ = EMITTER_SPHERE;
            emitterSize_ = Vector3::ZERO;
        }
        else
            emitterType_ = (EmitterType)GetStringListIndex(type.CString(), emitterTypeNames, EMITTER_SPHERE);
    }

    if (source.HasChild("emittersize"))
        emitterSize_ = source.GetChild("emittersize").GetVector3("value");

    if (source.HasChild("emitterradius"))
        emitterSize_.x_ = emitterSize_.y_ = emitterSize_.z_ = source.GetChild("emitterradius").GetFloat("value");

    if (source.HasChild("direction"))
        GetVector3MinMax(source.GetChild("direction"), directionMin_, directionMax_);

    if (source.HasChild("constantforce"))
        constantForce_ = source.GetChild("constantforce").GetVector3("value");

    if (source.HasChild("dampingforce"))
        dampingForce_ = source.GetChild("dampingforce").GetFloat("value");

    if (source.HasChild("activetime"))
        activeTime_ = source.GetChild("activetime").GetFloat("value");
    if (activeTime_ < 0.0f)
        activeTime_ = M_INFINITY;

    if (source.HasChild("inactivetime"))
        inactiveTime_ = source.GetChild("inactivetime").GetFloat("value");
    if (inactiveTime_ < 0.0f)
        inactiveTime_ = M_INFINITY;

    if (source.HasChild("emissionrate"))
        GetFloatMinMax(source.GetChild("emissionrate"), emissionRateMin_, emissionRateMax_);

    if (source.HasChild("interval"))
    {
        float intervalMin = 0.0f;
        float intervalMax = 0.0f;
        GetFloatMinMax(source.GetChild("interval"), intervalMin, intervalMax);
        emissionRateMax_ = 1.0f / intervalMin;
        emissionRateMin_ = 1.0f / intervalMax;
    }

    if (source.HasChild("particlesize"))
        GetVector2MinMax(source.GetChild("particlesize"), sizeMin_, sizeMax_);

    if (source.HasChild("timetolive"))
        GetFloatMinMax(source.GetChild("timetolive"), timeToLiveMin_, timeToLiveMax_);

    if (source.HasChild("velocity"))
        GetFloatMinMax(source.GetChild("velocity"), velocityMin_, velocityMax_);

    if (source.HasChild("rotation"))
        GetFloatMinMax(source.GetChild("rotation"), rotationMin_, rotationMax_);

    if (source.HasChild("rotationspeed"))
        GetFloatMinMax(source.GetChild("rotationspeed"), rotationSpeedMin_, rotationSpeedMax_);

    if (source.HasChild("faceCameraMode"))
    {
        String type = source.GetChild("faceCameraMode").GetAttributeLower("value");
        faceCameraMode_ = (FaceCameraMode)GetStringListIndex(type.CString(), faceCameraModeNames, FC_ROTATE_XYZ);
    }

    if (source.HasChild("sizedelta"))
    {
        XMLElement deltaElem = source.GetChild("sizedelta");
        if (deltaElem.HasAttribute("add"))
            sizeAdd_ = deltaElem.GetFloat("add");
        if (deltaElem.HasAttribute("mul"))
            sizeMul_ = deltaElem.GetFloat("mul");
    }

    if (source.HasChild("color"))
    {
        ColorFrame colorFrame(source.GetChild("color").GetColor("value"));
        SetColorFrame(0, colorFrame);
    }

    if (source.HasChild("colorfade"))
    {
        Vector<ColorFrame> fades;
        for (XMLElement colorFadeElem = source.GetChild("colorfade"); colorFadeElem;
             colorFadeElem = colorFadeElem.GetNext("colorfade"))
            fades.Push(ColorFrame(colorFadeElem.GetColor("color"), colorFadeElem.GetFloat("time")));

        SetColorFrames(fades);
    }

    if (colorFrames_.Empty())
        colorFrames_.Push(ColorFrame(Color::WHITE));

    if (source.HasChild("texanim"))
    {
        Vector<TextureFrame> animations;
        for (XMLElement animElem = source.GetChild("texanim"); animElem; animElem = animElem.GetNext("texanim"))
        {
            TextureFrame animation;
            animation.uv_ = animElem.GetRect("uv");
            animation.time_ = animElem.GetFloat("time");
            animations.Push(animation);
        }

        SetTextureFrames(animations);
    }

    return true;
}
コード例 #28
0
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");
    }
}
コード例 #29
0
bool ParticleEffect2D::Load(Deserializer& source)
{
    XMLFile xmlFile(context_);
    if (!xmlFile.Load(source))
        return false;

    XMLElement rootElem = xmlFile.GetRoot("particleEmitterConfig");
    if (!rootElem)
        return false;

    String texture = rootElem.GetChild("texture").GetAttribute("name");
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    sprite_= cache->GetResource<Sprite2D>(texture, false);
    // If sprite not found, try get in current directory
    if (!sprite_)
        sprite_= cache->GetResource<Sprite2D>(GetParentPath(GetName()) + texture);

    if (!sprite_)
        return false;

    sourcePositionVariance_ = ReadVector2(rootElem.GetChild("sourcePositionVariance"));

    speed_ = rootElem.GetChild("speed").GetFloat("value");
    speedVariance_ = rootElem.GetChild("speedVariance").GetFloat("value");
    
    particleLifeSpan_ = Max(0.01f, rootElem.GetChild("particleLifeSpan").GetFloat("value"));
    particleLifespanVariance_ = rootElem.GetChild("particleLifespanVariance").GetFloat("value");
    
    angle_ = rootElem.GetChild("angle").GetFloat("value");
    angleVariance_ = rootElem.GetChild("angleVariance").GetFloat("value");
    
    gravity_ = ReadVector2(rootElem.GetChild("gravity"));

    radialAcceleration_ = rootElem.GetChild("radialAcceleration").GetFloat("value");
    tangentialAcceleration_ = rootElem.GetChild("tangentialAcceleration").GetFloat("value");
    
    radialAccelVariance_ = rootElem.GetChild("radialAccelVariance").GetFloat("value");
    tangentialAccelVariance_ = rootElem.GetChild("tangentialAccelVariance").GetFloat("value");

    startColor_ = ReadColor(rootElem.GetChild("startColor"));
    startColorVariance_ = ReadColor(rootElem.GetChild("startColorVariance"));
    
    finishColor_ = ReadColor(rootElem.GetChild("finishColor"));
    finishColorVariance_ = ReadColor(rootElem.GetChild("finishColorVariance"));

    maxParticles_ = rootElem.GetChild("maxParticles").GetInt("value");
    
    startParticleSize_ = rootElem.GetChild("startParticleSize").GetFloat("value");
    startParticleSizeVariance_ = rootElem.GetChild("startParticleSizeVariance").GetFloat("value");
    
    finishParticleSize_ = rootElem.GetChild("finishParticleSize").GetFloat("value");
    FinishParticleSizeVariance_ = rootElem.GetChild("FinishParticleSizeVariance").GetFloat("value");
    
    duration_ = M_INFINITY;
    if (rootElem.HasChild("duration"))
    {
        float duration = rootElem.GetChild("duration").GetFloat("value");
        if (duration > 0.0f)
            duration_ = duration;
    }


    emitterType_ = (EmitterType2D)rootElem.GetChild("emitterType").GetInt("value");
    
    maxRadius_ = rootElem.GetChild("maxRadius").GetFloat("value");
    maxRadiusVariance_ = rootElem.GetChild("maxRadiusVariance").GetFloat("value");
    minRadius_ = rootElem.GetChild("minRadius").GetFloat("value");

    rotatePerSecond_ = rootElem.GetChild("rotatePerSecond").GetFloat("value");
    rotatePerSecondVariance_ = rootElem.GetChild("rotatePerSecondVariance").GetFloat("value");
    
    int blendFuncSource = rootElem.GetChild("blendFuncSource").GetInt("value");
    int blendFuncDestination = rootElem.GetChild("blendFuncDestination").GetInt("value");
    blendMode_ = BLEND_ALPHA;
    for (int i = 0; i < MAX_BLENDMODES; ++i)
    {
        if (blendFuncSource == srcBlendFuncs[i] && blendFuncDestination == destBlendFuncs[i])
        {
            blendMode_ = (BlendMode)i;
            break;
        }
    }

    rotationStart_ = rootElem.GetChild("rotationStart").GetFloat("value");
    rotationStartVariance_ = rootElem.GetChild("rotationStartVariance").GetFloat("value");
    
    rotationEnd_ = rootElem.GetChild("rotationEnd").GetFloat("value");
    rotationEndVariance_ = rootElem.GetChild("rotationEndVariance").GetFloat("value");

    return true;
}
コード例 #30
0
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");
            }
        }
    }
}