예제 #1
0
        protected void UpdateBoneMatrices(TSONode tso_node, TMOFrame tmo_frame)
        {
            matrixStack.Push();

            Matrix transform;

            if (tmo_frame != tmo_frame_one)
            {
                // TMO animation
                TMONode tmo_node;
                if (nodemap.TryGetValue(tso_node, out tmo_node))
                {
                    transform = tmo_frame.matrices[tmo_node.ID].m;
                }
                else
                {
                    transform = tso_node.transformation_matrix;
                }
            }
            else
            {
                transform = tso_node.transformation_matrix;
            }

            matrixStack.MultiplyMatrixLocal(transform);
            combinedMatrices[tmo_frame][tso_node] = matrixStack.Top;

            foreach (TSONode child_node in tso_node.child_nodes)
            {
                UpdateBoneMatrices(child_node, tmo_frame);
            }

            matrixStack.Pop();
        }
예제 #2
0
        public static Matrix GetBoneOffsetMatrix(TSONode bone)
        {
            Matrix mat = Matrix.Identity;

            while (bone != null)
            {
                mat.Multiply(bone.transformation_matrix);
                bone = bone.parent;
            }
            return(Matrix.Invert(mat));
        }
예제 #3
0
        public Matrix GetCombinedMatrix(TSONode tso_node)
        {
            TMOFrame tmo_frame;

            if (tso_node.slow > 0)
            {
                tmo_frame = GetTMOFrameSlow(tso_node.slow);
            }
            else
            {
                tmo_frame = GetTMOFrame();
            }
            return(combinedMatrices[tmo_frame][tso_node]);
        }
예제 #4
0
        public void Render()
        {
            device.BeginScene();

            {
                Matrix world_view_matrix            = world_matrix * Transform_View;
                Matrix world_view_projection_matrix = world_view_matrix * Transform_Projection;
                effect.SetValue("wld", world_matrix);
                effect.SetValue("wv", world_view_matrix);
                effect.SetValue("wvp", world_view_projection_matrix);
            }

            device.SetRenderTarget(0, dev_surface);
            device.DepthStencilSurface = dev_zbuf;
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.LightGray, 1.0f, 0);

            device.RenderState.AlphaBlendEnable = true;

            foreach (TSOFigure fig in TSOFigureList)
            {
                foreach (TSOFile tso in fig.TSOList)
                {
                    tso.BeginRender();

                    foreach (TSOMesh tm in tso.meshes)
                    {
                        foreach (TSOMesh tm_sub in tm.sub_meshes)
                        {
                            device.RenderState.VertexBlend = (VertexBlend)(4 - 1);

                            tso.SwitchShader(tm_sub);
                            Matrix[] clipped_boneMatrices = new Matrix[tm_sub.maxPalettes];

                            int i = 0;
                            for (int numPalettes = 0; numPalettes < tm_sub.maxPalettes; numPalettes++)
                            {
                                //device.Transform.SetWorldMatrixByIndex(numPalettes, combined_matrix);
                                TSONode bone = tm_sub.GetBone(numPalettes);
                                boneMatrices[numPalettes] = bone.GetOffsetMatrix() * fig.GetCombinedMatrix(bone);
                            }
                            Array.Copy(boneMatrices, clipped_boneMatrices, tm_sub.maxPalettes);
                            effect.SetValue(handle_LocalBoneMats, clipped_boneMatrices);

                            int npass = effect.Begin(0);
                            for (int ipass = 0; ipass < npass; ipass++)
                            {
                                effect.BeginPass(ipass);
                                tm_sub.dm.DrawSubset(i);
                                effect.EndPass();
                            }
                            effect.End();
                        }
                    }
                    tso.EndRender();
                }
            }

            int height = 24;

            for (int i = 0; i < keys.Length; i++)
            {
                if (keys[i])
                {
                    font.DrawText(null, ((Keys)i).ToString(), 0, height, Color.Black);
                    height += 24;
                }
            }

            device.EndScene();
            device.Present();
            Thread.Sleep(30);
        }
예제 #5
0
        public int Load(Stream source_stream)
        {
            try
            {
                reader = new BinaryReader(source_stream, System.Text.Encoding.Default);
            }
            catch (Exception)
            {
                Console.WriteLine("Error: This file cannot be read or does not exist.");
                return(-1);
            }

            byte[] file_header = new byte[4];
            file_header = reader.ReadBytes(4);

            if (!System.Text.Encoding.ASCII.GetString(file_header).Contains("TSO1"))
            {
                Console.WriteLine("Error: This seems not to be a TSO file.");
            }

            int node_count = reader.ReadInt32();

            nodes   = new TSONode[node_count];
            nodemap = new Dictionary <string, TSONode>();

            for (int i = 0; i < node_count; i++)
            {
                nodes[i]       = new TSONode();
                nodes[i].id    = i;
                nodes[i].name  = ReadString();
                nodes[i].sname = nodes[i].name.Substring(nodes[i].name.LastIndexOf('|') + 1);
                nodemap.Add(nodes[i].name, nodes[i]);

                //Console.WriteLine(i + ": " + nodes[i].sname);
            }

            for (int i = 0; i < node_count; i++)
            {
                int index = nodes[i].name.LastIndexOf('|');
                if (index <= 0)
                {
                    continue;
                }
                string pname = nodes[i].name.Substring(0, index);
                nodes[i].parent = nodemap[pname];
                nodes[i].parent.child_nodes.Add(nodes[i]);
            }

            {
                TSONode node;
                if (nodemap.TryGetValue("|W_Hips|W_Spine_Dummy|W_Spine1|W_Spine2|W_Spine3|Chichi_Right1", out node))
                {
                    node.SlowChildren();
                }
                if (nodemap.TryGetValue("|W_Hips|W_Spine_Dummy|W_Spine1|W_Spine2|W_Spine3|Chichi_Left1", out node))
                {
                    node.SlowChildren();
                }
            }

            int node_matrix_count = reader.ReadInt32();

            for (int i = 0; i < node_matrix_count; i++)
            {
                nodes[i].transformation_matrix = ReadMatrix();
            }
            for (int i = 0; i < node_matrix_count; i++)
            {
                nodes[i].ComputeOffsetMatrix();
            }

            UInt32 texture_count = reader.ReadUInt32();

            textures = new TSOTex[texture_count];
            for (int i = 0; i < texture_count; i++)
            {
                textures[i] = read_texture();
            }

            UInt32 script_count = reader.ReadUInt32();

            scripts = new TSOScript[script_count];
            for (int i = 0; i < script_count; i++)
            {
                scripts[i] = read_script();
            }

            UInt32 sub_script_count = reader.ReadUInt32();

            TSOScript[] sub_scripts = new TSOScript[sub_script_count];
            for (int i = 0; i < sub_script_count; i++)
            {
                sub_scripts[i] = read_sub_script();
            }
            scripts[0].sub_scripts = sub_scripts;

            UInt32 mesh_count = reader.ReadUInt32();

            meshes = new TSOMesh[mesh_count];
            for (int i = 0; i < mesh_count; i++)
            {
                TSOMesh mesh = read_mesh();
                meshes[i] = mesh;

                //Console.WriteLine("mesh name {0} len {1}", mesh.name, mesh.sub_meshes.Length);
            }
            reader.Close();
            return(0);
        }
예제 #6
0
        public TSOMesh read_mesh()
        {
            TSOMesh mesh = new TSOMesh();

            mesh.name             = ReadString();
            mesh.name             = mesh.name.Replace(":", "_colon_").Replace("#", "_sharp_"); //should be compatible with directx naming conventions
            mesh.transform_matrix = ReadMatrix();
            mesh.unknown1         = reader.ReadUInt32();
            mesh.sub_mesh_count   = reader.ReadUInt32();
            mesh.sub_meshes       = new TSOMesh[mesh.sub_mesh_count];

            mesh.spec           = 0;
            mesh.bone_index_LUT = new List <UInt32>();
            mesh.bone_LUT       = new List <TSONode>();

            mesh.vertices = new vertex_field[0];

            for (int a = 0; a < mesh.sub_mesh_count; a++)
            {
                TSOMesh act_mesh = new TSOMesh();
                mesh.sub_meshes[a] = act_mesh;

                act_mesh.name             = mesh.name + "_sub_" + a.ToString();
                act_mesh.transform_matrix = mesh.transform_matrix;
                act_mesh.unknown1         = mesh.unknown1;
                act_mesh.sub_mesh_count   = 0;

                act_mesh.spec = reader.ReadInt32();
                int bone_index_LUT_entry_count = reader.ReadInt32(); //numbones
                act_mesh.maxPalettes = 16;
                if (act_mesh.maxPalettes > bone_index_LUT_entry_count)
                {
                    act_mesh.maxPalettes = bone_index_LUT_entry_count;
                }
                act_mesh.bone_index_LUT = new List <UInt32>();
                act_mesh.bone_LUT       = new List <TSONode>();
                for (int i = 0; i < bone_index_LUT_entry_count; i++)
                {
                    act_mesh.bone_index_LUT.Add(reader.ReadUInt32());
                }
                int vertex_count = reader.ReadInt32(); //numvertices
                act_mesh.vertices = new vertex_field[vertex_count];
                for (int i = 0; i < vertex_count; i++)
                {
                    ReadVertex(ref act_mesh.vertices[i]);
                }
            }

            for (int a = 0; a < mesh.sub_mesh_count; a++)
            {
                TSOMesh sub_mesh = mesh.sub_meshes[a];

                for (int i = 0; i < sub_mesh.bone_index_LUT.Count; i++)
                {
                    UInt32  bone_index = sub_mesh.bone_index_LUT[i];
                    TSONode bone       = nodes[bone_index];
                    sub_mesh.bone_LUT.Add(bone);
                }
            }

            return(mesh);
        }
예제 #7
0
 public void ComputeOffsetMatrix()
 {
     offset_matrix = TSONode.GetBoneOffsetMatrix(this);
 }