Esempio n. 1
0
 public int[] GetBones(MeshPart layer)
 {
     if (layerBonesLookup != null)
     {
         return(layerBonesLookup[layer.LayerId]);
     }
     return(null);
 }
Esempio n. 2
0
            unsafe private bool AddTriangleBones(MeshPart layer, int iTriangle)
            {
                int *indices = stackalloc int[3];

                indices[0] = GetVertexIndex(layer.startIndex + 3 * iTriangle);
                indices[1] = GetVertexIndex(layer.startIndex + 3 * iTriangle + 1);
                indices[2] = GetVertexIndex(layer.startIndex + 3 * iTriangle + 2); //sixteenBits ? (int)((ushort*)pIbData)[layer.startIndex + 3 * iTriangle + 2] : ((int*)pIbData)[layer.startIndex + 3 * iTriangle + 2];

                if (AddTriangleBones(indices))
                {
                    foreach (var boneIdx in _tempBonesSet)
                    {
                        //add the bone to the layer
                        _boneLookup[boneIdx] = _layerBonesCount++;
                    }

                    //assign new bones indices tp trianglesVertices
                    for (int k = 0; k < 3; k++)
                    {
                        if (!_vertices[indices[k]])
                        {
                            //mark the vertex as processed
                            _vertices[indices[k]] = true;

                            float *pvBones   = GetVertexBones(indices[k]);
                            float *pvWeights = GetVertexWeights(indices[k]);

                            for (int j = 0; j < 4; j++)
                            {
                                if (pvWeights[j] > 0)
                                {
                                    pvBones[j] = _boneLookup[(int)pvBones[j]];
                                }
                            }
                        }
                    }

                    return(true);
                }

                return(false);
            }
Esempio n. 3
0
            void CloseLayer(MeshPart layer)
            {
                layer.IndexCount = layer.PrimitiveCount * 3;

                int vertexCount = 0;
                int startVertex = int.MaxValue;

                for (int i = 0; i < _vertices.Length; i++)
                {
                    if (_vertices[i])
                    {
                        vertexCount++;
                        startVertex = Math.Min(startVertex, i);
                    }
                    //reset processed vertex
                    _vertices[i] = false;
                }

                layer.vertexCount = vertexCount;
                layer.startVertex = startVertex;
                int[] invbones = new int[_layerBonesCount];
                for (int i = 0; i < _boneLookup.Length; i++)
                {
                    if (_boneLookup[i] >= 0)
                    {
                        invbones[_boneLookup[i]] = i;
                    }

                    //reset bones
                    _boneLookup[i] = -1;
                }

                _layerBones.Add(invbones);
                _newLayers.Add(layer);
                _layerBonesCount = 0;
            }
Esempio n. 4
0
            public void ReSkin(MeshSkin skin, int maxPalleteEntries)
            {
                this._maxPalleteEntries = maxPalleteEntries;
                this._mesh       = skin.Mesh;
                _sixteenBits     = _mesh.Is16BitIndices;
                _primitiveStride = 3 * (_sixteenBits ? 2 : 4);
                _vertexStride    = _mesh.VertexDescriptor.Size;
                _indicesOffset   = _mesh.VertexDescriptor.OffsetOf(IASemantic.BlendIndices, 0);
                _weightsOffset   = _mesh.VertexDescriptor.OffsetOf(IASemantic.BlendWeight, 0);
                _tempBonesSet    = new HashSet <int>();

                _ibDataStream = _mesh.IndexBuffer.Map();
                _vbNewData    = _mesh.VertexBuffer.ToArray <byte>();
                //vbDataStream.Read(vbNewData, 0, mesh.VertexBuffer.SizeInBytes);

                //holds an array of bones indices into the skin bones array, an array of bones for each layer
                _layerBones = new List <int[]>();

                //table containing a mapping betwing a skin bone index and a layer bone index
                _boneLookup = new int[skin._bones.Length];

                //a set of vertices indices into the vertex buffer
                _vertices = new bool[_mesh.VertexCount];

                //list of new layers
                _newLayers = new List <MeshPart>(_mesh.Layers.Length);

                //reset the bones mapping
                for (int i = 0; i < _boneLookup.Length; i++)
                {
                    _boneLookup[i] = -1;
                }

                //reset the vertex set
                Array.Clear(_vertices, 0, _vertices.Length);

                //current processing layer
                MeshPart newLayer = null;

                GCHandle pinH = GCHandle.Alloc(_vbNewData, GCHandleType.Pinned);

                _pVbDAta = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(_vbNewData, 0);

                //get  a  pointer to the indexbuffer stream
                _pIbData = (byte *)_ibDataStream.ToPointer();
                for (int matIdx = 0; matIdx < _mesh.MaterialSlots; matIdx++)
                {
                    //for each material get the corresponding layers
                    var layers = _mesh.GetLayersByMaterial(matIdx);

                    //create the first layer for matIdx
                    newLayer = new MeshPart();
                    newLayer.materialIndex = matIdx;
                    newLayer.startIndex    = layers[0].startIndex;

                    int primitiveCount = 0;

                    foreach (var layer in layers)
                    {
                        //loop through add to the layer as much bones as maxPalleteEntries
                        //newLayer.startIndex = Math.Min(newLayer.startIndex, layer.startIndex);
                        for (int itriangle = 0; itriangle < layer.primitiveCount; itriangle++)
                        {
                            primitiveCount++;
                            //check if the triangle can be added to the newLayer
                            if (!AddTriangleBones(layer, itriangle))
                            {
                                //the layer is full, close it and open a new layer
                                newLayer.primitiveCount = primitiveCount - 1;
                                CloseLayer(newLayer);

                                //start a new Layer
                                newLayer = new MeshPart();
                                newLayer.materialIndex = matIdx;
                                newLayer.startIndex    = layer.startIndex + 3 * itriangle;

                                //add the triangle to the newlayer
                                AddTriangleBones(layer, itriangle);
                                primitiveCount = 1;
                            }
                        }
                    }

                    newLayer.primitiveCount = primitiveCount;
                    CloseLayer(newLayer);
                }

                _mesh.Layers = _newLayers.ToArray();
                for (int i = 0; i < _layerBones.Count; i++)
                {
                    skin.SetBones(i, _layerBones[i]);
                }

                //for (int i = 0; i < mesh.VertexCount; i++)
                //{
                //    byte* bones = GetVertexBones(i);
                //    float* weights = GetVertexWeights(i);
                //    for (int j = 0; j < 4; j++)
                //    {
                //        if (bones[j] == 0xFF)
                //        {
                //            bones[j] = 0;
                //            weights[j] = 0;
                //        }
                //    }
                //}

                pinH.Free();

                _mesh.VertexBuffer.Unmap();
                _mesh.IndexBuffer.Unmap();

                _mesh.VertexBuffer.Write(_vbNewData);
            }
Esempio n. 5
0
        public void BlendLayers()
        {
            unsafe
            {
                Dictionary <int, List <MeshPart> > materialList = new Dictionary <int, List <MeshPart> >(MaterialLayersLookup.Length);
                for (int i = 0; i < MaterialLayersLookup.Length; i++)
                {
                    materialList.Add(i, new List <MeshPart>(MaterialLayersLookup[i]));
                }

                List <MeshPart> newLayers = new List <MeshPart>();

                var ds = _ib.Map(MapType.Read);

                byte * pIndices   = (byte *)ds;
                byte[] newIndices = new byte[_ib.SizeInBytes];

                fixed(byte *pNewIndices = newIndices)
                {
                    int iIndex = 0;
                    Dictionary <uint, bool> vertexLookup = new Dictionary <uint, bool>();

                    foreach (var v in materialList)
                    {
                        vertexLookup.Clear();

                        MeshPart newLayer = new MeshPart();
                        if (newLayer == null)
                        {
                            _ib.Unmap();
                            return;
                        }
                        newLayers.Add(newLayer);
                        newLayer.materialIndex = v.Key;
                        newLayer.startIndex    = iIndex;
                        newLayer.startVertex   = int.MaxValue;

                        foreach (var layer in v.Value)
                        {
                            newLayer.primitiveCount += layer.primitiveCount;
                            newLayer.startVertex     = Math.Min(newLayer.startVertex, layer.startVertex);

                            int indicesCount = layer.primitiveCount * 3;
                            for (int i = layer.startIndex; i < layer.startIndex + indicesCount; i++)
                            {
                                uint vertexIndex;
                                if (_is16BitIndices)
                                {
                                    vertexIndex = ((ushort *)pIndices)[i];
                                    ((ushort *)pNewIndices)[iIndex] = ((ushort *)pIndices)[i];
                                }
                                else
                                {
                                    vertexIndex = ((uint *)pIndices)[i];
                                    ((uint *)pNewIndices)[iIndex] = ((uint *)pIndices)[i];
                                }
                                iIndex++;
                                vertexLookup[vertexIndex] = true;
                            }
                        }
                        newLayer.vertexCount = vertexLookup.Keys.Count;
                        newLayer.indexCount  = newLayer.primitiveCount * 3;
                        materialList[v.Key].Clear();
                        materialList[v.Key].Add(newLayer);
                    }

                    Layers = newLayers.ToArray();

                    _ib.Unmap();
                    _ib.Write(pNewIndices, 0, newIndices.Length);
                }
            }
        }