Exemple #1
0
        private void runTest(int samples, double radius)
        {
            double[] times = new double[samples];

            Stopwatch watch = new Stopwatch();
            Random    rand  = new Random();

            Console.WriteLine("Cores: " + Environment.ProcessorCount);
            Console.WriteLine("64bit:" + Environment.Is64BitProcess + Environment.NewLine);

            for (int s = 0; s < samples; s++)
            {
                List <Vector3D>    points  = new List <Vector3D>();
                List <PoissonDisc> tPoints = PoissonDiscSampling.Sample3D(84357, radius, new Vector3D(5, 5, 5), 4, false);

                foreach (PoissonDisc disc in tPoints)
                {
                    points.Add(new Vector3D(disc.position.X, disc.position.Y, disc.position.Z));
                }

                ConvexHull3D hull = new ConvexHull3D();
                Console.WriteLine(points.Count);
                watch.Restart();
                points = hull.ConstructHull(points);
                watch.Stop();
                Console.WriteLine(points.Count);
                times[s] = watch.Elapsed.TotalMilliseconds;
            }
            Console.WriteLine(samples + ": avg => " + times.Average() + " | best => " + times.Min() + " | worst => " + times.Max());
        }
Exemple #2
0
 //metric form edges
 public Metric(Vector3[] edges, float m = 0f, int crew_capacity = 0, bool compute_hull=false)
     : this()
 {
     if(compute_hull) hull = new ConvexHull3D(edges);
     bounds = initBounds(edges);
     volume = boundsVolume(bounds);
     area   = boundsArea(bounds);
     mass   = m;
     CrewCapacity = crew_capacity;
 }
Exemple #3
0
        public void Cube_ConvexHull()
        {
            pointCloudSource = PointCloud.CreateCube_Corners_CenteredAt0(0.1f);
            PointCloud.SetColorOfListTo(pointCloudSource, Color.Red);
            List <Vector3> myListVectors = pointCloudSource.ListVectors;

            ConvexHull3D convHull = new ConvexHull3D(myListVectors);



            ShowPointCloud(pointCloudSource);
            System.Diagnostics.Debug.WriteLine("Number of faces: " + convHull.Faces.ListFaces.Count.ToString());
        }
Exemple #4
0
        public void Bunny_Hull()
        {
            string fileNameLong = pathUnitTests + "\\bunny.xyz";

            pointCloudSource = IOUtils.ReadXYZFile_ToVertices(fileNameLong, false);
            PointCloud.SetColorOfListTo(pointCloudSource, System.Drawing.Color.Red);

            List <Vector3> myListVectors = pointCloudSource.ListVectors;

            ConvexHull3D cHull = new ConvexHull3D(myListVectors);



            ShowPointCloud(pointCloudSource);
        }
        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);
        }
		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;
		}
Exemple #7
0
 //mesh metric
 public Metric(Part part, string mesh_name, bool compute_hull=false)
     : this()
 {
     if(string.IsNullOrEmpty(mesh_name)) return;
     MeshFilter m = part.FindModelComponent<MeshFilter>(mesh_name);
     if(m == null) { Utils.Log("[Metric] {0} does not have '{1}' mesh", part.name, mesh_name); return; }
     if(compute_hull) hull = new ConvexHull3D(uniqueVertices(m.sharedMesh));
     Vector3[] edges = BoundsEdges(m.sharedMesh.bounds);
     local2local(m.transform, part.partTransform, edges);
     bounds = initBounds(edges);
     volume = boundsVolume(bounds);
     area   = boundsArea(bounds);
     mass   = 0f;
 }
Exemple #8
0
 Bounds partsBounds(List<Part> parts, Transform vT, bool compute_hull=false)
 {
     //reset metric
     mass = 0;
     cost = 0;
     CrewCapacity = 0;
     Bounds b = default(Bounds);
     if(parts == null || parts.Count == 0)
     { Utils.Log("Metric.partsBounds: WARNING! No parts were provided."); return b; }
     //calculate bounds and convex hull
     float b_size = 0;
     List<Vector3> hull_points = compute_hull ? new List<Vector3>() : null;
     foreach(Part p in parts)
     {
         if(p == null) continue; //EditorLogic.SortedShipList returns List<Part>{null} when all parts are deleted
         foreach(MeshFilter m in p.FindModelComponents<MeshFilter>())
         {
             //skip meshes without renderer
             if(m.renderer == null || !m.renderer.enabled) continue;
             //skip meshes from the blacklist
             bool skip_mesh = false;
             foreach(string mesh_name in HangarConfig.Globals.MeshesToSkipList)
             {
                 if(mesh_name == "") continue;
                 skip_mesh = m.name.IndexOf(mesh_name, StringComparison.OrdinalIgnoreCase) >= 0;
                 if(skip_mesh) break;
             } if(skip_mesh) continue;
             //wheels are round and rotating >_<
             //TODO: rework this block for more efficiency: do not call Mesh.vertices twice
             Vector3[] edges = m.name.IndexOf("wheel", StringComparison.OrdinalIgnoreCase) >= 0 ?
                               m.sharedMesh.vertices : BoundsEdges(m.sharedMesh.bounds);
             updateBounds(ref b, local2local(m.transform, vT, edges));
             if(compute_hull)
             {
                 float m_size = Vector3.Scale(m.sharedMesh.bounds.size, m.transform.lossyScale).sqrMagnitude;
                 var verts = m_size > b_size/10? local2local(m.transform, vT, uniqueVertices(m.sharedMesh)) : edges;
                 hull_points.AddRange(verts);
                 b_size = b.size.sqrMagnitude;
             }
         }
         CrewCapacity += p.CrewCapacity;
         if(p.IsPhysicallySignificant())	mass += p.TotalMass();
         cost += p.TotalCost();
     }
     if(compute_hull && hull_points.Count >= 4)
         hull = new ConvexHull3D(hull_points);
     return b;
 }