Esempio n. 1
0
        private void DrawModelRecursive(ref Matrix4[] jointMatrix, SceneGraph curNode, BaseRenderer renderer, bool bSelectedPass)
        {
            switch (curNode.NodeType)
            {
            case J3DFormat.HierarchyDataTypes.Material:
                if (!bSelectedPass)
                {
                    GL.BindTexture(TextureTarget.Texture2D, GetGLTexIdFromCache(curNode.DataIndex));
                }
                break;

            case J3DFormat.HierarchyDataTypes.Batch:
                /* For each batch, we're going to enable the
                 * appropriate Vertex Attributes for that batch
                 * and set default values for vertex attribs that
                 * the batch doesn't use, then draw all primitives
                 * within it.*/

                if (bSelectedPass)
                {
                    #region Selected
                    float[] front_face_wireframe_color = { 1.0f, 1.0f, 1.0f, 1.0f };
                    float[] back_face_wireframe_color  = { 0.7f, 0.7f, 0.7f, 0.7f };

                    GL.LineWidth(1);
                    GL.Enable(EnableCap.CullFace);
                    //GL.Disable(EnableCap.DepthTest);
                    GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
                    GL.EnableVertexAttribArray((int)BaseRenderer.ShaderAttributeIds.Position);

                    // 1. Draw the back-faces with a darker color:
                    GL.CullFace(CullFaceMode.Back);
                    GL.VertexAttrib4((int)BaseRenderer.ShaderAttributeIds.Color, back_face_wireframe_color);
                    foreach (var packet in _renderList[curNode.DataIndex].Packets)
                    {
                        int vertexIndex = 0;
                        foreach (var primitive in packet.PrimList)
                        {
                            //Uhh...
                            ushort drawIndex  = packet.DrawIndexes[primitive.PosMatrixIndex[vertexIndex] / 3];
                            bool   isWeighted = _file.Draw.IsWeighted(drawIndex);

                            if (isWeighted)
                            {
                            }
                            else
                            {
                                var     jnt       = _file.Joints.GetJoint(curNode.DataIndex);
                                Vector3 jntRot    = jnt.GetRotation().ToDegrees();
                                Vector3 trans     = jnt.GetTranslation();
                                Matrix4 trnMatrix = Matrix4.CreateTranslation(trans);
                                Matrix4 rtMatrix  = Matrix4.CreateRotationX(jntRot.X) * Matrix4.CreateRotationY(jntRot.Y) *
                                                    Matrix4.CreateRotationZ(jntRot.Z);
                                Matrix4 sclMatrix = Matrix4.CreateScale(jnt.GetScale());

                                Matrix4 final = trnMatrix * rtMatrix * sclMatrix;

                                //renderer.SetModelMatrix(Matrix4.Identity);
                                renderer.SetModelMatrix(final);
                            }

                            GL.DrawArrays(primitive.DrawType, primitive.VertexStart, primitive.VertexCount);

                            vertexIndex++;
                        }
                    }


                    // 2. Draw the front-faces with a lighter color:
                    GL.CullFace(CullFaceMode.Front);
                    GL.VertexAttrib4((int)BaseRenderer.ShaderAttributeIds.Color, front_face_wireframe_color);

                    /*foreach (var primitive in _renderList[curNode.DataIndex])
                     * {
                     *  GL.DrawArrays(primitive.DrawType, primitive.VertexStart, primitive.VertexCount);
                     * }*/

                    GL.DisableVertexAttribArray((int)BaseRenderer.ShaderAttributeIds.Position);
                    GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                    //GL.Enable(EnableCap.DepthTest);
                    GL.LineWidth(1);
                    #endregion
                }
                else
                {
                    SetVertexAttribArraysForBatch(true, curNode.DataIndex);
                    //GL.CullFace(CullFaceMode.Front);
                    for (int packetIndex = 0; packetIndex < _renderList[curNode.DataIndex].Packets.Count; packetIndex++)
                    {
                        RenderPacket packet = _renderList[curNode.DataIndex].Packets[packetIndex];
                        foreach (var primitive in packet.PrimList)
                        {
                            renderer.SetModelMatrix(Matrix4.Identity);

                            if (primitive.PosMatrixIndex.Count > 0)
                            {
                                var transformedData = new J3DRenderer.VertexFormatLayout[primitive.VertexCount];

                                //For each vertex within this primitive, we're going to get its id.
                                for (int vertexIndex = 0; vertexIndex < primitive.VertexCount; vertexIndex++)
                                {
                                    ushort vertIndex = primitive.PosMatrixIndex[vertexIndex];
                                    ushort drawIndex = packet.DrawIndexes[vertIndex / 3];

                                    //ehh
                                    int seriously = 0;
                                    while (drawIndex == 0xFFFF)
                                    {
                                        RenderPacket prevPacket =
                                            _renderList[curNode.DataIndex].Packets[packetIndex - seriously];
                                        drawIndex = prevPacket.DrawIndexes[vertIndex / 3];
                                        seriously++;
                                    }

                                    bool isWeighted = _file.Draw.IsWeighted(drawIndex);
                                    if (isWeighted)
                                    {
                                        ushort numBonesAffecting =
                                            _file.Envelopes.GetCount(_file.Draw.GetIndex(drawIndex));

                                        //Much WTFs
                                        ushort offset = 0;
                                        for (ushort i = 0; i < _file.Draw.GetIndex(drawIndex); i++)
                                        {
                                            offset += _file.Envelopes.GetCount(i);
                                        }

                                        offset *= 2;
                                        Matrix4 finalTransform = Matrix4.Identity;
                                        for (ushort i = 0; i < numBonesAffecting; i++)
                                        {
                                            ushort boneIndex =
                                                _file.Envelopes.GetIndexOffset((ushort)(offset + (i * 0x2)));
                                            float boneWeight = _file.Envelopes.GetWeight((ushort)((offset / 2) + i));

                                            Matrix3x4 envMatrix      = _file.Envelopes.GetMatrix(boneIndex);
                                            Matrix4   newEnvelopeMtx = new Matrix4(envMatrix.Row0, envMatrix.Row1,
                                                                                   envMatrix.Row2, new Vector4(0, 0, 0, 1));

                                            SkeletonJoint joint = _skeleCopy[boneIndex];
                                            //Matrix4 transMatrix = Matrix4.CreateTranslation(joint.Position);
                                            //We need to use the bone's matrix from EVP1 to get the joint matrix
                                            Matrix4 jointMtx = joint.Rotation * newEnvelopeMtx;

                                            //finalTransform = Matrix4.Mult(jointMtx * newEnvelopeMtx, boneWeight) * finalTransform;
                                            //ToDo: This is the wrong scale.
                                            //AddScaleMatrix(ref finalTransform, Matrix4.Mult(jointMtx, newEnvelopeMtx), 1f);
                                        }

                                        transformedData[vertexIndex] = _vertDataBind[primitive.VertexStart + vertexIndex];

                                        Vector3 vertPosition = transformedData[vertexIndex].Position;
                                        transformedData[vertexIndex].Position = Vector3.TransformPosition(vertPosition, finalTransform);
                                    }
                                    else
                                    {
                                        //If the vertex is not weighted, we're just going to use the position
                                        //from the bone matrix. Something like this.
                                        Vector3 vertPosition =
                                            _vertDataBind[primitive.VertexStart + vertexIndex].Position;

                                        transformedData[vertexIndex] = _vertDataBind[primitive.VertexStart + vertexIndex];

                                        SkeletonJoint joint       = _skeleCopy[_file.Draw.GetIndex(drawIndex)];
                                        Matrix4       transMatrix = Matrix4.CreateTranslation(joint.Position);
                                        Matrix4       final       = joint.Rotation * transMatrix;
                                        transformedData[vertexIndex].Position = Vector3.TransformPosition(vertPosition, final);
                                    }
                                }

                                //Re-upload the subsection to the buffer.
                                GL.BindBuffer(BufferTarget.ArrayBuffer, _glVbo);
                                GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)(primitive.VertexStart * (9 * 4)),
                                                 (IntPtr)(primitive.VertexCount * (9 * 4)), transformedData);

                                float[] front_face_wireframe_color = { 1.0f, 1.0f, 1.0f, 1.0f };
                                GL.VertexAttrib4((int)BaseRenderer.ShaderAttributeIds.Color, front_face_wireframe_color);
                            }


                            GL.DrawArrays(primitive.DrawType, primitive.VertexStart, primitive.VertexCount);
                        }
                    }

                    SetVertexAttribArraysForBatch(false, curNode.DataIndex);
                }

                break;
            }

            foreach (SceneGraph subNode in curNode.Children)
            {
                DrawModelRecursive(ref jointMatrix, subNode, renderer, bSelectedPass);
            }
        }