Ejemplo n.º 1
0
        public SBHsdMaterial(HSD_DOBJ dobj)
        {
            _mobj = dobj.Mobj;

            /*if (_mobj.Textures != null)
             *  foreach (var tex in _mobj.Textures.List)
             *      Console.WriteLine(tex.Flags.ToString());*/
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="objFileStream"></param>
        /// <returns></returns>
        public static HSD_JOBJ GenerateEmblemModel(EmblemModel model)
        {
            List <GX_Vertex> vertexList = new List <GX_Vertex>();

            foreach (var ve in model.f)
            {
                foreach (var i in ve)
                {
                    var x = ((model.v[i - 1][0] - model.xRange.X) / Math.Abs(model.xRange.Y - model.xRange.X)) * model.aspectX;
                    var y = (1 - (model.v[i - 1][2] - model.yRange.X) / Math.Abs(model.xRange.Y - model.yRange.X)) * model.aspectY;

                    vertexList.Add(new GX_Vertex()
                    {
                        POS = new GXVector3(x * 6 - 3, y * 6 - 3, 0)
                    });
                }
            }

            HSD_JOBJ jobj = new HSD_JOBJ();

            jobj.Flags = JOBJ_FLAG.CLASSICAL_SCALING | JOBJ_FLAG.XLU;
            jobj.SX    = 3;
            jobj.SY    = 3;
            jobj.SZ    = 3;
            jobj.TZ    = 67.4f;

            HSD_DOBJ dobj = new HSD_DOBJ();

            dobj.Mobj = new HSD_MOBJ()
            {
                RenderFlags = RENDER_MODE.CONSTANT | RENDER_MODE.NO_ZUPDATE | RENDER_MODE.XLU,
                Material    = new HSD_Material()
                {
                    Alpha         = 0.6f,
                    Shininess     = 50,
                    DiffuseColor  = Color.FromArgb(255, 128, 128, 230),
                    SpecularColor = Color.FromArgb(255, 255, 255, 255),
                    AmbientColor  = Color.FromArgb(255, 128, 128, 128),
                }
            };
            jobj.Dobj = dobj;

            POBJ_Generator pobjGen = new POBJ_Generator();

            GXAttribName[] attrs = new GXAttribName[] { GXAttribName.GX_VA_POS, GXAttribName.GX_VA_NULL };
            dobj.Pobj       = pobjGen.CreatePOBJsFromTriangleList(vertexList, attrs, null);
            dobj.Pobj.Flags = 0;
            pobjGen.SaveChanges();

            return(jobj);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="vertices"></param>
        public void AddBuffer(HSD_DOBJ dobj, GX_Vertex[] vertices)
        {
            // generate buffer
            int buf;

            GL.GenBuffers(1, out buf);
            GL.BindBuffer(BufferTarget.ArrayBuffer, buf);
            GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * GX_Vertex.Stride, vertices, BufferUsageHint.StaticDraw);

            if (buf != -1)
            {
                attributeToBuffer.Add(dobj, buf);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        public static void MergeIntoOneObject(HSD_JOBJ jobj)
        {
            // gather all pobjs

            HSD_DOBJ result = null;

            List <HSD_POBJ> pobj = new List <HSD_POBJ>();

            foreach (var j in jobj.BreathFirstList)
            {
                if (j.Dobj != null)
                {
                    foreach (var d in j.Dobj.List)
                    {
                        if (d.Pobj != null)
                        {
                            foreach (var p in d.Pobj.List)
                            {
                                pobj.Add(p);
                            }
                        }
                    }

                    if (result == null)
                    {
                        result      = j.Dobj;
                        result.Next = null;
                    }
                }
                j.Dobj = null;
            }

            // link pobjs
            for (int i = 0; i < pobj.Count; i++)
            {
                if (i == pobj.Count - 1)
                {
                    pobj[i].Next = null;
                }
                else
                {
                    pobj[i].Next = pobj[i + 1];
                }
            }

            // put them all in the first dobj
            result.Pobj = pobj[0];
            jobj.Dobj   = result;
        }
Ejemplo n.º 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="vertices"></param>
        public void AddShapeSets(HSD_DOBJ dobj, List <List <GX_Shape> > shapes)
        {
            if (!dobjToShapes.ContainsKey(dobj))
            {
                dobjToShapes.Add(dobj, new int[shapes.Count]);
            }
            else
            {
                foreach (var v in dobjToShapes[dobj])
                {
                    GL.DeleteBuffer(v);
                }

                dobjToShapes[dobj] = new int[shapes.Count];
            }

            int si = 0;

            foreach (var shape in shapes)
            {
                // convert to array
                var arr = shape.ToArray();

                // generate buffer
                int buf;
                GL.GenBuffers(1, out buf);
                GL.BindBuffer(BufferTarget.ArrayBuffer, buf);
                GL.BufferData(BufferTarget.ArrayBuffer, arr.Length * GX_Shape.Stride, arr, BufferUsageHint.StaticDraw);

                if (buf != -1)
                {
                    dobjToShapes[dobj][si] = buf;
                }

                si++;
            }
        }
Ejemplo n.º 6
0
        public DOBJContextMenu() : base()
        {
            MenuItem ImportAfter = new MenuItem("Import DOBJ After");

            ImportAfter.Click += (sender, args) =>
            {
                if (MainForm.SelectedDataNode.Accessor is HSD_DOBJ dobj)
                {
                    var f = FileIO.OpenFile("DAT (.dat)|*.dat");
                    if (f != null)
                    {
                        HSDRawFile dat     = new HSDRawFile(f);
                        HSD_DOBJ   newDOBJ = new HSD_DOBJ();
                        newDOBJ._s = dat.Roots[0].Data._s;
                        if (newDOBJ._s.Length == newDOBJ.TrimmedSize)
                        {
                            newDOBJ.Next = dobj.Next;
                            dobj.Next    = newDOBJ;
                        }
                    }
                }
            };
            MenuItems.Add(ImportAfter);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        /// <param name="dobj"></param>
        /// <param name="parentJOBJ"></param>
        /// <param name="jobjManager"></param>
        public void RenderDOBJShader(Camera camera, HSD_DOBJ dobj, HSD_JOBJ parentJOBJ, JOBJManager jobjManager, bool selected = false)
        {
            if (dobj.Pobj == null)
                return;

            if (HiddenDOBJs.Contains(dobj) || (selected && OnlyRenderSelected))
                return;

            if (OnlyRenderSelected && SelectedDOBJ != null && SelectedDOBJ._s != dobj._s)
                return;
            
            var mobj = dobj.Mobj;
            var pobjs = dobj.Pobj.List;

            if(!DOBJtoBuffer.ContainsKey(dobj))
                LoadDOBJ(dobj, jobjManager);
            
            if (!DOBJtoBuffer.ContainsKey(dobj))
                return;

            if (GXShader == null)
            {
                GXShader = new Shader();
                GXShader.LoadShader(@"Shader\gx.vert");
                GXShader.LoadShader(@"Shader\gx.frag");
            }

            GL.UseProgram(GXShader.programId);

            var mvp = camera.MvpMatrix;
            GL.UniformMatrix4(GXShader.GetVertexAttributeUniformLocation("mvp"), false, ref mvp);

            Vector3 camPos = (camera.RotationMatrix * new Vector4(camera.Translation, 1)).Xyz;
            GXShader.SetVector3("cameraPos", camPos);

            Matrix4 single = Matrix4.Identity;
            if (parentJOBJ != null && jobjManager != null)
                single = jobjManager.GetWorldTransform(parentJOBJ);
            GL.UniformMatrix4(GXShader.GetVertexAttributeUniformLocation("singleBind"), false, ref single);

            var rootJOBJ = jobjManager.GetJOBJ(0);
            GXShader.SetBoolToInt("isRootBound", parentJOBJ?._s == rootJOBJ?._s);

            GXShader.SetWorldTransformBones(jobjManager.GetWorldTransforms());
            //GXShader.SetBindTransformBones(jobjManager.GetBindTransforms());

            var tb = jobjManager.GetBindTransforms();
            if (tb.Length > 0)
                GXShader.SetMatrix4x4("binds", tb);
            
            GL.Uniform3(GXShader.GetVertexAttributeUniformLocation("overlayColor"), OverlayColor);

            Matrix4 sphereMatrix = camera.ModelViewMatrix;
            sphereMatrix.Invert();
            sphereMatrix.Transpose();
            GXShader.SetMatrix4x4("sphereMatrix", ref sphereMatrix);

            float wscale = 1;
            float hscale = 1;
            bool mirrorX = false;
            bool mirrorY = false;
            if (mobj != null)
                BindMOBJ(GXShader, mobj, out wscale, out hscale, out mirrorX, out mirrorY);

            GL.BindBuffer(BufferTarget.ArrayBuffer, DOBJtoBuffer[dobj]);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("PNMTXIDX"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("PNMTXIDX"), 1, VertexAttribPointerType.Short, false, GX_Vertex.Stride, 0);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS"), 3, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 8);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM"), 3, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 20);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_CLR0"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_CLR0"), 4, VertexAttribPointerType.Float, true, GX_Vertex.Stride, 56);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX0"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX0"), 2, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 88);
            
            if (selected)
            {
                GL.Uniform1(GXShader.GetVertexAttributeUniformLocation("colorOverride"), 1);
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
            }
            else
            {
                GL.PolygonMode(MaterialFace.Back, PolygonMode.Fill);
                GL.Uniform1(GXShader.GetVertexAttributeUniformLocation("colorOverride"), 0);
            }

            foreach (var p in DOBJtoPOBJCache[dobj])
            {
                var en = p.Envelopes;
                GL.Uniform4(GXShader.GetVertexAttributeUniformLocation("envelopeIndex"), p.Envelopes.Length, ref p.Envelopes[0].X);

                var we = p.Weights;
                GL.Uniform4(GXShader.GetVertexAttributeUniformLocation("weights"), p.Weights.Length, ref p.Weights[0].X);
                
                GL.Uniform1(GXShader.GetVertexAttributeUniformLocation("hasEnvelopes"), p.HasWeighting ? 1 : 0);

                foreach (var dl in p.DisplayLists)
                    GL.DrawArrays(dl.PrimType, dl.Offset, dl.Count);
            }
            
            GL.DisableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("PNMTXIDX"));
            GL.DisableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS"));
            GL.DisableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM"));
            GL.DisableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX0"));

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            GL.UseProgram(0);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Prepares DOBJ for rendering by loading relevant information into a cache
        /// </summary>
        private void LoadDOBJ(HSD_DOBJ dobj, JOBJManager jobjManager)
        {
            if(DOBJtoBuffer.ContainsKey(dobj))
            {
                GL.DeleteBuffer(DOBJtoBuffer[dobj]);
                DOBJtoBuffer.Remove(dobj);
            }

            List<CachedPOBJ> pobjs = new List<CachedPOBJ>();
            List<GX_Vertex> vertices = new List<GX_Vertex>();
            int off = 0;
            foreach(var pobj in dobj.Pobj.List)
            {
                var dl = pobj.ToDisplayList();

                vertices.AddRange(dl.Vertices);

                var pobjCache = new CachedPOBJ();

                // build envelopes
                int eni = 0;
                foreach(var v in dl.Envelopes)
                {
                    Vector4 b = new Vector4();
                    Vector4 w = new Vector4();
                    for(int i = 0; i < v.EnvelopeCount; i++)
                    {
                        if (i >= 4)
                            break;
                        w[i] = v.GetWeightAt(i);
                        b[i] = jobjManager.IndexOf(v.GetJOBJAt(i));
                    }
                    pobjCache.Weights[eni] = w;
                    pobjCache.Envelopes[eni] = b;
                    eni++;
                    pobjCache.HasWeighting = v.EnvelopeCount > 0;
                }

                // load display list
                foreach (var v in dl.Primitives)
                {
                    pobjCache.DisplayLists.Add(new CachedDL()
                    {
                        Offset = off,
                        Count = v.Count,
                        PrimType = GXTranslator.toPrimitiveType(v.PrimitiveType)
                    });
                    off += v.Count;
                }

                pobjs.Add(pobjCache);
            }
            
            var arr = vertices.ToArray();

            int buf;
            GL.GenBuffers(1, out buf);
            GL.BindBuffer(BufferTarget.ArrayBuffer, buf);
            GL.BufferData(BufferTarget.ArrayBuffer, arr.Length * GX_Vertex.Stride, arr, BufferUsageHint.StaticDraw);

            DOBJtoBuffer.Add(dobj, buf);
            DOBJtoPOBJCache.Add(dobj, pobjs);
        }
Ejemplo n.º 9
0
        public static HSD_DOBJ GenerateOutlineMesh(HSD_DOBJ DOBJ)
        {
            var settings = new OutlineSettings();

            using (PropertyDialog d = new PropertyDialog("Outline Settings", settings))
            {
                if (d.ShowDialog() != DialogResult.OK)
                {
                    return(null);
                }
            }

            var pobjGen = new POBJ_Generator();

            pobjGen.UseTriangleStrips = settings.UseStrips;

            var newDOBJ = new HSD_DOBJ();

            newDOBJ.Mobj = new HSD_MOBJ()
            {
                Material = new HSD_Material()
                {
                    AmbientColor  = Color.White,
                    SpecularColor = Color.Black,
                    DiffuseColor  = settings.Color,
                    DIF_A         = 255,
                    SPC_A         = 255,
                    AMB_A         = 255,
                    Shininess     = 50,
                    Alpha         = 1
                },
                RenderFlags = RENDER_MODE.CONSTANT
            };

            foreach (var pobj in DOBJ.Pobj.List)
            {
                var dl = pobj.ToDisplayList();

                var vertices = dl.Vertices;

                GXAttribName[] attrs = new GXAttribName[]
                {
                    GXAttribName.GX_VA_POS,
                    GXAttribName.GX_VA_NULL
                };

                if (pobj.HasAttribute(GXAttribName.GX_VA_PNMTXIDX))
                {
                    attrs = new GXAttribName[]
                    {
                        GXAttribName.GX_VA_PNMTXIDX,
                        GXAttribName.GX_VA_POS,
                        GXAttribName.GX_VA_NULL
                    };
                }

                List <GX_Vertex> newVerties = new List <GX_Vertex>();

                var offset = 0;
                foreach (var prim in dl.Primitives)
                {
                    var verts = vertices.GetRange(offset, prim.Count);
                    offset += prim.Count;

                    switch (prim.PrimitiveType)
                    {
                    case GXPrimitiveType.Quads:
                        verts = TriangleConverter.QuadToList(verts);
                        break;

                    case GXPrimitiveType.TriangleStrip:
                        verts = TriangleConverter.StripToList(verts);
                        break;

                    case GXPrimitiveType.Triangles:
                        break;

                    default:
                        Console.WriteLine(prim.PrimitiveType);
                        break;
                    }

                    newVerties.AddRange(verts);
                }

                // extrude
                for (int i = 0; i < newVerties.Count; i++)
                {
                    var v = newVerties[i];
                    v.POS.X += v.NRM.X * settings.Size;
                    v.POS.Y += v.NRM.Y * settings.Size;
                    v.POS.Z += v.NRM.Z * settings.Size;
                    //v.CLR0.R = settings.Color.R / 255f;
                    //v.CLR0.G = settings.Color.G / 255f;
                    //v.CLR0.B = settings.Color.B / 255f;
                    //v.CLR0.A = settings.Color.A / 255f;
                    newVerties[i] = v;
                }

                // invert faces
                for (int i = 0; i < newVerties.Count; i += 3)
                {
                    var temp = newVerties[i];
                    newVerties[i]     = newVerties[i + 2];
                    newVerties[i + 2] = temp;
                }

                var newpobj = pobjGen.CreatePOBJsFromTriangleList(newVerties, attrs, dl.Envelopes);
                foreach (var p in newpobj.List)
                {
                    p.Flags |= POBJ_FLAG.CULLBACK | POBJ_FLAG.UNKNOWN1;
                }
                if (newDOBJ.Pobj == null)
                {
                    newDOBJ.Pobj = newpobj;
                }
                else
                {
                    newDOBJ.Pobj.Add(newpobj);
                }
            }

            pobjGen.SaveChanges();

            return(newDOBJ);
        }
Ejemplo n.º 10
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private void ProcessMesh(IOScene scene, IOMesh mesh, HSD_JOBJ rootnode)
        {
            HSD_JOBJ parent = rootnode;

            HashSet <HSD_JOBJ> nodes = new HashSet <HSD_JOBJ>();

            foreach (var j in rootnode.BreathFirstList)
            {
                nodes.Add(j);
            }


            if (mesh.ParentBone != null && _cache.NameToJOBJ.ContainsKey(mesh.ParentBone.Name))
            {
                parent = _cache.NameToJOBJ[mesh.ParentBone.Name];
            }


            HSD_DOBJ root = null;
            HSD_DOBJ prev = null;

            //var skeleton = rootnode.BreathFirstList;
            Console.WriteLine("Processing " + mesh.Name);

            bool singleBinded = mesh.Name.Contains("SINGLE");

            foreach (var poly in mesh.Polygons)
            {
                // Skip Empty Polygon
                if (poly.Indicies.Count == 0)
                {
                    continue;
                }


                // convert to triangles
                poly.ToTriangles(mesh);

                if (poly.PrimitiveType != IOPrimitive.TRIANGLE)
                {
                    continue;
                }


                // Generate DOBJ
                HSD_DOBJ dobj = new HSD_DOBJ();

                if (Settings.ImportMeshNames)
                {
                    dobj.ClassName = mesh.Name;
                }

                if (root == null)
                {
                    root = dobj;
                }
                else
                {
                    prev.Next = dobj;
                }
                prev = dobj;


                // generate material
                var material = scene.Materials.Find(e => e.Name == poly.MaterialName);

                dobj.Mobj = GenerateMaterial(material);


                Console.WriteLine(mesh.Name + " " + material?.Name);


                // reflective mobjs do not use uvs
                var hasReflection = false;

                // bump maps need tangents and bitangents
                var hasBump = false;

                // Assess needed attributes based on the material MOBJ
                if (mesh.Name.Contains("REFLECTIVE"))
                {
                    hasReflection = true;
                }
#if DEBUG
                if (Settings.MetalModel)
                {
                    hasReflection = true;
                }
#endif

                if (mesh.Name.Contains("BUMP"))
                {
                    hasBump = true;
                }

                if (dobj.Mobj.Textures != null)
                {
                    foreach (var t in dobj.Mobj.Textures.List)
                    {
                        if (t.Flags.HasFlag(TOBJ_FLAGS.COORD_REFLECTION))
                        {
                            hasReflection = true;
                        }
                        if (t.Flags.HasFlag(TOBJ_FLAGS.BUMP))
                        {
                            hasBump = true;
                        }
                    }
                }

                // assess attributes
                List <GXAttribName> Attributes = new List <GXAttribName>();

                if (mesh.HasEnvelopes() && Settings.ImportRigging && !singleBinded)
                {
                    Attributes.Add(GXAttribName.GX_VA_PNMTXIDX);

                    if (hasReflection)
                    {
                        Attributes.Add(GXAttribName.GX_VA_TEX0MTXIDX);

                        if (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 1)
                        {
                            Attributes.Add(GXAttribName.GX_VA_TEX1MTXIDX);
                        }

#if DEBUG
                        if (Settings.MetalModel && !Attributes.Contains(GXAttribName.GX_VA_TEX1MTXIDX))
                        {
                            Attributes.Add(GXAttribName.GX_VA_TEX1MTXIDX);
                        }
#endif
                    }
                }


                Attributes.Add(GXAttribName.GX_VA_POS);


                if (hasBump)
                {
                    Attributes.Add(GXAttribName.GX_VA_NBT);
                }
                else
                if (mesh.HasNormals && Settings.ImportNormals)
                {
                    Attributes.Add(GXAttribName.GX_VA_NRM);
                }


                if (mesh.HasColorSet(0) && Settings.ImportVertexColor)
                {
                    Attributes.Add(GXAttribName.GX_VA_CLR0);
                }

                if (mesh.HasColorSet(1) && Settings.ImportVertexColor)
                {
                    Attributes.Add(GXAttribName.GX_VA_CLR1);
                }


                if (mesh.HasUVSet(0) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX0);
                }

                if ((mesh.HasUVSet(1) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 1)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX1);
                }

                if ((mesh.HasUVSet(2) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 2)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX2);
                }

                if ((mesh.HasUVSet(3) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 3)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX3);
                }

                if ((mesh.HasUVSet(4) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 4)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX4);
                }

                if ((mesh.HasUVSet(5) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 5)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX5);
                }

                if ((mesh.HasUVSet(6) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 6)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX6);
                }

                if ((mesh.HasUVSet(7) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 7)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX7);
                }


                var vertices   = new List <GX_Vertex>();
                var jobjList   = new List <HSD_JOBJ[]>();
                var weightList = new List <float[]>();

                foreach (var face in poly.Indicies)
                {
                    var v = mesh.Vertices[face];

                    GX_Vertex vertex = new GX_Vertex();

                    var tkvert  = new Vector3(v.Position.X, v.Position.Y, v.Position.Z);
                    var tknrm   = new Vector3(v.Normal.X, v.Normal.Y, v.Normal.Z);
                    var tktan   = new Vector3(v.Tangent.X, v.Tangent.Y, v.Tangent.Z);
                    var tkbitan = new Vector3(v.Binormal.X, v.Binormal.Y, v.Binormal.Z);

                    var parentTransform = _cache.jobjToWorldTransform[parent].Inverted();

                    if (_cache.jobjToWorldTransform[parent] != Matrix4.Identity)
                    {
                        tkvert  = Vector3.TransformPosition(tkvert, parentTransform);
                        tknrm   = Vector3.TransformNormal(tknrm, parentTransform).Normalized();
                        tktan   = Vector3.TransformNormal(tktan, parentTransform).Normalized();
                        tkbitan = Vector3.TransformNormal(tkbitan, parentTransform).Normalized();
                    }


                    if (mesh.HasEnvelopes() && Settings.ImportRigging)
                    {
                        // create weighting lists
                        List <float>    weight = new List <float>();
                        List <HSD_JOBJ> bones  = new List <HSD_JOBJ>();

                        if (v.Envelope.Weights.Count == 0)
                        {
                            weight.Add(1);
                            bones.Add(rootnode);
                        }

                        if (v.Envelope.Weights.Count > 4)
                        {
                            throw new Exception($"Too many weights! {v.Envelope.Weights.Count} in {mesh.Name}");
                        }

                        foreach (var bw in v.Envelope.Weights)
                        {
                            // check if skeleton actually contains bone
                            if (_cache.NameToJOBJ.ContainsKey(bw.BoneName) && nodes.Contains(_cache.NameToJOBJ[bw.BoneName]))
                            {
                                // add envelope
                                bones.Add(_cache.NameToJOBJ[bw.BoneName]);
                                weight.Add(bw.Weight);

                                // indicate enveloped jobjs
                                if (!_cache.EnvelopedJOBJs.Contains(_cache.NameToJOBJ[bw.BoneName]))
                                {
                                    _cache.EnvelopedJOBJs.Add(_cache.NameToJOBJ[bw.BoneName]);
                                }
                            }
                            else
                            {
                                throw new Exception($"Bone not found \"{bw.BoneName}\" Weight: {bw.Weight} in {mesh.Name}");
                            }
                        }

                        jobjList.Add(bones.ToArray());
                        weightList.Add(weight.ToArray());

                        // invert single binds
                        if (v.Envelope.Weights.Count == 1)
                        {
                            var inv = _cache.jobjToWorldTransform[_cache.NameToJOBJ[v.Envelope.Weights[0].BoneName]].Inverted();
                            tkvert  = Vector3.TransformPosition(tkvert, inv);
                            tknrm   = Vector3.TransformNormal(tknrm, inv).Normalized();
                            tktan   = Vector3.TransformNormal(tknrm, inv).Normalized();
                            tkbitan = Vector3.TransformNormal(tknrm, inv).Normalized();
                        }
                    }

                    vertex.POS   = GXTranslator.fromVector3(tkvert);
                    vertex.NRM   = GXTranslator.fromVector3(tknrm.Normalized());
                    vertex.TAN   = GXTranslator.fromVector3(tktan);
                    vertex.BITAN = GXTranslator.fromVector3(tkbitan);

                    if (Settings.InvertNormals)
                    {
                        vertex.NRM.X   *= -1;
                        vertex.NRM.Y   *= -1;
                        vertex.NRM.Z   *= -1;
                        vertex.TAN.X   *= -1;
                        vertex.TAN.Y   *= -1;
                        vertex.TAN.Z   *= -1;
                        vertex.BITAN.X *= -1;
                        vertex.BITAN.Y *= -1;
                        vertex.BITAN.Z *= -1;
                    }

                    if (mesh.HasUVSet(0))
                    {
                        vertex.TEX0 = new GXVector2(v.UVs[0].X, v.UVs[0].Y);
                    }

                    if (mesh.HasUVSet(1))
                    {
                        vertex.TEX1 = new GXVector2(v.UVs[1].X, v.UVs[1].Y);
                    }

                    if (mesh.HasUVSet(2))
                    {
                        vertex.TEX2 = new GXVector2(v.UVs[2].X, v.UVs[2].Y);
                    }

                    if (mesh.HasUVSet(3))
                    {
                        vertex.TEX3 = new GXVector2(v.UVs[3].X, v.UVs[3].Y);
                    }

                    if (mesh.HasUVSet(4))
                    {
                        vertex.TEX4 = new GXVector2(v.UVs[4].X, v.UVs[4].Y);
                    }

                    if (mesh.HasUVSet(5))
                    {
                        vertex.TEX5 = new GXVector2(v.UVs[5].X, v.UVs[5].Y);
                    }

                    if (mesh.HasUVSet(6))
                    {
                        vertex.TEX6 = new GXVector2(v.UVs[6].X, v.UVs[6].Y);
                    }

                    if (mesh.HasUVSet(7))
                    {
                        vertex.TEX7 = new GXVector2(v.UVs[7].X, v.UVs[7].Y);
                    }

                    if (mesh.HasColorSet(0))
                    {
                        vertex.CLR0 = new GXColor4(
                            v.Colors[0].X * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[0].Y * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[0].Z * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            Settings.ImportVertexAlpha ? v.Colors[0].W : 1);
                    }

                    if (mesh.HasColorSet(1))
                    {
                        vertex.CLR1 = new GXColor4(
                            v.Colors[1].X * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[1].Y * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[1].Z * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            Settings.ImportVertexAlpha ? v.Colors[1].W : 1);
                    }

                    vertices.Add(vertex);
                }


                // generate pobjs
                HSD_POBJ pobj = null;

                if (mesh.HasEnvelopes() && Settings.ImportRigging && !singleBinded)
                {
                    pobj = _cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), jobjList, weightList);
                }
                else
                {
                    pobj = _cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), null);
                }

                if (singleBinded && jobjList.Count > 0 && jobjList[0].Length > 0)
                {
                    parent = jobjList[0][0];
                }

                if (pobj != null)
                {
                    if (dobj.Pobj == null)
                    {
                        dobj.Pobj = pobj;
                    }
                    else
                    {
                        dobj.Pobj.Add(pobj);
                    }
                }
            }

            if (parent.Dobj == null)
            {
                parent.Dobj = root;
            }
            else
            {
                parent.Dobj.Add(root);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private static HSD_DOBJ GetMeshes(ProcessingCache cache, ModelImportSettings settings, Scene scene, Node node)
        {
            HSD_DOBJ root = null;
            HSD_DOBJ prev = null;

            Console.WriteLine("Processing " + node.Name);

            foreach (int index in node.MeshIndices)
            {
                Mesh mesh     = scene.Meshes[index];
                var  material = scene.Materials[mesh.MaterialIndex];

                Console.WriteLine(mesh.Name + " " + material.Name);

                // Generate DOBJ
                HSD_DOBJ dobj = new HSD_DOBJ();

                // hack to make dobjs merged by texture
                if (settings.ImportTexture &&
                    settings.ForceMergeObjects == ForceGroupModes.Texture &&
                    material.HasTextureDiffuse &&
                    cache.TextureToDOBJ.ContainsKey(material.TextureDiffuse.FilePath))
                {
                    dobj = cache.TextureToDOBJ[material.TextureDiffuse.FilePath];
                }
                else
                {
                    if (root == null)
                    {
                        root = dobj;
                    }
                    else
                    {
                        prev.Next = dobj;
                    }
                    prev = dobj;

                    dobj.Mobj = GenerateMaterial(cache, settings, material);
                    if (settings.ForceMergeObjects == ForceGroupModes.Texture &&
                        material.HasTextureDiffuse &&
                        settings.ImportTexture)
                    {
                        cache.TextureToDOBJ.Add(material.TextureDiffuse.FilePath, dobj);
                    }
                }

                if (root != null && settings.ForceMergeObjects == ForceGroupModes.MeshGroup)
                {
                    dobj = root;
                }

                // Assessment
                if (!mesh.HasFaces)
                {
                    continue;
                }

                // Assess needed attributes based on the material MOBJ

                // reflective mobjs do not use uvs
                var hasReflection = false;
                // bump maps need tangents and bitangents
                var hasBump = false;

                if (dobj.Mobj.Textures != null)
                {
                    foreach (var t in dobj.Mobj.Textures.List)
                    {
                        if (t.Flags.HasFlag(TOBJ_FLAGS.COORD_REFLECTION))
                        {
                            hasReflection = true;
                        }
                        if (t.Flags.HasFlag(TOBJ_FLAGS.BUMP))
                        {
                            hasBump = true;
                        }
                    }
                }

                List <GXAttribName> Attributes = new List <GXAttribName>();

                // todo: rigging
                List <HSD_JOBJ>[] jobjs   = new List <HSD_JOBJ> [mesh.Vertices.Count];
                List <float>[]    weights = new List <float> [mesh.Vertices.Count];
                if (mesh.HasBones)
                {
                    Attributes.Add(GXAttribName.GX_VA_PNMTXIDX);

                    foreach (var v in mesh.Bones)
                    {
                        var jobj = cache.NameToJOBJ[v.Name];

                        if (!cache.EnvelopedJOBJs.Contains(jobj))
                        {
                            cache.EnvelopedJOBJs.Add(jobj);
                        }

                        if (v.HasVertexWeights)
                        {
                            foreach (var vw in v.VertexWeights)
                            {
                                if (jobjs[vw.VertexID] == null)
                                {
                                    jobjs[vw.VertexID] = new List <HSD_JOBJ>();
                                }
                                if (weights[vw.VertexID] == null)
                                {
                                    weights[vw.VertexID] = new List <float>();
                                }
                                if (vw.Weight > 0)
                                {
                                    jobjs[vw.VertexID].Add(jobj);
                                    weights[vw.VertexID].Add(vw.Weight);
                                }
                            }
                        }
                    }
                }

                if (hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX0MTXIDX);
                }

                if (mesh.HasVertices)
                {
                    Attributes.Add(GXAttribName.GX_VA_POS);
                }

                if (mesh.HasVertexColors(0) && settings.ShadingType == ShadingType.VertexColor)
                {
                    Attributes.Add(GXAttribName.GX_VA_CLR0);
                }

                //if (mesh.HasVertexColors(1) && settings.ImportVertexColors)
                //    Attributes.Add(GXAttribName.GX_VA_CLR1);

                if (!hasBump && mesh.HasNormals && settings.ShadingType == ShadingType.Material)
                {
                    Attributes.Add(GXAttribName.GX_VA_NRM);
                }

                if (hasBump)
                {
                    Attributes.Add(GXAttribName.GX_VA_NBT);
                }

                if (mesh.HasTextureCoords(0) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX0);
                }

                //if (mesh.HasTextureCoords(1))
                //    Attributes.Add(GXAttribName.GX_VA_TEX1);

                var vertices = new List <GX_Vertex>();
                var jobjList = new List <HSD_JOBJ[]>(vertices.Count);
                var wList    = new List <float[]>(vertices.Count);

                foreach (var face in mesh.Faces)
                {
                    PrimitiveType faceMode;
                    switch (face.IndexCount)
                    {
                    case 1:
                        faceMode = PrimitiveType.Point;
                        break;

                    case 2:
                        faceMode = PrimitiveType.Line;
                        break;

                    case 3:
                        faceMode = PrimitiveType.Triangle;
                        break;

                    default:
                        faceMode = PrimitiveType.Polygon;
                        break;
                    }

                    if (faceMode != PrimitiveType.Triangle)
                    {
                        continue;
                        //throw new NotSupportedException($"Non triangle primitive types not supported at this time {faceMode}");
                    }

                    for (int i = 0; i < face.IndexCount; i++)
                    {
                        int indicie = face.Indices[i];

                        GX_Vertex vertex = new GX_Vertex();

                        if (mesh.HasBones)
                        {
                            jobjList.Add(jobjs[indicie].ToArray());
                            wList.Add(weights[indicie].ToArray());

                            // Single Binds Get Inverted
                            var tkvert = new Vector3(mesh.Vertices[indicie].X, mesh.Vertices[indicie].Y, mesh.Vertices[indicie].Z) * settings.Scale;
                            var tknrm  = new Vector3(mesh.Normals[indicie].X, mesh.Normals[indicie].Y, mesh.Normals[indicie].Z);

                            Vector3 tktan   = Vector3.Zero;
                            Vector3 tkbitan = Vector3.Zero;

                            if (mesh.HasTangentBasis)
                            {
                                tktan   = new Vector3(mesh.Tangents[indicie].X, mesh.Tangents[indicie].Y, mesh.Tangents[indicie].Z);
                                tkbitan = new Vector3(mesh.BiTangents[indicie].X, mesh.BiTangents[indicie].Y, mesh.BiTangents[indicie].Z);
                            }

                            if (jobjs[indicie].Count == 1 || weights[indicie][0] == 1)
                            {
                                tkvert = Vector3.TransformPosition(tkvert, cache.jobjToInverseTransform[jobjs[indicie][0]]);
                                tknrm  = Vector3.TransformNormal(tknrm, cache.jobjToInverseTransform[jobjs[indicie][0]]);

                                if (mesh.HasTangentBasis)
                                {
                                    tktan   = Vector3.TransformNormal(tktan, cache.jobjToInverseTransform[jobjs[indicie][0]]);
                                    tkbitan = Vector3.TransformNormal(tkbitan, cache.jobjToInverseTransform[jobjs[indicie][0]]);
                                }
                            }

                            vertex.POS   = GXTranslator.fromVector3(tkvert);
                            vertex.NRM   = GXTranslator.fromVector3(tknrm);
                            vertex.TAN   = GXTranslator.fromVector3(tktan);
                            vertex.BITAN = GXTranslator.fromVector3(tkbitan);
                        }
                        else
                        {
                            if (mesh.HasVertices)
                            {
                                vertex.POS = new GXVector3(mesh.Vertices[indicie].X * settings.Scale, mesh.Vertices[indicie].Y * settings.Scale, mesh.Vertices[indicie].Z * settings.Scale);
                            }

                            if (mesh.HasNormals)
                            {
                                vertex.NRM = new GXVector3(mesh.Normals[indicie].X, mesh.Normals[indicie].Y, mesh.Normals[indicie].Z);
                            }

                            if (mesh.HasTangentBasis)
                            {
                                vertex.TAN   = new GXVector3(mesh.Tangents[indicie].X, mesh.Tangents[indicie].Y, mesh.Tangents[indicie].Z);
                                vertex.BITAN = new GXVector3(mesh.BiTangents[indicie].X, mesh.BiTangents[indicie].Y, mesh.BiTangents[indicie].Z);
                            }
                        }

                        if (settings.InvertNormals)
                        {
                            vertex.NRM.X *= -1;
                            vertex.NRM.Y *= -1;
                            vertex.NRM.Z *= -1;
                        }

                        if (mesh.HasTextureCoords(0))
                        {
                            vertex.TEX0 = new GXVector2(
                                mesh.TextureCoordinateChannels[0][indicie].X,
                                mesh.TextureCoordinateChannels[0][indicie].Y);
                        }

                        if (mesh.HasTextureCoords(1))
                        {
                            vertex.TEX1 = new GXVector2(
                                mesh.TextureCoordinateChannels[1][indicie].X,
                                mesh.TextureCoordinateChannels[1][indicie].Y);
                        }

                        if (mesh.HasVertexColors(0))
                        {
                            vertex.CLR0 = new GXColor4(
                                mesh.VertexColorChannels[0][indicie].R,
                                mesh.VertexColorChannels[0][indicie].G,
                                mesh.VertexColorChannels[0][indicie].B,
                                settings.ImportVertexAlpha ? mesh.VertexColorChannels[0][indicie].A : 1);
                        }

                        if (mesh.HasVertexColors(1))
                        {
                            vertex.CLR0 = new GXColor4(
                                mesh.VertexColorChannels[1][indicie].R,
                                mesh.VertexColorChannels[1][indicie].G,
                                mesh.VertexColorChannels[1][indicie].B,
                                settings.ImportVertexAlpha ? mesh.VertexColorChannels[1][indicie].A : 1);
                        }

                        vertices.Add(vertex);
                    }
                }

                HSD_POBJ pobj = null;
                if (mesh.HasBones)
                {
                    pobj = cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), jobjList, wList);
                }
                else
                {
                    pobj = cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), null);
                }
                if (pobj != null)
                {
                    if (dobj.Pobj == null)
                    {
                        dobj.Pobj = pobj;
                    }
                    else
                    {
                        dobj.Pobj.Add(pobj);
                    }
                }
            }

            return(root);
        }
Ejemplo n.º 12
0
 public DOBJHandler(HSD_DOBJ dobj)
 {
     _dobj = dobj;
 }
Ejemplo n.º 13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dobj"></param>
        /// <returns></returns>
        public bool BindBuffer(Shader GXShader, HSD_DOBJ dobj, int shapeset1, int shapeset2, float blend)
        {
            if (!attributeToBuffer.ContainsKey(dobj))
            {
                return(false);
            }

            GXShader.SetFloat("shape_blend", blend);

            // normal attributes
            GL.BindBuffer(BufferTarget.ArrayBuffer, attributeToBuffer[dobj]);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("PNMTXIDX"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("PNMTXIDX"), 1, VertexAttribPointerType.Short, false, GX_Vertex.Stride, 0);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS"), 3, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 8);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM"), 3, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 20);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_BTAN"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_TAN"), 3, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 32);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_TAN"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_BTAN"), 3, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 44);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_CLR0"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_CLR0"), 4, VertexAttribPointerType.Float, true, GX_Vertex.Stride, 56);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX0"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX0"), 2, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 88);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX1"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX1"), 2, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 96);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX2"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX2"), 2, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 104);

            GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX3"));
            GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_TEX3"), 2, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 112);


            // shape sets (if exists)
            if (dobjToShapes.ContainsKey(dobj))
            {
                if (shapeset1 < dobjToShapes[dobj].Length)
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, dobjToShapes[dobj][shapeset1]);

                    GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS"));
                    GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS"), 3, VertexAttribPointerType.Float, false, GX_Shape.Stride, 0);

                    GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM"));
                    GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM"), 3, VertexAttribPointerType.Float, false, GX_Shape.Stride, 12);
                }

                if (shapeset2 < dobjToShapes[dobj].Length)
                {
                    GL.BindBuffer(BufferTarget.ArrayBuffer, dobjToShapes[dobj][shapeset2]);

                    GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS_SHAPE"));
                    GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS_SHAPE"), 3, VertexAttribPointerType.Float, false, GX_Shape.Stride, 0);

                    GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM_SHAPE"));
                    GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM_SHAPE"), 3, VertexAttribPointerType.Float, false, GX_Shape.Stride, 12);
                }
            }
            else
            {
                GL.BindBuffer(BufferTarget.ArrayBuffer, attributeToBuffer[dobj]);

                GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS_SHAPE"));
                GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_POS_SHAPE"), 3, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 8);

                GL.EnableVertexAttribArray(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM_SHAPE"));
                GL.VertexAttribPointer(GXShader.GetVertexAttributeUniformLocation("GX_VA_NRM_SHAPE"), 3, VertexAttribPointerType.Float, false, GX_Vertex.Stride, 20);
            }
            return(true);
        }