/// <summary> /// Construct a mesh collision part from the specified vertices and indices. /// </summary> /// <param name="vertices">A list of all vertices contained in the mesh.</param> /// <param name="indices">A list of vertex indices that define the triangles in the mesh.</param> public MeshPart(Vector3[] vertices, int[] indices) { _body = new CompiledMesh(vertices, indices); ApplyTransform(ref Transform); }
/// <summary> /// Construct a mesh collision part from a pre-compiled mesh. /// </summary> /// <param name="mesh">The compiled mesh that that this skin part will use.</param> public MeshPart(CompiledMesh mesh) { _body = mesh; ApplyTransform(ref Transform); }
public override ModelContent Process(NodeContent input, ContentProcessorContext context) { var attributes = input.Children.ToDictionary(n => n.Name, n => n.OpaqueData); var nodesToRemove = (from node in input.Children where node.OpaqueData.GetAttribute(TYPE_ATTR_NAME, MeshType.Both) == MeshType.Physical select node).ToArray(); ModelContent model = base.Process(input, context); var parts = new List<CompiledPart>(); var materials = new List<Material>(); var mass = new MassProperties(); var centerOfMass = Vector3.Zero; foreach (var mesh in model.Meshes) { MeshType type = MeshType.Both; PhysicalShape shape = PhysicalShape.Mesh; float elasticity = _defaultElasticity, roughness = _defaultRoughness, density = _defaultDensity; if (attributes.ContainsKey(mesh.Name)) { type = attributes[mesh.Name].GetAttribute(TYPE_ATTR_NAME, MeshType.Both); if (type == MeshType.Visual) continue; elasticity = attributes[mesh.Name].GetAttribute(ELASTICITY_ATTR_NAME, _defaultElasticity); roughness = attributes[mesh.Name].GetAttribute(ROUGHNESS_ATTR_NAME, _defaultRoughness); density = attributes[mesh.Name].GetAttribute(DENSITY_ATTR_NAME, _defaultDensity); shape = attributes[mesh.Name].GetAttribute(SHAPE_ATTR_NAME, _defaultShape); } var meshCenterOfMass = Vector3.Zero; var meshMass = MassProperties.Immovable; CompiledPart meshPart = null; if (mesh.MeshParts.Count < 1) { continue; } int[] indices = mesh.MeshParts[0].IndexBuffer.Skip(mesh.MeshParts[0].StartIndex).Take(mesh.MeshParts[0].PrimitiveCount * 3).ToArray(); Vector3[] vertices = MeshToVertexArray(context.TargetPlatform, mesh); if (_windingOrder == WindingOrder.Clockwise) { ReverseWindingOrder(indices); } switch (shape) { case PhysicalShape.Mesh: { meshPart = new CompiledMesh(vertices, indices); meshMass = MassProperties.Immovable; meshCenterOfMass = GetMeshTranslation(mesh); } break; case PhysicalShape.Polyhedron: { var hull = new ConvexHull3D(vertices); meshPart = hull.ToPolyhedron(); meshMass = MassProperties.FromTriMesh(density, vertices, indices, out meshCenterOfMass); } break; case PhysicalShape.Sphere: { Sphere s; Sphere.Fit(vertices, out s); meshPart = new CompiledSphere(s.Center, s.Radius); meshMass = MassProperties.FromSphere(density, s.Center, s.Radius); meshCenterOfMass = s.Center; } break; case PhysicalShape.Capsule: { Capsule c; Capsule.Fit(vertices, out c); meshPart = new CompiledCapsule(c.P1, c.P2, c.Radius); meshMass = MassProperties.FromCapsule(density, c.P1, c.P2, c.Radius, out meshCenterOfMass); } break; } parts.Add(meshPart); materials.Add(new Material(elasticity, roughness)); Vector3.Multiply(ref meshCenterOfMass, meshMass.Mass, out meshCenterOfMass); Vector3.Add(ref centerOfMass, ref meshCenterOfMass, out centerOfMass); mass.Mass += meshMass.Mass; meshMass.Inertia.M44 = 0f; Matrix.Add(ref mass.Inertia, ref meshMass.Inertia, out mass.Inertia); } // compute mass properties Vector3.Divide(ref centerOfMass, mass.Mass, out centerOfMass); mass.Inertia.M44 = 1f; MassProperties.TranslateInertiaTensor(ref mass.Inertia, -mass.Mass, centerOfMass, out mass.Inertia); if (centerOfMass.Length() >= Constants.Epsilon) { var transform = Matrix.CreateTranslation(-centerOfMass.X, -centerOfMass.Y, -centerOfMass.Z); foreach (var p in parts) { p.Transform(ref transform); } transform = model.Root.Transform; transform.M41 -= centerOfMass.X; transform.M42 -= centerOfMass.Y; transform.M43 -= centerOfMass.Z; model.Root.Transform = transform; } mass = new MassProperties(mass.Mass, mass.Inertia); var rbm = new RigidBodyModel(mass, parts.ToArray(), materials.ToArray()); // remove non-visual nodes if (nodesToRemove.Length > 0) { foreach (var node in nodesToRemove) input.Children.Remove(node); model = base.Process(input, context); } model.Tag = rbm; return model; }