Example #1
0
        //---------------------------------------------------------------
        #region Variables and Properties
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Initialisation
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        #endregion
        //---------------------------------------------------------------

        //---------------------------------------------------------------
        #region Methods
        //---------------------------------------------------------------
        /// <summary>
        /// Fills a positionStream with skinned position data.
        /// </summary>
        /// <param name="target">The target position stream.</param>
        /// <param name="source">The source vector data.</param>
        /// <param name="bis">The stream containing the bone indices.</param>
        /// <param name="bws">The stream containing the bone weights.</param>
        /// <param name="joints">The bones to use for skinning.</param>
        /// <param name="skinShadow">Should the shadow part also be skinned?</param>
        public static void SoftSkin(PositionStream target, Vector3[] source,
                                    IBoneIndicesStream bis, IBoneWeightsStream bws, Matrix4[] joints, bool skinShadow)
        {
            // For every vertex, multiply the source vector with the influencing bones, weight and add the
            // result to the final result.
            Vector3[] targetData = (Vector3[])target.Data;
            Array.Clear(targetData, 0, targetData.Length);
            for (int i = 0; i < source.Length; i++)
            {
                //targetData[i].SetZero();

                byte[]  indices = bis.GetIndices(i);
                float[] weights = bws.GetWeights(i);
                int     length  = indices.Length;
                for (int iWeight = 0; iWeight < length; iWeight++)
                {
                    targetData[i].AddSkinned(source[i], ref joints[indices[iWeight]], weights[iWeight]);

                    /*Vector3 sourceVec = source[i];
                     * sourceVec.Mul( ref joints[ indices[iWeight] ] );
                     * targetData[i].AddWeighted( sourceVec, weights[iWeight] );*/
                }
            }
            if (skinShadow)
            {
                // is is ShadowVolumePrepared?
                if (target.Size != source.Length)
                {
                    System.Diagnostics.Debug.Assert(target.Size == source.Length * 2,
                                                    "Target positionStream must be the same size as source array - or twice the size of shadowVolumePrepared meshes!");
                    Array.Copy(target.Data, 0, target.Data, source.Length, source.Length);
                }
            }
        }
Example #2
0
 void SoftSkin(Matrix4[] preBound)
 {
     // Apply skinning on all subSets
     for (int iSubSet = 0; iSubSet < data.Length; iSubSet++)
     {
         SubSetData ssData = data[iSubSet];
         if (ssData != null)
         {
             VertexUnit         vu  = mesh.SubSets[iSubSet].VertexUnit;
             PositionStream     ps  = (PositionStream)vu[typeof(PositionStream)];
             IBoneIndicesStream bis = (IBoneIndicesStream)vu[typeof(IBoneIndicesStream)];
             IBoneWeightsStream bws = (IBoneWeightsStream)vu[typeof(IBoneWeightsStream)];
             // currently just the position stream is skinned!
             Skinning.SoftSkin(ps, ssData.Position, bis, bws, preBound, Shadowed);
             ps.Upload();
         }
     }
 }
Example #3
0
        /// <summary>
        /// Import a mesh from a stream.
        /// </summary>
        /// <param name="stream">Stream containing mesh data.</param>
        public void Import(Stream stream)
        {
            Profiler.Instance.Begin("Import binary mesh");
            // Header
            BinaryReader reader = new BinaryReader(stream);

            if (ReadString(reader) != "mesh" || ReadString(reader) != "v0.3")
            {
                throw new NotSupportedException("Can't load mesh, file not supported!");
            }

            // Joints
            int jointNum = ReadInt(reader);

            Joint[]   joints     = new Joint[jointNum];
            Matrix4[] jointArray = new Matrix4[jointNum];
            Hashtable jointTable = new Hashtable(joints.Length);

            for (int i = 0; i < joints.Length; i++)
            {
                string name   = ReadString(reader);
                string parent = ReadString(reader);

                reader.Read(matrixBytes, 0, matrixBytes.Length);
                Matrix4 m = Matrix4.From(matrixBytes);

                Joint parentJoint = null;
                if (parent != null && jointTable.Contains(parent))
                {
                    parentJoint = (Joint)jointTable[parent];
                }
                joints[i]        = new Joint(name, i, parentJoint);
                jointArray[i]    = m;
                jointTable[name] = joints[i];
            }
            skeleton = new Skeleton(jointArray, joints);

            // SubSet
            int subSetNum = ReadInt(reader);

            for (int i = 0; i < subSetNum; i++)
            {
                ArrayList streams = new ArrayList(10);
                // Header
                if (ReadString(reader) != "subset")
                {
                    throw new NotSupportedException("Error on loading subSet!");
                }
                string name        = ReadString(reader);
                string parentJoint = ReadString(reader);

                int attributeCount          = ReadInt(reader);
                StringDictionary attributes = new StringDictionary();
                for (int t = 0; t < attributeCount; t++)
                {
                    attributes.Add(ReadString(reader), ReadString(reader));
                }

                // IndexStream
                // Todo Replace ushort.MaxValue with size of vertex unit
                IndexStream indexStream = IndexStream.Create(ReadInt(reader), ushort.MaxValue);
                byte[]      indexBuffer = new byte[indexStream.Size * 4];
                reader.Read(indexBuffer, 0, indexStream.Size * 4);
                for (int t = 0; t < indexStream.Size; t++)
                {
                    indexStream[t] = BitConverter.ToInt32(indexBuffer, t * 4);
                }

                int            vertexSize = ReadInt(reader);
                PositionStream posStream  = new PositionStream(vertexSize);
                streams.Add(posStream);
                byte[] vertexBuffer = new byte[vertexSize * 12];
                reader.Read(vertexBuffer, 0, vertexSize * 12);
                for (int t = 0; t < vertexSize; t++)
                {
                    posStream[t] = Vector3.From(vertexBuffer, 12 * t);
                }

                NormalStream normalStream = new NormalStream(vertexSize);
                streams.Add(normalStream);
                reader.Read(vertexBuffer, 0, vertexSize * 12);
                for (int t = 0; t < vertexSize; t++)
                {
                    normalStream[t] = Vector3.From(vertexBuffer, t * 12);
                }

                ColorStream colorStream = new ColorStream(vertexSize);
                streams.Add(colorStream);
                reader.Read(vertexBuffer, 0, vertexSize * 12);
                for (int t = 0; t < vertexSize; t++)
                {
                    int r = Math.Basic.Clamp((int)(System.BitConverter.ToSingle(vertexBuffer, t * 12) * 255 + 0.5f), 0, 255);
                    int g = Math.Basic.Clamp((int)(System.BitConverter.ToSingle(vertexBuffer, 4 + t * 12) * 255 + 0.5f), 0, 255);
                    int b = Math.Basic.Clamp((int)(System.BitConverter.ToSingle(vertexBuffer, 8 + t * 12) * 255 + 0.5f), 0, 255);
                    colorStream[t] = System.Drawing.Color.FromArgb(r, g, b).ToArgb();
                }

                TextureStream[] textureStreams = new TextureStream[ReadInt(reader)];
                for (int t = 0; t < textureStreams.Length; t++)
                {
                    TextureStream texStream = new TextureStream(vertexSize);
                    streams.Add(texStream);
                    reader.Read(vertexBuffer, 0, vertexSize * 8);
                    for (int j = 0; j < vertexSize; j++)
                    {
                        texStream[j] = Vector2.From(vertexBuffer, j * 8);
                    }
                    textureStreams[t] = texStream;
                }

                IBoneIndicesStream boneStream    = null;
                IBoneWeightsStream weightsStream = null;
                int weightNum = ReadInt(reader);
                if (weightNum != 0)
                {
                    if (HardwareSkinning)
                    {
                        boneStream    = new BoneIndicesStream(vertexSize);
                        weightsStream = new BoneWeightsStream(vertexSize);
                    }
                    else
                    {
                        boneStream    = new SoftwareBoneIndicesStream(vertexSize);
                        weightsStream = new SoftwareBoneWeightsStream(vertexSize);
                    }
                    streams.Add(boneStream);
                    streams.Add(weightsStream);
                    ArrayList[] indicesList = new ArrayList[vertexSize];
                    ArrayList[] weightsList = new ArrayList[vertexSize];
                    for (int t = 0; t < vertexSize; t++)
                    {
                        indicesList[t] = new ArrayList(8);
                        weightsList[t] = new ArrayList(8);
                    }


                    byte[] weightBuffer = new byte[weightNum * 12];
                    reader.Read(weightBuffer, 0, weightNum * 12);
                    for (int t = 0; t < weightNum; t++)
                    {
                        int   vertexIndex = BitConverter.ToInt32(weightBuffer, t * 12);
                        int   jointIndex  = BitConverter.ToInt32(weightBuffer, 4 + t * 12);
                        float weight      = BitConverter.ToSingle(weightBuffer, 8 + t * 12);
                        indicesList[vertexIndex].Add((byte)jointIndex);
                        weightsList[vertexIndex].Add(weight);
                    }

                    for (int t = 0; t < vertexSize; t++)
                    {
                        boneStream.SetIndices(t, (byte[])indicesList[t].ToArray(typeof(byte)));
                        weightsStream.SetWeights(t, (float[])weightsList[t].ToArray(typeof(float)));
                    }
                }

                VertexUnit vertexUnit = new VertexUnit(streams);
                Mesh       mesh       = new Mesh(new SubSet(vertexUnit, indexStream));
                if (model == null)
                {
                    if (skeleton.Joints.Length != 0)
                    {
                        model = new Model(new SkinnedMesh(mesh, skeleton), skeleton);
                    }
                    else
                    {
                        model = new Model(mesh, skeleton);
                    }
                }
                else
                {
                    Joint attachTo = skeleton.RootJoint;
                    if (parentJoint != "")
                    {
                        attachTo = (jointTable[parentJoint] as Joint);
                    }
                    model.AttachModel(new Model(mesh, skeleton), attachTo);
                }
            }
            reader.Close();

            Profiler.Instance.End("Import binary mesh");
        }
Example #4
0
        /// <summary>
        /// import a mesh from a stream
        /// </summary>
        /// <param name="stream">stream containing mesh data</param>
        public void Import(Stream stream)
        {
            model    = null;
            skeleton = null;
            IndexStream      indexStream   = null;
            IVertexStream    currentStream = null;
            ArrayList        streams       = new ArrayList();
            StringDictionary attributes    = new StringDictionary();
            XmlTextReader    reader        = new XmlTextReader(stream);

            Matrix4[] jointArray   = null;
            Joint[]   joints       = null;
            Hashtable jointTable   = null;
            int       index        = 0;
            int       currentJoint = 0;
            int       vertexCount  = 0;
            int       binding      = -1;

            ArrayList[] indicesList = null;
            ArrayList[] weightsList = null;

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                    // <mesh>
                    case "mesh":
                        if (model != null)
                        {
                            throw new GraphicsException("Only one mesh allowed in mesh stream!");
                        }
                        model = new Model();
                        break;

                    // <subset>
                    case "subset":
                        string parentJoint = reader.GetAttribute("parentJoint");
                        if (parentJoint != null && parentJoint != "")
                        {
                            binding = (jointTable[parentJoint] as Joint).Index;
                        }
                        else
                        {
                            binding = -1;
                        }
                        break;

                    // <attributes>
                    case "attributes":
                        break;

                    case "attribute":
                        // todo !!!
                        attributes.Add(reader.GetAttribute("name"), reader.GetAttribute("value"));
                        break;

                    //<indexStream>
                    case "indexStream": {
                        index = 0;
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        indexStream = new IndexStream16(size);
                    }
                    break;

                    //<triangle>
                    case "triangle": {
                        int a = int.Parse(reader.GetAttribute("a"), culture);
                        int b = int.Parse(reader.GetAttribute("b"), culture);
                        int c = int.Parse(reader.GetAttribute("c"), culture);
                        indexStream[index++] = a;
                        indexStream[index++] = b;
                        indexStream[index++] = c;
                    }
                    break;

                    //<positionStream>
                    case "positionStream": {
                        index         = 0;
                        vertexCount   = int.Parse(reader.GetAttribute("size"), culture);
                        currentStream = new PositionStream(vertexCount);
                        streams.Add(currentStream);
                    }
                    break;

                    //<vector3>
                    case "vector3": {
                        float x = float.Parse(reader.GetAttribute("x"), culture);
                        float y = float.Parse(reader.GetAttribute("y"), culture);
                        float z = float.Parse(reader.GetAttribute("z"), culture);
                        (currentStream as PositionStream)[index++] = new Vector3(x, y, z);
                    }
                    break;

                    //<normalStream>
                    case "normalStream": {
                        index = 0;
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        currentStream = new NormalStream(size);
                        streams.Add(currentStream);
                    }
                    break;

                    //<colorStream>
                    case "colorStream": {
                        index = 0;
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        currentStream = new ColorStream(size);
                        streams.Add(currentStream);
                    }
                    break;

                    //<color>
                    case "color": {
                        int r = (int)((float.Parse(reader.GetAttribute("r"), culture)) * 255.0f + 0.5f);
                        int g = (int)((float.Parse(reader.GetAttribute("g"), culture)) * 255.0f + 0.5f);
                        int b = (int)((float.Parse(reader.GetAttribute("b"), culture)) * 255.0f + 0.5f);
                        (currentStream as ColorStream)[index++] = System.Drawing.Color.FromArgb(r, g, b).ToArgb();
                    }
                    break;

                    //<textureStream>
                    case "textureStream": {
                        index = 0;
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        currentStream = new TextureStream(size);
                        streams.Add(currentStream);
                    }
                    break;

                    //<vector2>
                    case "vector2": {
                        float x = float.Parse(reader.GetAttribute("x"), culture);
                        float y = float.Parse(reader.GetAttribute("y"), culture);
                        (currentStream as TextureStream)[index++] = new Vector2(x, y);
                    }
                    break;

                    case "joints": {
                        int size = int.Parse(reader.GetAttribute("size"), culture);
                        jointArray   = new Matrix4[size];
                        joints       = new Joint[size];
                        jointTable   = new Hashtable();
                        currentJoint = 0;
                    }
                    break;

                    case "joint": {
                        string  jointName  = reader.GetAttribute("name");
                        string  parentName = reader.GetAttribute("parent");
                        Matrix4 m          = new Matrix4(float.Parse(reader.GetAttribute("a1"), culture),
                                                         float.Parse(reader.GetAttribute("a2"), culture),
                                                         float.Parse(reader.GetAttribute("a3"), culture),
                                                         float.Parse(reader.GetAttribute("a4"), culture),
                                                         float.Parse(reader.GetAttribute("b1"), culture),
                                                         float.Parse(reader.GetAttribute("b2"), culture),
                                                         float.Parse(reader.GetAttribute("b3"), culture),
                                                         float.Parse(reader.GetAttribute("b4"), culture),
                                                         float.Parse(reader.GetAttribute("c1"), culture),
                                                         float.Parse(reader.GetAttribute("c2"), culture),
                                                         float.Parse(reader.GetAttribute("c3"), culture),
                                                         float.Parse(reader.GetAttribute("c4"), culture),
                                                         float.Parse(reader.GetAttribute("d1"), culture),
                                                         float.Parse(reader.GetAttribute("d2"), culture),
                                                         float.Parse(reader.GetAttribute("d3"), culture),
                                                         float.Parse(reader.GetAttribute("d4"), culture));
                        jointArray[currentJoint] = m; //new Joint(jointName, m);
                        Joint parent = null;
                        if (parentName != null && jointTable.Contains(parentName))
                        {
                            parent = (Joint)jointTable[parentName];
                        }
                        joints[currentJoint]  = new Joint(jointName, currentJoint, parent);
                        jointTable[jointName] = joints[currentJoint];
                        currentJoint++;
                    }
                    break;

                    case "weights": {
                        index = 0;
                        //vertexCount = int.Parse(reader.GetAttribute("size"), culture);
                        indicesList = new ArrayList[vertexCount];
                        weightsList = new ArrayList[vertexCount];
                        for (int i = 0; i < vertexCount; i++)
                        {
                            indicesList[i] = new ArrayList(8);
                            weightsList[i] = new ArrayList(8);
                        }
                    }
                    break;

                    case "weight": {
                        int   vertexIndex = int.Parse(reader.GetAttribute("vertexIndex"));
                        byte  jointIndex  = byte.Parse(reader.GetAttribute("jointIndex"));
                        float value       = float.Parse(reader.GetAttribute("weight"), culture);
                        indicesList[vertexIndex].Add(jointIndex);
                        weightsList[vertexIndex].Add(value);
                    }
                    break;
                    }
                }

                if (reader.NodeType == XmlNodeType.EndElement)
                {
                    if (reader.Name.Equals("weights"))
                    {
                        IBoneIndicesStream bis = null;
                        IBoneWeightsStream bws = null;
                        if (HardwareSkinning)
                        {
                            bis = new BoneIndicesStream(vertexCount);
                            bws = new BoneWeightsStream(vertexCount);
                        }
                        else
                        {
                            bis = new SoftwareBoneIndicesStream(vertexCount);
                            bws = new SoftwareBoneWeightsStream(vertexCount);
                        }
                        for (int i = 0; i < vertexCount; i++)
                        {
                            bis.SetIndices(i, (byte[])indicesList[i].ToArray(typeof(byte)));
                            bws.SetWeights(i, (float[])weightsList[i].ToArray(typeof(float)));
                        }
                        streams.Add(bis);
                        streams.Add(bws);
                    }
                    else if (reader.Name.Equals("subset"))
                    {
                        VertexUnit vertexUnit = new VertexUnit(streams);
                        if (binding == -1)
                        {
                            model.Mesh = new Mesh(new SubSet(vertexUnit, indexStream));
                        }
                        else
                        {
                            model.AttachModel(new Model(new Mesh(new SubSet(vertexUnit, indexStream)), null), binding);
                        }
                        streams.Clear();
                    }
                }
            }
            ;

            reader.Close();
            if (jointArray != null && joints != null)
            {
                skeleton = new Skeleton(jointArray, joints);
            }
            model.Skeleton = skeleton;
        }