Esempio n. 1
0
        public static XElement generateXmlByItem(RenderBase item)
        {
            XElement xml = new XElement("Node");

            item.setAttrToXml(ref xml);
            return(xml);
        }
        /// <summary>
        ///     Creates a Index Buffer for a Mesh, trying to repeat as less Vertices as possible.
        /// </summary>
        /// <param name="mesh">The Mesh that should be optimized</param>
        /// <returns></returns>
        public static optimizedMesh optimizeMesh(RenderBase.OMesh mesh)
        {
            optimizedMesh output = new optimizedMesh();

            output.hasNormal = mesh.hasNormal;
            output.hasTangent = mesh.hasTangent;
            output.hasColor = mesh.hasColor;
            output.hasNode = mesh.hasNode;
            output.hasWeight = mesh.hasWeight;
            output.texUVCount = mesh.texUVCount;

            for (int i = 0; i < mesh.vertices.Count; i++)
            {
                bool found = false;
                for (int j = 1; j <= optimizerLookBack; j++)
                {
                    int p = output.vertices.Count - j;
                    if (p < 0 || p >= output.vertices.Count) break;
                    if (output.vertices[p].Equals(mesh.vertices[i]))
                    {
                        output.indices.Add((uint)p);
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    output.vertices.Add(mesh.vertices[i]);
                    output.indices.Add((uint)(output.vertices.Count - 1));
                }
            }

            return output;
        }
        public async Task <string> RenderContent <T>(T content, string name = null) where T : ContentBase
        {
            var renderData = new RenderBase <T>(_hostingOptions, content);

            var html = await _viewRender.Render <RenderBase <T>, T>(name ?? typeof(T).Name, renderData);

            return(html);
        }
        public OModelExportForm(RenderBase.OModelGroup models, int modelIndex = -1)
        {
            InitializeComponent();

            mdls = models;
            mdlIndex = modelIndex;
            if (modelIndex > -1) TxtModelName.Text = mdls.model[mdlIndex].name;
        }
        public OTextureExportForm(RenderBase.OModelGroup models, int textureIndex = -1)
        {
            InitializeComponent();

            mdls = models;
            texIndex = textureIndex;
            if (textureIndex > -1) TxtTextureName.Text = mdls.texture[texIndex].name;
        }
 /// <summary>
 ///     Calculates the minimun and maximum vector values for a Model.
 /// </summary>
 /// <param name="mdl">The target model</param>
 /// <param name="vertex">The current mesh vertex</param>
 public static void calculateBounds(RenderBase.OModel mdl, RenderBase.OVertex vertex)
 {
     if (vertex.position.x < mdl.minVector.x) mdl.minVector.x = vertex.position.x;
     if (vertex.position.x > mdl.maxVector.x) mdl.maxVector.x = vertex.position.x;
     if (vertex.position.y < mdl.minVector.y) mdl.minVector.y = vertex.position.y;
     if (vertex.position.y > mdl.maxVector.y) mdl.maxVector.y = vertex.position.y;
     if (vertex.position.z < mdl.minVector.z) mdl.minVector.z = vertex.position.z;
     if (vertex.position.z > mdl.maxVector.z) mdl.maxVector.z = vertex.position.z;
 }
 /// <summary>
 ///     Initializes the control with animation data.
 /// </summary>
 /// <param name="renderEngine">Renderer used to render the model</param>
 /// <param name="ctrl">The animation control</param>
 /// <param name="anms">The list with animations</param>
 /// <param name="t">The animation type (used on Export/Import options)</param>
 public void initialize(RenderEngine renderEngine, RenderEngine.animationControl ctrl, RenderBase.OAnimationListBase anms, FileIO.fileType t)
 {
     renderer = renderEngine;
     control = ctrl;
     animations = anms;
     type = t;
     control.FrameChanged += Control_FrameChanged;
     updateList();
 }
Esempio n. 8
0
        public void addNodeInfo(TreeNode node, RenderBase render)
        {
            TreeNode chldNode = new TreeNode();

            chldNode.Text = render.Name + (render.Tag.Length > 0 ? (":" + render.Tag) : (""));
            chldNode.Tag  = render.uniqueName;
            chldNode.SelectedImageIndex = chldNode.ImageIndex = ImageIndexPng;

            if (render is RenderScene)
            {
                this.treeView1.Nodes.Add(chldNode);

                //List<RenderBase> childItems = (render as TDPanel).ChildItems;
                //for (int i = childItems.Count - 1; i >= 0; i-- )
                //{
                //    addNodeInfo(chldNode, childItems[i]);
                //}
                foreach (RenderBase item in (render as TDPanel).ChildItems)
                {
                    addNodeInfo(chldNode, item);
                }
                chldNode.Expand();
            }
            else if (render is TDPanel)
            {
                if ((render as TDPanel).panelPath.Length == 0)
                {
                    chldNode.SelectedImageIndex = chldNode.ImageIndex = ImageIndexPng;
                    //List<RenderBase> childItems = (render as TDPanel).ChildItems;
                    //for (int i = childItems.Count - 1; i >= 0; i--)
                    //{
                    //    addNodeInfo(chldNode, childItems[i]);
                    //}
                    foreach (RenderBase item in (render as TDPanel).ChildItems)
                    {
                        addNodeInfo(chldNode, item);
                    }
                }
                else
                {
                    chldNode.Text = chldNode.Text + ":" + (render as TDPanel).panelPath;
                }
                if (node != null)
                {
                    node.Nodes.Add(chldNode);
                }
            }
            else
            {
                chldNode.SelectedImageIndex = chldNode.ImageIndex = ImageIndexPng;
                if (node != null)
                {
                    node.Nodes.Add(chldNode);
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        ///     Interpolates a point between two vectors using Linear Interpolation.
        /// </summary>
        /// <param name="a">First vector</param>
        /// <param name="b">Second vector</param>
        /// <param name="mu">Value between 0-1 of the interpolation amount</param>
        /// <returns></returns>
        public static RenderBase.OVector3 interpolateLinear(RenderBase.OVector3 a, RenderBase.OVector3 b, float mu)
        {
            RenderBase.OVector3 output = new RenderBase.OVector3();

            output.x = interpolateLinear(a.x, b.x, mu);
            output.y = interpolateLinear(a.y, b.y, mu);
            output.z = interpolateLinear(a.z, b.z, mu);

            return output;
        }
Esempio n. 10
0
        public override void Undo()
        {
            RenderBase item = renderScene.getRenderByUniqueName(uniqueName);

            if (item == null)
            {
                return;
            }
            item.removeFromParent();
        }
Esempio n. 11
0
        public override void Redo()
        {
            RenderBase item = renderScene.getRenderByUniqueName(uniqueName);

            if (item == null)
            {
                return;
            }
            item.pos = _finish;
        }
 /// <summary>
 ///     Interpolates a Key Frame from a list of Key Frames.
 /// </summary>
 /// <param name="sourceFrame">The list of key frames</param>
 /// <param name="frame">The frame that should be returned or interpolated from the list</param>
 /// <returns></returns>
 public static float getKey(RenderBase.OAnimationKeyFrameGroup sourceFrame, float frame)
 {
     switch (sourceFrame.interpolation)
     {
         case RenderBase.OInterpolationMode.step: return interpolateStep(sourceFrame.keyFrames, frame);
         case RenderBase.OInterpolationMode.linear: return interpolateLinear(sourceFrame.keyFrames, frame);
         case RenderBase.OInterpolationMode.hermite: return interpolateHermite(sourceFrame.keyFrames, frame);
         default: return 0; //Shouldn't happen
     }
 }
Esempio n. 13
0
        public override void Undo()
        {
            RenderBase item = renderScene.getRenderByUniqueName(uniqueName);

            if (item == null)
            {
                return;
            }
            item.size = _orign;
        }
Esempio n. 14
0
        public UConstantBuffer(RenderBase rb, int size)
        {
            this.RenderBase = rb;

            Buffer = new Buffer(rb.Device, new BufferDescription()
            {
                Usage          = ResourceUsage.Dynamic,
                SizeInBytes    = size,
                BindFlags      = BindFlags.ConstantBuffer,
                CpuAccessFlags = CpuAccessFlags.Write,
                OptionFlags    = ResourceOptionFlags.None,
            });
        }
Esempio n. 15
0
        public override void Redo()
        {
            RenderBase item = renderScene.getRenderByUniqueName(parentUnique);

            if (item == null)
            {
                return;
            }
            RenderBase undoItem = UIHelper.CEGenerateViewByXml(xml, item);

            if (undoItem != null)
            {
                undoItem.uniqueName = this.uniqueName;
            }
        }
Esempio n. 16
0
            public override void SetValue(object component, object value)
            {
                if (component is RenderBase)
                {
                    RenderBase  render = component as RenderBase;
                    RenderScene scene  = render.getRenderScene();
                    render.recordOriStatus();
                    mProp.SetValue(component, value);
                    if (scene == null)
                    {
                        return;
                    }
                    if (mProp.Name == "pos")
                    {
                        scene.commandManager.AddCommand(new CommandMove(scene, render));
                    }
                    else if (mProp.Name == "size")
                    {
                        scene.commandManager.AddCommand(new CommandResize(scene, render));
                    }
                    else if (mProp.Name == "anchorPos")
                    {
                        scene.commandManager.AddCommand(new CommandAnchorPos(scene, render));
                    }
                    else if (mProp.Name == "scale")
                    {
                        scene.commandManager.AddCommand(new CommandScale(scene, render));
                    }
                    else if (mProp.Name == "Tag")
                    {
                        EventManager.RaiserEvent(Constant.RenderItemChange, scene, null);
                    }


                    scene.checkModifyStatus();
                }
                else
                {
                    mProp.SetValue(component, value);
                }
            }
Esempio n. 17
0
        public static RenderBase CEGenerateItemByName(String type, String path = null, RenderBase parent = null)
        {
            RenderBase item = null;

            try
            {
                if (parent != null)
                {
                    parent.recordChildItems();
                }
                item = generateItemByName(type, path, parent);
            }
            catch (NestException ex)
            {
                if (parent != null)
                {
                    parent.recoverChildItems();
                }
                EventManager.RaiserEvent(Constant.StatusInfoChange, null, String.Format("{0} 文件不能嵌套使用", ex.Message));
            }
            return(item);
        }
Esempio n. 18
0
        /// <summary>
        ///     Exports a model to the Wavefront OBJ format.
        /// </summary>
        /// <param name="model">The model to be exported</param>
        /// <param name="fileName">The output file name</param>
        /// <param name="modelIndex">The index of the model that should be exported</param>
        public static void export(RenderBase.OModelGroup model, string fileName, int modelIndex)
        {
            StringBuilder output = new StringBuilder();

            RenderBase.OModel mdl = model.model[modelIndex];

            int faceIndexBase = 1;
            for (int objIndex = 0; objIndex < mdl.mesh.Count; objIndex++)
            {
                output.AppendLine("g " + mdl.mesh[objIndex].name);
                output.AppendLine(null);

                output.AppendLine("usemtl " + mdl.material[mdl.mesh[objIndex].materialId].name0 + ".png");
                output.AppendLine(null);

                MeshUtils.optimizedMesh obj = MeshUtils.optimizeMesh(mdl.mesh[objIndex]);
                foreach (RenderBase.OVertex vertex in obj.vertices)
                {
                    output.AppendLine("v " + getString(vertex.position.x) + " " + getString(vertex.position.y) + " " + getString(vertex.position.z));
                    output.AppendLine("vn " + getString(vertex.normal.x) + " " + getString(vertex.normal.y) + " " + getString(vertex.normal.z));
                    output.AppendLine("vt " + getString(vertex.texture0.x) + " " + getString(vertex.texture0.y));
                }
                output.AppendLine(null);

                for (int i = 0; i < obj.indices.Count; i += 3)
                {
                    output.AppendLine(
                        string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}",
                        faceIndexBase + obj.indices[i],
                        faceIndexBase + obj.indices[i + 1],
                        faceIndexBase + obj.indices[i + 2]));
                }
                faceIndexBase += obj.vertices.Count;
                output.AppendLine(null);
            }

            File.WriteAllText(fileName, output.ToString());
        }
Esempio n. 19
0
        private static RenderBase generateViewByPath(String path, RenderBase parent = null)
        {
            String   absPath = UIProject.Instance().GetRealFile(path);
            String   content = FileHelper.GetFullContent(absPath);
            XElement xml     = XmlHelper.Parse(content);

            if (xml == null)
            {
                return(null);
            }
            if (parent != null && path.Length > 0 && parent.checkParentPathNest(UIProject.Instance().GetRelativePath(absPath)))
            {
                throw new NestException(UIProject.Instance().GetRelativePath(absPath));
            }
            xml.SetAttributeValue("Name", Constant.TypePanel);
            RenderBase render = generateViewByXml(xml, parent);

            if (render is TDPanel)
            {
                (render as TDPanel).panelPath = UIProject.Instance().GetRelativePath(absPath);
            }
            return(render);
        }
Esempio n. 20
0
        private void MainForm_Load(object sender, EventArgs e)
        {
            // create render instance ..//創建render instance
            this.Base = new RenderBase();//先去執行構造函數

            // create render log instance ..//創建render日志instance
            this.LogMsg = new RenderEvents();

            // append to logs object ..//追加到日志對象
            RenderEvents.AppendLog(string.Format("{0}", "initialize render base service has successful."));

            // setting list view sort provider ..//設置list view排序provider
            this.ListView_Render_Status.ListViewItemSorter = ListViewSorter;
            this.ListViewSorter.Order = SortOrder.Descending;

            // start read server data information thread ..//開始讀服務器數據信息線程
            Thread StateThread = new Thread(new ThreadStart(this.ReadData));

            StateThread.Priority = ThreadPriority.BelowNormal;
            StateThread.Start();

            // append to logs object ..//追加到日志對象
            RenderEvents.AppendLog(string.Format("{0}", "start data object delegate thread."));
        }
Esempio n. 21
0
        private static RenderBase generateViewByXml(XElement xml, RenderBase parent)
        {
            if (xml == null)
            {
                return(null);
            }
            RenderBase item = null;

            String name = XmlHelper.GetString(xml, "Name");
            String path = XmlHelper.GetString(xml, "Path");

            if (name.Length > 0)
            {
                if (parent != null && path.Length > 0 && parent.checkParentPathNest(path))
                {
                    throw new NestException(UIProject.Instance().GetRelativePath(path));
                }
                item = generateItemByName(name, path, parent);
                if (item == null)
                {
                    return(item);
                }
                item.getAttrByXml(xml);
                //XElement child = xml.Element("Child");
                //if (child != null)
                //{
                //    foreach (XElement element in child.Elements("Node"))
                //    {
                //        generateViewByXml(element, item);
                //    }
                //}
                item.loadComplete();
            }

            return(item);
        }
Esempio n. 22
0
        public void SetSelectItem(RenderBase render)
        {
            if (render == null)
            {
                propGrid.SelectedObject = null;
                return;
            }
            XmlNode     tmpXNode    = DynamicObj.propXmlDoc.SelectSingleNode("Components/Component[@Name='" + render.Name + "']");
            XmlNodeList tmpXPropLst = null;

            if (tmpXNode != null)
            {
                tmpXPropLst = tmpXNode.SelectNodes("Propertys/Property");
            }
            CustomProperty cp = new CustomProperty(render, tmpXPropLst);

            tmpXNode = DynamicObj.propXmlDoc.SelectSingleNode("Components/Component[@Name='Base']");
            if (tmpXNode != null)
            {
                tmpXPropLst = tmpXNode.SelectNodes("Propertys/Property");
                cp.AddProperty(tmpXPropLst);
            }
            propGrid.SelectedObject = cp;
        }
 /// <summary>
 ///     Creates a Quaternion from a Quaternion Vector4.
 /// </summary>
 /// <param name="vector">The quaternion vector</param>
 /// <returns></returns>
 private Quaternion getQuaternion(RenderBase.OVector4 vector)
 {
     return new Quaternion(vector.x, vector.y, vector.z, vector.w);
 }
Esempio n. 24
0
        public static String generateSrcByItem(RenderBase item)
        {
            XElement xml = generateXmlByItem(item);

            return(xml.ToString());
        }
Esempio n. 25
0
        /// <summary>
        ///     Interpolates a point between two vectors using Linear Interpolation.
        /// </summary>
        /// <param name="a">First vector</param>
        /// <param name="b">Second vector</param>
        /// <param name="mu">Value between 0-1 of the interpolation amount</param>
        /// <returns></returns>
        public static RenderBase.OVector4 interpolateLinear(RenderBase.OVector4 a, RenderBase.OVector4 b, float mu)
        {
            RenderBase.OVector4 output = new RenderBase.OVector4();

            output.x = interpolateLinear(a.x, b.x, mu);
            output.y = interpolateLinear(a.y, b.y, mu);
            output.z = interpolateLinear(a.z, b.z, mu);
            output.w = interpolateLinear(a.w, b.w, mu);

            return output;
        }
Esempio n. 26
0
        /// <summary>
        ///     Exports a Model to the Collada format.
        ///     See: https://www.khronos.org/files/collada_spec_1_4.pdf for more information.
        /// </summary>
        /// <param name="model">The Model that will be exported</param>
        /// <param name="fileName">The output File Name</param>
        /// <param name="modelIndex">Index of the model to be exported</param>
        /// <param name="skeletalAnimationIndex">(Optional) Index of the skeletal animation</param>
        public static void export(RenderBase.OModelGroup model, string fileName, int modelIndex, int skeletalAnimationIndex = -1)
        {
            RenderBase.OModel mdl = model.model[modelIndex];
            COLLADA dae = new COLLADA();
            COLLADA daeShiny = new COLLADA();

            dae.asset.created = DateTime.Now.ToString("yyyy-MM-ddThh:mm:ssZ");
            dae.asset.modified = dae.asset.created;

            daeShiny.asset.created = DateTime.Now.ToString("yyyy-MM-ddThh:mm:ssZ");
            daeShiny.asset.modified = dae.asset.created;

            bool hasShiny = false;

            // Attempt to detect packaged textures. See http://www.github.com/Quibilia/Ohana3DS-Transfigured for directions.
            try
            {
                string modelDir;
                string sDir;
                string[] texDirs;
                string[] texFiles;

                modelDir = Path.GetFileNameWithoutExtension(fileName).Remove(4);
                sDir = Path.GetDirectoryName(fileName);
                texDirs = Directory.GetDirectories(Path.Combine(sDir, "../../Textures/"));

                foreach (string texDir in texDirs)
                {
                    if (texDir.Contains(modelDir))
                    {
                        texFiles = Directory.GetFiles(texDir);

                        if (Directory.Exists(texDir.Replace("Textures", "Models/DAE")) == false && texDir.Contains("Xtra") == false)
                        {
                            Directory.CreateDirectory(texDir.Replace("Textures", "Models/DAE"));
                        }

                        bool hasIris = false;

                        foreach (string texFile in texFiles)
                        {
                            if (texFile.Contains("Iris1"))
                            {
                                hasIris = true;
                            }
                        }

                        foreach (string texFile in texFiles)
                        {
                            if (texFile.Contains("Xtra") == false)
                            {
                                Bitmap tempBMP = (Bitmap)Bitmap.FromFile(texFile);

                                if (texFile.Contains("Body") && texFile.Contains("Nor") == false)
                                {
                                    int w = tempBMP.Width / 2;

                                    Bitmap scaledBMP = new Bitmap(tempBMP, tempBMP.Width / 2, tempBMP.Height);
                                    Bitmap reverseBMP = new Bitmap(tempBMP, tempBMP.Width / 2, tempBMP.Height);
                                    reverseBMP.RotateFlip(RotateFlipType.RotateNoneFlipX);

                                    Bitmap finalBMP = new Bitmap(tempBMP.Width, tempBMP.Height);

                                    for (int x = 0; x < scaledBMP.Width; x++)
                                    {
                                        for (int y = 0; y < scaledBMP.Height; y++)
                                        {
                                            finalBMP.SetPixel(x, y, scaledBMP.GetPixel(x, y));
                                        }
                                    }

                                    for (int x = 0; x < reverseBMP.Width; x++)
                                    {
                                        for (int y = 0; y < reverseBMP.Height; y++)
                                        {
                                            finalBMP.SetPixel(x + reverseBMP.Width, y, reverseBMP.GetPixel(x, y));
                                        }
                                    }

                                    if (texFile.Contains("BodyA2") == false && texFile.Contains("BodyB2") == false && texFile.Contains("Body2") == false)
                                    {
                                        finalBMP.Save(texFile.Replace("Textures", "Models/DAE"));

                                        model.texture.Add(new RenderBase.OTexture(finalBMP, texFile.Replace("Textures", "Models/DAE")));
                                    }
                                }
                                else if (texFile.Contains("Iris1"))
                                {
                                    Bitmap eyeBMP = (Bitmap)Bitmap.FromFile(texFile.Replace("Iris", "Eye"));

                                    foreach (string norFile in texFiles)
                                    {
                                        if (norFile.Contains("Xtra") == false && norFile.Contains("EyeNor"))
                                        {
                                            Bitmap thisEye = new Bitmap(eyeBMP.Width / 2, eyeBMP.Height / 4);
                                            Bitmap norBMP = (Bitmap)Bitmap.FromFile(norFile);
                                            Bitmap thisNor = new Bitmap(norBMP.Width / 4, norBMP.Height / 4);
                                            Bitmap finalBMP = new Bitmap(eyeBMP.Width * 2, eyeBMP.Height);

                                            int eye = 0;
                                            int half = 0;
                                            bool reflectEye = false;
                                            bool reflectIris = true;
                                            bool reflectNor = true;

                                            for (int eyeY = 0; eyeY < 4; eyeY++)
                                            {
                                                eye = 0;

                                                for (int eyeX = 0; eyeX < 2; eyeX++)
                                                {
                                                    reflectEye = !reflectEye;
                                                    reflectNor = !reflectNor;
                                                    reflectIris = !reflectIris;

                                                    for (half = 0; half < 2; half++)
                                                    {
                                                        for (int x = half * (eyeBMP.Width / 2); x < (half + 1) * (eyeBMP.Width / 2); x++)
                                                        {
                                                            for (int y = eyeY * (eyeBMP.Height / 4); y < (eyeY + 1) * (eyeBMP.Height / 4); y++)
                                                            {
                                                                thisEye.SetPixel(x - (half * (eyeBMP.Width / 2)), y - (eyeY * (eyeBMP.Height / 4)), eyeBMP.GetPixel(x, y));
                                                            }
                                                        }

                                                        for (int x = (half * 2) * (norBMP.Width / 4); x < ((half * 2) + 1) * (norBMP.Width / 4); x++)
                                                        {
                                                            for (int y = eyeY * (norBMP.Height / 4); y < (eyeY + 1) * (norBMP.Height / 4); y++)
                                                            {
                                                                thisNor.SetPixel(x - ((half * 2) * (norBMP.Width / 4)), y - (eyeY * (norBMP.Height / 4)), norBMP.GetPixel(x, y));
                                                            }
                                                        }

                                                        if (reflectEye == true)
                                                        {
                                                            thisEye.RotateFlip(RotateFlipType.RotateNoneFlipX);
                                                        }

                                                        reflectEye = !reflectEye;

                                                        if (reflectNor == true)
                                                        {
                                                            thisNor.RotateFlip(RotateFlipType.RotateNoneFlipX);
                                                        }

                                                        if (reflectIris == true)
                                                        {
                                                            tempBMP.RotateFlip(RotateFlipType.RotateNoneFlipX);
                                                            reflectIris = false;
                                                        }

                                                        // By now, tempBMP, thisEye, and thisNor should all be the same size.

                                                        for (int x = 0; x < tempBMP.Width; x++)
                                                        {
                                                            for (int y = 0; y < tempBMP.Height; y++)
                                                            {
                                                                if (tempBMP.GetPixel(x, y).A >= 0x7F && thisNor.GetPixel(x, y).A >= 0x7F)
                                                                {
                                                                    thisEye.SetPixel(x, y, tempBMP.GetPixel(x, y));
                                                                }
                                                            }
                                                        }

                                                        for (int x = eye * (norBMP.Width / 4); x < (eye + 1) * (norBMP.Width / 4); x++)
                                                        {
                                                            for (int y = eyeY * (norBMP.Height / 4); y < (eyeY + 1) * (norBMP.Height / 4); y++)
                                                            {
                                                                finalBMP.SetPixel(x, y, thisEye.GetPixel(x - (eye * (norBMP.Width / 4)), y - (eyeY * (norBMP.Height / 4))));
                                                            }
                                                        }

                                                        if (eye == 3)
                                                        {
                                                            eye--;
                                                        }
                                                        else if (eye == 1)
                                                        {
                                                            eye += 2;
                                                        }
                                                        else if (eye == 0)
                                                        {
                                                            eye++;
                                                        }
                                                        else if (eye == 2)
                                                        {
                                                            eye -= 2;
                                                        }
                                                    }
                                                }
                                            }

                                            finalBMP.Save(texFile.Replace("Textures", "Models/DAE"));
                                            model.texture.Add(new RenderBase.OTexture(finalBMP, texFile.Replace("Textures", "Models/DAE")));
                                        }
                                    }
                                }
                                else if (texFile.Contains("Mouth1") && texFile.Contains("Nor") == false)
                                {
                                    bool hasNormals = false;

                                    foreach (string norFile in texFiles)
                                    {
                                        // If the mouth has a normal file, the UV coordinates expect it split across the image border.

                                        if (norFile.Contains("Mouth") && norFile.Contains("Nor"))
                                        {
                                            hasNormals = true;
                                        }
                                    }

                                    if (hasNormals == true)
                                    {
                                        Bitmap thisHalf = new Bitmap(tempBMP.Width / 2, tempBMP.Height / 4);
                                        Bitmap finalBMP = new Bitmap(tempBMP.Width * 2, tempBMP.Height);

                                        for (int halfY = 0; halfY < 4; halfY++)
                                        {
                                            for (int halfX = 0; halfX < 2; halfX++)
                                            {
                                                for (int x = halfX * (tempBMP.Width / 2); x < (halfX + 1) * (tempBMP.Width / 2); x++)
                                                {
                                                    for (int y = halfY * (tempBMP.Height / 4); y < (halfY + 1) * (tempBMP.Height / 4); y++)
                                                    {
                                                        thisHalf.SetPixel(x - (halfX * (tempBMP.Width / 2)), y - (halfY * (tempBMP.Height / 4)), tempBMP.GetPixel(x, y));
                                                    }
                                                }

                                                for (int x = halfX * (tempBMP.Width / 2); x < (halfX + 1) * (tempBMP.Width / 2); x++)
                                                {
                                                    for (int y = halfY * (tempBMP.Height / 4); y < (halfY + 1) * (tempBMP.Height / 4); y++)
                                                    {
                                                        finalBMP.SetPixel(x, y, thisHalf.GetPixel(x - (halfX * (tempBMP.Width / 2)), y - (halfY * (tempBMP.Height / 4))));
                                                    }
                                                }

                                                for (int x = halfX * (tempBMP.Width / 2); x < (halfX + 1) * (tempBMP.Width / 2); x++)
                                                {
                                                    for (int y = halfY * (tempBMP.Height / 4); y < (halfY + 1) * (tempBMP.Height / 4); y++)
                                                    {
                                                        finalBMP.SetPixel(finalBMP.Width - (x + 1), y, thisHalf.GetPixel(x - (halfX * (tempBMP.Width / 2)), y - (halfY * (tempBMP.Height / 4))));
                                                    }
                                                }
                                            }
                                        }

                                        finalBMP.Save(texFile.Replace("Textures", "Models/DAE"));
                                        model.texture.Add(new RenderBase.OTexture(finalBMP, texFile.Replace("Textures", "Models/DAE")));
                                    }
                                    else
                                    {
                                        // If the mouth doesn't have a normal file, the UV coordinates expect it as-is. Hooray!

                                        tempBMP.Save(texFile.Replace("Textures", "Models/DAE"));
                                        model.texture.Add(new RenderBase.OTexture(tempBMP, texFile.Replace("Textures", "Models/DAE")));
                                    }
                                }
                                else if (texFile.Contains("Eye1") && hasIris == false && texFile.Contains("AEye") == false && texFile.Contains("BEye") == false & texFile.Contains("CEye") == false)
                                {
                                    if (tempBMP.Width == tempBMP.Height)
                                    {
                                        tempBMP.Save(texFile.Replace("Textures", "Models/DAE"));
                                        model.texture.Add(new RenderBase.OTexture(tempBMP, texFile.Replace("Textures", "Models/DAE")));
                                    }
                                    else
                                    {
                                        Bitmap thisEye = new Bitmap(tempBMP.Width / 2, tempBMP.Height / 4);
                                        Bitmap finalBMP = new Bitmap(tempBMP.Width * 2, tempBMP.Height);

                                        for (int eyeY = 0; eyeY < 4; eyeY++)
                                        {
                                            for (int eyeX = 0; eyeX < 2; eyeX++)
                                            {
                                                for (int x = eyeX * (tempBMP.Width / 2); x < (eyeX + 1) * (tempBMP.Width / 2); x++)
                                                {
                                                    for (int y = eyeY * (tempBMP.Height / 4); y < (eyeY + 1) * (tempBMP.Height / 4); y++)
                                                    {
                                                        thisEye.SetPixel(x - (eyeX * (tempBMP.Width / 2)), y - (eyeY * (tempBMP.Height / 4)), tempBMP.GetPixel(x, y));
                                                    }
                                                }

                                                for (int x = eyeX * (tempBMP.Width / 2); x < (eyeX + 1) * (tempBMP.Width / 2); x++)
                                                {
                                                    for (int y = eyeY * (tempBMP.Height / 4); y < (eyeY + 1) * (tempBMP.Height / 4); y++)
                                                    {
                                                        finalBMP.SetPixel(x, y, thisEye.GetPixel(x - (eyeX * (tempBMP.Width / 2)), y - (eyeY * (tempBMP.Height / 4))));
                                                    }
                                                }

                                                for (int x = eyeX * (tempBMP.Width / 2); x < (eyeX + 1) * (tempBMP.Width / 2); x++)
                                                {
                                                    for (int y = eyeY * (tempBMP.Height / 4); y < (eyeY + 1) * (tempBMP.Height / 4); y++)
                                                    {
                                                        finalBMP.SetPixel(finalBMP.Width - (x + 1), y, thisEye.GetPixel(x - (eyeX * (tempBMP.Width / 2)), y - (eyeY * (tempBMP.Height / 4))));
                                                    }
                                                }
                                            }
                                        }

                                        finalBMP.Save(texFile.Replace("Textures", "Models/DAE"));
                                        model.texture.Add(new RenderBase.OTexture(finalBMP, texFile.Replace("Textures", "Models/DAE")));
                                    }
                                }
                                else if (texFile.Contains("AEye") || texFile.Contains("BEye") || texFile.Contains("CEye"))
                                {
                                    Bitmap finalBMP = new Bitmap(tempBMP, tempBMP.Width / 2, tempBMP.Height);

                                    finalBMP.Save(texFile.Replace("Textures", "Models/DAE"));
                                    model.texture.Add(new RenderBase.OTexture(finalBMP, texFile.Replace("Textures", "Models/DAE")));
                                }
                                else if (texFile.Contains("Fire"))
                                {
                                    Bitmap finalBMP = new Bitmap(tempBMP);

                                    foreach (string bodyFile in texFiles)
                                    {
                                        if ((bodyFile.Contains("Body1") || bodyFile.Contains("BodyA1")) && bodyFile.Contains("Nor") == false)
                                        {
                                            Bitmap bodyBMP = (Bitmap)Bitmap.FromFile(bodyFile);

                                            byte r, g, b;

                                            // Most-Frequent Body Color
                                            Color MFBC = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00), LFBC = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00);
                                            int LF = 0, SF = 65536;

                                            List<Color> colors = new List<Color>();
                                            List<int> freqs = new List<int>();

                                            for (int x = 0; x < bodyBMP.Width; x++)
                                            {
                                                for (int y = 0; y < bodyBMP.Height; y++)
                                                {
                                                    r = bodyBMP.GetPixel(x, y).R;
                                                    g = bodyBMP.GetPixel(x, y).G;
                                                    b = bodyBMP.GetPixel(x, y).B;

                                                    if (bodyBMP.GetPixel(x, y).A != 0x00)
                                                    {
                                                        bool matchFound = false;

                                                        foreach (Color c in colors)
                                                        {
                                                            if (c.R == r && c.G == g && c.B == b)
                                                            {
                                                                matchFound = true;
                                                                int freq = freqs[colors.IndexOf(c)];
                                                                freq++;

                                                                freqs[colors.IndexOf(c)] = freq;
                                                            }
                                                        }

                                                        if (matchFound == false)
                                                        {
                                                            colors.Add(Color.FromArgb(r, g, b));
                                                            freqs.Add(1);
                                                        }
                                                    }
                                                }
                                            }

                                            int tolerance = 18;

                                            foreach (Color c in colors)
                                            {
                                                if (freqs[colors.IndexOf(c)] > LF)
                                                {
                                                    LF = freqs[colors.IndexOf(c)];
                                                    MFBC = c;
                                                }
                                                else if (freqs[colors.IndexOf(c)] + 150 < SF)
                                                {
                                                    if (c.R <= (c.G - tolerance) || c.R >= (c.G + tolerance))
                                                    {
                                                        if (c.B <= (c.G - tolerance) || c.B >= (c.G + tolerance))
                                                        {
                                                            SF = freqs[colors.IndexOf(c)];
                                                            LFBC = c;
                                                        }
                                                    }
                                                }
                                            }

                                            bool mfbcgray = false;
                                            bool lfbcgray = false;
                                            bool bothgray = false;
                                            bool neithergray = false;

                                            if (MFBC.R > (MFBC.G - tolerance) && MFBC.R < (MFBC.G + tolerance))
                                            {
                                                if (MFBC.B > (MFBC.G - tolerance) && MFBC.B < (MFBC.G + tolerance))
                                                {
                                                    mfbcgray = true;
                                                }
                                            }

                                            if (LFBC.R > (LFBC.G - tolerance) && LFBC.R < (LFBC.G + tolerance))
                                            {
                                                if (LFBC.B > (LFBC.G - tolerance) && LFBC.B < (LFBC.G + tolerance))
                                                {
                                                    lfbcgray = true;
                                                }
                                            }

                                            if (mfbcgray && lfbcgray)
                                            {
                                                bothgray = true;
                                            }

                                            if (!mfbcgray && !lfbcgray)
                                            {
                                                neithergray = true;
                                            }

                                            Color baseOperator;
                                            Color accentOperator;

                                            if (bothgray)
                                            {
                                                baseOperator = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00);
                                                accentOperator = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00);
                                            }
                                            else if (neithergray)
                                            {
                                                baseOperator = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00);
                                                accentOperator = Color.FromArgb(0xFF, 0xFF, 0xFF, 0x00);
                                            }
                                            else
                                            {
                                                if (mfbcgray)
                                                {
                                                    baseOperator = LFBC;
                                                    accentOperator = LFBC;
                                                }
                                                else if (lfbcgray)
                                                {
                                                    baseOperator = MFBC;
                                                    accentOperator = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF);
                                                }
                                                else
                                                {
                                                    // Just to satisfy C#...
                                                    baseOperator = MFBC;
                                                    accentOperator = LFBC;
                                                }
                                            }

                                            for (int x = 0; x < finalBMP.Width; x++)
                                            {
                                                for (int y = 0; y < finalBMP.Height; y++)
                                                {
                                                    Color tempColor = tempBMP.GetPixel(x, y);
                                                    Color finalColor;

                                                    if (tempColor.R < 0x10 && tempColor.G < 0x10 && tempColor.B < 0x10)
                                                    {
                                                        finalColor = Color.FromArgb(0x1F, baseOperator.R, baseOperator.G, baseOperator.B);
                                                    }
                                                    else
                                                    {
                                                        finalColor = Color.FromArgb(0x1F, tempColor.R & accentOperator.R, tempColor.G & accentOperator.G, tempColor.B & accentOperator.B);
                                                    }

                                                    finalBMP.SetPixel(x, y, finalColor);
                                                }
                                            }

                                            finalBMP.Save(texFile.Replace("Textures", "Models/DAE"));
                                            model.texture.Add(new RenderBase.OTexture(finalBMP, texFile.Replace("Textures", "Models/DAE")));
                                        }
                                    }
                                }
                                else
                                {
                                    if (texFile.Contains("Iris2") == false && texFile.Contains("Eye2") == false && texFile.Contains("Mouth2") == false)
                                    {
                                        tempBMP.Save(texFile.Replace("Textures", "Models/DAE"));
                                        model.texture.Add(new RenderBase.OTexture(tempBMP, texFile.Replace("Textures", "Models/DAE")));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch // No packaged textures detected...
            {
            }

            foreach (RenderBase.OTexture tex in model.texture)
            {
                daeImage img = new daeImage();

                string n = Path.GetFileNameWithoutExtension(tex.name);

                img.id = n;
                img.name = n;

                if (tex.name.Contains("Shiny"))
                {
                    img.id += "_shiny";
                    img.name += "_shiny";

                    hasShiny = true;
                }

                img.id += "_id";

                img.init_from = tex.name;

                if (img.id.Contains("_shiny"))
                {
                    daeShiny.library_images.Add(img);
                }
                else
                {
                    dae.library_images.Add(img);
                }
            }

            #region Normal

            int currentMat = 0;

            foreach (RenderBase.OMaterial mat in mdl.material)
            {
                if (mat.name0 == null)
                {
                    mat.name0 = mat.name;
                }

                mdl.material[currentMat].name = mat.name;
                mdl.material[currentMat].name0 = mat.name0;

                currentMat++;

                daeMaterial mtl = new daeMaterial();
                mtl.name = mat.name + "_mat";
                mtl.id = mtl.name + "_id";
                mtl.instance_effect.url = "#eff_" + mtl.id;

                dae.library_materials.Add(mtl);

                daeEffect eff = new daeEffect();
                eff.id = "eff_" + mtl.id;
                eff.name = "eff_" + mtl.name;

                daeParam surface = new daeParam();
                surface.surface = new daeParamSurfaceElement();
                surface.sid = "img_surface";
                surface.surface.type = "2D";
                surface.surface.init_from = mat.name0 + "_id";
                surface.surface.format = "PNG";
                eff.profile_COMMON.newparam.Add(surface);

                bool fire = false;

                for (int i = 0; i < dae.library_images.Count; i++)
                {
                    if (dae.library_images[i].init_from.Contains(mat.name) || dae.library_images[i].id.Contains(mat.name) || dae.library_images[i].init_from.Contains(mat.name0) || dae.library_images[i].id.Contains(mat.name0))
                    {
                        if (dae.library_images[i].init_from.Contains("Nor") == false)
                        {
                            if (mat.name.Contains("Fire"))
                            {
                                fire = true;

                                dae.library_images[i].name = dae.library_images[i].name.Replace("Mask", "1");
                                dae.library_images[i].id = dae.library_images[i].id.Replace("Mask", "1");
                                dae.library_images[i].init_from = dae.library_images[i].init_from.Replace("Mask", "1");

                                mat.name = mat.name.Replace("Mask", "1");
                                mat.name0 = mat.name0.Replace("Mask", "1");
                            }

                            surface.surface.init_from = dae.library_images[i].id;
                        }
                    }
                }

                daeParam sampler = new daeParam();
                sampler.sampler2D = new daeParamSampler2DElement();
                sampler.sid = "img_sampler";
                sampler.sampler2D.source = "img_surface";

                switch (mat.textureMapper[0].wrapU)
                {
                    case RenderBase.OTextureWrap.repeat: sampler.sampler2D.wrap_s = "WRAP"; break;
                    case RenderBase.OTextureWrap.mirroredRepeat: sampler.sampler2D.wrap_s = "MIRROR"; break;
                    case RenderBase.OTextureWrap.clampToEdge: sampler.sampler2D.wrap_s = "CLAMP"; break;
                    case RenderBase.OTextureWrap.clampToBorder: sampler.sampler2D.wrap_s = "BORDER"; break;
                    default: sampler.sampler2D.wrap_s = "WRAP"; break;
                }

                switch (mat.textureMapper[0].wrapV)
                {
                    case RenderBase.OTextureWrap.repeat: sampler.sampler2D.wrap_t = "WRAP"; break;
                    case RenderBase.OTextureWrap.mirroredRepeat: sampler.sampler2D.wrap_t = "MIRROR"; break;
                    case RenderBase.OTextureWrap.clampToEdge: sampler.sampler2D.wrap_t = "CLAMP"; break;
                    case RenderBase.OTextureWrap.clampToBorder: sampler.sampler2D.wrap_t = "BORDER"; break;
                    default: sampler.sampler2D.wrap_t = "WRAP"; break;
                }

                switch (mat.textureMapper[0].minFilter)
                {
                    case RenderBase.OTextureMinFilter.linearMipmapLinear: sampler.sampler2D.minfilter = "LINEAR_MIPMAP_LINEAR"; break;
                    case RenderBase.OTextureMinFilter.linearMipmapNearest: sampler.sampler2D.minfilter = "LINEAR_MIPMAP_NEAREST"; break;
                    case RenderBase.OTextureMinFilter.nearestMipmapLinear: sampler.sampler2D.minfilter = "NEAREST_MIPMAP_LINEAR"; break;
                    case RenderBase.OTextureMinFilter.nearestMipmapNearest: sampler.sampler2D.minfilter = "NEAREST_MIPMAP_NEAREST"; break;
                    default: sampler.sampler2D.minfilter = "NONE"; break;
                }

                switch (mat.textureMapper[0].magFilter)
                {
                    case RenderBase.OTextureMagFilter.linear: sampler.sampler2D.magfilter = "LINEAR"; break;
                    case RenderBase.OTextureMagFilter.nearest: sampler.sampler2D.magfilter = "NEAREST"; break;
                    default: sampler.sampler2D.magfilter = "NONE"; break;
                }

                sampler.sampler2D.mipfilter = sampler.sampler2D.magfilter;

                eff.profile_COMMON.newparam.Add(sampler);

                eff.profile_COMMON.technique.sid = "img_technique";

                eff.profile_COMMON.technique.phong.emission.set(Color.Black);
                eff.profile_COMMON.technique.phong.ambient.set(Color.Black);
                eff.profile_COMMON.technique.phong.specular.set(Color.White);

                eff.profile_COMMON.technique.phong.diffuse.texture.texture = "img_sampler";

                eff.profile_COMMON.technique.phong.transparency = new daePhongTransparent();

                if (fire)
                {
                    eff.profile_COMMON.technique.phong.transparency.value = "0.1";
                }
                else
                {
                    eff.profile_COMMON.technique.phong.transparency.value = "1.0";
                }

                dae.library_effects.Add(eff);
            }

            string jointNames = null;
            string invBindPoses = null;
            for (int index = 0; index < mdl.skeleton.Count; index++)
            {
                RenderBase.OMatrix transform = new RenderBase.OMatrix();
                transformSkeleton(mdl.skeleton, index, ref transform);

                jointNames += mdl.skeleton[index].name;
                daeMatrix mtx = new daeMatrix();
                mtx.set(transform.invert());
                invBindPoses += mtx.data;
                if (index < mdl.skeleton.Count - 1)
                {
                    jointNames += " ";
                    invBindPoses += " ";
                }
            }

            int meshIndex = 0;
            daeVisualScene vs = new daeVisualScene();
            vs.name = "vs_" + mdl.name;
            vs.id = vs.name + "_id";
            if (mdl.skeleton.Count > 0) writeSkeleton(mdl.skeleton, 0, ref vs.node);

            bool rightIris = false;

            foreach (RenderBase.OMesh obj in mdl.mesh)
            {
                float largestUV = 0.0f;

                //Geometry
                daeGeometry geometry = new daeGeometry();

                string meshName = "mesh_" + meshIndex++ + "_" + obj.name;
                geometry.id = meshName + "_id";
                geometry.name = meshName;

                MeshUtils.optimizedMesh mesh = MeshUtils.optimizeMesh(obj);
                List<float> positions = new List<float>();
                List<float> normals = new List<float>();
                List<float> uv0 = new List<float>();
                List<float> uv1 = new List<float>();
                List<float> uv2 = new List<float>();
                List<float> colors = new List<float>();

                if (obj.name.Contains("Iris"))
                {
                    foreach (RenderBase.OVertex vtx in mesh.vertices)
                    {
                        if (mesh.texUVCount > 0)
                        {
                            if (vtx.texture0.x > largestUV)
                            {
                                largestUV = vtx.texture0.x;
                            }
                        }
                    }

                    foreach (RenderBase.OVertex vtx in mesh.vertices)
                    {
                        if (mesh.texUVCount > 0)
                        {
                            vtx.texture0.x = largestUV - vtx.texture0.x;

                            if (rightIris)
                            {
                                vtx.texture0.x = 1.25f - vtx.texture0.x;
                            }
                        }

                        if (mesh.texUVCount > 1)
                        {
                            vtx.texture1.x = largestUV - vtx.texture1.x;

                            if (rightIris)
                            {
                                vtx.texture1.x = 1.25f - vtx.texture1.x;
                            }
                        }

                        if (mesh.texUVCount > 2)
                        {
                            vtx.texture2.x = largestUV - vtx.texture2.x;

                            if (rightIris)
                            {
                                vtx.texture2.x = 1.25f - vtx.texture2.x;
                            }
                        }
                    }

                    rightIris = !rightIris;
                }
                else if (obj.name.Contains("Eye"))
                {
                    foreach (RenderBase.OVertex vtx in mesh.vertices)
                    {
                        if (mesh.texUVCount > 0)
                        {
                            if (vtx.texture0.x > largestUV)
                            {
                                largestUV = vtx.texture0.x;
                            }
                        }
                    }
                    foreach (RenderBase.OVertex vtx in mesh.vertices)
                    {
                        if (mesh.texUVCount > 0)
                        {
                            vtx.texture0.x = largestUV - vtx.texture0.x;
                        }

                        if (mesh.texUVCount > 1)
                        {
                            vtx.texture1.x = largestUV - vtx.texture1.x;
                        }

                        if (mesh.texUVCount > 2)
                        {
                            vtx.texture2.x = largestUV - vtx.texture2.x;
                        }
                    }
                }

                foreach (RenderBase.OVertex vtx in mesh.vertices)
                {
                    positions.Add(vtx.position.x);
                    positions.Add(vtx.position.y);
                    positions.Add(vtx.position.z);

                    if (mesh.hasNormal)
                    {
                        normals.Add(vtx.normal.x);
                        normals.Add(vtx.normal.y);
                        normals.Add(vtx.normal.z);
                    }

                    if (mesh.texUVCount > 0)
                    {
                        uv0.Add(vtx.texture0.x);
                        uv0.Add(vtx.texture0.y);
                    }

                    if (mesh.texUVCount > 1)
                    {
                        uv1.Add(vtx.texture1.x);
                        uv1.Add(vtx.texture1.y);
                    }

                    if (mesh.texUVCount > 2)
                    {
                        uv2.Add(vtx.texture2.x);
                        uv2.Add(vtx.texture2.y);
                    }

                    if (mesh.hasColor)
                    {
                        colors.Add(((vtx.diffuseColor >> 16) & 0xff) / 255f);
                        colors.Add(((vtx.diffuseColor >> 8) & 0xff) / 255f);
                        colors.Add((vtx.diffuseColor & 0xff) / 255f);
                        colors.Add(((vtx.diffuseColor >> 24) & 0xff) / 255f);
                    }
                }

                daeSource position = new daeSource();
                position.name = meshName + "_position";
                position.id = position.name + "_id";
                position.float_array = new daeFloatArray();
                position.float_array.id = position.name + "_array_id";
                position.float_array.set(positions);
                position.technique_common.accessor.source = "#" + position.float_array.id;
                position.technique_common.accessor.count = (uint)mesh.vertices.Count;
                position.technique_common.accessor.stride = 3;
                position.technique_common.accessor.addParam("X", "float");
                position.technique_common.accessor.addParam("Y", "float");
                position.technique_common.accessor.addParam("Z", "float");

                geometry.mesh.source.Add(position);

                daeSource normal = new daeSource();
                if (mesh.hasNormal)
                {
                    normal.name = meshName + "_normal";
                    normal.id = normal.name + "_id";
                    normal.float_array = new daeFloatArray();
                    normal.float_array.id = normal.name + "_array_id";
                    normal.float_array.set(normals);
                    normal.technique_common.accessor.source = "#" + normal.float_array.id;
                    normal.technique_common.accessor.count = (uint)mesh.vertices.Count;
                    normal.technique_common.accessor.stride = 3;
                    normal.technique_common.accessor.addParam("X", "float");
                    normal.technique_common.accessor.addParam("Y", "float");
                    normal.technique_common.accessor.addParam("Z", "float");

                    geometry.mesh.source.Add(normal);
                }

                daeSource[] texUV = new daeSource[3];
                for (int i = 0; i < mesh.texUVCount; i++)
                {
                    texUV[i] = new daeSource();

                    texUV[i].name = meshName + "_uv" + i;
                    texUV[i].id = texUV[i].name + "_id";
                    texUV[i].float_array = new daeFloatArray();
                    texUV[i].float_array.id = texUV[i].name + "_array_id";
                    texUV[i].technique_common.accessor.source = "#" + texUV[i].float_array.id;
                    texUV[i].technique_common.accessor.count = (uint)mesh.vertices.Count;
                    texUV[i].technique_common.accessor.stride = 2;
                    texUV[i].technique_common.accessor.addParam("S", "float");
                    texUV[i].technique_common.accessor.addParam("T", "float");

                    geometry.mesh.source.Add(texUV[i]);
                }

                daeSource color = new daeSource();
                if (mesh.hasColor)
                {
                    color.name = meshName + "_color";
                    color.id = color.name + "_id";
                    color.float_array = new daeFloatArray();
                    color.float_array.id = color.name + "_array_id";
                    color.float_array.set(colors);
                    color.technique_common.accessor.source = "#" + color.float_array.id;
                    color.technique_common.accessor.count = (uint)mesh.vertices.Count;
                    color.technique_common.accessor.stride = 4;
                    color.technique_common.accessor.addParam("R", "float");
                    color.technique_common.accessor.addParam("G", "float");
                    color.technique_common.accessor.addParam("B", "float");
                    color.technique_common.accessor.addParam("A", "float");

                    geometry.mesh.source.Add(color);
                }

                geometry.mesh.vertices.id = meshName + "_vertices_id";
                geometry.mesh.vertices.addInput("POSITION", "#" + position.id);

                geometry.mesh.triangles.material = mdl.material[obj.materialId].name + "_mat";
                geometry.mesh.triangles.addInput("VERTEX", "#" + geometry.mesh.vertices.id);
                if (mesh.hasNormal) geometry.mesh.triangles.addInput("NORMAL", "#" + normal.id);
                if (mesh.hasColor) geometry.mesh.triangles.addInput("COLOR", "#" + color.id);
                if (mesh.texUVCount > 0)
                {
                    texUV[0].float_array.set(uv0);
                    geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[0].id);
                }
                if (mesh.texUVCount > 1)
                {
                    texUV[1].float_array.set(uv1);
                    geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[1].id, 0, 1);
                }
                if (mesh.texUVCount > 2)
                {
                    texUV[2].float_array.set(uv2);
                    geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[2].id, 0, 2);
                }
                geometry.mesh.triangles.set(mesh.indices);

                dae.library_geometries.Add(geometry);

                bool hasNode = obj.vertices[0].node.Count > 0;
                bool hasWeight = obj.vertices[0].weight.Count > 0;
                bool hasController = hasNode && hasWeight;

                //Controller
                daeController controller = new daeController();
                if (hasController)
                {
                    controller.id = meshName + "_ctrl_id";

                    controller.skin.source = "#" + geometry.id;
                    controller.skin.bind_shape_matrix.set(new RenderBase.OMatrix());

                    daeSource joints = new daeSource();
                    joints.id = meshName + "_ctrl_joint_names_id";
                    joints.Name_array = new daeNameArray();
                    joints.Name_array.id = meshName + "_ctrl_joint_names_array_id";
                    joints.Name_array.count = (uint)mdl.skeleton.Count;
                    joints.Name_array.data = jointNames;
                    joints.technique_common.accessor.source = "#" + joints.Name_array.id;
                    joints.technique_common.accessor.count = joints.Name_array.count;
                    joints.technique_common.accessor.stride = 1;
                    joints.technique_common.accessor.addParam("JOINT", "Name");

                    controller.skin.src.Add(joints);

                    daeSource bindPoses = new daeSource();
                    bindPoses.id = meshName + "_ctrl_inv_bind_poses_id";
                    bindPoses.float_array = new daeFloatArray();
                    bindPoses.float_array.id = meshName + "_ctrl_inv_bind_poses_array_id";
                    bindPoses.float_array.count = (uint)(mdl.skeleton.Count * 16);
                    bindPoses.float_array.data = invBindPoses;
                    bindPoses.technique_common.accessor.source = "#" + bindPoses.float_array.id;
                    bindPoses.technique_common.accessor.count = (uint)mdl.skeleton.Count;
                    bindPoses.technique_common.accessor.stride = 16;
                    bindPoses.technique_common.accessor.addParam("TRANSFORM", "float4x4");

                    controller.skin.src.Add(bindPoses);

                    daeSource weights = new daeSource();
                    weights.id = meshName + "_ctrl_weights_id";
                    weights.float_array = new daeFloatArray();
                    weights.float_array.id = meshName + "_ctrl_weights_array_id";
                    weights.technique_common.accessor.source = "#" + weights.float_array.id;
                    weights.technique_common.accessor.stride = 1;
                    weights.technique_common.accessor.addParam("WEIGHT", "float");

                    StringBuilder w = new StringBuilder();
                    StringBuilder vcount = new StringBuilder();
                    StringBuilder v = new StringBuilder();

                    float[] wLookBack = new float[32];
                    uint wLookBackIndex = 0;
                    int buffLen = 0;

                    int wIndex = 0;
                    int wCount = 0;
                    foreach (RenderBase.OVertex vtx in mesh.vertices)
                    {
                        int count = Math.Min(vtx.node.Count, vtx.weight.Count);

                        vcount.Append(count + " ");
                        for (int n = 0; n < count; n++)
                        {
                            v.Append(vtx.node[n] + " ");
                            bool found = false;
                            uint bPos = (wLookBackIndex - 1) & 0x1f;
                            for (int i = 0; i < buffLen; i++)
                            {
                                if (wLookBack[bPos] == vtx.weight[n])
                                {
                                    v.Append(wIndex - (i + 1) + " ");
                                    found = true;
                                    break;
                                }
                                bPos = (bPos - 1) & 0x1f;
                            }

                            if (!found)
                            {
                                v.Append(wIndex++ + " ");
                                w.Append(vtx.weight[n].ToString(CultureInfo.InvariantCulture) + " ");
                                wCount++;

                                wLookBack[wLookBackIndex] = vtx.weight[n];
                                wLookBackIndex = (wLookBackIndex + 1) & 0x1f;
                                if (buffLen < wLookBack.Length) buffLen++;
                            }
                        }
                    }

                    weights.float_array.data = w.ToString().TrimEnd();
                    weights.float_array.count = (uint)wCount;
                    weights.technique_common.accessor.count = (uint)wCount;

                    controller.skin.src.Add(weights);
                    controller.skin.vertex_weights.vcount = vcount.ToString().TrimEnd();
                    controller.skin.vertex_weights.v = v.ToString().TrimEnd();
                    controller.skin.vertex_weights.count = (uint)mesh.vertices.Count;
                    controller.skin.joints.addInput("JOINT", "#" + joints.id);
                    controller.skin.joints.addInput("INV_BIND_MATRIX", "#" + bindPoses.id);

                    controller.skin.vertex_weights.addInput("JOINT", "#" + joints.id);
                    controller.skin.vertex_weights.addInput("WEIGHT", "#" + weights.id, 1);

                    if (dae.library_controllers == null) dae.library_controllers = new List<daeController>();
                    dae.library_controllers.Add(controller);
                }

                //Visual scene node
                daeNode node = new daeNode();
                node.name = "vsn_" + meshName;
                node.id = node.name + "_id";
                node.matrix.set(new RenderBase.OMatrix());
                if (hasController)
                {
                    node.instance_controller = new daeInstanceController();
                    node.instance_controller.url = "#" + controller.id;
                    node.instance_controller.skeleton = "#" + mdl.skeleton[0].name + "_bone_id";
                    node.instance_controller.bind_material.technique_common.instance_material.symbol = mdl.material[obj.materialId].name + "_mat";
                    node.instance_controller.bind_material.technique_common.instance_material.target = "#" + mdl.material[obj.materialId].name + "_mat_id";
                }
                else
                {
                    node.instance_geometry = new daeInstanceGeometry();
                    node.instance_geometry.url = "#" + geometry.id;
                    node.instance_geometry.bind_material.technique_common.instance_material.symbol = mdl.material[obj.materialId].name + "_mat";
                    node.instance_geometry.bind_material.technique_common.instance_material.target = "#" + mdl.material[obj.materialId].name + "_mat_id";
                }

                vs.node.Add(node);
            }
            dae.library_visual_scenes.Add(vs);

            daeInstaceVisualScene scene = new daeInstaceVisualScene();
            scene.url = "#" + vs.id;
            dae.scene.Add(scene);

            XmlWriterSettings settings = new XmlWriterSettings
            {
                Encoding = Encoding.UTF8,
                Indent = true
            };

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", "http://www.collada.org/2005/11/COLLADASchema");
            XmlSerializer serializer = new XmlSerializer(typeof(COLLADA));
            XmlWriter output = XmlWriter.Create(new FileStream(fileName.Replace(".bch", ".dae").Replace("BCH", "DAE"), FileMode.Create), settings);
            serializer.Serialize(output, dae, ns);
            output.Close();

            #endregion

            #region Shiny

            if (hasShiny)
            {
                currentMat = 0;

                foreach (RenderBase.OMaterial mat in mdl.material)
                {
                    if (mat.name0 == null)
                    {
                        mat.name0 = mat.name;
                    }

                    mat.name += "_shiny";
                    mat.name0 += "_shiny";

                    mdl.material[currentMat].name = mat.name;
                    mdl.material[currentMat].name0 = mat.name0;

                    currentMat++;

                    daeMaterial mtl = new daeMaterial();
                    mtl.name = mat.name + "_mat";
                    mtl.id = mtl.name + "_id";
                    mtl.instance_effect.url = "#eff_" + mtl.id;

                    daeShiny.library_materials.Add(mtl);

                    daeEffect eff = new daeEffect();
                    eff.id = "eff_" + mtl.id;
                    eff.name = "eff_" + mtl.name;

                    daeParam surface = new daeParam();
                    surface.surface = new daeParamSurfaceElement();
                    surface.sid = "img_surface";
                    surface.surface.type = "2D";
                    surface.surface.init_from = mat.name0 + "_id";
                    surface.surface.format = "PNG";
                    eff.profile_COMMON.newparam.Add(surface);

                    bool fire = false;

                    for (int i = 0; i < daeShiny.library_images.Count; i++)
                    {
                        if (daeShiny.library_images[i].init_from.Contains(mat.name) || daeShiny.library_images[i].id.Contains(mat.name) || daeShiny.library_images[i].init_from.Contains(mat.name0) || daeShiny.library_images[i].id.Contains(mat.name0))
                        {
                            if (daeShiny.library_images[i].init_from.Contains("Nor") == false)
                            {
                                if (mat.name.Contains("Fire"))
                                {
                                    fire = true;

                                    daeShiny.library_images[i].name = daeShiny.library_images[i].name.Replace("Mask", "1");
                                    daeShiny.library_images[i].id = daeShiny.library_images[i].id.Replace("Mask", "1");
                                    daeShiny.library_images[i].init_from = daeShiny.library_images[i].init_from.Replace("Mask", "1");

                                    mat.name = mat.name.Replace("Mask", "1");
                                    mat.name0 = mat.name0.Replace("Mask", "1");
                                }

                                surface.surface.init_from = daeShiny.library_images[i].id;
                            }
                        }
                    }

                    if (mat.name.Contains("Fire"))
                    {
                        fire = true;
                    }

                    daeParam sampler = new daeParam();
                    sampler.sampler2D = new daeParamSampler2DElement();
                    sampler.sid = "img_sampler";
                    sampler.sampler2D.source = "img_surface";

                    switch (mat.textureMapper[0].wrapU)
                    {
                        case RenderBase.OTextureWrap.repeat: sampler.sampler2D.wrap_s = "WRAP"; break;
                        case RenderBase.OTextureWrap.mirroredRepeat: sampler.sampler2D.wrap_s = "MIRROR"; break;
                        case RenderBase.OTextureWrap.clampToEdge: sampler.sampler2D.wrap_s = "CLAMP"; break;
                        case RenderBase.OTextureWrap.clampToBorder: sampler.sampler2D.wrap_s = "BORDER"; break;
                        default: sampler.sampler2D.wrap_s = "WRAP"; break;
                    }

                    switch (mat.textureMapper[0].wrapV)
                    {
                        case RenderBase.OTextureWrap.repeat: sampler.sampler2D.wrap_t = "WRAP"; break;
                        case RenderBase.OTextureWrap.mirroredRepeat: sampler.sampler2D.wrap_t = "MIRROR"; break;
                        case RenderBase.OTextureWrap.clampToEdge: sampler.sampler2D.wrap_t = "CLAMP"; break;
                        case RenderBase.OTextureWrap.clampToBorder: sampler.sampler2D.wrap_t = "BORDER"; break;
                        default: sampler.sampler2D.wrap_t = "WRAP"; break;
                    }

                    switch (mat.textureMapper[0].minFilter)
                    {
                        case RenderBase.OTextureMinFilter.linearMipmapLinear: sampler.sampler2D.minfilter = "LINEAR_MIPMAP_LINEAR"; break;
                        case RenderBase.OTextureMinFilter.linearMipmapNearest: sampler.sampler2D.minfilter = "LINEAR_MIPMAP_NEAREST"; break;
                        case RenderBase.OTextureMinFilter.nearestMipmapLinear: sampler.sampler2D.minfilter = "NEAREST_MIPMAP_LINEAR"; break;
                        case RenderBase.OTextureMinFilter.nearestMipmapNearest: sampler.sampler2D.minfilter = "NEAREST_MIPMAP_NEAREST"; break;
                        default: sampler.sampler2D.minfilter = "NONE"; break;
                    }

                    switch (mat.textureMapper[0].magFilter)
                    {
                        case RenderBase.OTextureMagFilter.linear: sampler.sampler2D.magfilter = "LINEAR"; break;
                        case RenderBase.OTextureMagFilter.nearest: sampler.sampler2D.magfilter = "NEAREST"; break;
                        default: sampler.sampler2D.magfilter = "NONE"; break;
                    }

                    sampler.sampler2D.mipfilter = sampler.sampler2D.magfilter;

                    eff.profile_COMMON.newparam.Add(sampler);

                    eff.profile_COMMON.technique.sid = "img_technique";

                    eff.profile_COMMON.technique.phong.emission.set(Color.Black);
                    eff.profile_COMMON.technique.phong.ambient.set(Color.Black);
                    eff.profile_COMMON.technique.phong.specular.set(Color.White);

                    eff.profile_COMMON.technique.phong.diffuse.texture.texture = "img_sampler";

                    eff.profile_COMMON.technique.phong.transparency = new daePhongTransparent();

                    if (fire)
                    {
                        eff.profile_COMMON.technique.phong.transparency.value = "0.1";
                    }
                    else
                    {
                        eff.profile_COMMON.technique.phong.transparency.value = "1.0";
                    }

                    daeShiny.library_effects.Add(eff);
                }

                jointNames = null;
                invBindPoses = null;
                for (int index = 0; index < mdl.skeleton.Count; index++)
                {
                    RenderBase.OMatrix transform = new RenderBase.OMatrix();
                    transformSkeleton(mdl.skeleton, index, ref transform);

                    jointNames += mdl.skeleton[index].name;
                    daeMatrix mtx = new daeMatrix();
                    mtx.set(transform.invert());
                    invBindPoses += mtx.data;
                    if (index < mdl.skeleton.Count - 1)
                    {
                        jointNames += " ";
                        invBindPoses += " ";
                    }
                }

                meshIndex = 0;
                vs = new daeVisualScene();
                vs.name = "vs_" + mdl.name;
                vs.id = vs.name + "_id";
                if (mdl.skeleton.Count > 0) writeSkeleton(mdl.skeleton, 0, ref vs.node);

                rightIris = false;

                foreach (RenderBase.OMesh obj in mdl.mesh)
                {
                    float largestUV = 0.0f;

                    //Geometry
                    daeGeometry geometry = new daeGeometry();

                    string meshName = "mesh_" + meshIndex++ + "_" + obj.name;
                    geometry.id = meshName + "_id";
                    geometry.name = meshName;

                    MeshUtils.optimizedMesh mesh = MeshUtils.optimizeMesh(obj);
                    List<float> positions = new List<float>();
                    List<float> normals = new List<float>();
                    List<float> uv0 = new List<float>();
                    List<float> uv1 = new List<float>();
                    List<float> uv2 = new List<float>();
                    List<float> colors = new List<float>();

                    if (obj.name.Contains("Iris"))
                    {
                        foreach (RenderBase.OVertex vtx in mesh.vertices)
                        {
                            if (mesh.texUVCount > 0)
                            {
                                if (vtx.texture0.x > largestUV)
                                {
                                    largestUV = vtx.texture0.x;
                                }
                            }
                        }

                        foreach (RenderBase.OVertex vtx in mesh.vertices)
                        {
                            if (mesh.texUVCount > 0)
                            {
                                vtx.texture0.x = largestUV - vtx.texture0.x;

                                if (rightIris)
                                {
                                    vtx.texture0.x = 1.25f - vtx.texture0.x;
                                }
                            }

                            if (mesh.texUVCount > 1)
                            {
                                vtx.texture1.x = largestUV - vtx.texture1.x;

                                if (rightIris)
                                {
                                    vtx.texture1.x = 1.25f - vtx.texture1.x;
                                }
                            }

                            if (mesh.texUVCount > 2)
                            {
                                vtx.texture2.x = largestUV - vtx.texture2.x;

                                if (rightIris)
                                {
                                    vtx.texture2.x = 1.25f - vtx.texture2.x;
                                }
                            }
                        }

                        rightIris = !rightIris;
                    }
                    else if (obj.name.Contains("Eye"))
                    {
                        foreach (RenderBase.OVertex vtx in mesh.vertices)
                        {
                            if (mesh.texUVCount > 0)
                            {
                                if (vtx.texture0.x > largestUV)
                                {
                                    largestUV = vtx.texture0.x;
                                }
                            }
                        }

                        foreach (RenderBase.OVertex vtx in mesh.vertices)
                        {
                            if (mesh.texUVCount > 0)
                            {
                                vtx.texture0.x = largestUV - vtx.texture0.x;
                            }

                            if (mesh.texUVCount > 1)
                            {
                                vtx.texture1.x = largestUV - vtx.texture1.x;
                            }

                            if (mesh.texUVCount > 2)
                            {
                                vtx.texture2.x = largestUV - vtx.texture2.x;
                            }
                        }
                    }

                    foreach (RenderBase.OVertex vtx in mesh.vertices)
                    {
                        positions.Add(vtx.position.x);
                        positions.Add(vtx.position.y);
                        positions.Add(vtx.position.z);

                        if (mesh.hasNormal)
                        {
                            normals.Add(vtx.normal.x);
                            normals.Add(vtx.normal.y);
                            normals.Add(vtx.normal.z);
                        }

                        if (mesh.texUVCount > 0)
                        {
                            uv0.Add(vtx.texture0.x);
                            uv0.Add(vtx.texture0.y);
                        }

                        if (mesh.texUVCount > 1)
                        {
                            uv1.Add(vtx.texture1.x);
                            uv1.Add(vtx.texture1.y);
                        }

                        if (mesh.texUVCount > 2)
                        {
                            uv2.Add(vtx.texture2.x);
                            uv2.Add(vtx.texture2.y);
                        }

                        if (mesh.hasColor)
                        {
                            colors.Add(((vtx.diffuseColor >> 16) & 0xff) / 255f);
                            colors.Add(((vtx.diffuseColor >> 8) & 0xff) / 255f);
                            colors.Add((vtx.diffuseColor & 0xff) / 255f);
                            colors.Add(((vtx.diffuseColor >> 24) & 0xff) / 255f);
                        }
                    }

                    daeSource position = new daeSource();
                    position.name = meshName + "_position";
                    position.id = position.name + "_id";
                    position.float_array = new daeFloatArray();
                    position.float_array.id = position.name + "_array_id";
                    position.float_array.set(positions);
                    position.technique_common.accessor.source = "#" + position.float_array.id;
                    position.technique_common.accessor.count = (uint)mesh.vertices.Count;
                    position.technique_common.accessor.stride = 3;
                    position.technique_common.accessor.addParam("X", "float");
                    position.technique_common.accessor.addParam("Y", "float");
                    position.technique_common.accessor.addParam("Z", "float");

                    geometry.mesh.source.Add(position);

                    daeSource normal = new daeSource();
                    if (mesh.hasNormal)
                    {
                        normal.name = meshName + "_normal";
                        normal.id = normal.name + "_id";
                        normal.float_array = new daeFloatArray();
                        normal.float_array.id = normal.name + "_array_id";
                        normal.float_array.set(normals);
                        normal.technique_common.accessor.source = "#" + normal.float_array.id;
                        normal.technique_common.accessor.count = (uint)mesh.vertices.Count;
                        normal.technique_common.accessor.stride = 3;
                        normal.technique_common.accessor.addParam("X", "float");
                        normal.technique_common.accessor.addParam("Y", "float");
                        normal.technique_common.accessor.addParam("Z", "float");

                        geometry.mesh.source.Add(normal);
                    }

                    daeSource[] texUV = new daeSource[3];
                    for (int i = 0; i < mesh.texUVCount; i++)
                    {
                        texUV[i] = new daeSource();

                        texUV[i].name = meshName + "_uv" + i;
                        texUV[i].id = texUV[i].name + "_id";
                        texUV[i].float_array = new daeFloatArray();
                        texUV[i].float_array.id = texUV[i].name + "_array_id";
                        texUV[i].technique_common.accessor.source = "#" + texUV[i].float_array.id;
                        texUV[i].technique_common.accessor.count = (uint)mesh.vertices.Count;
                        texUV[i].technique_common.accessor.stride = 2;
                        texUV[i].technique_common.accessor.addParam("S", "float");
                        texUV[i].technique_common.accessor.addParam("T", "float");

                        geometry.mesh.source.Add(texUV[i]);
                    }

                    daeSource color = new daeSource();
                    if (mesh.hasColor)
                    {
                        color.name = meshName + "_color";
                        color.id = color.name + "_id";
                        color.float_array = new daeFloatArray();
                        color.float_array.id = color.name + "_array_id";
                        color.float_array.set(colors);
                        color.technique_common.accessor.source = "#" + color.float_array.id;
                        color.technique_common.accessor.count = (uint)mesh.vertices.Count;
                        color.technique_common.accessor.stride = 4;
                        color.technique_common.accessor.addParam("R", "float");
                        color.technique_common.accessor.addParam("G", "float");
                        color.technique_common.accessor.addParam("B", "float");
                        color.technique_common.accessor.addParam("A", "float");

                        geometry.mesh.source.Add(color);
                    }

                    geometry.mesh.vertices.id = meshName + "_vertices_id";
                    geometry.mesh.vertices.addInput("POSITION", "#" + position.id);

                    geometry.mesh.triangles.material = mdl.material[obj.materialId].name + "_mat";
                    geometry.mesh.triangles.addInput("VERTEX", "#" + geometry.mesh.vertices.id);
                    if (mesh.hasNormal) geometry.mesh.triangles.addInput("NORMAL", "#" + normal.id);
                    if (mesh.hasColor) geometry.mesh.triangles.addInput("COLOR", "#" + color.id);
                    if (mesh.texUVCount > 0)
                    {
                        texUV[0].float_array.set(uv0);
                        geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[0].id);
                    }
                    if (mesh.texUVCount > 1)
                    {
                        texUV[1].float_array.set(uv1);
                        geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[1].id, 0, 1);
                    }
                    if (mesh.texUVCount > 2)
                    {
                        texUV[2].float_array.set(uv2);
                        geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[2].id, 0, 2);
                    }
                    geometry.mesh.triangles.set(mesh.indices);

                    daeShiny.library_geometries.Add(geometry);

                    bool hasNode = obj.vertices[0].node.Count > 0;
                    bool hasWeight = obj.vertices[0].weight.Count > 0;
                    bool hasController = hasNode && hasWeight;

                    //Controller
                    daeController controller = new daeController();
                    if (hasController)
                    {
                        controller.id = meshName + "_ctrl_id";

                        controller.skin.source = "#" + geometry.id;
                        controller.skin.bind_shape_matrix.set(new RenderBase.OMatrix());

                        daeSource joints = new daeSource();
                        joints.id = meshName + "_ctrl_joint_names_id";
                        joints.Name_array = new daeNameArray();
                        joints.Name_array.id = meshName + "_ctrl_joint_names_array_id";
                        joints.Name_array.count = (uint)mdl.skeleton.Count;
                        joints.Name_array.data = jointNames;
                        joints.technique_common.accessor.source = "#" + joints.Name_array.id;
                        joints.technique_common.accessor.count = joints.Name_array.count;
                        joints.technique_common.accessor.stride = 1;
                        joints.technique_common.accessor.addParam("JOINT", "Name");

                        controller.skin.src.Add(joints);

                        daeSource bindPoses = new daeSource();
                        bindPoses.id = meshName + "_ctrl_inv_bind_poses_id";
                        bindPoses.float_array = new daeFloatArray();
                        bindPoses.float_array.id = meshName + "_ctrl_inv_bind_poses_array_id";
                        bindPoses.float_array.count = (uint)(mdl.skeleton.Count * 16);
                        bindPoses.float_array.data = invBindPoses;
                        bindPoses.technique_common.accessor.source = "#" + bindPoses.float_array.id;
                        bindPoses.technique_common.accessor.count = (uint)mdl.skeleton.Count;
                        bindPoses.technique_common.accessor.stride = 16;
                        bindPoses.technique_common.accessor.addParam("TRANSFORM", "float4x4");

                        controller.skin.src.Add(bindPoses);

                        daeSource weights = new daeSource();
                        weights.id = meshName + "_ctrl_weights_id";
                        weights.float_array = new daeFloatArray();
                        weights.float_array.id = meshName + "_ctrl_weights_array_id";
                        weights.technique_common.accessor.source = "#" + weights.float_array.id;
                        weights.technique_common.accessor.stride = 1;
                        weights.technique_common.accessor.addParam("WEIGHT", "float");

                        StringBuilder w = new StringBuilder();
                        StringBuilder vcount = new StringBuilder();
                        StringBuilder v = new StringBuilder();

                        float[] wLookBack = new float[32];
                        uint wLookBackIndex = 0;
                        int buffLen = 0;

                        int wIndex = 0;
                        int wCount = 0;
                        foreach (RenderBase.OVertex vtx in mesh.vertices)
                        {
                            int count = Math.Min(vtx.node.Count, vtx.weight.Count);

                            vcount.Append(count + " ");
                            for (int n = 0; n < count; n++)
                            {
                                v.Append(vtx.node[n] + " ");
                                bool found = false;
                                uint bPos = (wLookBackIndex - 1) & 0x1f;
                                for (int i = 0; i < buffLen; i++)
                                {
                                    if (wLookBack[bPos] == vtx.weight[n])
                                    {
                                        v.Append(wIndex - (i + 1) + " ");
                                        found = true;
                                        break;
                                    }
                                    bPos = (bPos - 1) & 0x1f;
                                }

                                if (!found)
                                {
                                    v.Append(wIndex++ + " ");
                                    w.Append(vtx.weight[n].ToString(CultureInfo.InvariantCulture) + " ");
                                    wCount++;

                                    wLookBack[wLookBackIndex] = vtx.weight[n];
                                    wLookBackIndex = (wLookBackIndex + 1) & 0x1f;
                                    if (buffLen < wLookBack.Length) buffLen++;
                                }
                            }
                        }

                        weights.float_array.data = w.ToString().TrimEnd();
                        weights.float_array.count = (uint)wCount;
                        weights.technique_common.accessor.count = (uint)wCount;

                        controller.skin.src.Add(weights);
                        controller.skin.vertex_weights.vcount = vcount.ToString().TrimEnd();
                        controller.skin.vertex_weights.v = v.ToString().TrimEnd();
                        controller.skin.vertex_weights.count = (uint)mesh.vertices.Count;
                        controller.skin.joints.addInput("JOINT", "#" + joints.id);
                        controller.skin.joints.addInput("INV_BIND_MATRIX", "#" + bindPoses.id);

                        controller.skin.vertex_weights.addInput("JOINT", "#" + joints.id);
                        controller.skin.vertex_weights.addInput("WEIGHT", "#" + weights.id, 1);

                        if (daeShiny.library_controllers == null) daeShiny.library_controllers = new List<daeController>();
                        daeShiny.library_controllers.Add(controller);
                    }

                    //Visual scene node
                    daeNode node = new daeNode();
                    node.name = "vsn_" + meshName;
                    node.id = node.name + "_id";
                    node.matrix.set(new RenderBase.OMatrix());
                    if (hasController)
                    {
                        node.instance_controller = new daeInstanceController();
                        node.instance_controller.url = "#" + controller.id;
                        node.instance_controller.skeleton = "#" + mdl.skeleton[0].name + "_bone_id";
                        node.instance_controller.bind_material.technique_common.instance_material.symbol = mdl.material[obj.materialId].name + "_mat";
                        node.instance_controller.bind_material.technique_common.instance_material.target = "#" + mdl.material[obj.materialId].name + "_mat_id";
                    }
                    else
                    {
                        node.instance_geometry = new daeInstanceGeometry();
                        node.instance_geometry.url = "#" + geometry.id;
                        node.instance_geometry.bind_material.technique_common.instance_material.symbol = mdl.material[obj.materialId].name + "_mat";
                        node.instance_geometry.bind_material.technique_common.instance_material.target = "#" + mdl.material[obj.materialId].name + "_mat_id";
                    }

                    vs.node.Add(node);
                }
                daeShiny.library_visual_scenes.Add(vs);

                scene = new daeInstaceVisualScene();
                scene.url = "#" + vs.id;
                daeShiny.scene.Add(scene);

                settings = new XmlWriterSettings
                {
                    Encoding = Encoding.UTF8,
                    Indent = true
                };

                ns = new XmlSerializerNamespaces();
                ns.Add("", "http://www.collada.org/2005/11/COLLADASchema");
                serializer = new XmlSerializer(typeof(COLLADA));
                output = XmlWriter.Create(new FileStream(fileName.Replace(".bch", "_Shiny.dae").Replace("BCH", "DAE"), FileMode.Create), settings);
                serializer.Serialize(output, daeShiny, ns);
                output.Close();
            }
            #endregion
        }
Esempio n. 27
0
        private static RenderBase generateItemByName(String type, String path = null, RenderBase parent = null)
        {
            RenderBase item       = null;
            bool       isComplete = true;

            switch (type)
            {
            case Constant.TypeSprite:
                item = new TDSprite();
                break;

            case Constant.TypeSliderBar:
                item = new TDSliderBar();
                break;

            case Constant.TypeScale9:
                item = new TDScale9();
                break;

            case Constant.TypeButton:
                item = new TDButton();
                break;

            case Constant.TypeCheckBox:
                item = new TDCheckBox();
                break;

            case Constant.TypeInput:
                item = new TDInput();
                break;

            case Constant.TypeProgressBar:
                item = new TDProgressBar();
                break;

            case Constant.TypeText:
                item = new TDText();
                break;

            case Constant.TypePanel:
                if (path == null || path.Length == 0)
                {
                    item = new TDPanel();
                }
                else
                {
                    item = generateViewByPath(path, parent);
                }
                isComplete = true;
                break;

            case Constant.TypePage:
                item = new TDPage();
                break;

            default:
                item = null;
                break;
            }
            if (parent != null && item != null && item.getParent() == null)
            {
                item.setParent(parent);
            }
            if (item != null && isComplete)
            {
                item.loadComplete();
            }

            return(item);
        }
Esempio n. 28
0
        /// <summary>
        ///     Gets an Animation Key frame from the BCH file.
        ///     The Reader position must be set to the beggining of the Key Frame Data.
        /// </summary>
        /// <param name="input">The BCH file Reader</param>
        /// <param name="header">The BCH file header</param>
        /// <returns></returns>
        private static void getAnimationKeyFrame(BinaryReader input, RenderBase.OAnimationKeyFrameGroup frame)
        {
            frame.startFrame = input.ReadSingle();
            frame.endFrame = input.ReadSingle();

            uint frameFlags = input.ReadUInt32();
            frame.preRepeat = (RenderBase.ORepeatMethod)(frameFlags & 0xf);
            frame.postRepeat = (RenderBase.ORepeatMethod)((frameFlags >> 8) & 0xf);

            uint segmentFlags = input.ReadUInt32();
            frame.interpolation = (RenderBase.OInterpolationMode)(segmentFlags & 0xf);
            RenderBase.OSegmentQuantization quantization = (RenderBase.OSegmentQuantization)((segmentFlags >> 8) & 0xff);
            uint entries = segmentFlags >> 16;
            float valueScale = input.ReadSingle();
            float valueOffset = input.ReadSingle();
            float frameScale  = input.ReadSingle();
            float frameOffset = input.ReadSingle();

            uint offset = input.ReadUInt32();
            if (offset < input.BaseStream.Length) input.BaseStream.Seek(offset, SeekOrigin.Begin);
            for (int key = 0; key < entries; key++)
            {
                RenderBase.OAnimationKeyFrame keyFrame = new RenderBase.OAnimationKeyFrame();

                switch (quantization)
                {
                    case RenderBase.OSegmentQuantization.hermite128:
                        keyFrame.frame = input.ReadSingle();
                        keyFrame.value = input.ReadSingle();
                        keyFrame.inSlope = input.ReadSingle();
                        keyFrame.outSlope = input.ReadSingle();
                        break;
                    case RenderBase.OSegmentQuantization.hermite64:
                        uint h64Value = input.ReadUInt32();
                        keyFrame.frame = h64Value & 0xfff;
                        keyFrame.value = h64Value >> 12;
                        keyFrame.inSlope = input.ReadInt16() / 256f;
                        keyFrame.outSlope = input.ReadInt16() / 256f;
                        break;
                    case RenderBase.OSegmentQuantization.hermite48:
                        keyFrame.frame = input.ReadByte();
                        keyFrame.value = input.ReadUInt16();
                        byte slope0 = input.ReadByte();
                        byte slope1 = input.ReadByte();
                        byte slope2 = input.ReadByte();
                        keyFrame.inSlope = IOUtils.signExtend(slope0 | ((slope1 & 0xf) << 8), 12) / 32f;
                        keyFrame.outSlope = IOUtils.signExtend((slope1 >> 4) | (slope2 << 4), 12) / 32f;
                        break;
                    case RenderBase.OSegmentQuantization.unifiedHermite96:
                        keyFrame.frame = input.ReadSingle();
                        keyFrame.value = input.ReadSingle();
                        keyFrame.inSlope = input.ReadSingle();
                        keyFrame.outSlope = keyFrame.inSlope;
                        break;
                    case RenderBase.OSegmentQuantization.unifiedHermite48:
                        keyFrame.frame = input.ReadUInt16() / 32f;
                        keyFrame.value = input.ReadUInt16();
                        keyFrame.inSlope = input.ReadInt16() / 256f;
                        keyFrame.outSlope = keyFrame.inSlope;
                        break;
                    case RenderBase.OSegmentQuantization.unifiedHermite32:
                        keyFrame.frame = input.ReadByte();
                        ushort uH32Value = input.ReadUInt16();
                        keyFrame.value = uH32Value & 0xfff;
                        keyFrame.inSlope = IOUtils.signExtend((uH32Value >> 12) | (input.ReadByte() << 4), 12) / 32f;
                        keyFrame.outSlope = keyFrame.inSlope;
                        break;
                    case RenderBase.OSegmentQuantization.stepLinear64:
                        keyFrame.frame = input.ReadSingle();
                        keyFrame.value = input.ReadSingle();
                        break;
                    case RenderBase.OSegmentQuantization.stepLinear32:
                        uint sL32Value = input.ReadUInt32();
                        keyFrame.frame = sL32Value & 0xfff;
                        keyFrame.value = sL32Value >> 12;
                        break;
                }

                keyFrame.frame = (keyFrame.frame * frameScale) + frameOffset;
                keyFrame.value = (keyFrame.value * valueScale) + valueOffset;

                frame.keyFrames.Add(keyFrame);
            }
        }
Esempio n. 29
0
 /// <summary>
 ///     Transforms a Skeleton from relative to absolute positions.
 /// </summary>
 /// <param name="skeleton">The skeleton</param>
 /// <param name="index">Index of the bone to convert</param>
 /// <param name="target">Target matrix to save bone transformation</param>
 private static void transformSkeleton(List<RenderBase.OBone> skeleton, int index, ref RenderBase.OMatrix target)
 {
     target *= RenderBase.OMatrix.rotateX(skeleton[index].rotation.x);
     target *= RenderBase.OMatrix.rotateY(skeleton[index].rotation.y);
     target *= RenderBase.OMatrix.rotateZ(skeleton[index].rotation.z);
     target *= RenderBase.OMatrix.translate(skeleton[index].translation);
     if (skeleton[index].parentId > -1) transformSkeleton(skeleton, skeleton[index].parentId, ref target);
 }
Esempio n. 30
0
        private void SlaveThread()
        {
            ScanPort runConnect = null;
            bool     NoProtocol = true;//ProtocolBase、RenderBase未開啟

            try
            {
                // create object instance ..
                runConnect = new ScanPort();
                do
                {
                    //新增備援機制 是否是主機,如果不是建立連接測試類,如果可以連接主機,則不啟動備援,如果連接主機不通,則啟動備援機制
                    #region 本機是主機
                    if (EnvHostBase.LocalIpAddress.ToString() == Settings.Default.MasterServer)
                    {
                        if (NoProtocol)
                        {
                            this.OperationBase = new RenderBase(this.EnvData, this.EnvLog)
                            {
                                ConnectPort = this.__ListenRenderPort
                            };
                            this.PortalBase = new ProtocolBase(this.EnvData, this.EnvLog)
                            {
                                ConnectPort = this.__ListenRenderPort,
                                ListenPort  = this.__ListenClientPort,
                                MaxHistory  = this.__JobHistoryMaxRecord
                            };
                            //開啟監聽端口6601
                            this.MasterBase = new SlaveBase(this.EnvLog)
                            {
                                _listenSlavePort = this.__ServerSyncPort
                            };
                            NoProtocol = false;
                        }
                    }
                    #endregion

                    #region 本機非主機
                    else
                    {
                        //主機未啟動
                        if (!runConnect.Scan(System.Net.IPAddress.Parse(Settings.Default.MasterServer), this.__ServerSyncPort))
                        {
                            if (this.OperationBase == null)
                            {
                                this.OperationBase = new RenderBase(this.EnvData, this.EnvLog)
                                {
                                    ConnectPort = this.__ListenRenderPort
                                };
                            }
                            if (this.PortalBase == null)
                            {
                                this.PortalBase = new ProtocolBase(this.EnvData, this.EnvLog)
                                {
                                    ConnectPort = this.__ListenRenderPort,
                                    ListenPort  = this.__ListenClientPort,
                                    MaxHistory  = this.__JobHistoryMaxRecord
                                };
                            }
                        }
                        //主機已啟動
                        else
                        {
                            //取消与客户端以及render端沟通的线程
                            if (this.OperationBase != null)
                            {
                                this.OperationBase.Dispose();
                                this.OperationBase = null;
                            }
                            if (this.PortalBase != null)
                            {
                                this.PortalBase.Dispose();
                                this.PortalBase = null;
                            }
                        }
                    }

                    #endregion
                    Thread.Sleep(1000);
                } while (!requestStop);
            }
            catch (Exception ex)
            {
                string ExceptionMsg = ex.Message + "Master to Slave!";

                // write to log file ..
                //EnvLog.Writer(AssemblyInfoClass.ProductInfo, Log.Level.Error, ExceptionMsg, true);
            }
        }
 /// <summary>
 ///     Gets the current frame of a Material Animation integer value.
 /// </summary>
 /// <param name="data">The animation data</param>
 /// <param name="color">The integer value where the animation will be applied</param>
 private void getMaterialAnimationInt(RenderBase.OMaterialAnimationData data, ref int value)
 {
     if (data.frameList[0].exists) value = (int)AnimationUtils.getKey(data.frameList[0], ctrlMA.Frame);
 }
        /// <summary>
        ///     Gets a MDX Matrix from a RenderBase Matrix.
        /// </summary>
        /// <param name="mtx">RenderBase matrix</param>
        /// <returns></returns>
        private Matrix getMatrix(RenderBase.OMatrix mtx)
        {
            Matrix output = Matrix.Identity;

            output.M11 = mtx.M11;
            output.M12 = mtx.M12;
            output.M13 = mtx.M13;
            output.M14 = mtx.M14;

            output.M21 = mtx.M21;
            output.M22 = mtx.M22;
            output.M23 = mtx.M23;
            output.M24 = mtx.M24;

            output.M31 = mtx.M31;
            output.M32 = mtx.M32;
            output.M33 = mtx.M33;
            output.M34 = mtx.M34;

            output.M41 = mtx.M41;
            output.M42 = mtx.M42;
            output.M43 = mtx.M43;
            output.M44 = mtx.M44;

            return output;
        }
 /// <summary>
 ///     Gets the current frame of a Material Animation 2-D vector.
 /// </summary>
 /// <param name="data">The animation data</param>
 /// <param name="color">The vector where the animation will be applied</param>
 private void getMaterialAnimationVector2(RenderBase.OMaterialAnimationData data, ref Vector2 vector)
 {
     if (data.frameList[0].exists) vector.X = AnimationUtils.getKey(data.frameList[0], ctrlMA.Frame);
     if (data.frameList[1].exists) vector.Y = AnimationUtils.getKey(data.frameList[1], ctrlMA.Frame);
 }
Esempio n. 34
0
 public CommandAnchorPos(RenderScene scene, RenderBase render)
     : base(scene, render.uniqueName)
 {
     this._orign  = render.oriAnchorPos;
     this._finish = render.anchorPos;
 }
 /// <summary>
 ///     Adds a single texture to the model and the cache.
 /// </summary>
 /// <param name="texture">The texture to be added</param>
 public void addTexture(RenderBase.OTexture texture)
 {
     models.texture.Add(texture);
     cacheTexture(texture);
 }
        /// <summary>
        ///     Gets a DirectX Stencil operation from a RenderBase Stencil operation.
        /// </summary>
        /// <param name="function">The stencil operation</param>
        /// <returns></returns>
        private StencilOperation getStencilOperation(RenderBase.OStencilOp operation)
        {
            switch (operation)
            {
                case RenderBase.OStencilOp.decrease: return StencilOperation.Decrement;
                case RenderBase.OStencilOp.decreaseWrap: return StencilOperation.DecrementSaturation;
                case RenderBase.OStencilOp.increase: return StencilOperation.Increment;
                case RenderBase.OStencilOp.increaseWrap: return StencilOperation.IncrementSaturation;
                case RenderBase.OStencilOp.keep: return StencilOperation.Keep;
                case RenderBase.OStencilOp.replace: return StencilOperation.Replace;
                case RenderBase.OStencilOp.zero: return StencilOperation.Zero;
            }

            return 0;
        }
        /// <summary>
        ///     Gets a DirectX Compare from a RenderBase Compare.
        /// </summary>
        /// <param name="function">The compare test function</param>
        /// <returns></returns>
        private Compare getCompare(RenderBase.OTestFunction function)
        {
            switch (function)
            {
                case RenderBase.OTestFunction.always: return Compare.Always;
                case RenderBase.OTestFunction.equal: return Compare.Equal;
                case RenderBase.OTestFunction.greater: return Compare.Greater;
                case RenderBase.OTestFunction.greaterOrEqual: return Compare.GreaterEqual;
                case RenderBase.OTestFunction.less: return Compare.Less;
                case RenderBase.OTestFunction.lessOrEqual: return Compare.LessEqual;
                case RenderBase.OTestFunction.never: return Compare.Never;
                case RenderBase.OTestFunction.notEqual: return Compare.NotEqual;
            }

            return 0;
        }
        /// <summary>
        ///     Decodes a PICA200 Texture.
        /// </summary>
        /// <param name="data">Buffer with the Texture</param>
        /// <param name="width">Width of the Texture</param>
        /// <param name="height">Height of the Texture</param>
        /// <param name="format">Pixel Format of the Texture</param>
        /// <returns></returns>
        public static Bitmap decode(byte[] data, int width, int height, RenderBase.OTextureFormat format)
        {
            byte[] output = new byte[width * height * 4];
            long dataOffset = 0;
            bool toggle = false;

            switch (format)
            {
                case RenderBase.OTextureFormat.rgba8:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + ((tY * 8 + y) * width)) * 4;

                                Buffer.BlockCopy(data, (int)dataOffset + 1, output, (int)outputOffset, 3);
                                output[outputOffset + 3] = data[dataOffset];

                                dataOffset += 4;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.rgb8:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                Buffer.BlockCopy(data, (int)dataOffset, output, (int)outputOffset, 3);
                                output[outputOffset + 3] = 0xff;

                                dataOffset += 3;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.rgba5551:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                ushort pixelData = (ushort)(data[dataOffset] | (data[dataOffset + 1] << 8));

                                byte r = (byte)(((pixelData >> 1) & 0x1f) << 3);
                                byte g = (byte)(((pixelData >> 6) & 0x1f) << 3);
                                byte b = (byte)(((pixelData >> 11) & 0x1f) << 3);
                                byte a = (byte)((pixelData & 1) * 0xff);

                                output[outputOffset] = (byte)(r | (r >> 5));
                                output[outputOffset + 1] = (byte)(g | (g >> 5));
                                output[outputOffset + 2] = (byte)(b | (b >> 5));
                                output[outputOffset + 3] = a;

                                dataOffset += 2;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.rgb565:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                ushort pixelData = (ushort)(data[dataOffset] | (data[dataOffset + 1] << 8));

                                byte r = (byte)((pixelData & 0x1f) << 3);
                                byte g = (byte)(((pixelData >> 5) & 0x3f) << 2);
                                byte b = (byte)(((pixelData >> 11) & 0x1f) << 3);

                                output[outputOffset] = (byte)(r | (r >> 5));
                                output[outputOffset + 1] = (byte)(g | (g >> 6));
                                output[outputOffset + 2] = (byte)(b | (b >> 5));
                                output[outputOffset + 3] = 0xff;

                                dataOffset += 2;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.rgba4:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                ushort pixelData = (ushort)(data[dataOffset] | (data[dataOffset + 1] << 8));

                                byte r = (byte)((pixelData >> 4) & 0xf);
                                byte g = (byte)((pixelData >> 8) & 0xf);
                                byte b = (byte)((pixelData >> 12) & 0xf);
                                byte a = (byte)(pixelData & 0xf);

                                output[outputOffset] = (byte)(r | (r << 4));
                                output[outputOffset + 1] = (byte)(g | (g << 4));
                                output[outputOffset + 2] = (byte)(b | (b << 4));
                                output[outputOffset + 3] = (byte)(a | (a << 4));

                                dataOffset += 2;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.la8:
                case RenderBase.OTextureFormat.hilo8:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                output[outputOffset] = data[dataOffset];
                                output[outputOffset + 1] = data[dataOffset];
                                output[outputOffset + 2] = data[dataOffset];
                                output[outputOffset + 3] = data[dataOffset + 1];

                                dataOffset += 2;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.l8:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                output[outputOffset] = data[dataOffset];
                                output[outputOffset + 1] = data[dataOffset];
                                output[outputOffset + 2] = data[dataOffset];
                                output[outputOffset + 3] = 0xff;

                                dataOffset++;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.a8:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                output[outputOffset] = 0xff;
                                output[outputOffset + 1] = 0xff;
                                output[outputOffset + 2] = 0xff;
                                output[outputOffset + 3] = data[dataOffset];

                                dataOffset++;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.la4:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                output[outputOffset] = (byte)(data[dataOffset] >> 4);
                                output[outputOffset + 1] = (byte)(data[dataOffset] >> 4);
                                output[outputOffset + 2] = (byte)(data[dataOffset] >> 4);
                                output[outputOffset + 3] = (byte)(data[dataOffset] & 0xf);

                                dataOffset++;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.l4:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                byte c = toggle ? (byte)((data[dataOffset++] & 0xf0) >> 4) : (byte)(data[dataOffset] & 0xf);
                                toggle = !toggle;
                                c = (byte)((c << 4) | c);
                                output[outputOffset] = c;
                                output[outputOffset + 1] = c;
                                output[outputOffset + 2] = c;
                                output[outputOffset + 3] = 0xff;
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.a4:
                    for (int tY = 0; tY < height / 8; tY++)
                    {
                        for (int tX = 0; tX < width / 8; tX++)
                        {
                            for (int pixel = 0; pixel < 64; pixel++)
                            {
                                int x = tileOrder[pixel] % 8;
                                int y = (tileOrder[pixel] - x) / 8;
                                long outputOffset = ((tX * 8) + x + (((tY * 8 + y)) * width)) * 4;

                                output[outputOffset] = 0xff;
                                output[outputOffset + 1] = 0xff;
                                output[outputOffset + 2] = 0xff;
                                byte a = toggle ? (byte)((data[dataOffset++] & 0xf0) >> 4) : (byte)(data[dataOffset] & 0xf);
                                toggle = !toggle;
                                output[outputOffset + 3] = (byte)((a << 4) | a);
                            }
                        }
                    }
                    break;

                case RenderBase.OTextureFormat.etc1:
                case RenderBase.OTextureFormat.etc1a4:
                    byte[] decodedData = etc1Decode(data, width, height, format == RenderBase.OTextureFormat.etc1a4);
                    int[] etc1Order = etc1Scramble(width, height);

                    int i = 0;
                    for (int tY = 0; tY < height / 4; tY++) {
                        for (int tX = 0; tX < width / 4; tX++) {
                            int TX = etc1Order[i] % (width / 4);
                            int TY = (etc1Order[i] - TX) / (width / 4);
                            for (int y = 0; y < 4; y++) {
                                for (int x = 0; x < 4; x++) {
                                    dataOffset = ((TX * 4) + x + (((TY * 4) + y) * width)) * 4;
                                    long outputOffset = ((tX * 4) + x + (((tY * 4 + y)) * width)) * 4;

                                    Buffer.BlockCopy(decodedData, (int)dataOffset, output, (int)outputOffset, 4);
                                }
                            }
                            i += 1;
                        }
                    }

                    break;
            }

            return TextureUtils.getBitmap(output.ToArray(), width, height);
        }
Esempio n. 39
0
        /// <summary>
        ///     Opens the windows used for a model.
        ///     More windows can be opened later, for files with model and other data.
        /// </summary>
        /// <param name="model">The model</param>
        /// <param name="name">The file name (without the full path and extension)</param>
        private void launchModel(RenderBase.OModelGroup model, string name)
        {
            OViewportWindow viewportWindow = new OViewportWindow();
            OModelWindow modelWindow = new OModelWindow();
            OTextureWindow textureWindow = new OTextureWindow();
            OAnimationsWindow animationWindow = new OAnimationsWindow();

            viewportWindow.Title = name;

            RenderEngine renderer = new RenderEngine();
            renderer.MSAALevel = Settings.Default.reAALevel;
            renderer.bgColor = Settings.Default.reBgColor;
            renderer.useLegacyTexturing = Settings.Default.reUseLegacyTexturing;
            renderer.showGrid = Settings.Default.reShowGrids;
            renderer.showHUD = Settings.Default.reShowHUD;
            renderer.model = model;

            launchWindow(viewportWindow);
            DockContainer.dockMainWindow();
            launchWindow(modelWindow, false);
            launchWindow(textureWindow, false);
            launchWindow(animationWindow, false);

            WindowManager.Refresh();

            modelWindow.initialize(renderer);
            textureWindow.initialize(renderer);
            animationWindow.initialize(renderer);
            viewportWindow.initialize(renderer);
        }
Esempio n. 40
0
        /// <summary>
        ///     Exports a Model to the Source Model format.
        ///     Note: SMD model specification doesnt support Model and Skeletal Animation on the same SMD.
        ///     See: https://developer.valvesoftware.com/wiki/Studiomdl_Data for more information.
        /// </summary>
        /// <param name="model">The Model that will be exported</param>
        /// <param name="fileName">The output File Name</param>
        /// <param name="modelIndex">Index of the model to be exported</param>
        /// <param name="skeletalAnimationIndex">(Optional) Index of the skeletal animation</param>
        public static void export(RenderBase.OModelGroup model, string fileName, int modelIndex, int skeletalAnimationIndex = -1)
        {
            RenderBase.OModel mdl = model.model[modelIndex];
            StringBuilder output = new StringBuilder();

            output.AppendLine("version 1");
            output.AppendLine("nodes");
            for (int i = 0; i < mdl.skeleton.Count; i++)
            {
                output.AppendLine(i + " \"" + mdl.skeleton[i].name + "\" " + mdl.skeleton[i].parentId);
            }
            output.AppendLine("end");
            output.AppendLine("skeleton");
            if (skeletalAnimationIndex == -1)
            {
                output.AppendLine("time 0");
                int index = 0;
                foreach (RenderBase.OBone bone in mdl.skeleton)
                {
                    string line = index.ToString();
                    line += " " + getString(bone.translation.x);
                    line += " " + getString(bone.translation.y);
                    line += " " + getString(bone.translation.z);
                    line += " " + getString(bone.rotation.x);
                    line += " " + getString(bone.rotation.y);
                    line += " " + getString(bone.rotation.z);
                    output.AppendLine(line);
                    index++;
                }
            }
            else
            {
                bool error = false;
                for (float frame = 0; frame < model.skeletalAnimation.list[skeletalAnimationIndex].frameSize; frame += 1)
                {
                    output.AppendLine("time " + ((int)frame).ToString());
                    for (int index = 0; index < mdl.skeleton.Count; index++)
                    {
                        RenderBase.OBone newBone = new RenderBase.OBone();
                        newBone.parentId = mdl.skeleton[index].parentId;
                        newBone.rotation = new RenderBase.OVector3(mdl.skeleton[index].rotation);
                        newBone.translation = new RenderBase.OVector3(mdl.skeleton[index].translation);
                        foreach (RenderBase.OSkeletalAnimationBone b in ((RenderBase.OSkeletalAnimation)model.skeletalAnimation.list[skeletalAnimationIndex]).bone)
                        {
                            if (b.isFrameFormat || b.isFullBakedFormat) error = true;
                            if (b.name == mdl.skeleton[index].name && !b.isFrameFormat && !b.isFullBakedFormat)
                            {
                                if (b.rotationX.exists) newBone.rotation.x = AnimationUtils.getKey(b.rotationX, frame);
                                if (b.rotationY.exists) newBone.rotation.y = AnimationUtils.getKey(b.rotationY, frame);
                                if (b.rotationZ.exists) newBone.rotation.z = AnimationUtils.getKey(b.rotationZ, frame);

                                if (b.translationX.exists)
                                {
                                    newBone.translation.x = AnimationUtils.getKey(b.translationX, frame);
                                    newBone.translation.x *= mdl.skeleton[index].absoluteScale.x;
                                }

                                if (b.translationY.exists)
                                {
                                    newBone.translation.y = AnimationUtils.getKey(b.translationY, frame);
                                    newBone.translation.y *= mdl.skeleton[index].absoluteScale.y;
                                }

                                if (b.translationZ.exists)
                                {
                                    newBone.translation.z = AnimationUtils.getKey(b.translationZ, frame);
                                    newBone.translation.z *= mdl.skeleton[index].absoluteScale.z;
                                }

                                break;
                            }
                        }

                        string line = index.ToString();
                        line += " " + getString(newBone.translation.x);
                        line += " " + getString(newBone.translation.y);
                        line += " " + getString(newBone.translation.z);
                        line += " " + getString(newBone.rotation.x);
                        line += " " + getString(newBone.rotation.y);
                        line += " " + getString(newBone.rotation.z);
                        output.AppendLine(line);
                    }
                }

                if (error) MessageBox.Show(
                    "One or more bones uses an animation type unsupported by Source Model!",
                    "Warning",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
            }
            output.AppendLine("end");

            if (skeletalAnimationIndex == -1)
            {
                output.AppendLine("triangles");
                uint triangleCount = 0;
                int objectIndex = 0;
                foreach (RenderBase.OMesh obj in mdl.mesh)
                {
                    string textureName = mdl.material[obj.materialId].name0 ?? "material_" + objectIndex.ToString();

                    foreach (RenderBase.OVertex vertex in obj.vertices)
                    {
                        if (triangleCount == 0) output.AppendLine(textureName);

                        string line = "0";

                        line += " " + getString(vertex.position.x);
                        line += " " + getString(vertex.position.y);
                        line += " " + getString(vertex.position.z);
                        line += " " + getString(vertex.normal.x);
                        line += " " + getString(vertex.normal.y);
                        line += " " + getString(vertex.normal.z);
                        line += " " + getString(vertex.texture0.x);
                        line += " " + getString(vertex.texture0.y);

                        int nodeCount = Math.Min(vertex.node.Count, vertex.weight.Count);
                        line += " " + nodeCount;
                        for (int i = 0; i < nodeCount; i++)
                        {
                            line += " " + vertex.node[i];
                            line += " " + getString(vertex.weight[i]);
                        }

                        output.AppendLine(line);
                        triangleCount = (triangleCount + 1) % 3;
                    }

                    objectIndex++;
                }
                output.AppendLine("end");
            }

            File.WriteAllText(fileName, output.ToString());
        }
Esempio n. 41
0
        /// <summary>
        ///     Gets an Animation Key frame from the CGFX file.
        ///     The Reader position must be set to the beggining of the Key Frame Data.
        /// </summary>
        /// <param name="input">The CGFX file Reader</param>
        /// <param name="header">The CGFX file header</param>
        /// <returns></returns>
        private static void getAnimationKeyFrame(BinaryReader input, RenderBase.OAnimationKeyFrameGroup frame)
        {
            float startFrame = input.ReadSingle();
            float endFrame = input.ReadSingle();
            input.BaseStream.Seek(0x10, SeekOrigin.Current);

            frame.startFrame = input.ReadSingle();
            frame.endFrame = input.ReadSingle();
            uint segmentFlags = input.ReadUInt32();
            switch (segmentFlags & 0xf)
            {
                case 0: frame.interpolation = RenderBase.OInterpolationMode.step; break;
                case 4: frame.interpolation = RenderBase.OInterpolationMode.linear; break;
                case 8: frame.interpolation = RenderBase.OInterpolationMode.hermite; break;
            }
            RenderBase.OSegmentQuantization quantization = (RenderBase.OSegmentQuantization)(segmentFlags >> 5);

            uint entries = input.ReadUInt32();
            float invDuration = input.ReadSingle();
            float valueScale = 1;
            float valueOffset = 0;
            float frameScale = 1;

            if (quantization != RenderBase.OSegmentQuantization.hermite128 &&
                quantization != RenderBase.OSegmentQuantization.unifiedHermite96 &&
                quantization != RenderBase.OSegmentQuantization.stepLinear64)
            {
                valueScale = input.ReadSingle();
                valueOffset = input.ReadSingle();
                frameScale = input.ReadSingle();
            }

            for (int key = 0; key < entries; key++)
            {
                RenderBase.OAnimationKeyFrame keyFrame = new RenderBase.OAnimationKeyFrame();

                switch (quantization)
                {
                    case RenderBase.OSegmentQuantization.hermite128:
                        keyFrame.frame = input.ReadSingle();
                        keyFrame.value = input.ReadSingle();
                        keyFrame.inSlope = input.ReadSingle();
                        keyFrame.outSlope = input.ReadSingle();
                        break;
                    case RenderBase.OSegmentQuantization.hermite64:
                        uint h64Value = input.ReadUInt32();
                        keyFrame.frame = h64Value & 0xfff;
                        keyFrame.value = h64Value >> 12;
                        keyFrame.inSlope = input.ReadInt16() / 256f;
                        keyFrame.outSlope = input.ReadInt16() / 256f;
                        break;
                    case RenderBase.OSegmentQuantization.hermite48:
                        keyFrame.frame = input.ReadByte();
                        keyFrame.value = input.ReadUInt16();
                        byte slope0 = input.ReadByte();
                        byte slope1 = input.ReadByte();
                        byte slope2 = input.ReadByte();
                        keyFrame.inSlope = IOUtils.signExtend(slope0 | ((slope1 & 0xf) << 8), 12) / 32f;
                        keyFrame.outSlope = IOUtils.signExtend((slope1 >> 4) | (slope2 << 4), 12) / 32f;
                        break;
                    case RenderBase.OSegmentQuantization.unifiedHermite96:
                        keyFrame.frame = input.ReadSingle();
                        keyFrame.value = input.ReadSingle();
                        keyFrame.inSlope = input.ReadSingle();
                        keyFrame.outSlope = keyFrame.inSlope;
                        break;
                    case RenderBase.OSegmentQuantization.unifiedHermite48:
                        keyFrame.frame = input.ReadUInt16() / 32f;
                        keyFrame.value = input.ReadUInt16();
                        keyFrame.inSlope = input.ReadInt16() / 256f;
                        keyFrame.outSlope = keyFrame.inSlope;
                        break;
                    case RenderBase.OSegmentQuantization.unifiedHermite32:
                        keyFrame.frame = input.ReadByte();
                        ushort uH32Value = input.ReadUInt16();
                        keyFrame.value = uH32Value & 0xfff;
                        keyFrame.inSlope = IOUtils.signExtend((uH32Value >> 12) | (input.ReadByte() << 4), 12) / 32f;
                        keyFrame.outSlope = keyFrame.inSlope;
                        break;
                    case RenderBase.OSegmentQuantization.stepLinear64:
                        keyFrame.frame = input.ReadSingle();
                        keyFrame.value = input.ReadSingle();
                        break;
                    case RenderBase.OSegmentQuantization.stepLinear32:
                        uint sL32Value = input.ReadUInt32();
                        keyFrame.frame = sL32Value & 0xfff;
                        keyFrame.value = sL32Value >> 12;
                        break;
                }

                keyFrame.frame = (keyFrame.frame * frameScale) + startFrame;
                keyFrame.value = (keyFrame.value * valueScale) + valueOffset;

                frame.keyFrames.Add(keyFrame);
            }
        }
Esempio n. 42
0
        /// <summary>
        ///     Exports a Model to the Collada format.
        ///     See: https://www.khronos.org/files/collada_spec_1_4.pdf for more information.
        /// </summary>
        /// <param name="model">The Model that will be exported</param>
        /// <param name="fileName">The output File Name</param>
        /// <param name="modelIndex">Index of the model to be exported</param>
        /// <param name="skeletalAnimationIndex">(Optional) Index of the skeletal animation</param>
        public static void export(RenderBase.OModelGroup model, string fileName, int modelIndex, int skeletalAnimationIndex = -1)
        {
            RenderBase.OModel mdl = model.model[modelIndex];
            COLLADA dae = new COLLADA();

            dae.asset.created = DateTime.Now.ToString("yyyy-MM-ddThh:mm:ssZ");
            dae.asset.modified = dae.asset.created;

            foreach (RenderBase.OTexture tex in model.texture)
            {
                daeImage img = new daeImage();
                img.id = tex.name + "_id";
                img.name = tex.name;
                img.init_from = "./" + tex.name + ".png";

                dae.library_images.Add(img);
            }

            foreach (RenderBase.OMaterial mat in mdl.material)
            {
                daeMaterial mtl = new daeMaterial();
                mtl.name = mat.name + "_mat";
                mtl.id = mtl.name + "_id";
                mtl.instance_effect.url = "#eff_" + mat.name + "_id";

                dae.library_materials.Add(mtl);

                daeEffect eff = new daeEffect();
                eff.id = "eff_" + mat.name + "_id";
                eff.name = "eff_" + mat.name;

                daeParam surface = new daeParam();
                surface.surface = new daeParamSurfaceElement();
                surface.sid = "img_surface";
                surface.surface.type = "2D";
                surface.surface.init_from = mat.name0 + "_id";
                surface.surface.format = "PNG";
                eff.profile_COMMON.newparam.Add(surface);

                daeParam sampler = new daeParam();
                sampler.sampler2D = new daeParamSampler2DElement();
                sampler.sid = "img_sampler";
                sampler.sampler2D.source = "img_surface";

                switch (mat.textureMapper[0].wrapU)
                {
                    case RenderBase.OTextureWrap.repeat: sampler.sampler2D.wrap_s = "WRAP"; break;
                    case RenderBase.OTextureWrap.mirroredRepeat: sampler.sampler2D.wrap_s = "MIRROR"; break;
                    case RenderBase.OTextureWrap.clampToEdge: sampler.sampler2D.wrap_s = "CLAMP"; break;
                    case RenderBase.OTextureWrap.clampToBorder: sampler.sampler2D.wrap_s = "BORDER"; break;
                    default: sampler.sampler2D.wrap_s = "NONE"; break;
                }

                switch (mat.textureMapper[0].wrapV)
                {
                    case RenderBase.OTextureWrap.repeat: sampler.sampler2D.wrap_t = "WRAP"; break;
                    case RenderBase.OTextureWrap.mirroredRepeat: sampler.sampler2D.wrap_t = "MIRROR"; break;
                    case RenderBase.OTextureWrap.clampToEdge: sampler.sampler2D.wrap_t = "CLAMP"; break;
                    case RenderBase.OTextureWrap.clampToBorder: sampler.sampler2D.wrap_t = "BORDER"; break;
                    default: sampler.sampler2D.wrap_t = "NONE"; break;
                }

                switch (mat.textureMapper[0].minFilter)
                {
                    case RenderBase.OTextureMinFilter.linearMipmapLinear: sampler.sampler2D.minfilter = "LINEAR_MIPMAP_LINEAR"; break;
                    case RenderBase.OTextureMinFilter.linearMipmapNearest: sampler.sampler2D.minfilter = "LINEAR_MIPMAP_NEAREST"; break;
                    case RenderBase.OTextureMinFilter.nearestMipmapLinear: sampler.sampler2D.minfilter = "NEAREST_MIPMAP_LINEAR"; break;
                    case RenderBase.OTextureMinFilter.nearestMipmapNearest: sampler.sampler2D.minfilter = "NEAREST_MIPMAP_NEAREST"; break;
                    default: sampler.sampler2D.minfilter = "NONE"; break;
                }

                switch (mat.textureMapper[0].magFilter)
                {
                    case RenderBase.OTextureMagFilter.linear: sampler.sampler2D.magfilter = "LINEAR"; break;
                    case RenderBase.OTextureMagFilter.nearest: sampler.sampler2D.magfilter = "NEAREST"; break;
                    default: sampler.sampler2D.magfilter = "NONE"; break;
                }

                sampler.sampler2D.mipfilter = sampler.sampler2D.magfilter;

                eff.profile_COMMON.newparam.Add(sampler);

                eff.profile_COMMON.technique.sid = "img_technique";
                eff.profile_COMMON.technique.phong.emission.set(Color.Black);
                eff.profile_COMMON.technique.phong.ambient.set(Color.Black);
                eff.profile_COMMON.technique.phong.specular.set(Color.White);
                eff.profile_COMMON.technique.phong.diffuse.texture.texture = "img_sampler";

                dae.library_effects.Add(eff);
            }

            string jointNames = null;
            string invBindPoses = null;
            for (int index = 0; index < mdl.skeleton.Count; index++)
            {
                RenderBase.OMatrix transform = new RenderBase.OMatrix();
                transformSkeleton(mdl.skeleton, index, ref transform);

                jointNames += mdl.skeleton[index].name;
                daeMatrix mtx = new daeMatrix();
                mtx.set(transform.invert());
                invBindPoses += mtx.data;
                if (index < mdl.skeleton.Count - 1)
                {
                    jointNames += " ";
                    invBindPoses += " ";
                }
            }

            int meshIndex = 0;
            daeVisualScene vs = new daeVisualScene();
            vs.name = "vs_" + mdl.name;
            vs.id = vs.name + "_id";
            if (mdl.skeleton.Count > 0) writeSkeleton(mdl.skeleton, 0, ref vs.node);
            foreach (RenderBase.OMesh obj in mdl.mesh)
            {
                //Geometry
                daeGeometry geometry = new daeGeometry();

                string meshName = "mesh_" + meshIndex++ + "_" + obj.name;
                geometry.id = meshName + "_id";
                geometry.name = meshName;

                MeshUtils.optimizedMesh mesh = MeshUtils.optimizeMesh(obj);
                List<float> positions = new List<float>();
                List<float> normals = new List<float>();
                List<float> uv0 = new List<float>();
                List<float> uv1 = new List<float>();
                List<float> uv2 = new List<float>();
                List<float> colors = new List<float>();
                foreach (RenderBase.OVertex vtx in mesh.vertices)
                {
                    positions.Add(vtx.position.x);
                    positions.Add(vtx.position.y);
                    positions.Add(vtx.position.z);

                    if (mesh.hasNormal)
                    {
                        normals.Add(vtx.normal.x);
                        normals.Add(vtx.normal.y);
                        normals.Add(vtx.normal.z);
                    }

                    if (mesh.texUVCount > 0)
                    {
                        uv0.Add(vtx.texture0.x);
                        uv0.Add(vtx.texture0.y);
                    }

                    if (mesh.texUVCount > 1)
                    {
                        uv1.Add(vtx.texture1.x);
                        uv1.Add(vtx.texture1.y);
                    }

                    if (mesh.texUVCount > 2)
                    {
                        uv2.Add(vtx.texture2.x);
                        uv2.Add(vtx.texture2.y);
                    }

                    if (mesh.hasColor)
                    {
                        colors.Add(((vtx.diffuseColor >> 16) & 0xff) / 255f);
                        colors.Add(((vtx.diffuseColor >> 8) & 0xff) / 255f);
                        colors.Add((vtx.diffuseColor & 0xff) / 255f);
                        colors.Add(((vtx.diffuseColor >> 24) & 0xff) / 255f);
                    }
                }

                daeSource position = new daeSource();
                position.name = meshName + "_position";
                position.id = position.name + "_id";
                position.float_array = new daeFloatArray();
                position.float_array.id = position.name + "_array_id";
                position.float_array.set(positions);
                position.technique_common.accessor.source = "#" + position.float_array.id;
                position.technique_common.accessor.count = (uint)mesh.vertices.Count;
                position.technique_common.accessor.stride = 3;
                position.technique_common.accessor.addParam("X", "float");
                position.technique_common.accessor.addParam("Y", "float");
                position.technique_common.accessor.addParam("Z", "float");

                geometry.mesh.source.Add(position);

                daeSource normal = new daeSource();
                if (mesh.hasNormal)
                {
                    normal.name = meshName + "_normal";
                    normal.id = normal.name + "_id";
                    normal.float_array = new daeFloatArray();
                    normal.float_array.id = normal.name + "_array_id";
                    normal.float_array.set(normals);
                    normal.technique_common.accessor.source = "#" + normal.float_array.id;
                    normal.technique_common.accessor.count = (uint)mesh.vertices.Count;
                    normal.technique_common.accessor.stride = 3;
                    normal.technique_common.accessor.addParam("X", "float");
                    normal.technique_common.accessor.addParam("Y", "float");
                    normal.technique_common.accessor.addParam("Z", "float");

                    geometry.mesh.source.Add(normal);
                }

                daeSource[] texUV = new daeSource[3];
                for (int i = 0; i < mesh.texUVCount; i++)
                {
                    texUV[i] = new daeSource();

                    texUV[i].name = meshName + "_uv" + i;
                    texUV[i].id = texUV[i].name + "_id";
                    texUV[i].float_array = new daeFloatArray();
                    texUV[i].float_array.id = texUV[i].name + "_array_id";
                    texUV[i].technique_common.accessor.source = "#" + texUV[i].float_array.id;
                    texUV[i].technique_common.accessor.count = (uint)mesh.vertices.Count;
                    texUV[i].technique_common.accessor.stride = 2;
                    texUV[i].technique_common.accessor.addParam("S", "float");
                    texUV[i].technique_common.accessor.addParam("T", "float");

                    geometry.mesh.source.Add(texUV[i]);
                }

                daeSource color = new daeSource();
                if (mesh.hasColor)
                {
                    color.name = meshName + "_color";
                    color.id = color.name + "_id";
                    color.float_array = new daeFloatArray();
                    color.float_array.id = color.name + "_array_id";
                    color.float_array.set(colors);
                    color.technique_common.accessor.source = "#" + color.float_array.id;
                    color.technique_common.accessor.count = (uint)mesh.vertices.Count;
                    color.technique_common.accessor.stride = 4;
                    color.technique_common.accessor.addParam("R", "float");
                    color.technique_common.accessor.addParam("G", "float");
                    color.technique_common.accessor.addParam("B", "float");
                    color.technique_common.accessor.addParam("A", "float");

                    geometry.mesh.source.Add(color);
                }

                geometry.mesh.vertices.id = meshName + "_vertices_id";
                geometry.mesh.vertices.addInput("POSITION", "#" + position.id);


                geometry.mesh.triangles.material = mdl.material[obj.materialId].name;
                geometry.mesh.triangles.addInput("VERTEX", "#" + geometry.mesh.vertices.id);
                if (mesh.hasNormal) geometry.mesh.triangles.addInput("NORMAL", "#" + normal.id);
                if (mesh.hasColor) geometry.mesh.triangles.addInput("COLOR", "#" + color.id);
                if (mesh.texUVCount > 0)
                {
                    texUV[0].float_array.set(uv0);
                    geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[0].id);
                }
                if (mesh.texUVCount > 1)
                {
                    texUV[1].float_array.set(uv1);
                    geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[1].id, 0, 1);
                }
                if (mesh.texUVCount > 2)
                {
                    texUV[2].float_array.set(uv2);
                    geometry.mesh.triangles.addInput("TEXCOORD", "#" + texUV[2].id, 0, 2);
                }
                geometry.mesh.triangles.set(mesh.indices);

                dae.library_geometries.Add(geometry);

                bool hasNode = obj.vertices[0].node.Count > 0;
                bool hasWeight = obj.vertices[0].weight.Count > 0;
                bool hasController = hasNode && hasWeight;

                //Controller
                daeController controller = new daeController();
                if (hasController)
                {
                    controller.id = meshName + "_ctrl_id";

                    controller.skin.source = "#" + geometry.id;
                    controller.skin.bind_shape_matrix.set(new RenderBase.OMatrix());

                    daeSource joints = new daeSource();
                    joints.id = meshName + "_ctrl_joint_names_id";
                    joints.Name_array = new daeNameArray();
                    joints.Name_array.id = meshName + "_ctrl_joint_names_array_id";
                    joints.Name_array.count = (uint)mdl.skeleton.Count;
                    joints.Name_array.data = jointNames;
                    joints.technique_common.accessor.source = "#" + joints.Name_array.id;
                    joints.technique_common.accessor.count = joints.Name_array.count;
                    joints.technique_common.accessor.stride = 1;
                    joints.technique_common.accessor.addParam("JOINT", "Name");

                    controller.skin.src.Add(joints);

                    daeSource bindPoses = new daeSource();
                    bindPoses.id = meshName +"_ctrl_inv_bind_poses_id";
                    bindPoses.float_array = new daeFloatArray();
                    bindPoses.float_array.id = meshName + "_ctrl_inv_bind_poses_array_id";
                    bindPoses.float_array.count = (uint)(mdl.skeleton.Count * 16);
                    bindPoses.float_array.data = invBindPoses;
                    bindPoses.technique_common.accessor.source = "#" + bindPoses.float_array.id;
                    bindPoses.technique_common.accessor.count = (uint)mdl.skeleton.Count;
                    bindPoses.technique_common.accessor.stride = 16;
                    bindPoses.technique_common.accessor.addParam("TRANSFORM", "float4x4");

                    controller.skin.src.Add(bindPoses);

                    daeSource weights = new daeSource();
                    weights.id = meshName + "_ctrl_weights_id";
                    weights.float_array = new daeFloatArray();
                    weights.float_array.id = meshName + "_ctrl_weights_array_id";
                    weights.technique_common.accessor.source = "#" + weights.float_array.id;
                    weights.technique_common.accessor.stride = 1;
                    weights.technique_common.accessor.addParam("WEIGHT", "float");

                    StringBuilder w = new StringBuilder();
                    StringBuilder vcount = new StringBuilder();
                    StringBuilder v = new StringBuilder();

                    float[] wLookBack = new float[32];
                    uint wLookBackIndex = 0;
                    int buffLen = 0;

                    int wIndex = 0;
                    int wCount = 0;
                    foreach (RenderBase.OVertex vtx in mesh.vertices)
                    {
                        int count = Math.Min(vtx.node.Count, vtx.weight.Count);

                        vcount.Append(count + " ");
                        for (int n = 0; n < count; n++)
                        {
                            v.Append(vtx.node[n] + " ");
                            bool found = false;
                            uint bPos = (wLookBackIndex - 1) & 0x1f;
                            for (int i = 0; i < buffLen; i++)
                            {
                                if (wLookBack[bPos] == vtx.weight[n])
                                {
                                    v.Append(wIndex - (i + 1) + " ");
                                    found = true;
                                    break;
                                }
                                bPos = (bPos - 1) & 0x1f;
                            }

                            if (!found)
                            {
                                v.Append(wIndex++ + " ");
                                w.Append(vtx.weight[n].ToString(CultureInfo.InvariantCulture) + " ");
                                wCount++;

                                wLookBack[wLookBackIndex] = vtx.weight[n];
                                wLookBackIndex = (wLookBackIndex + 1) & 0x1f;
                                if (buffLen < wLookBack.Length) buffLen++;
                            }
                        }
                    }

                    weights.float_array.data = w.ToString().TrimEnd();
                    weights.float_array.count = (uint)wCount;
                    weights.technique_common.accessor.count = (uint)wCount;

                    controller.skin.src.Add(weights);
                    controller.skin.vertex_weights.vcount = vcount.ToString().TrimEnd();
                    controller.skin.vertex_weights.v = v.ToString().TrimEnd();
                    controller.skin.vertex_weights.count = (uint)mesh.vertices.Count;
                    controller.skin.joints.addInput("JOINT", "#" + joints.id);
                    controller.skin.joints.addInput("INV_BIND_MATRIX", "#" + bindPoses.id);

                    controller.skin.vertex_weights.addInput("JOINT", "#" + joints.id);
                    controller.skin.vertex_weights.addInput("WEIGHT", "#" + weights.id, 1);

                    if (dae.library_controllers == null) dae.library_controllers = new List<daeController>();
                    dae.library_controllers.Add(controller);
                }

                //Visual scene node
                daeNode node = new daeNode();
                node.name = "vsn_" + meshName;
                node.id = node.name + "_id";
                node.matrix.set(new RenderBase.OMatrix());
                if (hasController)
                {
                    node.instance_controller = new daeInstanceController();
                    node.instance_controller.url = "#" + controller.id;
                    node.instance_controller.skeleton = "#" + mdl.skeleton[0].name + "_bone_id";
                    node.instance_controller.bind_material.technique_common.instance_material.symbol = mdl.material[obj.materialId].name;
                    node.instance_controller.bind_material.technique_common.instance_material.target = "#" + mdl.material[obj.materialId].name + "_mat_id";
                }
                else
                {
                    node.instance_geometry = new daeInstanceGeometry();
                    node.instance_geometry.url = "#" + geometry.id;
                    node.instance_geometry.bind_material.technique_common.instance_material.symbol = mdl.material[obj.materialId].name;
                    node.instance_geometry.bind_material.technique_common.instance_material.target = "#" + mdl.material[obj.materialId].name + "_mat_id";
                }

                vs.node.Add(node);
            }
            dae.library_visual_scenes.Add(vs);

            daeInstaceVisualScene scene = new daeInstaceVisualScene();
            scene.url = "#" + vs.id;
            dae.scene.Add(scene);

            XmlWriterSettings settings = new XmlWriterSettings
            {
                Encoding = Encoding.UTF8,
                Indent = true
            };

            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", "http://www.collada.org/2005/11/COLLADASchema");
            XmlSerializer serializer = new XmlSerializer(typeof(COLLADA));
            XmlWriter output = XmlWriter.Create(new FileStream(fileName, FileMode.Create), settings);
            serializer.Serialize(output, dae, ns);
            output.Close();
        }
Esempio n. 43
0
            public void set(RenderBase.OMatrix mtx)
            {
                StringBuilder strArray = new StringBuilder();
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        if (i == 3 && j == 3)
                            strArray.Append(mtx[j, i].ToString(CultureInfo.InvariantCulture));
                        else
                            strArray.Append(mtx[j, i].ToString(CultureInfo.InvariantCulture) + " ");
                    }

                }
                data = strArray.ToString();
            }
Esempio n. 44
0
 /// <summary>
 ///     Loads a SMES file.
 /// </summary>
 /// <param name="fileName">File Name of the SMES file</param>
 /// <returns></returns>
 public static void load(string fileName, RenderBase.OModel model)
 {
     load(new MemoryStream(File.ReadAllBytes(fileName)), model);
 }
Esempio n. 45
0
 public CommandResize(RenderScene scene, RenderBase render)
     : base(scene, render.uniqueName)
 {
     this._orign  = render.oriSize;
     this._finish = render.size;
 }
Esempio n. 46
0
        /// <summary>
        ///     Loads a SMES file.
        ///     Note that SMES must start at offset 0x0.
        /// </summary>
        /// <param name="data">Stream of the SMES file.</param>
        /// <returns></returns>
        public static void load(Stream data, RenderBase.OModel model, bool ignoreMaterial = false)
        {
            BinaryReader input = new BinaryReader(data);

            //The node indices points to the index directly relative to the tree index on the Skeleton
            //Therefore, we must build a table to translate from the Skeleton Index to the absolute Bone Tree Index
            List<int> nodeBinding = new List<int>();
            buildNodeBinding(model.skeleton, 0, ref nodeBinding);

            string smesMagic = IOUtils.readStringWithLength(input, 4);
            uint dataTableOffset = input.ReadUInt32();
            uint meshCount = input.ReadUInt32();
            for (int meshIndex = 0; meshIndex < meshCount; meshIndex++)
            {
                //Mesh descriptor
                data.Seek(0xc + meshIndex * 0x20, SeekOrigin.Begin);
                uint vector3TableEntries = input.ReadUInt32();
                uint vector3TableOffset = input.ReadUInt32();
                uint attributesCount = input.ReadUInt32();
                uint primitiveCount = input.ReadUInt32();
                uint vertexBufferOffset = input.ReadUInt32();
                uint indexSectionOffset = input.ReadUInt32();
                uint renderPriority = input.ReadUInt32();
                uint materialIndex = input.ReadUInt32();

                //Index Buffer section
                data.Seek(indexSectionOffset, SeekOrigin.Begin);

                RenderBase.OMesh obj = new RenderBase.OMesh();
                if (!ignoreMaterial) obj.materialId = (ushort)materialIndex;
                obj.isVisible = true;
                obj.hasNormal = true;
                obj.hasTangent = true;
                obj.texUVCount = 1;

                ushort[] nodes = null;
                uint skinningMode = 0;
                bool hasData = true;
                while (hasData)
                {
                    string magic = IOUtils.readStringWithLength(input, 4);
                    uint sectionLength = input.ReadUInt32();
                    long startOffset = data.Position;
                    
                    switch (magic)
                    {
                        case "SKIN": skinningMode = input.ReadUInt32(); break; //0 = rigid, 1 = smooth
                        case "BONI":
                            nodes = new ushort[input.ReadUInt16()];
                            for (int n = 0; n < nodes.Length; n++) nodes[n] = input.ReadUInt16();
                            obj.hasNode = true;
                            obj.hasWeight = true;
                            break;
                        case "IDX ":
                            input.ReadUInt16();
                            ushort indicesCount = input.ReadUInt16();

                            //Note: The Stride seems to always be 0x40
                            uint vertexStride = (indexSectionOffset - vertexBufferOffset) / primitiveCount;
                            for (int i = 0; i < indicesCount; i++)
                            {
                                ushort index = input.ReadUInt16();

                                long position = data.Position;
                                data.Seek(vertexBufferOffset + index * vertexStride, SeekOrigin.Begin);

                                RenderBase.OVertex vertex = new RenderBase.OVertex();
                                vertex.diffuseColor = 0xffffffff;
                                vertex.position = new RenderBase.OVector3(input.ReadSingle(), input.ReadSingle(), input.ReadSingle());
                                vertex.normal = new RenderBase.OVector3(input.ReadSingle(), input.ReadSingle(), input.ReadSingle());
                                vertex.tangent = new RenderBase.OVector3(input.ReadSingle(), input.ReadSingle(), input.ReadSingle());
                                vertex.texture0 = new RenderBase.OVector2(input.ReadSingle(), input.ReadSingle());

                                if (model.skeleton.Count > 0)
                                {
                                    if (nodes != null && nodes.Length > 0)
                                    {
                                        byte b0 = input.ReadByte();
                                        byte b1 = input.ReadByte();
                                        byte b2 = input.ReadByte();
                                        byte b3 = input.ReadByte();

                                        if (b0 < nodes.Length) vertex.node.Add(nodeBinding[nodes[b0]]);
                                        if (skinningMode > 0)
                                        {
                                            if (b1 < nodes.Length) vertex.node.Add(nodeBinding[nodes[b1]]);
                                            if (b2 < nodes.Length) vertex.node.Add(nodeBinding[nodes[b2]]);
                                            if (b3 < nodes.Length) vertex.node.Add(nodeBinding[nodes[b3]]);
                                        }
                                    }

                                    vertex.weight.Add(input.ReadSingle());
                                    if (skinningMode > 0)
                                    {
                                        vertex.weight.Add(input.ReadSingle());
                                        vertex.weight.Add(input.ReadSingle());
                                        vertex.weight.Add(input.ReadSingle());
                                    }
                                }

                                MeshUtils.calculateBounds(model, vertex);
                                obj.vertices.Add(vertex);

                                data.Seek(position, SeekOrigin.Begin);
                            }
                            break;
                        default: hasData = false; break;
                    }

                    data.Seek(startOffset + sectionLength, SeekOrigin.Begin);
                }

                model.mesh.Add(obj);
            }

            data.Close();
        }
Esempio n. 47
0
 public CommandMove(RenderScene scene, RenderBase render)
     : base(scene, render.uniqueName)
 {
     this._orign  = render.oriPos;
     this._finish = render.pos;
 }
Esempio n. 48
0
 /// <summary>
 ///     Transforms a Node from relative to absolute positions.
 /// </summary>
 /// <param name="nodes">A list with all nodes</param>
 /// <param name="index">Index of the node to convert</param>
 /// <param name="target">Target matrix to save node transformation</param>
 private static void transformNode(List<node> nodes, int index, ref RenderBase.OMatrix target)
 {
     target *= nodes[index].transform;
     if (nodes[index].parentId > -1) transformNode(nodes, nodes[index].parentId, ref target);
 }
Esempio n. 49
0
 private static RenderBase generateViewBySrc(String src, RenderBase parent)
 {
     return(generateViewByXml(XmlHelper.Parse(src), parent));
 }
        /// <summary>
        ///     Gets the current frame of a Material Animation color.
        /// </summary>
        /// <param name="data">The animation data</param>
        /// <param name="color">The color where the animation will be applied</param>
        private void getMaterialAnimationColor(RenderBase.OMaterialAnimationData data, ref Color color)
        {
            float r = AnimationUtils.getKey(data.frameList[0], ctrlMA.Frame);
            float g = AnimationUtils.getKey(data.frameList[1], ctrlMA.Frame);
            float b = AnimationUtils.getKey(data.frameList[2], ctrlMA.Frame);
            float a = AnimationUtils.getKey(data.frameList[3], ctrlMA.Frame);

            byte R = data.frameList[0].exists ? (byte)(r * 0xff) : color.R;
            byte G = data.frameList[1].exists ? (byte)(g * 0xff) : color.G;
            byte B = data.frameList[2].exists ? (byte)(b * 0xff) : color.B;
            byte A = data.frameList[3].exists ? (byte)(a * 0xff) : color.A;

            color = Color.FromArgb(A, R, G, B);
        }
Esempio n. 51
0
 public CommandAdd(RenderScene scene, RenderBase opItem)
     : base(scene, opItem.uniqueName)
 {
     xml          = UIHelper.generateXmlByItem(opItem);
     parentUnique = opItem.getParent().uniqueName;
 }
        /// <summary>
        ///     Creates a Quaternion from a Rotation 3-D Vector.
        /// </summary>
        /// <param name="vector">The rotation vector</param>
        /// <returns></returns>
        private Quaternion getQuaternion(RenderBase.OVector3 vector)
        {
            Quaternion output = Quaternion.Identity;

            output *= Quaternion.RotationAxis(new Vector3(1, 0, 0), vector.x);
            output *= Quaternion.RotationAxis(new Vector3(0, 1, 0), vector.y);
            output *= Quaternion.RotationAxis(new Vector3(0, 0, 1), vector.z);

            return output;
        }