/// <summary>
        ///
        /// </summary>
        /// <param name="jobj"></param>
        public static void CalculateCollisionFlags(this KAR_grCollisionNode coll)
        {
            var verts = coll.Vertices;
            var tris  = coll.Triangles;

            foreach (var tri in tris)
            {
                // calculate surface normal
                var v0 = GXTranslator.toVector3(verts[tri.V1]);
                var v1 = GXTranslator.toVector3(verts[tri.V2]);
                var v2 = GXTranslator.toVector3(verts[tri.V3]);

                var faceNrm = Vector3.Cross(v1 - v0, v2 - v0).Normalized();

                tri.Flags &= ~0x7;

                // guess flag
                if (faceNrm.Y > 0.5f)
                {
                    tri.Flags |= 0x04;
                }
                else
                if (faceNrm.Y <= 0.5f && faceNrm.Y > -0.5f)
                {
                    tri.Flags |= 0x02;
                }
                else
                {
                    tri.Flags |= 0x01;
                }
            }

            coll.Triangles = tris;
        }
Ejemplo n.º 2
0
        public void Render(HSDAccessor a, int windowWidth, int windowHeight)
        {
            if (a is KAR_grCollisionNode cn && cn != Node)
            {
                Node      = cn;
                Vertices  = Node.Vertices;
                Triangles = Node.Triangles;
                Joints    = Node.Joints;

                ZoneVertices  = Node.ZoneVertices;
                ZoneTriangles = Node.ZoneTriangles;
                ZoneJoints    = Node.ZoneJoints;
            }

            if (Node == null)
            {
                return;
            }

            GL.PushAttrib(AttribMask.AllAttribBits);

            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            GL.Begin(PrimitiveType.Triangles);

            foreach (var t in Triangles)
            {
                if ((t.Flags & 0x1) == 0x1)
                {
                    GL.Color4(1f, 0f, 0f, 0.5f);
                }
                if ((t.Flags & 0x2) == 0x2)
                {
                    GL.Color4(0f, 1f, 0f, 0.5f);
                }
                if ((t.Flags & 0x4) == 0x4)
                {
                    GL.Color4(0f, 0f, 1f, 0.5f);
                }

                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V1]));
                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V2]));
                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V3]));
            }

            GL.End();

            GL.PopAttrib();
        }
Ejemplo n.º 3
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.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mobj"></param>
        public void BindMOBJ(Shader shader, HSD_MOBJ mobj, HSD_JOBJ parentJOBJ, MatAnimManager animation)
        {
            if (mobj == null)
            {
                return;
            }

            GL.Enable(EnableCap.Texture2D);

            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            GL.Enable(EnableCap.AlphaTest);
            GL.AlphaFunc(AlphaFunction.Greater, 0f);

            GL.DepthMask(!mobj.RenderFlags.HasFlag(RENDER_MODE.NO_ZUPDATE));

            // Pixel Processing
            shader.SetInt("alphaOp", -1);   // none
            shader.SetInt("alphaComp0", 7); // always
            shader.SetInt("alphaComp1", 7);

            // Materials
            var color = mobj.Material;

            if (color != null)
            {
                MaterialState.Ambient.X = color.AMB_R / 255f;
                MaterialState.Ambient.Y = color.AMB_G / 255f;
                MaterialState.Ambient.Z = color.AMB_B / 255f;
                MaterialState.Ambient.W = color.AMB_A / 255f;

                MaterialState.Diffuse.X = color.DIF_R / 255f;
                MaterialState.Diffuse.Y = color.DIF_G / 255f;
                MaterialState.Diffuse.Z = color.DIF_B / 255f;
                MaterialState.Diffuse.W = color.DIF_A / 255f;

                MaterialState.Specular.X = color.SPC_R / 255f;
                MaterialState.Specular.Y = color.SPC_G / 255f;
                MaterialState.Specular.Z = color.SPC_B / 255f;
                MaterialState.Specular.W = color.SPC_A / 255f;

                MaterialState.Shininess = color.Shininess;
                MaterialState.Alpha     = color.Alpha;

                if (animation != null)
                {
                    animation.GetMaterialState(mobj, ref MaterialState);
                }

                shader.SetVector4("ambientColor", MaterialState.Ambient);
                shader.SetVector4("diffuseColor", MaterialState.Diffuse);
                shader.SetVector4("specularColor", MaterialState.Specular);
                shader.SetFloat("shinniness", MaterialState.Shininess);
                shader.SetFloat("alpha", MaterialState.Alpha);
            }

            var pp = mobj.PEDesc;

            if (pp != null)
            {
                MaterialState.Ref0 = pp.AlphaRef0 / 255f;
                MaterialState.Ref1 = pp.AlphaRef1 / 255f;

                if (animation != null)
                {
                    animation.GetMaterialState(mobj, ref MaterialState);
                }

                GL.BlendFunc(GXTranslator.toBlendingFactor(pp.SrcFactor), GXTranslator.toBlendingFactor(pp.DstFactor));
                GL.DepthFunc(GXTranslator.toDepthFunction(pp.DepthFunction));

                shader.SetInt("alphaOp", (int)pp.AlphaOp);
                shader.SetInt("alphaComp0", (int)pp.AlphaComp0);
                shader.SetInt("alphaComp1", (int)pp.AlphaComp1);
                shader.SetFloat("alphaRef0", MaterialState.Ref0);
                shader.SetFloat("alphaRef1", MaterialState.Ref1);
            }

            var enableAll = mobj.RenderFlags.HasFlag(RENDER_MODE.DF_ALL);

            shader.SetBoolToInt("no_zupdate", mobj.RenderFlags.HasFlag(RENDER_MODE.NO_ZUPDATE));
            shader.SetBoolToInt("enableSpecular", parentJOBJ.Flags.HasFlag(JOBJ_FLAG.SPECULAR) && mobj.RenderFlags.HasFlag(RENDER_MODE.SPECULAR));
            shader.SetBoolToInt("enableDiffuse", parentJOBJ.Flags.HasFlag(JOBJ_FLAG.LIGHTING) && mobj.RenderFlags.HasFlag(RENDER_MODE.DIFFUSE));
            shader.SetBoolToInt("useConstant", mobj.RenderFlags.HasFlag(RENDER_MODE.CONSTANT));
            shader.SetBoolToInt("useVertexColor", mobj.RenderFlags.HasFlag(RENDER_MODE.VERTEX));
            shader.SetBoolToInt("useToonShading", mobj.RenderFlags.HasFlag(RENDER_MODE.TOON));

            // Textures
            for (int i = 0; i < MAX_TEX; i++)
            {
                shader.SetBoolToInt($"hasTEX[{i}]", mobj.RenderFlags.HasFlag(RENDER_MODE.TEX0 + (i << 4)) || enableAll);
            }

            shader.SetInt("BumpTexture", -1);

            //LoadTextureConstants(shader);

            // Bind Textures
            if (mobj.Textures != null)
            {
                var textures = mobj.Textures.List;
                for (int i = 0; i < textures.Count; i++)
                {
                    if (i > MAX_TEX)
                    {
                        break;
                    }

                    var tex        = textures[i];
                    var displayTex = tex;

                    if (tex.ImageData == null)
                    {
                        continue;
                    }

                    var blending = tex.Blending;

                    var transform = Matrix4.CreateScale(tex.SX, tex.SY, tex.SZ) *
                                    Matrix4.CreateFromQuaternion(Math3D.FromEulerAngles(tex.RZ, tex.RY, tex.RX)) *
                                    Matrix4.CreateTranslation(tex.TX, tex.TY, tex.TZ);

                    if (tex.SY != 0 && tex.SX != 0 && tex.SZ != 0)
                    {
                        transform.Invert();
                    }

                    if (animation != null)
                    {
                        var state = animation.GetTextureAnimState(tex);
                        if (state != null)
                        {
                            displayTex = state.TOBJ;
                            blending   = state.Blending;
                            transform  = state.Transform;
                        }
                    }

                    // make sure texture is loaded
                    PreLoadTexture(displayTex);

                    // grab texture id
                    var texid = TextureManager.Get(imageBufferTextureIndex[displayTex.ImageData.ImageData]);

                    // set texture
                    GL.ActiveTexture(TextureUnit.Texture0 + i);
                    GL.BindTexture(TextureTarget.Texture2D, texid);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)GXTranslator.toWrapMode(tex.WrapS));
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)GXTranslator.toWrapMode(tex.WrapT));
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)GXTranslator.toMagFilter(tex.MagFilter));

                    var wscale = tex.WScale;
                    var hscale = tex.HScale;

                    var mirrorX = tex.WrapS == GXWrapMode.MIRROR;
                    var mirrorY = tex.WrapT == GXWrapMode.MIRROR;

                    var flags = tex.Flags;

                    int coordType = (int)flags & 0xF;
                    int colorOP   = ((int)flags >> 16) & 0xF;
                    int alphaOP   = ((int)flags >> 20) & 0xF;

                    if (flags.HasFlag(TOBJ_FLAGS.BUMP))
                    {
                        colorOP = 4;
                    }

                    shader.SetInt($"sampler{i}", i);
                    shader.SetInt($"TEX[{i}].gensrc", (int)tex.GXTexGenSrc);
                    shader.SetBoolToInt($"TEX[{i}].is_ambient", flags.HasFlag(TOBJ_FLAGS.LIGHTMAP_AMBIENT));
                    shader.SetBoolToInt($"TEX[{i}].is_diffuse", flags.HasFlag(TOBJ_FLAGS.LIGHTMAP_DIFFUSE));
                    shader.SetBoolToInt($"TEX[{i}].is_specular", flags.HasFlag(TOBJ_FLAGS.LIGHTMAP_SPECULAR));
                    shader.SetBoolToInt($"TEX[{i}].is_ext", flags.HasFlag(TOBJ_FLAGS.LIGHTMAP_EXT));
                    shader.SetBoolToInt($"TEX[{i}].is_bump", flags.HasFlag(TOBJ_FLAGS.BUMP));
                    shader.SetInt($"TEX[{i}].color_operation", colorOP);
                    shader.SetInt($"TEX[{i}].alpha_operation", alphaOP);
                    shader.SetInt($"TEX[{i}].coord_type", coordType);
                    shader.SetFloat($"TEX[{i}].blend", blending);
                    shader.SetBoolToInt($"TEX[{i}].mirror_fix", mirrorY);
                    shader.SetVector2($"TEX[{i}].uv_scale", wscale, hscale);
                    shader.SetMatrix4x4($"TEX[{i}].transform", ref transform);

                    var  tev    = tex.TEV;
                    bool useTev = tev != null && tev.active.HasFlag(TOBJ_TEVREG_ACTIVE.COLOR_TEV);
                    shader.SetBoolToInt($"hasTev[{i}]", useTev);
                    if (useTev)
                    {
                        shader.SetInt($"Tev[{i}].color_op", (int)tev.color_op);
                        shader.SetInt($"Tev[{i}].color_bias", (int)tev.color_bias);
                        shader.SetInt($"Tev[{i}].color_scale", (int)tev.color_scale);
                        shader.SetBoolToInt($"Tev[{i}].color_clamp", tev.color_clamp);
                        shader.SetInt($"Tev[{i}].color_a", (int)tev.color_a_in);
                        shader.SetInt($"Tev[{i}].color_b", (int)tev.color_b_in);
                        shader.SetInt($"Tev[{i}].color_c", (int)tev.color_c_in);
                        shader.SetInt($"Tev[{i}].color_d", (int)tev.color_d_in);

                        shader.SetInt($"Tev[{i}].alpha_op", (int)tev.alpha_op);
                        shader.SetInt($"Tev[{i}].alpha_bias", (int)tev.alpha_bias);
                        shader.SetInt($"Tev[{i}].alpha_scale", (int)tev.alpha_scale);
                        shader.SetBoolToInt($"Tev[{i}].alpha_clamp", tev.alpha_clamp);
                        shader.SetInt($"Tev[{i}].alpha_a", (int)tev.alpha_a_in);
                        shader.SetInt($"Tev[{i}].alpha_b", (int)tev.alpha_b_in);
                        shader.SetInt($"Tev[{i}].alpha_c", (int)tev.alpha_c_in);
                        shader.SetInt($"Tev[{i}].alpha_d", (int)tev.alpha_d_in);

                        shader.SetColor($"Tev[{i}].konst", tev.constant, tev.constantAlpha);
                        shader.SetColor($"Tev[{i}].tev0", tev.tev0, tev.tev0Alpha);
                        shader.SetColor($"Tev[{i}].tev1", tev.tev1, tev.tev1Alpha);
                    }
                }
            }
        }
Ejemplo n.º 5
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.º 6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="pobj"></param>
        private Mesh ProcessPOBJ(HSD_POBJ pobj, HSD_JOBJ parent, HSD_JOBJ singleBind)
        {
            Mesh m = new Mesh();

            m.Name          = "pobj";
            m.PrimitiveType = PrimitiveType.Triangle;

            m.MaterialIndex = 0;

            var dl        = pobj.ToDisplayList();
            var envelopes = pobj.EnvelopeWeights;

            var parentTransform = Matrix4.Identity;

            if (parent != null)
            {
                parentTransform = WorldTransforms[jobjToIndex[parent]];
            }

            var singleBindTransform = Matrix4.Identity;

            if (singleBind != null)
            {
                singleBindTransform = WorldTransforms[jobjToIndex[singleBind]];
            }

            Dictionary <HSD_JOBJ, Bone> jobjToBone = new Dictionary <HSD_JOBJ, Bone>();

            if (envelopes != null)
            {
                foreach (var jobj in Jobjs)
                {
                    var bone = new Bone();
                    bone.Name         = JobjNodes[jobjToIndex[jobj]].Name;
                    bone.OffsetMatrix = Matrix4ToMatrix4x4(WorldTransforms[jobjToIndex[jobj]].Inverted());
                    m.Bones.Add(bone);
                    jobjToBone.Add(jobj, bone);
                }
            }

            /*foreach (var en in envelopes)
             * {
             *  foreach (var jobj in en.JOBJs)
             *  {
             *      if (!jobjToBone.ContainsKey(jobj))
             *      {
             *          var bone = new Bone();
             *          bone.Name = JobjNodes[jobjToIndex[jobj]].Name;
             *          bone.OffsetMatrix = Matrix4ToMatrix4x4(WorldTransforms[jobjToIndex[jobj]].Inverted());
             *          m.Bones.Add(bone);
             *          jobjToBone.Add(jobj, bone);
             *      }
             *  }
             * }*/


            if (singleBind != null && !jobjToBone.ContainsKey(singleBind))
            {
                var bone = new Bone();
                bone.Name         = JobjNodes[jobjToIndex[singleBind]].Name;
                bone.OffsetMatrix = Matrix4ToMatrix4x4(WorldTransforms[jobjToIndex[singleBind]].Inverted());
                m.Bones.Add(bone);
                jobjToBone.Add(singleBind, bone);
            }

            int offset = 0;
            var vIndex = -1;

            foreach (var prim in dl.Primitives)
            {
                var verts = dl.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;
                }

                for (int i = m.VertexCount; i < m.VertexCount + verts.Count; i += 3)
                {
                    var f = new Face();
                    f.Indices.Add(i);
                    f.Indices.Add(i + 1);
                    f.Indices.Add(i + 2);
                    m.Faces.Add(f);
                }

                foreach (var v in verts)
                {
                    vIndex++;
                    if (singleBind != null)
                    {
                        var vertexWeight = new VertexWeight();
                        vertexWeight.VertexID = vIndex;
                        vertexWeight.Weight   = 1;
                        jobjToBone[singleBind].VertexWeights.Add(vertexWeight);
                    }
                    Matrix4 weight = Matrix4.Identity;
                    foreach (var a in pobj.Attributes)
                    {
                        switch (a.AttributeName)
                        {
                        case GXAttribName.GX_VA_PNMTXIDX:

                            var en = envelopes[v.PNMTXIDX / 3];
                            for (int w = 0; w < en.EnvelopeCount; w++)
                            {
                                var vertexWeight = new VertexWeight();
                                vertexWeight.VertexID = vIndex;
                                vertexWeight.Weight   = en.Weights[w];
                                jobjToBone[en.JOBJs[w]].VertexWeights.Add(vertexWeight);
                            }

                            if (en.EnvelopeCount == 1 && jobjToIndex[parent] == 0)
                            {
                                weight = WorldTransforms[jobjToIndex[en.JOBJs[0]]];
                            }

                            break;

                        case GXAttribName.GX_VA_POS:
                            var vert = Vector3.TransformPosition(GXTranslator.toVector3(v.POS), parentTransform);
                            vert = Vector3.TransformPosition(vert, weight);
                            vert = Vector3.TransformPosition(vert, singleBindTransform);
                            m.Vertices.Add(new Vector3D(vert.X, vert.Y, vert.Z));
                            break;

                        case GXAttribName.GX_VA_NRM:
                            var nrm = Vector3.TransformNormal(GXTranslator.toVector3(v.NRM), parentTransform);
                            nrm = Vector3.TransformNormal(nrm, weight);
                            nrm = Vector3.TransformNormal(nrm, singleBindTransform);
                            m.Normals.Add(new Vector3D(nrm.X, nrm.Y, nrm.Z));
                            break;

                        case GXAttribName.GX_VA_CLR0:
                            m.VertexColorChannels[0].Add(new Color4D(v.CLR0.R, v.CLR0.G, v.CLR0.B, v.CLR0.A));
                            break;

                        case GXAttribName.GX_VA_CLR1:
                            m.VertexColorChannels[1].Add(new Color4D(v.CLR1.R, v.CLR1.G, v.CLR1.B, v.CLR1.A));
                            break;

                        case GXAttribName.GX_VA_TEX0:
                            m.TextureCoordinateChannels[0].Add(new Vector3D(v.TEX0.X, v.TEX0.Y, 1));
                            break;

                        case GXAttribName.GX_VA_TEX1:
                            m.TextureCoordinateChannels[1].Add(new Vector3D(v.TEX1.X, v.TEX1.Y, 1));
                            break;

                        case GXAttribName.GX_VA_TEX2:
                            m.TextureCoordinateChannels[2].Add(new Vector3D(v.TEX2.X, v.TEX2.Y, 1));
                            break;

                        case GXAttribName.GX_VA_TEX3:
                            m.TextureCoordinateChannels[3].Add(new Vector3D(v.TEX3.X, v.TEX3.Y, 1));
                            break;

                        case GXAttribName.GX_VA_TEX4:
                            m.TextureCoordinateChannels[4].Add(new Vector3D(v.TEX4.X, v.TEX4.Y, 1));
                            break;

                        case GXAttribName.GX_VA_TEX5:
                            m.TextureCoordinateChannels[5].Add(new Vector3D(v.TEX5.X, v.TEX5.Y, 1));
                            break;

                        case GXAttribName.GX_VA_TEX6:
                            m.TextureCoordinateChannels[6].Add(new Vector3D(v.TEX6.X, v.TEX6.Y, 1));
                            break;

                        case GXAttribName.GX_VA_TEX7:
                            m.TextureCoordinateChannels[7].Add(new Vector3D(v.TEX7.X, v.TEX7.Y, 1));
                            break;
                        }
                    }
                }
            }

            return(m);
        }