コード例 #1
0
ファイル: Animatable.cpp プロジェクト: ViteFalcon/Urho3D
bool Animatable::SaveXML(XMLElement& dest) const
{
    if (!Serializable::SaveXML(dest))
        return false;

    // Object animation without name
    if (objectAnimation_ && objectAnimation_->GetName().Empty())
    {
        XMLElement elem = dest.CreateChild("objectanimation");
        if (!objectAnimation_->SaveXML(elem))
            return false;
    }

    for (HashMap<String, SharedPtr<AttributeAnimationInfo> >::ConstIterator i = attributeAnimationInfos_.Begin(); i != attributeAnimationInfos_.End(); ++i)
    {
        ValueAnimation* attributeAnimation = i->second_->GetAnimation();
        if (attributeAnimation->GetOwner())
            continue;

        const AttributeInfo& attr = i->second_->GetAttributeInfo();
        XMLElement elem = dest.CreateChild("attributeanimation");
        elem.SetAttribute("name", attr.name_);
        if (!attributeAnimation->SaveXML(elem))
            return false;

        elem.SetAttribute("wrapmode", wrapModeNames[i->second_->GetWrapMode()]);
        elem.SetFloat("speed", i->second_->GetSpeed());
    }

    return true;
}
コード例 #2
0
ファイル: Node.cpp プロジェクト: acremean/urho3d
bool Node::SaveXML(XMLElement& dest)
{
    // Write node ID
    if (!dest.SetInt("id", id_))
        return false;
    
    // Write attributes
    if (!Serializable::SaveXML(dest))
        return false;
    
    // Write components
    for (unsigned i = 0; i < components_.Size(); ++i)
    {
        Component* component = components_[i];
        XMLElement compElem = dest.CreateChild("component");
        if (!component->SaveXML(compElem))
            return false;
    }
    
    // Write child nodes
    for (unsigned i = 0; i < children_.Size(); ++i)
    {
        Node* node = children_[i];
        XMLElement childElem = dest.CreateChild("node");
        if (!node->SaveXML(childElem))
            return false;
    }
    
    return true;
}
コード例 #3
0
bool ValueAnimation::SaveXML(XMLElement& dest) const
{
    dest.SetAttribute("interpolationmethod", interpMethodNames[interpolationMethod_]);
    if (interpolationMethod_ == IM_SPLINE)
        dest.SetFloat("splinetension", splineTension_);

    for (unsigned i = 0; i < keyFrames_.Size(); ++i)
    {
        const VAnimKeyFrame& keyFrame = keyFrames_[i];
        XMLElement keyFrameEleme = dest.CreateChild("keyframe");
        keyFrameEleme.SetFloat("time", keyFrame.time_);
        keyFrameEleme.SetVariant(keyFrame.value_);
    }

    for (unsigned i = 0; i < eventFrames_.Size(); ++i)
    {
        const VAnimEventFrame& eventFrame = eventFrames_[i];
        XMLElement eventFrameElem = dest.CreateChild("eventframe");
        eventFrameElem.SetFloat("time", eventFrame.time_);
        eventFrameElem.SetUInt("eventtype", eventFrame.eventType_.Value());
        eventFrameElem.CreateChild("eventdata").SetVariantMap(eventFrame.eventData_);
    }

    return true;
}
コード例 #4
0
ファイル: Menu.cpp プロジェクト: acremean/urho3d
bool Menu::SaveXML(XMLElement& dest)
{
    // Write type and internal flag
    if (!dest.SetString("type", GetTypeName()))
        return false;
    if (internal_)
    {
        if (!dest.SetBool("internal", internal_))
            return false;
    }
    
    // Write attributes
    if (!Serializable::SaveXML(dest))
        return false;
    
    // Write child elements
    for (unsigned i = 0; i < children_.Size(); ++i)
    {
        UIElement* element = children_[i];
        XMLElement childElem = dest.CreateChild("element");
        if (!element->SaveXML(childElem))
            return false;
    }
    
    // Save the popup element as a "virtual" child element
    if (popup_)
    {
        XMLElement childElem = dest.CreateChild("element");
        childElem.SetBool("popup", true);
        if (!popup_->SaveXML(childElem))
            return false;
    }
    
    return true;
}
コード例 #5
0
/// Save account information to a file
void GameEconomicGameClient::SaveConfiguration(Configuration &configuration)
{
    /// Get Resource
    ResourceCache * cache = GetSubsystem<ResourceCache>();
    FileSystem * fileSystem = GetSubsystem<FileSystem>();

    String configFileName;

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


    /// Check if the account file information exist
    if(fileSystem->FileExists(configFileName.CString()))
    {
        fileSystem->Delete(configFileName.CString());
    }

    cout << "It got here "<<endl;

    File saveFile(context_, configFileName.CString(), FILE_WRITE);

    XMLFile * preferencefileconfig  = new XMLFile(context_);

    XMLElement configElem = preferencefileconfig   -> CreateRoot("Configuration");
    XMLElement GameModeConfigurationElement = configElem.CreateChild("GameModeConfiguration");
    XMLElement VideoConfigurationElement= configElem.CreateChild("VideoConfiguration");

    /// Set true false
    if(configuration.GameModeForceTablet==true)
    {
        GameModeConfigurationElement.SetAttribute("GameModeForceTablet", "true");
    }
    else
    {
        GameModeConfigurationElement.SetAttribute("GameModeForceTablet", "false");
    }

    /// Convert video bloom to float
    String VideoBloomParamValue1String(configuration.VideoBloomParam1);
    String VideoBloomParamValue2String(configuration.VideoBloomParam2);

    /// Copy values testing
    VideoConfigurationElement.SetAttribute("BloomParam1",VideoBloomParamValue1String);
    VideoConfigurationElement.SetAttribute("BloomParam2",VideoBloomParamValue2String);

    preferencefileconfig->Save(saveFile);

    return;
}
コード例 #6
0
ファイル: UnknownComponent.cpp プロジェクト: Hevedy/Urho3D
bool UnknownComponent::SaveXML(XMLElement& dest) const
{
    if (dest.IsNull())
    {
        LOGERROR("Could not save " + GetTypeName() + ", null destination element");
        return false;
    }
    
    if (!useXML_)
        LOGWARNING("UnknownComponent loaded in binary mode, attributes will be empty for XML save");
    
    // Write type and ID
    if (!dest.SetString("type", GetTypeName()))
        return false;
    if (!dest.SetInt("id", id_))
        return false;
    
    for (unsigned i = 0; i < xmlAttributeInfos_.Size(); ++i)
    {
        XMLElement attrElem = dest.CreateChild("attribute");
        attrElem.SetAttribute("name", xmlAttributeInfos_[i].name_);
        attrElem.SetAttribute("value", xmlAttributes_[i]);
    }
    
    return true;
}
コード例 #7
0
bool Animation::Save(Serializer& dest) const
{
    // Write ID, name and length
    dest.WriteFileID("UANI");
    dest.WriteString(animationName_);
    dest.WriteFloat(length_);

    // Write tracks
    dest.WriteUInt(tracks_.Size());
    for (HashMap<StringHash, AnimationTrack>::ConstIterator i = tracks_.Begin(); i != tracks_.End(); ++i)
    {
        const AnimationTrack& track = i->second_;
        dest.WriteString(track.name_);
        dest.WriteUByte(track.channelMask_);
        dest.WriteUInt(track.keyFrames_.Size());

        // Write keyframes of the track
        for (unsigned j = 0; j < track.keyFrames_.Size(); ++j)
        {
            const 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_);
        }
    }

    // If triggers have been defined, write an XML file for them
    if (!triggers_.Empty() || HasMetadata())
    {
        File* destFile = dynamic_cast<File*>(&dest);
        if (destFile)
        {
            String xmlName = ReplaceExtension(destFile->GetName(), ".xml");

            SharedPtr<XMLFile> xml(new XMLFile(context_));
            XMLElement rootElem = xml->CreateRoot("animation");

            for (unsigned i = 0; i < triggers_.Size(); ++i)
            {
                XMLElement triggerElem = rootElem.CreateChild("trigger");
                triggerElem.SetFloat("time", triggers_[i].time_);
                triggerElem.SetVariant(triggers_[i].data_);
            }

            SaveMetadataToXML(rootElem);

            File xmlFile(context_, xmlName, FILE_WRITE);
            xml->Save(xmlFile);
        }
        else
            ATOMIC_LOGWARNING("Can not save animation trigger data when not saving into a file");
    }

    return true;
}
コード例 #8
0
ファイル: ParticleEffect2D.cpp プロジェクト: aster2013/Urho3D
void ParticleEffect2D::WriteColor(XMLElement& element, const String& name, const Color& color) const
{
	XMLElement child = element.CreateChild(name);
	child.SetFloat("red", color.r_);
	child.SetFloat("green", color.g_);
	child.SetFloat("blue", color.b_);
	child.SetFloat("alpha", color.a_);
}
コード例 #9
0
void CubemapGenerator::SaveCubemapXML()
{
    SharedPtr<XMLFile> xmlFile(new XMLFile(context_));
    XMLElement rootElem = xmlFile->CreateRoot("cubemap");

    String prefix = resourcePath_ + namePrefix_ + "_";

    String name = prefix + GetFaceName(FACE_POSITIVE_X) + ".png";
    rootElem.CreateChild("face").SetAttribute("name", name);
    name = prefix + GetFaceName(FACE_NEGATIVE_X) + ".png";
    rootElem.CreateChild("face").SetAttribute("name", name);
    name = prefix + GetFaceName(FACE_POSITIVE_Y) + ".png";
    rootElem.CreateChild("face").SetAttribute("name", name);
    name = prefix + GetFaceName(FACE_NEGATIVE_Y) + ".png";
    rootElem.CreateChild("face").SetAttribute("name", name);
    name = prefix + GetFaceName(FACE_POSITIVE_Z) + ".png";
    rootElem.CreateChild("face").SetAttribute("name", name);
    name = prefix + GetFaceName(FACE_NEGATIVE_Z) + ".png";
    rootElem.CreateChild("face").SetAttribute("name", name);

    String xmlPath = outputPathAbsolute_ + namePrefix_ + ".xml";

    SharedPtr<File> file(new File(context_, xmlPath, FILE_WRITE));
    xmlFile->Save(*file, "    ");
    file->Close();

    ResourceCache* cache = GetSubsystem<ResourceCache>();
    TextureCube* texcube = cache->GetResource<TextureCube>(resourcePath_ + namePrefix_ + ".xml");
    if (texcube)
        cache->ReloadResource(texcube);

}
コード例 #10
0
ファイル: Material.cpp プロジェクト: SkunkWorks99/Urho3D
bool Material::Save(XMLElement& dest) const
{
    if (dest.IsNull())
    {
        LOGERROR("Can not save material to null XML element");
        return false;
    }
    
    // Write techniques
    for (unsigned i = 0; i < techniques_.Size(); ++i)
    {
        const TechniqueEntry& entry = techniques_[i];
        if (!entry.technique_)
            continue;
        
        XMLElement techniqueElem = dest.CreateChild("technique");
        techniqueElem.SetString("name", entry.technique_->GetName());
        techniqueElem.SetInt("quality", entry.qualityLevel_);
        techniqueElem.SetFloat("loddistance", entry.lodDistance_);
    }
    
    // Write texture units
    for (unsigned j = 0; j < MAX_MATERIAL_TEXTURE_UNITS; ++j)
    {
        Texture* texture = GetTexture((TextureUnit)j);
        if (texture)
        {
            XMLElement textureElem = dest.CreateChild("texture");
            textureElem.SetString("unit", textureUnitNames[j]);
            textureElem.SetString("name", texture->GetName());
        }
    }
    
    // Write shader parameters
    for (HashMap<StringHash, MaterialShaderParameter>::ConstIterator j = shaderParameters_.Begin(); j != shaderParameters_.End(); ++j)
    {
        XMLElement parameterElem = dest.CreateChild("parameter");
        parameterElem.SetString("name", j->second_.name_);
        parameterElem.SetVectorVariant("value", j->second_.value_);
    }
    
    // Write culling modes
    XMLElement cullElem = dest.CreateChild("cull");
    cullElem.SetString("value", cullModeNames[cullMode_]);
    
    XMLElement shadowCullElem = dest.CreateChild("shadowcull");
    shadowCullElem.SetString("value", cullModeNames[shadowCullMode_]);
    
    // Write depth bias
    XMLElement depthBiasElem = dest.CreateChild("depthbias");
    depthBiasElem.SetFloat("constant", depthBias_.constantBias_);
    depthBiasElem.SetFloat("slopescaled", depthBias_.slopeScaledBias_);
    
    return true;
}
コード例 #11
0
ファイル: ObjectAnimation.cpp プロジェクト: Boshin/Urho3D
bool ObjectAnimation::SaveXML(XMLElement& dest) const
{
    for (HashMap<String, SharedPtr<ValueAnimationInfo> >::ConstIterator i = attributeAnimationInfos_.Begin(); i != attributeAnimationInfos_.End(); ++i)
    {
        XMLElement animElem = dest.CreateChild("attributeanimation");
        animElem.SetAttribute("name", i->first_);

        const ValueAnimationInfo* info = i->second_;
        if (!info->GetAnimation()->SaveXML(animElem))
            return false;

        animElem.SetAttribute("wrapmode", wrapModeNames[info->GetWrapMode()]);
        animElem.SetFloat("speed", info->GetSpeed());
    }

    return true;
}
コード例 #12
0
ファイル: SpriteSheet2D.cpp プロジェクト: AGreatFish/Urho3D
bool SpriteSheet2D::Save(Serializer& dest) const
{
    if (!texture_)
        return false;

    SharedPtr<XMLFile> xmlFile(new XMLFile(context_));    
    XMLElement rootElem = xmlFile->CreateRoot("spritesheet");
    rootElem.SetAttribute("texture", texture_->GetName());

    for (HashMap<String, SharedPtr<Sprite2D> >::ConstIterator i = spriteMapping_.Begin(); i != spriteMapping_.End(); ++i)
    {
        XMLElement spriteElem = rootElem.CreateChild("sprite");
        spriteElem.SetAttribute("name", i->first_);
        Sprite2D* sprite = i->second_;
        spriteElem.SetIntRect("rectangle", sprite->GetRectangle());
        spriteElem.SetVector2("hotspot", sprite->GetHotSpot());
    }

    return xmlFile->Save(dest);
}
コード例 #13
0
ファイル: Animation2D.cpp プロジェクト: nexagames/Urho3D
bool Animation2D::Save(Serializer& dest) const
{
    XMLFile xmlFile(context_);
    XMLElement rootElem = xmlFile.CreateRoot("Animation");
    
    float endTime = 0.0f;
    for (unsigned i = 0; i < frameSprites_.Size(); ++i)
    {
        XMLElement frameElem = rootElem.CreateChild("Frame");
        frameElem.SetFloat("duration", frameEndTimes_[i] - endTime);
        endTime = frameEndTimes_[i];

        Sprite2D* sprite = frameSprites_[i];
        SpriteSheet2D* spriteSheet = sprite->GetSpriteSheet();
        if (!spriteSheet)
            frameElem.SetString("sprite", sprite->GetName());
        else
            frameElem.SetString("sprite", spriteSheet->GetName() + "@" + sprite->GetName());
    }

    return xmlFile.Save(dest);
}
コード例 #14
0
ファイル: Menu.cpp プロジェクト: 03050903/Urho3D
bool Menu::SaveXML(XMLElement& dest) const
{
    if (!Button::SaveXML(dest))
        return false;

    // Save the popup element as a "virtual" child element
    if (popup_)
    {
        XMLElement childElem = dest.CreateChild("element");
        childElem.SetBool("popup", true);
        if (!popup_->SaveXML(childElem))
            return false;

        // Filter popup implicit attributes
        if (!FilterPopupImplicitAttributes(childElem))
        {
            URHO3D_LOGERROR("Could not remove popup implicit attributes");
            return false;
        }
    }

    return true;
}
コード例 #15
0
bool ParticleEffect::Save(XMLElement& dest) const
{
    if (dest.IsNull())
    {
        URHO3D_LOGERROR("Can not save particle effect to null XML element");
        return false;
    }

    XMLElement childElem = dest.CreateChild("material");
    childElem.SetAttribute("name", GetResourceName(material_));

    childElem = dest.CreateChild("numparticles");
    childElem.SetInt("value", numParticles_);

    childElem = dest.CreateChild("updateinvisible");
    childElem.SetBool("enable", updateInvisible_);

    childElem = dest.CreateChild("relative");
    childElem.SetBool("enable", relative_);

    childElem = dest.CreateChild("scaled");
    childElem.SetBool("enable", scaled_);

    childElem = dest.CreateChild("sorted");
    childElem.SetBool("enable", sorted_);

    childElem = dest.CreateChild("fixedscreensize");
    childElem.SetBool("enable", fixedScreenSize_);

    childElem = dest.CreateChild("animlodbias");
    childElem.SetFloat("value", animationLodBias_);

    childElem = dest.CreateChild("emittertype");
    childElem.SetAttribute("value", emitterTypeNames[emitterType_]);

    childElem = dest.CreateChild("emittersize");
    childElem.SetVector3("value", emitterSize_);

    childElem = dest.CreateChild("direction");
    childElem.SetVector3("min", directionMin_);
    childElem.SetVector3("max", directionMax_);

    childElem = dest.CreateChild("constantforce");
    childElem.SetVector3("value", constantForce_);

    childElem = dest.CreateChild("dampingforce");
    childElem.SetFloat("value", dampingForce_);

    childElem = dest.CreateChild("activetime");
    childElem.SetFloat("value", activeTime_);

    childElem = dest.CreateChild("inactivetime");
    childElem.SetFloat("value", inactiveTime_);

    childElem = dest.CreateChild("emissionrate");
    childElem.SetFloat("min", emissionRateMin_);
    childElem.SetFloat("max", emissionRateMax_);

    childElem = dest.CreateChild("particlesize");
    childElem.SetVector2("min", sizeMin_);
    childElem.SetVector2("max", sizeMax_);

    childElem = dest.CreateChild("timetolive");
    childElem.SetFloat("min", timeToLiveMin_);
    childElem.SetFloat("max", timeToLiveMax_);

    childElem = dest.CreateChild("velocity");
    childElem.SetFloat("min", velocityMin_);
    childElem.SetFloat("max", velocityMax_);

    childElem = dest.CreateChild("rotation");
    childElem.SetFloat("min", rotationMin_);
    childElem.SetFloat("max", rotationMax_);

    childElem = dest.CreateChild("rotationspeed");
    childElem.SetFloat("min", rotationSpeedMin_);
    childElem.SetFloat("max", rotationSpeedMax_);

    childElem = dest.CreateChild("sizedelta");
    childElem.SetFloat("add", sizeAdd_);
    childElem.SetFloat("mul", sizeMul_);

    childElem = dest.CreateChild("faceCameraMode");
    childElem.SetAttribute("value", faceCameraModeNames[faceCameraMode_]);

    if (colorFrames_.Size() == 1)
    {
        childElem = dest.CreateChild("color");
        childElem.SetColor("value", colorFrames_[0].color_);
    }

    if (colorFrames_.Size() > 1)
    {
        for (unsigned i = 0; i < colorFrames_.Size(); ++i)
        {
            childElem = dest.CreateChild("colorfade");
            childElem.SetColor("color", colorFrames_[i].color_);
            childElem.SetFloat("time", colorFrames_[i].time_);
        }
    }

    for (unsigned i = 0; i < textureFrames_.Size(); ++i)
    {
        childElem = dest.CreateChild("texanim");
        childElem.SetRect("uv", textureFrames_[i].uv_);
        childElem.SetFloat("time", textureFrames_[i].time_);
    }

    return true;
}
コード例 #16
0
ファイル: ParticleEffect2D.cpp プロジェクト: aster2013/Urho3D
bool ParticleEffect2D::Save(Serializer& dest) const
{
    if (!sprite_)
        return false;

    XMLFile xmlFile(context_);
    XMLElement rootElem = xmlFile.CreateRoot("particleEmitterConfig");

    String fileName = GetFileNameAndExtension(sprite_->GetName());
    rootElem.CreateChild("texture").SetAttribute("name", fileName);

    WriteVector2(rootElem, "sourcePosition", Vector2::ZERO);
    WriteVector2(rootElem, "sourcePositionVariance", sourcePositionVariance_);

    WriteFloat(rootElem, "speed", speed_);
    WriteFloat(rootElem, "speedVariance", speedVariance_);

    WriteFloat(rootElem, "particleLifeSpan", particleLifeSpan_);
    WriteFloat(rootElem, "particleLifespanVariance", particleLifespanVariance_);

    WriteFloat(rootElem, "angle", angle_);
    WriteFloat(rootElem, "angleVariance", angleVariance_);

    WriteVector2(rootElem, "gravity", gravity_);

    WriteFloat(rootElem, "radialAcceleration", radialAcceleration_);
    WriteFloat(rootElem, "tangentialAcceleration", tangentialAcceleration_);

    WriteFloat(rootElem, "radialAccelVariance", radialAccelVariance_);
    WriteFloat(rootElem, "tangentialAccelVariance", tangentialAccelVariance_);

    WriteColor(rootElem, "startColor", startColor_);
    WriteColor(rootElem, "startColorVariance", startColorVariance_);

    WriteColor(rootElem, "finishColor", finishColor_);
    WriteColor(rootElem, "finishColorVariance", finishColorVariance_);

    WriteInt(rootElem, "maxParticles", maxParticles_);

    WriteFloat(rootElem, "startParticleSize", startParticleSize_);
    WriteFloat(rootElem, "startParticleSizeVariance", startParticleSizeVariance_);

    WriteFloat(rootElem, "finishParticleSize", finishParticleSize_);
    // Typo in pex file
    WriteFloat(rootElem, "FinishParticleSizeVariance", FinishParticleSizeVariance_);

    float duration = duration_;
    if (duration == M_INFINITY)
        duration = -1.0f;
    WriteFloat(rootElem, "duration", duration);
    WriteInt(rootElem, "emitterType", (int)emitterType_);

    WriteFloat(rootElem, "maxRadius", maxRadius_);
    WriteFloat(rootElem, "maxRadiusVariance", maxRadiusVariance_);
    WriteFloat(rootElem, "minRadius", minRadius_);
    WriteFloat(rootElem, "minRadiusVariance", minRadiusVariance_);

    WriteFloat(rootElem, "rotatePerSecond", rotatePerSecond_);
    WriteFloat(rootElem, "rotatePerSecondVariance", rotatePerSecondVariance_);

    WriteInt(rootElem, "blendFuncSource", srcBlendFuncs[blendMode_]);
    WriteInt(rootElem, "blendFuncDestination", destBlendFuncs[blendMode_]);

    WriteFloat(rootElem, "rotationStart", rotationStart_);
    WriteFloat(rootElem, "rotationStartVariance", rotationStartVariance_);

    WriteFloat(rootElem, "rotationEnd", rotationEnd_);
    WriteFloat(rootElem, "rotationEndVariance", rotationEndVariance_);

	return xmlFile.Save(dest);
}
コード例 #17
0
ファイル: ParticleEffect2D.cpp プロジェクト: aster2013/Urho3D
void ParticleEffect2D::WriteFloat(XMLElement& element, const String& name, float value) const
{
	XMLElement child = element.CreateChild(name);
	child.SetFloat("value", value);
}
コード例 #18
0
ファイル: ParticleEffect2D.cpp プロジェクト: aster2013/Urho3D
void ParticleEffect2D::WriteVector2(XMLElement& element,const String& name,const Vector2& value) const
{
	XMLElement child = element.CreateChild(name);
	child.SetFloat("x", value.x_);
	child.SetFloat("y", value.y_);
}
コード例 #19
0
ファイル: SpritePacker.cpp プロジェクト: nonconforme/Urho3D
void Run(Vector<String>& arguments)
{
    if (arguments.Size() < 2)
        Help();

    SharedPtr<Context> context(new Context());
    context->RegisterSubsystem(new FileSystem(context));
    context->RegisterSubsystem(new Log(context));
    FileSystem* fileSystem = context->GetSubsystem<FileSystem>();

    Vector<String> inputFiles;
    String outputFile;
    String spriteSheetFileName;
    bool debug = false;
    unsigned padX = 0;
    unsigned padY = 0;
    unsigned offsetX = 0;
    unsigned offsetY = 0;
    unsigned frameWidth = 0;
    unsigned frameHeight = 0;
    bool help = false;
    bool trim = false;

    while (arguments.Size() > 0)
    {
        String arg = arguments[0];
        arguments.Erase(0);

        if (arg.Empty())
            continue;

        if (arg.StartsWith("-"))
        {
            if (arg == "-px")      { padX = ToUInt(arguments[0]); arguments.Erase(0); }
            else if (arg == "-py") { padY = ToUInt(arguments[0]); arguments.Erase(0); }
            else if (arg == "-ox") { offsetX = ToUInt(arguments[0]); arguments.Erase(0); }
            else if (arg == "-oy") { offsetY = ToUInt(arguments[0]); arguments.Erase(0); }
            else if (arg == "-frameWidth") { frameWidth = ToUInt(arguments[0]); arguments.Erase(0); }
            else if (arg == "-frameHeight") { frameHeight = ToUInt(arguments[0]); arguments.Erase(0); }
            else if (arg == "-trim") { trim = true; }
            else if (arg == "-xml")  { spriteSheetFileName = arguments[0]; arguments.Erase(0); }
            else if (arg == "-h")  { help = true; break; }
            else if (arg == "-debug")  { debug = true; }
        }
        else
            inputFiles.Push(arg);
    }

    if (help)
        Help();

    if (inputFiles.Size() < 2)
        ErrorExit("An input and output file must be specified.");

    if (frameWidth ^ frameHeight)
        ErrorExit("Both frameHeight and frameWidth must be ommited or specified.");

    // take last input file as output
    if (inputFiles.Size() > 1)
    {
        outputFile = inputFiles[inputFiles.Size() - 1];
        LOGINFO("Output file set to " + outputFile + ".");
        inputFiles.Erase(inputFiles.Size() - 1);
    }

    // set spritesheet name to outputfile.xml if not specified
    if (spriteSheetFileName.Empty())
        spriteSheetFileName = ReplaceExtension(outputFile, ".xml");

    if (GetParentPath(spriteSheetFileName) != GetParentPath(outputFile))
        ErrorExit("Both output xml and png must be in the same folder");

    // check all input files exist
    for (unsigned i = 0; i < inputFiles.Size(); ++i)
    {
        LOGINFO("Checking " + inputFiles[i] + " to see if file exists.");
        if (!fileSystem->FileExists(inputFiles[i]))
            ErrorExit("File " + inputFiles[i] + " does not exist.");
    }

    // Set the max offset equal to padding to prevent images from going out of bounds
    offsetX = Min((int)offsetX, (int)padX);
    offsetY = Min((int)offsetY, (int)padY);

    Vector<SharedPtr<PackerInfo > > packerInfos;

    for (unsigned i = 0; i < inputFiles.Size(); ++i)
    {
        String path = inputFiles[i];
        String name = ReplaceExtension(GetFileName(path), "");
        File file(context, path);
        Image image(context);

        if (!image.Load(file))
            ErrorExit("Could not load image " + path + ".");

        if (image.IsCompressed())
            ErrorExit(path + " is compressed. Compressed images are not allowed.");

        SharedPtr<PackerInfo> packerInfo(new PackerInfo(path, name));
        int imageWidth = image.GetWidth();
        int imageHeight = image.GetHeight();
        int trimOffsetX = 0;
        int trimOffsetY = 0;
        int adjustedWidth = imageWidth;
        int adjustedHeight = imageHeight;

        if (trim)
        {
            int minX = imageWidth;
            int minY = imageHeight;
            int maxX = 0;
            int maxY = 0;

            for (int y = 0; y < imageHeight; ++y)
            {
                for (int x = 0; x < imageWidth; ++x)
                {
                    bool found = (image.GetPixelInt(x, y) & 0x000000ff) != 0;
                    if (found) {
                        minX = Min(minX, x);
                        minY = Min(minY, y);
                        maxX = Max(maxX, x);
                        maxY = Max(maxY, y);
                    }
                }
            }

            trimOffsetX = minX;
            trimOffsetY = minY;
            adjustedWidth = maxX - minX + 1;
            adjustedHeight = maxY - minY + 1;
        }

        if (trim)
        {
            packerInfo->frameWidth = imageWidth;
            packerInfo->frameHeight = imageHeight;
        }
        else if (frameWidth || frameHeight)
        {
            packerInfo->frameWidth = frameWidth;
            packerInfo->frameHeight = frameHeight;
        }
        packerInfo->width = adjustedWidth;
        packerInfo->height = adjustedHeight;
        packerInfo->offsetX -= trimOffsetX;
        packerInfo->offsetY -= trimOffsetY;
        packerInfos.Push(packerInfo);
    }

    int packedWidth = MAX_TEXTURE_SIZE;
    int packedHeight = MAX_TEXTURE_SIZE;
    {
        // fill up an list of tries in increasing size and take the first win
        Vector<IntVector2> tries;
        for(unsigned x=2; x<11; ++x)
        {
            for(unsigned y=2; y<11; ++y)
                tries.Push(IntVector2((1<<x), (1<<y)));
        }

        // load rectangles
        stbrp_rect* packerRects = new stbrp_rect[packerInfos.Size()];
        for (unsigned i = 0; i < packerInfos.Size(); ++i)
        {
            PackerInfo* packerInfo = packerInfos[i];
            stbrp_rect* packerRect = &packerRects[i];
            packerRect->id = i;
            packerRect->h = packerInfo->height + padY;
            packerRect->w = packerInfo->width + padX;
        }

        bool success = false;
        while (tries.Size() > 0)
        {
            IntVector2 size = tries[0];
            tries.Erase(0);
            bool fit = true;
            int textureHeight = size.y_;
            int textureWidth = size.x_;
            if (success && textureHeight * textureWidth > packedWidth * packedHeight)
                continue;

            stbrp_context packerContext;
            stbrp_node packerMemory[PACKER_NUM_NODES];
            stbrp_init_target(&packerContext, textureWidth, textureHeight, packerMemory, packerInfos.Size());
            stbrp_pack_rects(&packerContext, packerRects, packerInfos.Size());

            // check to see if everything fit
            for (unsigned i = 0; i < packerInfos.Size(); ++i)
            {
                stbrp_rect* packerRect = &packerRects[i];
                if (!packerRect->was_packed)
                {
                    fit = false;
                    break;
                }
            }
            if (fit)
            {
                success = true;
                // distribute values to packer info
                for (unsigned i = 0; i < packerInfos.Size(); ++i)
                {
                    stbrp_rect* packerRect = &packerRects[i];
                    PackerInfo* packerInfo = packerInfos[packerRect->id];
                    packerInfo->x = packerRect->x;
                    packerInfo->y = packerRect->y;
                }
                packedWidth = size.x_;
                packedHeight = size.y_;
            }
        }
        delete packerRects;
        if (!success)
            ErrorExit("Could not allocate for all images.  The max sprite sheet texture size is " + String(MAX_TEXTURE_SIZE) + "x" + String(MAX_TEXTURE_SIZE) + ".");
    }


    // create image for spritesheet
    Image spriteSheetImage(context);
    spriteSheetImage.SetSize(packedWidth, packedHeight, 4);

    // zero out image
    spriteSheetImage.SetData((unsigned char*)calloc(sizeof(unsigned char), packedWidth * packedHeight * 4));

    XMLFile xml(context);
    XMLElement root = xml.CreateRoot("TextureAtlas");
    root.SetAttribute("imagePath", GetFileNameAndExtension(outputFile));

    for (unsigned i = 0; i < packerInfos.Size(); ++i)
    {
        SharedPtr<PackerInfo> packerInfo = packerInfos[i];
        XMLElement subTexture = root.CreateChild("SubTexture");
        subTexture.SetString("name", packerInfo->name);
        subTexture.SetInt("x", packerInfo->x + offsetX);
        subTexture.SetInt("y", packerInfo->y + offsetY);
        subTexture.SetInt("width", packerInfo->width);
        subTexture.SetInt("height", packerInfo->height);

        if (packerInfo->frameWidth || packerInfo->frameHeight)
        {
            subTexture.SetInt("frameWidth", packerInfo->frameWidth);
            subTexture.SetInt("frameHeight", packerInfo->frameHeight);
            subTexture.SetInt("offsetX", packerInfo->offsetX);
            subTexture.SetInt("offsetY", packerInfo->offsetY);
        }

        LOGINFO("Transfering " + packerInfo->path + " to sprite sheet.");

        File file(context, packerInfo->path);
        Image image(context);
        if (!image.Load(file))
            ErrorExit("Could not load image " + packerInfo->path + ".");

        for (int y = 0; y < packerInfo->height; ++y)
        {
            for (int x = 0; x < packerInfo->width; ++x)
            {
                unsigned color = image.GetPixelInt(x - packerInfo->offsetX, y - packerInfo->offsetY);
                spriteSheetImage.SetPixelInt(
                    packerInfo->x + offsetX + x,
                    packerInfo->y + offsetY + y, color);
            }
        }
    }

    if (debug)
    {
        unsigned OUTER_BOUNDS_DEBUG_COLOR = Color::BLUE.ToUInt();
        unsigned INNER_BOUNDS_DEBUG_COLOR = Color::GREEN.ToUInt();

        LOGINFO("Drawing debug information.");
        for (unsigned i = 0; i < packerInfos.Size(); ++i)
        {
            SharedPtr<PackerInfo> packerInfo = packerInfos[i];

            // Draw outer bounds
            for (int x = 0; x < packerInfo->frameWidth; ++x)
            {
                spriteSheetImage.SetPixelInt(packerInfo->x + x, packerInfo->y, OUTER_BOUNDS_DEBUG_COLOR);
                spriteSheetImage.SetPixelInt(packerInfo->x + x, packerInfo->y + packerInfo->frameHeight, OUTER_BOUNDS_DEBUG_COLOR);
            }
            for (int y = 0; y < packerInfo->frameHeight; ++y)
            {
                spriteSheetImage.SetPixelInt(packerInfo->x, packerInfo->y + y, OUTER_BOUNDS_DEBUG_COLOR);
                spriteSheetImage.SetPixelInt(packerInfo->x + packerInfo->frameWidth, packerInfo->y + y, OUTER_BOUNDS_DEBUG_COLOR);
            }

            // Draw inner bounds
            for (int x = 0; x < packerInfo->width; ++x)
            {
                spriteSheetImage.SetPixelInt(packerInfo->x + offsetX + x, packerInfo->y + offsetY, INNER_BOUNDS_DEBUG_COLOR);
                spriteSheetImage.SetPixelInt(packerInfo->x + offsetX + x, packerInfo->y + offsetY + packerInfo->height, INNER_BOUNDS_DEBUG_COLOR);
            }
            for (int y = 0; y < packerInfo->height; ++y)
            {
                spriteSheetImage.SetPixelInt(packerInfo->x + offsetX, packerInfo->y + offsetY + y, INNER_BOUNDS_DEBUG_COLOR);
                spriteSheetImage.SetPixelInt(packerInfo->x + offsetX + packerInfo->width, packerInfo->y + offsetY + y, INNER_BOUNDS_DEBUG_COLOR);
            }
        }
    }

    LOGINFO("Saving output image.");
    spriteSheetImage.SavePNG(outputFile);

    LOGINFO("Saving SpriteSheet xml file.");
    File spriteSheetFile(context);
    spriteSheetFile.Open(spriteSheetFileName, FILE_WRITE);
    xml.Save(spriteSheetFile);
}
コード例 #20
0
ファイル: Font.cpp プロジェクト: jjiezheng/urho3d
bool Font::SaveXML(Serializer& dest, int pointSize, bool usedGlyphs)
{
    const FontFace* fontFace = GetFace(pointSize);
    if (!fontFace)
        return false;

    PROFILE(FontSaveXML);

    SharedPtr<FontFace> packedFontFace;
    if (usedGlyphs)
    {
        // Save used glyphs only, try to pack them first
        packedFontFace = Pack(fontFace);
        if (packedFontFace)
            fontFace = packedFontFace;
        else
            return false;
    }

    SharedPtr<XMLFile> xml(new XMLFile(context_));
    XMLElement rootElem = xml->CreateRoot("font");

    // Information
    XMLElement childElem = rootElem.CreateChild("info");
    String fileName = GetFileName(GetName());
    childElem.SetAttribute("face", fileName);
    childElem.SetAttribute("size", String(pointSize));

    // Common
    childElem = rootElem.CreateChild("common");
    childElem.SetInt("lineHeight", fontFace->rowHeight_);
    unsigned pages = fontFace->textures_.Size();
    childElem.SetInt("pages", pages);

    // Construct the path to store the texture
    String pathName;
    File* file = dynamic_cast<File*>(&dest);
    if (file)
        // If serialize to file, use the file's path
        pathName = GetPath(file->GetName());
    else
        // Otherwise, use the font resource's path
        pathName = "Data/" + GetPath(GetName());

    // Pages
    childElem = rootElem.CreateChild("pages");
    for (unsigned i = 0; i < pages; ++i)
    {
        XMLElement pageElem = childElem.CreateChild("page");
        pageElem.SetInt("id", i);
        String texFileName = fileName + "_" + String(i) + ".png";
        pageElem.SetAttribute("file", texFileName);

        // Save the font face texture to image file
        SaveFaceTexture(fontFace->textures_[i], pathName + texFileName);
    }

    // Chars and kernings
    XMLElement charsElem = rootElem.CreateChild("chars");
    unsigned numGlyphs = fontFace->glyphs_.Size();
    charsElem.SetInt("count", numGlyphs);
    XMLElement kerningsElem;
    bool hasKerning = fontFace->hasKerning_;
    if (hasKerning)
        kerningsElem = rootElem.CreateChild("kernings");
    for (HashMap<unsigned, unsigned>::ConstIterator i = fontFace->glyphMapping_.Begin(); i != fontFace->glyphMapping_.End(); ++i)
    {
        // Char
        XMLElement charElem = charsElem.CreateChild("char");
        charElem.SetInt("id", i->first_);
        FontGlyph glyph = fontFace->glyphs_[i->second_];
        charElem.SetInt("x", glyph.x_);
        charElem.SetInt("y", glyph.y_);
        charElem.SetInt("width", glyph.width_);
        charElem.SetInt("height", glyph.height_);
        charElem.SetInt("xoffset", glyph.offsetX_);
        charElem.SetInt("yoffset", glyph.offsetY_);
        charElem.SetInt("xadvance", glyph.advanceX_);
        charElem.SetInt("page", glyph.page_);

        // Kerning
        if (hasKerning)
        {
            for (HashMap<unsigned, unsigned>::ConstIterator j = glyph.kerning_.Begin(); j != glyph.kerning_.End(); ++j)
            {
                // To conserve space, only write when amount is non zero
                if (j->second_ == 0)
                    continue;

                XMLElement kerningElem = kerningsElem.CreateChild("kerning");
                kerningElem.SetInt("first", i->first_);
                kerningElem.SetInt("second", j->first_);
                kerningElem.SetInt("amount", j->second_);
            }
        }
    }

    return xml->Save(dest);
}