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; } } }
/// <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)); }