コード例 #1
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new AssetManager();

                AssetParameters.ColliderShapes = AssetParameters.ColliderShapes.Where(x => x != null &&
                                                                                      (x.GetType() != typeof(ConvexHullColliderShapeDesc) || ((ConvexHullColliderShapeDesc)x).Model != null)).ToList();

                //pre process special types
                foreach (var convexHullDesc in
                         (from shape in AssetParameters.ColliderShapes let type = shape.GetType() where type == typeof(ConvexHullColliderShapeDesc) select shape)
                         .Cast <ConvexHullColliderShapeDesc>())
                {
                    //decompose and fill vertex data

                    var loadSettings = new AssetManagerLoaderSettings
                    {
                        ContentFilter = AssetManagerLoaderSettings.NewContentFilterByType(typeof(Mesh))
                    };

                    var modelAsset = assetManager.Load <Model>(AttachedReferenceManager.GetUrl(convexHullDesc.Model), loadSettings);
                    if (modelAsset == null)
                    {
                        continue;
                    }

                    convexHullDesc.ConvexHulls        = new List <List <List <Vector3> > >();
                    convexHullDesc.ConvexHullsIndices = new List <List <List <uint> > >();

                    commandContext.Logger.Info("Processing convex hull generation, this might take a while!");

                    var nodeTransforms = new List <Matrix>();

                    //pre-compute all node transforms, assuming nodes are ordered... see ModelViewHierarchyUpdater
                    var nodesLength = modelAsset.Hierarchy.Nodes.Length;
                    for (var i = 0; i < nodesLength; i++)
                    {
                        Matrix localMatrix;
                        TransformComponent.CreateMatrixTRS(
                            ref modelAsset.Hierarchy.Nodes[i].Transform.Translation,
                            ref modelAsset.Hierarchy.Nodes[i].Transform.Rotation,
                            ref modelAsset.Hierarchy.Nodes[i].Transform.Scaling, out localMatrix);

                        Matrix worldMatrix;
                        if (modelAsset.Hierarchy.Nodes[i].ParentIndex != -1)
                        {
                            var nodeTransform = nodeTransforms[modelAsset.Hierarchy.Nodes[i].ParentIndex];
                            Matrix.Multiply(ref localMatrix, ref nodeTransform, out worldMatrix);
                        }
                        else
                        {
                            worldMatrix = localMatrix;
                        }

                        nodeTransforms.Add(worldMatrix);
                    }

                    for (var i = 0; i < nodesLength; i++)
                    {
                        var i1 = i;
                        if (modelAsset.Meshes.All(x => x.NodeIndex != i1))
                        {
                            continue;                                                // no geometry in the node
                        }
                        var combinedVerts   = new List <float>();
                        var combinedIndices = new List <uint>();

                        var hullsList = new List <List <Vector3> >();
                        convexHullDesc.ConvexHulls.Add(hullsList);

                        var indicesList = new List <List <uint> >();
                        convexHullDesc.ConvexHullsIndices.Add(indicesList);

                        foreach (var meshData in modelAsset.Meshes.Where(x => x.NodeIndex == i1))
                        {
                            var indexOffset = (uint)combinedVerts.Count / 3;

                            var stride          = meshData.Draw.VertexBuffers[0].Declaration.VertexStride;
                            var vertexDataAsset = assetManager.Load <Graphics.Buffer>(AttachedReferenceManager.GetUrl(meshData.Draw.VertexBuffers[0].Buffer));
                            var vertexData      = vertexDataAsset.GetSerializationData().Content;
                            var vertexIndex     = meshData.Draw.VertexBuffers[0].Offset;
                            for (var v = 0; v < meshData.Draw.VertexBuffers[0].Count; v++)
                            {
                                var posMatrix = Matrix.Translation(new Vector3(BitConverter.ToSingle(vertexData, vertexIndex + 0), BitConverter.ToSingle(vertexData, vertexIndex + 4), BitConverter.ToSingle(vertexData, vertexIndex + 8)));

                                Matrix rotatedMatrix;
                                var    nodeTransform = nodeTransforms[i];
                                Matrix.Multiply(ref posMatrix, ref nodeTransform, out rotatedMatrix);

                                combinedVerts.Add(rotatedMatrix.TranslationVector.X);
                                combinedVerts.Add(rotatedMatrix.TranslationVector.Y);
                                combinedVerts.Add(rotatedMatrix.TranslationVector.Z);

                                vertexIndex += stride;
                            }

                            var indexDataAsset = assetManager.Load <Graphics.Buffer>(AttachedReferenceManager.GetUrl(meshData.Draw.IndexBuffer.Buffer));
                            var indexData      = indexDataAsset.GetSerializationData().Content;
                            var indexIndex     = meshData.Draw.IndexBuffer.Offset;
                            for (var v = 0; v < meshData.Draw.IndexBuffer.Count; v++)
                            {
                                if (meshData.Draw.IndexBuffer.Is32Bit)
                                {
                                    combinedIndices.Add(BitConverter.ToUInt32(indexData, indexIndex) + indexOffset);
                                    indexIndex += 4;
                                }
                                else
                                {
                                    combinedIndices.Add(BitConverter.ToUInt16(indexData, indexIndex) + indexOffset);
                                    indexIndex += 2;
                                }
                            }
                        }

                        var decompositionDesc = new ConvexHullMesh.DecompositionDesc
                        {
                            VertexCount   = (uint)combinedVerts.Count / 3,
                            IndicesCount  = (uint)combinedIndices.Count,
                            Vertexes      = combinedVerts.ToArray(),
                            Indices       = combinedIndices.ToArray(),
                            Depth         = convexHullDesc.Depth,
                            PosSampling   = convexHullDesc.PosSampling,
                            PosRefine     = convexHullDesc.PosRefine,
                            AngleSampling = convexHullDesc.AngleSampling,
                            AngleRefine   = convexHullDesc.AngleRefine,
                            Alpha         = convexHullDesc.Alpha,
                            Threshold     = convexHullDesc.Threshold,
                            SimpleHull    = convexHullDesc.SimpleWrap
                        };

                        lock (this)
                        {
                            convexHullMesh = new ConvexHullMesh();
                        }

                        convexHullMesh.Generate(decompositionDesc);

                        var count = convexHullMesh.Count;

                        commandContext.Logger.Info("Node generated " + count + " convex hulls");

                        var vertexCountHull = 0;

                        for (uint h = 0; h < count; h++)
                        {
                            float[] points;
                            convexHullMesh.CopyPoints(h, out points);

                            var pointList = new List <Vector3>();

                            for (var v = 0; v < points.Length; v += 3)
                            {
                                var vert = new Vector3(points[v + 0], points[v + 1], points[v + 2]);
                                pointList.Add(vert);

                                vertexCountHull++;
                            }

                            hullsList.Add(pointList);

                            uint[] indices;
                            convexHullMesh.CopyIndices(h, out indices);

                            for (var t = 0; t < indices.Length; t += 3)
                            {
                                Utilities.Swap(ref indices[t], ref indices[t + 2]);
                            }

                            var indexList = new List <uint>(indices);

                            indicesList.Add(indexList);
                        }

                        lock (this)
                        {
                            convexHullMesh.Dispose();
                            convexHullMesh = null;
                        }

                        commandContext.Logger.Info("For a total of " + vertexCountHull + " vertexes");
                    }
                }

                var runtimeShape = new PhysicsColliderShape {
                    Descriptions = AssetParameters.ColliderShapes
                };

                assetManager.Save(Url, runtimeShape);

                return(Task.FromResult(ResultStatus.Successful));
            }
コード例 #2
0
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new ContentManager();

                // Cloned list of collider shapes
                var descriptions = Parameters.ColliderShapes.ToList();

                Parameters.ColliderShapes = Parameters.ColliderShapes.Where(x => x != null &&
                                                                            (x.GetType() != typeof(ConvexHullColliderShapeDesc) || ((ConvexHullColliderShapeDesc)x).Model != null)).ToList();

                //pre process special types
                foreach (var convexHullDesc in
                         (from shape in Parameters.ColliderShapes let type = shape.GetType() where type == typeof(ConvexHullColliderShapeDesc) select shape)
                         .Cast <ConvexHullColliderShapeDesc>())
                {
                    // Clone the convex hull shape description so the fields that should not be serialized can be cleared (Model in this case)
                    ConvexHullColliderShapeDesc convexHullDescClone = new ConvexHullColliderShapeDesc
                    {
                        Scaling       = convexHullDesc.Scaling,
                        LocalOffset   = convexHullDesc.LocalOffset,
                        LocalRotation = convexHullDesc.LocalRotation,
                        Depth         = convexHullDesc.Depth,
                        PosSampling   = convexHullDesc.PosSampling,
                        AngleSampling = convexHullDesc.AngleSampling,
                        PosRefine     = convexHullDesc.PosRefine,
                        AngleRefine   = convexHullDesc.AngleRefine,
                        Alpha         = convexHullDesc.Alpha,
                        Threshold     = convexHullDesc.Threshold,
                    };

                    // Replace shape in final result with cloned description
                    int replaceIndex = descriptions.IndexOf(convexHullDesc);
                    descriptions[replaceIndex] = convexHullDescClone;

                    var loadSettings = new ContentManagerLoaderSettings
                    {
                        ContentFilter = ContentManagerLoaderSettings.NewContentFilterByType(typeof(Mesh), typeof(Skeleton))
                    };

                    var modelAsset = assetManager.Load <Model>(AttachedReferenceManager.GetUrl(convexHullDesc.Model), loadSettings);
                    if (modelAsset == null)
                    {
                        continue;
                    }

                    convexHullDescClone.ConvexHulls        = new List <List <List <Vector3> > >();
                    convexHullDescClone.ConvexHullsIndices = new List <List <List <uint> > >();

                    commandContext.Logger.Info("Processing convex hull generation, this might take a while!");

                    var nodeTransforms = new List <Matrix>();

                    //pre-compute all node transforms, assuming nodes are ordered... see ModelViewHierarchyUpdater

                    if (modelAsset.Skeleton == null)
                    {
                        Matrix baseMatrix;
                        Matrix.Transformation(ref convexHullDescClone.Scaling, ref convexHullDescClone.LocalRotation, ref convexHullDescClone.LocalOffset, out baseMatrix);
                        nodeTransforms.Add(baseMatrix);
                    }
                    else
                    {
                        var nodesLength = modelAsset.Skeleton.Nodes.Length;
                        for (var i = 0; i < nodesLength; i++)
                        {
                            Matrix localMatrix;
                            Matrix.Transformation(
                                ref modelAsset.Skeleton.Nodes[i].Transform.Scale,
                                ref modelAsset.Skeleton.Nodes[i].Transform.Rotation,
                                ref modelAsset.Skeleton.Nodes[i].Transform.Position, out localMatrix);

                            Matrix worldMatrix;
                            if (modelAsset.Skeleton.Nodes[i].ParentIndex != -1)
                            {
                                var nodeTransform = nodeTransforms[modelAsset.Skeleton.Nodes[i].ParentIndex];
                                Matrix.Multiply(ref localMatrix, ref nodeTransform, out worldMatrix);
                            }
                            else
                            {
                                worldMatrix = localMatrix;
                            }

                            if (i == 0)
                            {
                                Matrix baseMatrix;
                                Matrix.Transformation(ref convexHullDescClone.Scaling, ref convexHullDescClone.LocalRotation, ref convexHullDescClone.LocalOffset, out baseMatrix);
                                nodeTransforms.Add(baseMatrix * worldMatrix);
                            }
                            else
                            {
                                nodeTransforms.Add(worldMatrix);
                            }
                        }
                    }

                    for (var i = 0; i < nodeTransforms.Count; i++)
                    {
                        var i1 = i;
                        if (modelAsset.Meshes.All(x => x.NodeIndex != i1))
                        {
                            continue;                                                // no geometry in the node
                        }
                        var combinedVerts   = new List <float>();
                        var combinedIndices = new List <uint>();

                        var hullsList = new List <List <Vector3> >();
                        convexHullDescClone.ConvexHulls.Add(hullsList);

                        var indicesList = new List <List <uint> >();
                        convexHullDescClone.ConvexHullsIndices.Add(indicesList);

                        foreach (var meshData in modelAsset.Meshes.Where(x => x.NodeIndex == i1))
                        {
                            var indexOffset = (uint)combinedVerts.Count / 3;

                            var stride = meshData.Draw.VertexBuffers[0].Declaration.VertexStride;

                            var    vertexBufferRef = AttachedReferenceManager.GetAttachedReference(meshData.Draw.VertexBuffers[0].Buffer);
                            byte[] vertexData;
                            if (vertexBufferRef.Data != null)
                            {
                                vertexData = ((BufferData)vertexBufferRef.Data).Content;
                            }
                            else if (!vertexBufferRef.Url.IsNullOrEmpty())
                            {
                                var dataAsset = assetManager.Load <Buffer>(vertexBufferRef.Url);
                                vertexData = dataAsset.GetSerializationData().Content;
                            }
                            else
                            {
                                continue;
                            }

                            var vertexIndex = meshData.Draw.VertexBuffers[0].Offset;
                            for (var v = 0; v < meshData.Draw.VertexBuffers[0].Count; v++)
                            {
                                var posMatrix = Matrix.Translation(new Vector3(BitConverter.ToSingle(vertexData, vertexIndex + 0), BitConverter.ToSingle(vertexData, vertexIndex + 4), BitConverter.ToSingle(vertexData, vertexIndex + 8)));

                                Matrix rotatedMatrix;
                                var    nodeTransform = nodeTransforms[i];
                                Matrix.Multiply(ref posMatrix, ref nodeTransform, out rotatedMatrix);

                                combinedVerts.Add(rotatedMatrix.TranslationVector.X);
                                combinedVerts.Add(rotatedMatrix.TranslationVector.Y);
                                combinedVerts.Add(rotatedMatrix.TranslationVector.Z);

                                vertexIndex += stride;
                            }

                            var    indexBufferRef = AttachedReferenceManager.GetAttachedReference(meshData.Draw.IndexBuffer.Buffer);
                            byte[] indexData;
                            if (indexBufferRef.Data != null)
                            {
                                indexData = ((BufferData)indexBufferRef.Data).Content;
                            }
                            else if (!indexBufferRef.Url.IsNullOrEmpty())
                            {
                                var dataAsset = assetManager.Load <Buffer>(indexBufferRef.Url);
                                indexData = dataAsset.GetSerializationData().Content;
                            }
                            else
                            {
                                throw new Exception("Failed to find index buffer while building a convex hull.");
                            }

                            var indexIndex = meshData.Draw.IndexBuffer.Offset;
                            for (var v = 0; v < meshData.Draw.IndexBuffer.Count; v++)
                            {
                                if (meshData.Draw.IndexBuffer.Is32Bit)
                                {
                                    combinedIndices.Add(BitConverter.ToUInt32(indexData, indexIndex) + indexOffset);
                                    indexIndex += 4;
                                }
                                else
                                {
                                    combinedIndices.Add(BitConverter.ToUInt16(indexData, indexIndex) + indexOffset);
                                    indexIndex += 2;
                                }
                            }
                        }

                        var decompositionDesc = new ConvexHullMesh.DecompositionDesc
                        {
                            VertexCount   = (uint)combinedVerts.Count / 3,
                            IndicesCount  = (uint)combinedIndices.Count,
                            Vertexes      = combinedVerts.ToArray(),
                            Indices       = combinedIndices.ToArray(),
                            Depth         = convexHullDesc.Depth,
                            PosSampling   = convexHullDesc.PosSampling,
                            PosRefine     = convexHullDesc.PosRefine,
                            AngleSampling = convexHullDesc.AngleSampling,
                            AngleRefine   = convexHullDesc.AngleRefine,
                            Alpha         = convexHullDesc.Alpha,
                            Threshold     = convexHullDesc.Threshold,
                            SimpleHull    = convexHullDesc.SimpleWrap
                        };

                        var convexHullMesh = new ConvexHullMesh();

                        convexHullMesh.Generate(decompositionDesc);

                        var count = convexHullMesh.Count;

                        commandContext.Logger.Info("Node generated " + count + " convex hulls");

                        var vertexCountHull = 0;

                        for (uint h = 0; h < count; h++)
                        {
                            float[] points;
                            convexHullMesh.CopyPoints(h, out points);

                            var pointList = new List <Vector3>();

                            for (var v = 0; v < points.Length; v += 3)
                            {
                                var vert = new Vector3(points[v + 0], points[v + 1], points[v + 2]);
                                pointList.Add(vert);

                                vertexCountHull++;
                            }

                            hullsList.Add(pointList);

                            uint[] indices;
                            convexHullMesh.CopyIndices(h, out indices);

                            for (var t = 0; t < indices.Length; t += 3)
                            {
                                Utilities.Swap(ref indices[t], ref indices[t + 2]);
                            }

                            var indexList = new List <uint>(indices);

                            indicesList.Add(indexList);
                        }

                        convexHullMesh.Dispose();

                        commandContext.Logger.Info("For a total of " + vertexCountHull + " vertexes");
                    }
                }

                var runtimeShape = new PhysicsColliderShape {
                    Descriptions = descriptions
                };

                assetManager.Save(Url, runtimeShape);

                return(Task.FromResult(ResultStatus.Successful));
            }