private void UpdateNode(ref ModelNodeTransformation node)
        {
            // Compute LocalMatrix
            if ((node.Flags & ModelNodeFlags.EnableTransform) == ModelNodeFlags.EnableTransform)
            {
                TransformationComponent.CreateMatrixTRS(ref node.Transform.Translation, ref node.Transform.Rotation, ref node.Transform.Scaling, out node.LocalMatrix);
            }

            var nodeTransformationsLocal = this.nodeTransformations;

            var parentIndex = node.ParentIndex;

            // Update Enabled
            bool renderingEnabledRecursive = (node.Flags & ModelNodeFlags.EnableRender) == ModelNodeFlags.EnableRender;

            if (parentIndex != -1)
            {
                renderingEnabledRecursive &= nodeTransformationsLocal[parentIndex].RenderingEnabledRecursive;
            }

            node.RenderingEnabledRecursive = renderingEnabledRecursive;

            if (renderingEnabledRecursive)
            {
                // Compute WorldMatrix
                if (parentIndex != -1)
                {
                    Matrix.Multiply(ref node.LocalMatrix, ref nodeTransformationsLocal[parentIndex].WorldMatrix, out node.WorldMatrix);
                }
                else
                {
                    node.WorldMatrix = node.LocalMatrix;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Updades the graphics transformation from the given physics transformation
        /// </summary>
        /// <param name="physicsTransform"></param>
        internal void UpdateTransformationComponent(Matrix physicsTransform)
        {
            var entity = (Entity)Collider.EntityObject;

            if (Shape.Shape.LocalOffset != Vector3.Zero || Shape.Shape.LocalRotation != Quaternion.Identity)
            {
                physicsTransform = Matrix.Multiply(Shape.Shape.NegativeCenterMatrix, physicsTransform);
            }

            var rotation    = Quaternion.RotationMatrix(physicsTransform);
            var translation = physicsTransform.TranslationVector;

            //Invert up axis in the case of a Sprite
            if (Sprite)
            {
                translation.Y = -translation.Y;
            }

            if (entity.Transformation.UseTRS)
            {
                entity.Transformation.Translation = translation;
                entity.Transformation.Rotation    = rotation;
            }
            else
            {
                var worldMatrix = entity.Transformation.WorldMatrix;

                Vector3 scale;
                scale.X = (float)Math.Sqrt((worldMatrix.M11 * worldMatrix.M11) + (worldMatrix.M12 * worldMatrix.M12) + (worldMatrix.M13 * worldMatrix.M13));
                scale.Y = (float)Math.Sqrt((worldMatrix.M21 * worldMatrix.M21) + (worldMatrix.M22 * worldMatrix.M22) + (worldMatrix.M23 * worldMatrix.M23));
                scale.Z = (float)Math.Sqrt((worldMatrix.M31 * worldMatrix.M31) + (worldMatrix.M32 * worldMatrix.M32) + (worldMatrix.M33 * worldMatrix.M33));

                TransformationComponent.CreateMatrixTRS(ref translation, ref rotation, ref scale, out entity.Transformation.WorldMatrix);
                if (entity.Transformation.Parent == null)
                {
                    entity.Transformation.LocalMatrix = entity.Transformation.WorldMatrix;
                }
                else
                {
                    //We are not root so we need to derive the local matrix as well
                    var inverseParent = entity.Transformation.Parent.WorldMatrix;
                    inverseParent.Invert();
                    entity.Transformation.LocalMatrix = Matrix.Multiply(entity.Transformation.WorldMatrix, inverseParent);
                }
            }
        }
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                var assetManager = new AssetManager();

                //pre process special types
                foreach (var shape in asset.Data.ColliderShapes)
                {
                    var type = shape.GetType();
                    if (type == typeof(ConvexHullColliderShapeDesc))
                    {
                        var convexHullDesc = (ConvexHullColliderShapeDesc)shape;

                        //decompose and fill vertex data
                        if (convexHullDesc.Model != null)
                        {
                            var loadSettings = new AssetManagerLoaderSettings
                            {
                                ContentFilter = AssetManagerLoaderSettings.NewContentFilterByType(typeof(MeshData))
                            };

                            var modelAsset = assetManager.Load <ModelData>(convexHullDesc.Model.Location, loadSettings);
                            if (modelAsset != null)
                            {
                                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;
                                    TransformationComponent.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 <BufferData>(meshData.Draw.VertexBuffers[0].Buffer.Location);

                                        var vertexData  = vertexDataAsset.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 <BufferData>(meshData.Draw.IndexBuffer.Buffer.Location);

                                        var indexData  = indexDataAsset.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");
                                }
                            }
                        }

                        //clear up the reference as we don't need this data anymore
                        convexHullDesc.Model = null;
                    }
                }

                assetManager.Save(Url, asset.Data);

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