Наследование: GraphNode
Пример #1
0
 public AStarNode(double latestCosts, double costsToEnd, MeshNode node, AStarNode precedent)
 {
     mLatestCosts = latestCosts;
     mCostsToEnd = costsToEnd;
     mNode = node;
     mPrecedent = precedent;
 }
Пример #2
0
		int GetBox ( MeshNode node ) {
			if ( count >= arr.Length ) EnsureCapacity ( count+1 );

			arr[count] = new BBTreeBox ( node );
			count++;
			return count-1;
		}
Пример #3
0
        static void exportBone(BinaryWriter dest, MeshNode target,  Assimp.Scene scene, int boneID)
        {
            Assimp.Node node = target.node;

            exportString(dest, node.Name);
            if (node.Parent!=null)
                exportString(dest, node.Parent.Name);
            else
                exportString(dest, "");

            Matrix4x4 mat = new Matrix4x4(node.Transform.A1, node.Transform.A2, node.Transform.A3, node.Transform.A4, node.Transform.B1, node.Transform.B2, node.Transform.B3, node.Transform.B4, node.Transform.C1, node.Transform.C2, node.Transform.C3, node.Transform.C4, node.Transform.D1, node.Transform.D2, node.Transform.D3, node.Transform.D4);
            mat.Transpose();

            exportMatrix(dest, mat);

            Bone bone = target.bone;
            if (bone != null)
            {
                mat = new Matrix4x4(bone.OffsetMatrix.A1, bone.OffsetMatrix.A2, bone.OffsetMatrix.A3, bone.OffsetMatrix.A4, bone.OffsetMatrix.B1, bone.OffsetMatrix.B2, bone.OffsetMatrix.B3, bone.OffsetMatrix.B4, bone.OffsetMatrix.C1, bone.OffsetMatrix.C2, bone.OffsetMatrix.C3, bone.OffsetMatrix.C4, bone.OffsetMatrix.D1, bone.OffsetMatrix.D2, bone.OffsetMatrix.D3, bone.OffsetMatrix.D4);
                mat.Transpose();
            }
            else
                mat = Matrix4x4.Identity;

            exportMatrix(dest, mat);
        }
Пример #4
0
		/** Rebuilds the tree using the specified nodes.
		 * This is faster and gives better quality results compared to calling Insert with all nodes
		 */
		public void RebuildFrom (MeshNode[] nodes) {
			Clear();

			if (nodes.Length == 0) {
				return;
			}

			if (nodes.Length == 1) {
				GetBox(nodes[0]);
				return;
			}

			// We will use approximately 2N tree nodes
			EnsureCapacity(Mathf.CeilToInt (nodes.Length * 2.1f));

			// Make a copy of the nodes array since we will be modifying it
			var nodeCopies = new MeshNode[nodes.Length];
			for (int i = 0; i < nodes.Length; i++) nodeCopies[i] = nodes[i];

			RebuildFromInternal(nodeCopies, 0, nodes.Length, false);
		}
Пример #5
0
			public BBTreeBox (MeshNode node) {
				this.node = node;
				var first = node.GetVertex(0);
				var min = new Int2(first.x,first.z);
				Int2 max = min;

				for (int i=1;i<node.GetVertexCount();i++) {
					var p = node.GetVertex(i);
					min.x = Math.Min (min.x,p.x);
					min.y = Math.Min (min.y,p.z);

					max.x = Math.Max (max.x,p.x);
					max.y = Math.Max (max.y,p.z);
				}

				rect = new IntRect (min.x,min.y,max.x,max.y);
				left = right = -1;
			}
Пример #6
0
		static bool NodeIntersectsCircle (MeshNode node, Vector3 p, float radius) {

			if (float.IsPositiveInfinity(radius)) return true;

			/** \bug Is not correct on the Y axis */
			return (p - node.ClosestPointOnNode (p)).sqrMagnitude < radius*radius;
		}
Пример #7
0
		/** Calculates the bounding box in XZ space of all nodes between \a from (inclusive) and \a to (exclusive) */
		static IntRect NodeBounds (MeshNode[] nodes, int from, int to) {
			if (to - from <= 0) throw new ArgumentException();

			var first = nodes[from].GetVertex(0);
			var min = new Int2(first.x,first.z);
			Int2 max = min;

			for (int j = from; j < to; j++) {
				var node = nodes[j];
				var nverts = node.GetVertexCount();
				for (int i = 0; i < nverts; i++) {
					var p = node.GetVertex(i);
					min.x = Math.Min (min.x, p.x);
					min.y = Math.Min (min.y, p.z);

					max.x = Math.Max (max.x, p.x);
					max.y = Math.Max (max.y, p.z);
				}
			}

			return new IntRect (min.x, min.y, max.x, max.y);
		}
Пример #8
0
		public void InternalOnPostScan () {
			
#if !ASTAR_NO_POINT_GRAPH
			if ( AstarPath.active.astarData.pointGraph == null ) {
				AstarPath.active.astarData.AddGraph ( new PointGraph () );
			}
			
			//Get nearest nodes from the first point graph, assuming both start and end transforms are nodes
			startNode = AstarPath.active.astarData.pointGraph.AddNode ( new NodeLink3Node(AstarPath.active), (Int3)StartTransform.position );//AstarPath.active.astarData.pointGraph.GetNearest(StartTransform.position).node as PointNode;
			startNode.link = this;
			endNode = AstarPath.active.astarData.pointGraph.AddNode ( new NodeLink3Node(AstarPath.active), (Int3)EndTransform.position ); //AstarPath.active.astarData.pointGraph.GetNearest(EndTransform.position).node as PointNode;
			endNode.link = this;
#else
			throw new System.Exception ("Point graphs are not included. Check your A* Optimization settings.");
#endif
			connectedNode1 = null;
			connectedNode2 = null;
			
			if (startNode == null || endNode == null) {
				startNode = null;
				endNode = null;
				return;
			}
			
			postScanCalled = true;
			reference[startNode] = this;
			reference[endNode] = this;
			Apply( true );
		}
        private Ragdoll CreateRagdoll(MeshNode meshNode)
        {
            var mesh     = meshNode.Mesh;
            var skeleton = mesh.Skeleton;

            // Extract the vertices from the mesh sorted per bone.
            var verticesPerBone = new List <Vector3> [skeleton.NumberOfBones];
            // Also get the AABB of the model.
            Aabb?aabb = null;

            foreach (var submesh in mesh.Submeshes)
            {
                // Get vertex element info.
                var vertexDeclaration = submesh.VertexBuffer.VertexDeclaration;
                var vertexElements    = vertexDeclaration.GetVertexElements();

                // Get the vertex positions.
                var positionElement = vertexElements.First(e => e.VertexElementUsage == VertexElementUsage.Position);
                if (positionElement.VertexElementFormat != VertexElementFormat.Vector3)
                {
                    throw new NotSupportedException("For vertex positions only VertexElementFormat.Vector3 is supported.");
                }
                var positions = new Vector3[submesh.VertexCount];
                submesh.VertexBuffer.GetData(
                    submesh.StartVertex * vertexDeclaration.VertexStride + positionElement.Offset,
                    positions,
                    0,
                    submesh.VertexCount,
                    vertexDeclaration.VertexStride);

                // Get the bone indices.
                var boneIndexElement = vertexElements.First(e => e.VertexElementUsage == VertexElementUsage.BlendIndices);
                if (boneIndexElement.VertexElementFormat != VertexElementFormat.Byte4)
                {
                    throw new NotSupportedException();
                }
                var boneIndicesArray = new Byte4[submesh.VertexCount];
                submesh.VertexBuffer.GetData(
                    submesh.StartVertex * vertexDeclaration.VertexStride + boneIndexElement.Offset,
                    boneIndicesArray,
                    0,
                    submesh.VertexCount,
                    vertexDeclaration.VertexStride);

                // Get the bone weights.
                var boneWeightElement = vertexElements.First(e => e.VertexElementUsage == VertexElementUsage.BlendWeight);
                if (boneWeightElement.VertexElementFormat != VertexElementFormat.Vector4)
                {
                    throw new NotSupportedException();
                }
                var boneWeightsArray = new Vector4[submesh.VertexCount];
                submesh.VertexBuffer.GetData(
                    submesh.StartVertex * vertexDeclaration.VertexStride + boneWeightElement.Offset,
                    boneWeightsArray,
                    0,
                    submesh.VertexCount,
                    vertexDeclaration.VertexStride);

                // Sort the vertices per bone.
                for (int i = 0; i < submesh.VertexCount; i++)
                {
                    var vertex = (Vector3)positions[i];

                    // Here, we only check the first bone index. We could also check the
                    // bone weights to add the vertex to all bone vertex lists where the
                    // weight is high...
                    Vector4 boneIndices = boneIndicesArray[i].ToVector4();
                    //Vector4 boneWeights = boneWeightsArray[i];
                    int boneIndex = (int)boneIndices.X;
                    if (verticesPerBone[boneIndex] == null)
                    {
                        verticesPerBone[boneIndex] = new List <Vector3>();
                    }
                    verticesPerBone[boneIndex].Add(vertex);

                    // Add vertex to AABB.
                    if (aabb == null)
                    {
                        aabb = new Aabb(vertex, vertex);
                    }
                    else
                    {
                        aabb.Value.Grow(vertex);
                    }
                }
            }

            // We create a body for each bone with vertices.
            int numberOfBodies = verticesPerBone.Count(vertices => vertices != null);

            // We use the same mass properties for all bodies. This is not realistic but more stable
            // because large mass differences or thin bodies (arms!) are less stable.
            // We use the mass properties of sphere proportional to the size of the model.
            const float totalMass = 80; // The total mass of the ragdoll.
            var         massFrame = MassFrame.FromShapeAndMass(new SphereShape(aabb.Value.Extent.Y / 8), Vector3.One, totalMass / numberOfBodies, 0.1f, 1);

            var material = new UniformMaterial();

            Ragdoll ragdoll = new Ragdoll();

            for (int boneIndex = 0; boneIndex < skeleton.NumberOfBones; boneIndex++)
            {
                var boneVertices = verticesPerBone[boneIndex];
                if (boneVertices != null)
                {
                    var bindPoseInverse = (Pose)skeleton.GetBindPoseAbsoluteInverse(boneIndex);

                    // Compute bounding capsule.
                    //float radius;
                    //float height;
                    //Pose pose;
                    //GeometryHelper.ComputeBoundingCapsule(boneVertices, out radius, out height, out pose);
                    //Shape shape = new TransformedShape(new GeometricObject(new CapsuleShape(radius, height), pose));

                    // Compute convex hull.
                    var   points = GeometryHelper.CreateConvexHull(boneVertices, 32, 0).ToTriangleMesh().Vertices;
                    Shape shape  = new ConvexHullOfPoints(points.Count > 0 ? points : boneVertices);

                    ragdoll.Bodies.Add(new RigidBody(shape, massFrame, material));
                    ragdoll.BodyOffsets.Add(bindPoseInverse);
                }
                else
                {
                    ragdoll.Bodies.Add(null);
                    ragdoll.BodyOffsets.Add(Pose.Identity);
                }
            }

            return(ragdoll);
        }
Пример #10
0
		public void Apply ( bool forceNewCheck ) {
			//TODO
			//This function assumes that connections from the n1,n2 nodes never need to be removed in the future (e.g because the nodes move or something)
			NNConstraint nn = NNConstraint.None;
			nn.distanceXZ = true;
			int graph = (int)startNode.GraphIndex;
			
			//Search all graphs but the one which start and end nodes are on
			nn.graphMask = ~(1 << graph);
			
			bool same = true;
			
			if (true) {
				NNInfo n1 = AstarPath.active.GetNearest(StartTransform.position, nn);
				same &= n1.node == connectedNode1 && n1.node != null;
				connectedNode1 = n1.node as MeshNode;
				clamped1 = n1.clampedPosition;
				if ( connectedNode1 != null ) Debug.DrawRay ( (Vector3)connectedNode1.position, Vector3.up*5,Color.red);
			}
			
			if (true) {
				NNInfo n2 = AstarPath.active.GetNearest(EndTransform.position, nn);
				same &= n2.node == connectedNode2 && n2.node != null;
				connectedNode2 = n2.node as MeshNode;
				clamped2 = n2.clampedPosition;
				if ( connectedNode2 != null ) Debug.DrawRay ( (Vector3)connectedNode2.position, Vector3.up*5,Color.cyan);
			}
			
			if (connectedNode2 == null || connectedNode1 == null) return;
			
			startNode.SetPosition ( (Int3)StartTransform.position );
			endNode.SetPosition ( (Int3)EndTransform.position );
			
			if ( same && !forceNewCheck ) return;
			
			RemoveConnections(startNode);
			RemoveConnections(endNode);
			
			uint cost = (uint)Mathf.RoundToInt(((Int3)(StartTransform.position-EndTransform.position)).costMagnitude*costFactor);
			startNode.AddConnection (endNode, cost);
			endNode.AddConnection(startNode, cost);
			
			Int3 dir = connectedNode2.position - connectedNode1.position;
			
			for ( int a=0;a<connectedNode1.GetVertexCount();a++) {
				Int3 va1 = connectedNode1.GetVertex ( a );
				Int3 va2 = connectedNode1.GetVertex ( (a+1) % connectedNode1.GetVertexCount() );
				
				if ( Int3.DotLong ( (va2-va1).Normal2D (), dir ) > 0 ) continue;
				
				for ( int b=0;b<connectedNode2.GetVertexCount();b++) {
					Int3 vb1 = connectedNode2.GetVertex ( b );
					Int3 vb2 = connectedNode2.GetVertex ( (b+1) % connectedNode2.GetVertexCount() );
					
					if ( Int3.DotLong ( (vb2-vb1).Normal2D (), dir ) < 0 ) continue;
					
					
					//Debug.DrawLine ((Vector3)va1, (Vector3)va2, Color.magenta);
					//Debug.DrawLine ((Vector3)vb1, (Vector3)vb2, Color.cyan);
					//Debug.Break ();
					
					if ( Int3.Angle ( (vb2-vb1), (va2-va1) ) > (170.0/360.0f)*Mathf.PI*2 ) {
						
						float t1 = 0;
						float t2 = 1;
						
						t2 = System.Math.Min ( t2, AstarMath.NearestPointFactor ( va1, va2, vb1 ) );
						t1 = System.Math.Max ( t1, AstarMath.NearestPointFactor ( va1, va2, vb2 ) );
						
						if ( t2 < t1 ) {
							Debug.LogError ("Wait wut!? " + t1 + " " + t2 + " " + va1 + " " + va2 + " " + vb1 + " " + vb2+"\nTODO, fix this error" );
						} else {
						
							Vector3 pa = (Vector3)(va2-va1)*t1 + (Vector3)va1;
							Vector3 pb = (Vector3)(va2-va1)*t2 + (Vector3)va1;
							
							startNode.portalA = pa;
							startNode.portalB = pb;
							
							endNode.portalA = pb;
							endNode.portalB = pa;
							
							//Enqueue connections between nodes, or replace old connections if existing
							connectedNode1.AddConnection(startNode, (uint)Mathf.RoundToInt (((Int3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
							connectedNode2.AddConnection(endNode, (uint)Mathf.RoundToInt (((Int3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));
							
							startNode.AddConnection(connectedNode1, (uint)Mathf.RoundToInt (((Int3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
							endNode.AddConnection(connectedNode2, (uint)Mathf.RoundToInt (((Int3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));
							
							return;
						}
					}
				}
			}
			
		}
Пример #11
0
		public void Apply ( bool forceNewCheck ) {
			//TODO
			//This function assumes that connections from the n1,n2 nodes never need to be removed in the future (e.g because the nodes move or something)
			NNConstraint nn = NNConstraint.None;
			int graph = (int)startNode.GraphIndex;
			
			//Search all graphs but the one which start and end nodes are on
			nn.graphMask = ~(1 << graph);
			
			startNode.SetPosition ( (Int3)StartTransform.position );
			endNode.SetPosition ( (Int3)EndTransform.position );
			
			RemoveConnections(startNode);
			RemoveConnections(endNode);
			
			uint cost = (uint)Mathf.RoundToInt(((Int3)(StartTransform.position-EndTransform.position)).costMagnitude*costFactor);
			startNode.AddConnection (endNode, cost);
			endNode.AddConnection(startNode, cost);
			
			if (connectedNode1 == null || forceNewCheck) {
				NNInfo n1 = AstarPath.active.GetNearest(StartTransform.position, nn);
				connectedNode1 = n1.node as MeshNode;
				clamped1 = n1.clampedPosition;
			}
			
			if (connectedNode2 == null || forceNewCheck) {
				NNInfo n2 = AstarPath.active.GetNearest(EndTransform.position, nn);
				connectedNode2 = n2.node as MeshNode;
				clamped2 = n2.clampedPosition;
			}
			
			if (connectedNode2 == null || connectedNode1 == null) return;
			
			//Enqueue connections between nodes, or replace old connections if existing
			connectedNode1.AddConnection(startNode, (uint)Mathf.RoundToInt (((Int3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
			if ( !oneWay ) connectedNode2.AddConnection(endNode, (uint)Mathf.RoundToInt (((Int3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));

			if ( !oneWay ) startNode.AddConnection(connectedNode1, (uint)Mathf.RoundToInt (((Int3)(clamped1 - StartTransform.position)).costMagnitude*costFactor));
			endNode.AddConnection(connectedNode2, (uint)Mathf.RoundToInt (((Int3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));
			
		}
Пример #12
0
        // Interpolate between to skeleton animation poses and apply the result to
        // the specified MeshNode.
        private static void InterpolatePose(MeshNode meshNode, SkeletonPose pose0, SkeletonPose pose1, float w)
        {
            var skeletonPose = meshNode.SkeletonPose;

            SkeletonPoseTraits.Instance.Interpolate(ref pose0, ref pose1, w, ref skeletonPose);
        }
Пример #13
0
        public LookAtIKSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            var modelNode = ContentManager.Load <ModelNode>("Dude/Dude");

            _meshNode           = modelNode.GetSubtree().OfType <MeshNode>().First().Clone();
            _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
            SampleHelper.EnablePerPixelLighting(_meshNode);
            GraphicsScreen.Scene.Children.Add(_meshNode);

            var animations       = _meshNode.Mesh.Animations;
            var loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First())
            {
                LoopBehavior = LoopBehavior.Cycle,
                Duration     = TimeSpan.MaxValue,
            };

            AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose);

            // Create LookAtIKSolvers for some spine bones, the neck and the head.

            _spine1IK = new LookAtIKSolver
            {
                SkeletonPose = _meshNode.SkeletonPose,
                BoneIndex    = 3,

                // The bone space axis that points in look direction.
                Forward = Vector3F.UnitY,

                // The bone space axis that points in up direction
                Up = Vector3F.UnitX,

                // An arbitrary rotation limit.
                Limit = ConstantsF.PiOver4,

                // We use a weight of 1 for the head, and lower weights for all other bones. Thus, most
                // of the looking will be done by the head bone, and the influence on the other bones is
                // smaller.
                Weight = 0.2f,

                // It is important to set the EyeOffsets. If we do not set EyeOffsets, the IK solver
                // assumes that the eyes are positioned in the origin of the bone.
                // Approximate EyeOffsets are sufficient.
                EyeOffset = new Vector3F(0.8f, 0, 0),
            };

            _spine2IK = new LookAtIKSolver
            {
                SkeletonPose = _meshNode.SkeletonPose,
                BoneIndex    = 4,
                Forward      = Vector3F.UnitY,
                Up           = Vector3F.UnitX,
                Limit        = ConstantsF.PiOver4,
                Weight       = 0.2f,
                EyeOffset    = new Vector3F(0.64f, 0, 0),
            };

            _spine3IK = new LookAtIKSolver
            {
                SkeletonPose = _meshNode.SkeletonPose,
                BoneIndex    = 5,
                Forward      = Vector3F.UnitY,
                Up           = Vector3F.UnitX,
                Limit        = ConstantsF.PiOver4,
                Weight       = 0.3f,
                EyeOffset    = new Vector3F(0.48f, 0, 0),
            };

            _neckIK = new LookAtIKSolver
            {
                SkeletonPose = _meshNode.SkeletonPose,
                BoneIndex    = 6,
                Forward      = Vector3F.UnitY,
                Up           = Vector3F.UnitX,
                Limit        = ConstantsF.PiOver4,
                Weight       = 0.4f,
                EyeOffset    = new Vector3F(0.32f, 0, 0),
            };

            _headIK = new LookAtIKSolver
            {
                SkeletonPose = _meshNode.SkeletonPose,
                BoneIndex    = 7,
                Forward      = Vector3F.UnitY,
                Up           = Vector3F.UnitX,
                EyeOffset    = new Vector3F(0.16f, 0.16f, 0),
                Weight       = 1.0f,
                Limit        = ConstantsF.PiOver4,
            };
        }
Пример #14
0
		public override void OnGraphsPostUpdate () {
			//if (connectedNode1 != null && connectedNode2 != null) {
			if (!AstarPath.active.isScanning) {
				
				if (connectedNode1 != null && connectedNode1.Destroyed) {
					connectedNode1 = null;
				}
				if (connectedNode2 != null && connectedNode2.Destroyed) {
					connectedNode2 = null;
				}
				
				if (!postScanCalled) {
					OnPostScan();
				} else {
					//OnPostScan will also call this method
					/** \todo Can mess up pathfinding, wrap in delegate */
					Apply( false );
				}
			}
		}
Пример #15
0
        protected override void OnLoad()
        {
            var contentManager = _services.GetInstance <ContentManager>();
            var scene          = _services.GetInstance <IScene>();

            _debugRenderer = _services.GetInstance <DebugRenderer>();

            // Load materials (*.drmat files) which define the used shaders and material
            // properties (e.g. textures, colors, etc.).
            var bloodMaterial      = contentManager.Load <Material>("Decals/Blood");
            var crackMaterial      = contentManager.Load <Material>("Decals/Crack");
            var bulletHoleMaterial = contentManager.Load <Material>("Decals/BulletHole");

            // Decal materials (like materials of meshes) usually have several render passes
            // (such as "GBuffer", "Material"). Decal materials without a "Material" pass can
            // be used to render only normal maps without color changes:
            //crackMaterial.Remove("Material");

            // Add some DecalNodes, which define where a material is projected onto the scene.
            var bloodDecal0 = new DecalNode(bloodMaterial);

            bloodDecal0.NormalThreshold = MathHelper.ToRadians(75);
            bloodDecal0.LookAt(new Vector3F(0.7f, 0.6f, 0.7f), new Vector3F(0.7f, 0.6f, 0), new Vector3F(0.1f, 1, 0));
            bloodDecal0.Width   = 1.1f;
            bloodDecal0.Height  = 1.1f;
            bloodDecal0.Depth   = 1;
            bloodDecal0.Options = DecalOptions.ProjectOnStatic;
            scene.Children.Add(bloodDecal0);
            _decals.Add(bloodDecal0);

            var bloodDecal1 = new DecalNode(bloodMaterial);

            bloodDecal1.LookAt(new Vector3F(0.0f, 0.2f, 1.9f), new Vector3F(0.0f, 0, 1.9f), new Vector3F(1.0f, 0, -0.5f));
            bloodDecal1.Width  = 1.6f;
            bloodDecal1.Height = 1.6f;
            bloodDecal1.Depth  = 0.5f;
            scene.Children.Add(bloodDecal1);
            _decals.Add(bloodDecal1);

            var crackDecal0 = new DecalNode(crackMaterial);

            crackDecal0.NormalThreshold = MathHelper.ToRadians(75);
            crackDecal0.LookAt(new Vector3F(-0.7f, 0.7f, 0.7f), new Vector3F(-0.7f, 0.7f, 0), new Vector3F(0.1f, 1, 0));
            crackDecal0.Width   = 1.75f;
            crackDecal0.Height  = 1.75f;
            crackDecal0.Depth   = 0.6f;
            crackDecal0.Options = DecalOptions.ProjectOnStatic;
            scene.Children.Add(crackDecal0);
            _decals.Add(crackDecal0);

            var crackDecal1 = crackDecal0.Clone();
            var position    = new Vector3F(2.0f, 0.2f, 2.0f);

            crackDecal1.LookAt(position, position + new Vector3F(0, -1, 0), new Vector3F(-0.8f, 0, 1.0f));
            crackDecal1.Width  = 2.5f;
            crackDecal1.Height = 2.5f;
            crackDecal1.Depth  = 0.5f;
            scene.Children.Add(crackDecal1);
            _decals.Add(crackDecal1);

            var bulletHole0 = new DecalNode(bulletHoleMaterial);

            bulletHole0.NormalThreshold = MathHelper.ToRadians(90);
            bulletHole0.LookAt(new Vector3F(0.0f, 0.8f, 0.7f), new Vector3F(0.0f, 0.7f, 0), new Vector3F(0.1f, -1, 0));
            bulletHole0.Width     = 0.20f;
            bulletHole0.Height    = 0.20f;
            bulletHole0.Depth     = 1f;
            bulletHole0.DrawOrder = 10; // Draw over other decals.
            scene.Children.Add(bulletHole0);
            _decals.Add(bulletHole0);

            var bulletHole1 = bulletHole0.Clone();

            bulletHole1.LookAt(new Vector3F(-0.4f, 0.9f, 0.7f), new Vector3F(-0.4f, 0.9f, 0), new Vector3F(0.1f, 1, 0));
            scene.Children.Add(bulletHole1);
            _decals.Add(bulletHole1);

            var bulletHole2 = bulletHole0.Clone();

            bulletHole2.LookAt(new Vector3F(-0.2f, 0.8f, 0.7f), new Vector3F(-0.2f, 0.0f, 0), new Vector3F(0.1f, -1, 0));
            scene.Children.Add(bulletHole2);
            _decals.Add(bulletHole2);

            var bulletHole3 = bulletHole0.Clone();

            bulletHole3.LookAt(new Vector3F(3.0f, 1.0f, 2.0f), new Vector3F(3.0f, 1.0f, 1), new Vector3F(0.3f, 1, 0));
            scene.Children.Add(bulletHole3);
            _decals.Add(bulletHole3);

            var bulletHole4 = bulletHole0.Clone();

            bulletHole4.LookAt(new Vector3F(2.5f, 0.7f, 2.0f), new Vector3F(3.0f, 0.7f, 1.0f), new Vector3F(-0.1f, -1, 0));
            scene.Children.Add(bulletHole4);
            _decals.Add(bulletHole4);

            var bulletHole5 = bulletHole0.Clone();

            bulletHole5.LookAt(new Vector3F(2.7f, 1.2f, 2.0f), new Vector3F(3.0f, 1.2f, 1.0f), new Vector3F(-0.5f, -1, 0));
            scene.Children.Add(bulletHole5);
            _decals.Add(bulletHole5);

            var bulletHole6 = bulletHole0.Clone();

            bulletHole6.LookAt(new Vector3F(3.2f, 0.4f, 2.0f), new Vector3F(3.0f, 0.4f, 1), new Vector3F(-0.3f, -0.5f, 0));
            scene.Children.Add(bulletHole6);
            _decals.Add(bulletHole6);

            // Get the first dynamic mesh (the rusty cube) and add a decal as a child.
            MeshNode meshNode    = ((Scene)scene).GetSubtree().OfType <MeshNode>().First(n => !n.IsStatic);
            var      bulletHole7 = bulletHole0.Clone();

            bulletHole7.LookAt(new Vector3F(0, 0, -0.6f), new Vector3F(0, 0, 0), new Vector3F(0, 1, 0));
            bulletHole7.Depth = 0.2f;
            meshNode.Children = new SceneNodeCollection {
                bulletHole7
            };
            _decals.Add(bulletHole7);
        }
Пример #16
0
 public MeshTri(MeshNode a, MeshNode b, MeshNode c)
 {
     this.a = a;
     this.b = b;
     this.c = c;
 }
Пример #17
0
        /// <summary>
        /// Computes the intersection of <see cref="MeshNode"/>s.
        /// </summary>
        /// <param name="meshNodePairs">
        /// A collection of <see cref="MeshNode"/> pairs.The renderer computes the intersection volume
        /// of each pair.
        /// </param>
        /// <param name="color">The diffuse color used for the intersection.</param>
        /// <param name="alpha">The opacity of the intersection.</param>
        /// <param name="maxConvexity">
        /// The maximum convexity of the submeshes. A convex mesh has a convexity of 1. A concave mesh
        /// has a convexity greater than 1. Convexity is the number of layers required for depth peeling
        /// (= the number of front face layers when looking at the object).
        /// </param>
        /// <param name="context">The render context.</param>
        /// <remarks>
        /// <para>
        /// This method renders an off-screen image (color and depth) of the intersection volume. This
        /// operation destroys the currently set render target and depth/stencil buffer.
        /// </para>
        /// </remarks>
        /// <exception cref="ObjectDisposedException">
        /// The <see cref="IntersectionRenderer"/> has already been disposed.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="meshNodePairs"/> or <see cref="context"/> is
        /// <see langword="null"/>.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// The convexity must be greater than 0.
        /// </exception>
        /// <exception cref="GraphicsException">
        /// Invalid render context: Graphics service is not set.
        /// </exception>
        /// <exception cref="GraphicsException">
        /// Invalid render context: Wrong graphics device.
        /// </exception>
        /// <exception cref="GraphicsException">
        /// Invalid render context: Scene is not set.
        /// </exception>
        /// <exception cref="GraphicsException">
        /// Invalid render context: Camera node needs to be set in render context.
        /// </exception>
        public void ComputeIntersection(IEnumerable <Pair <MeshNode> > meshNodePairs,
                                        Vector3 color, float alpha, float maxConvexity, RenderContext context)
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException("IntersectionRenderer has already been disposed.");
            }
            if (meshNodePairs == null)
            {
                throw new ArgumentNullException("meshNodePairs");
            }
            if (maxConvexity < 1)
            {
                throw new ArgumentOutOfRangeException("maxConvexity", "The max convexity must be greater than 0.");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (context.GraphicsService == null)
            {
                throw new GraphicsException("Invalid render context: Graphics service is not set.");
            }
            if (_graphicsService != context.GraphicsService)
            {
                throw new GraphicsException("Invalid render context: Wrong graphics service.");
            }
            if (context.CameraNode == null)
            {
                throw new GraphicsException("Camera node needs to be set in render context.");
            }
            if (context.Scene == null)
            {
                throw new GraphicsException("A scene needs to be set in the render context.");
            }

            // Create 2 ordered pairs for each unordered pair.
            _pairs.Clear();
            foreach (var pair in meshNodePairs)
            {
                if (pair.First == null || pair.Second == null)
                {
                    continue;
                }

                // Frustum culling.
                if (!context.Scene.HaveContact(pair.First, context.CameraNode))
                {
                    continue;
                }
                if (!context.Scene.HaveContact(pair.Second, context.CameraNode))
                {
                    continue;
                }

                _pairs.Add(new Pair <MeshNode, MeshNode>(pair.First, pair.Second));
                _pairs.Add(new Pair <MeshNode, MeshNode>(pair.Second, pair.First));
            }

            var renderTargetPool = _graphicsService.RenderTargetPool;

            if (_pairs.Count == 0)
            {
                renderTargetPool.Recycle(_intersectionImage);
                _intersectionImage = null;
                return;
            }

            // Color and alpha are applied in RenderIntersection().
            _color = color;
            _alpha = alpha;

            var graphicsDevice = _graphicsService.GraphicsDevice;

            // Save original render states.
            var originalBlendState        = graphicsDevice.BlendState;
            var originalDepthStencilState = graphicsDevice.DepthStencilState;
            var originalRasterizerState   = graphicsDevice.RasterizerState;
            var originalScissorRectangle  = graphicsDevice.ScissorRectangle;

            // Get offscreen render targets.
            var viewport = context.Viewport;

            viewport.X      = 0;
            viewport.Y      = 0;
            viewport.Width  = (int)(viewport.Width / DownsampleFactor);
            viewport.Height = (int)(viewport.Height / DownsampleFactor);
            var renderTargetFormat = new RenderTargetFormat(viewport.Width, viewport.Height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);

            // Try to reuse any existing render targets.
            // (Usually they are recycled in RenderIntersection()).
            var currentScene = _intersectionImage;

            if (currentScene == null || !renderTargetFormat.IsCompatibleWith(currentScene))
            {
                currentScene.SafeDispose();
                currentScene = renderTargetPool.Obtain2D(renderTargetFormat);
            }
            var lastScene = renderTargetPool.Obtain2D(renderTargetFormat);

            // Set shared effect parameters.
            var cameraNode = context.CameraNode;
            var view       = (Matrix)cameraNode.View;
            var projection = cameraNode.Camera.Projection;
            var near       = projection.Near;
            var far        = projection.Far;

            _parameterViewportSize.SetValue(new Vector2(viewport.Width, viewport.Height));

            // The DepthEpsilon has to be tuned if depth peeling does not work because
            // of numerical problems equality z comparisons.
            _parameterCameraParameters.SetValue(new Vector3(near, far - near, 0.0000001f));
            _parameterView.SetValue(view);
            _parameterProjection.SetValue((Matrix)projection);

            var defaultTexture = _graphicsService.GetDefaultTexture2DBlack();

            // Handle all pairs.
            bool isFirstPass = true;

            while (true)
            {
                // Find a mesh node A and all mesh nodes to which it needs to be clipped.
                MeshNode meshNodeA = null;
                _partners.Clear();
                for (int i = 0; i < _pairs.Count; i++)
                {
                    var pair = _pairs[i];

                    if (pair.First == null)
                    {
                        continue;
                    }

                    if (meshNodeA == null)
                    {
                        meshNodeA = pair.First;
                    }

                    if (pair.First == meshNodeA)
                    {
                        _partners.Add(pair.Second);

                        //  Remove this pair.
                        _pairs[i] = new Pair <MeshNode, MeshNode>();
                    }
                }

                // Abort if we have handled all pairs.
                if (meshNodeA == null)
                {
                    break;
                }

                var worldTransformA = (Matrix)(meshNodeA.PoseWorld * Matrix.CreateScale(meshNodeA.ScaleWorld));

                if (EnableScissorTest)
                {
                    // Scissor rectangle of A.
                    var scissorA = GraphicsHelper.GetScissorRectangle(context.CameraNode, viewport, meshNodeA);

                    // Union of scissor rectangles of partners.
                    Rectangle partnerRectangle = GraphicsHelper.GetScissorRectangle(context.CameraNode, viewport, _partners[0]);
                    for (int i = 1; i < _partners.Count; i++)
                    {
                        var a = GraphicsHelper.GetScissorRectangle(context.CameraNode, viewport, _partners[i]);
                        partnerRectangle = Rectangle.Union(partnerRectangle, a);
                    }

                    // Use intersection of A and partners.
                    graphicsDevice.ScissorRectangle = Rectangle.Intersect(scissorA, partnerRectangle);

                    // We store the union of all scissor rectangles for use in RenderIntersection().
                    if (isFirstPass)
                    {
                        _totalScissorRectangle = graphicsDevice.ScissorRectangle;
                    }
                    else
                    {
                        _totalScissorRectangle = Rectangle.Union(_totalScissorRectangle, graphicsDevice.ScissorRectangle);
                    }
                }

                // Depth peeling of A.
                for (int layer = 0; layer < maxConvexity; layer++)
                {
                    // Set and clear render target.
                    graphicsDevice.SetRenderTarget(currentScene);
                    graphicsDevice.Clear(new Color(1, 1, 1, 0)); // RGB = "a large depth", A = "empty area"

                    // Render a depth layer of A.
                    graphicsDevice.DepthStencilState = DepthStencilStateWriteLess;
                    graphicsDevice.BlendState        = BlendState.Opaque;
                    graphicsDevice.RasterizerState   = EnableScissorTest ? CullCounterClockwiseScissor : RasterizerState.CullCounterClockwise;
                    _parameterWorld.SetValue(worldTransformA);
                    _parameterTexture.SetValue((layer == 0) ? defaultTexture : lastScene);
                    _passPeel.Apply();
                    foreach (var submesh in meshNodeA.Mesh.Submeshes)
                    {
                        submesh.Draw();
                    }

                    // Render partners to set stencil.
                    graphicsDevice.DepthStencilState = DepthStencilStateOnePassStencilFail;
                    graphicsDevice.BlendState        = BlendStateNoWrite;
                    graphicsDevice.RasterizerState   = EnableScissorTest ? CullNoneScissor : RasterizerState.CullNone;
                    foreach (var partner in _partners)
                    {
                        _parameterWorld.SetValue((Matrix)(partner.PoseWorld * Matrix.CreateScale(partner.ScaleWorld)));
                        _passMark.Apply();
                        foreach (var submesh in partner.Mesh.Submeshes)
                        {
                            submesh.Draw();
                        }
                    }

                    // Clear depth buffer. Leave stencil buffer unchanged.
                    graphicsDevice.Clear(ClearOptions.DepthBuffer, new Color(0, 1, 0), 1, 0);

                    // Render A to compute lighting.
                    graphicsDevice.DepthStencilState = DepthStencilStateStencilNotEqual0;
                    graphicsDevice.BlendState        = BlendState.Opaque;
                    graphicsDevice.RasterizerState   = EnableScissorTest ? CullCounterClockwiseScissor :  RasterizerState.CullCounterClockwise;
                    _parameterWorld.SetValue(worldTransformA);
                    _passDraw.Apply();
                    foreach (var submesh in meshNodeA.Mesh.Submeshes)
                    {
                        submesh.Draw();
                    }

                    // Combine last intersection image with current.
                    if (!isFirstPass)
                    {
                        graphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
                        graphicsDevice.BlendState        = BlendState.Opaque;
                        graphicsDevice.RasterizerState   = EnableScissorTest ? CullNoneScissor : RasterizerState.CullNone;
                        _parameterTexture.SetValue(lastScene);
                        _passCombine.Apply();
                        graphicsDevice.DrawFullScreenQuad();
                    }

                    isFirstPass = false;

                    // ----- Swap render targets.
                    MathHelper.Swap(ref lastScene, ref currentScene);
                }
            }

            // Store final images for RenderIntersection.
            _intersectionImage = lastScene;

            // Scale scissor rectangle back to full-screen resolution.
            if (DownsampleFactor > 1)
            {
                _totalScissorRectangle.X      = (int)(_totalScissorRectangle.X * DownsampleFactor);
                _totalScissorRectangle.Y      = (int)(_totalScissorRectangle.Y * DownsampleFactor);
                _totalScissorRectangle.Width  = (int)(_totalScissorRectangle.Width * DownsampleFactor);
                _totalScissorRectangle.Height = (int)(_totalScissorRectangle.Height * DownsampleFactor);
            }


            // Restore original render state.
            graphicsDevice.BlendState        = originalBlendState ?? BlendState.Opaque;
            graphicsDevice.DepthStencilState = originalDepthStencilState ?? DepthStencilState.Default;
            graphicsDevice.RasterizerState   = originalRasterizerState ?? RasterizerState.CullCounterClockwise;
            graphicsDevice.ScissorRectangle  = originalScissorRectangle;

            renderTargetPool.Recycle(currentScene);
            _partners.Clear();
            _pairs.Clear();
        }
Пример #18
0
        public ActiveRagdollSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            GraphicsScreen.DrawReticle = true;

            // Add game objects which allow to shoot balls and grab rigid bodies.
            _ballShooterObject = new BallShooterObject(Services)
            {
                Speed = 10
            };
            GameObjectService.Objects.Add(_ballShooterObject);
            _grabObject = new GrabObject(Services);
            GameObjectService.Objects.Add(_grabObject);

            var modelNode = ContentManager.Load <ModelNode>("Dude/Dude");

            _meshNode           = modelNode.GetSubtree().OfType <MeshNode>().First().Clone();
            _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0));
            SampleHelper.EnablePerPixelLighting(_meshNode);
            GraphicsScreen.Scene.Children.Add(_meshNode);

            // Create a copy of the dude's skeleton.
            _targetSkeletonPose = SkeletonPose.Create(_meshNode.Mesh.Skeleton);

            // Animate the _targetSkeletonPose.
            var animations       = _meshNode.Mesh.Animations;
            var loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First())
            {
                LoopBehavior = LoopBehavior.Cycle,
                Duration     = TimeSpan.MaxValue,
            };

            AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_targetSkeletonPose);

            // Create a ragdoll for the Dude model.
            _ragdoll = new Ragdoll();
            DudeRagdollCreator.Create(_targetSkeletonPose, _ragdoll, Simulation, 0.571f);

            // Set the world space pose of the whole ragdoll. And copy the bone poses of the
            // current skeleton pose.
            _ragdoll.Pose = _meshNode.PoseWorld;
            _ragdoll.UpdateBodiesFromSkeleton(_targetSkeletonPose);

            // In this sample we use an active ragdoll. We need joints because constraint ragdoll
            // motors only affect the body rotations.
            _ragdoll.EnableJoints();

            // We disable limits. If limits are enabled, the ragdoll could get unstable if
            // the animation tries to move a limb beyond an allowed limit. (This happens if
            // a pose in the animation violates one of our limits.)
            _ragdoll.DisableLimits();

            // Set all motors to constraint motors. Constraint motors are like springs that
            // rotate the limbs to a target position.
            foreach (RagdollMotor motor in _ragdoll.Motors)
            {
                if (motor != null)
                {
                    motor.Mode = RagdollMotorMode.Constraint;
                    motor.ConstraintDamping = 10000;
                    motor.ConstraintSpring  = 100000;
                }
            }
            _ragdoll.EnableMotors();

            // Add rigid bodies and the constraints of the ragdoll to the simulation.
            _ragdoll.AddToSimulation(Simulation);

            // Add a rigid body.
            var box = new RigidBody(new BoxShape(0.4f, 0.4f, 0.4f))
            {
                Name = "Box",
                Pose = new Pose(new Vector3F(0, 3, 0)),
            };

            Simulation.RigidBodies.Add(box);
        }
Пример #19
0
        public PassiveRagdollSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            GraphicsScreen.DrawReticle = true;

            // Add game objects which allow to shoot balls and grab rigid bodies.
            _ballShooterObject = new BallShooterObject(Services)
            {
                Speed = 10
            };
            GameObjectService.Objects.Add(_ballShooterObject);
            _grabObject = new GrabObject(Services);
            GameObjectService.Objects.Add(_grabObject);

            var modelNode = ContentManager.Load <ModelNode>("Dude/Dude");

            _meshNode           = modelNode.GetSubtree().OfType <MeshNode>().First().Clone();
            _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0));
            SampleHelper.EnablePerPixelLighting(_meshNode);
            GraphicsScreen.Scene.Children.Add(_meshNode);

            // Create a ragdoll for the Dude model.
            _ragdoll = new Ragdoll();
            DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f);

            // Set the world space pose of the whole ragdoll. And copy the bone poses of the
            // current skeleton pose.
            _ragdoll.Pose = _meshNode.PoseWorld;
            _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose);

            // Uncomment to disable dynamic movement (for debugging during ragdoll creation):
            //foreach (var body in _ragdoll.Bodies)
            //  if (body != null)
            //    body.MotionType = MotionType.Kinematic;

            // In this sample we use a passive ragdoll where we need joints to hold the
            // limbs together and limits to restrict angular movement.
            _ragdoll.EnableJoints();
            _ragdoll.EnableLimits();

            // Set all motors to constraint motors that only use damping. This adds a damping
            // effect to all ragdoll limbs.
            foreach (RagdollMotor motor in _ragdoll.Motors)
            {
                if (motor != null)
                {
                    motor.Mode = RagdollMotorMode.Constraint;
                    motor.ConstraintDamping = 5;
                    motor.ConstraintSpring  = 0;
                }
            }
            _ragdoll.EnableMotors();

            // Add rigid bodies and the constraints of the ragdoll to the simulation.
            _ragdoll.AddToSimulation(Simulation);

            // Add a rigid body.
            var box = new RigidBody(new BoxShape(0.4f, 0.4f, 0.4f))
            {
                Name = "Box",
                Pose = new Pose(new Vector3F(0, 3, 0)),
            };

            Simulation.RigidBodies.Add(box);
        }
Пример #20
0
    public MeshNode ConstructMeshTree()
    {
        // Create the grid
        CreateGrid();

        // Do the hierarchical clustering on the grid
        Dictionary <Vector3, MeshNode> slotClusterAssign = new Dictionary <Vector3, MeshNode>();
        int maxClusterSize = 1;

        // Assign the slotClusterAssign
        foreach (Vector3 key in slots.Keys)
        {
            slotClusterAssign.Add(key, new MeshNode(slots[key].GetMesh(), key, slots[key].GetOffset()));
        }

        // Processing queue
        Queue <List <Vector3> > clusters = new Queue <List <Vector3> >();

        // Add initial clusters to the queue
        System.Random  rand        = new System.Random();
        List <Vector3> randomOrder = new List <Vector3>(slotClusterAssign.Keys);

        randomOrder.Sort((x, y) => rand.Next(100000));
        foreach (Vector3 key in randomOrder)
        {
            List <Vector3> cluster = new List <Vector3>();
            cluster.Add(key);
            clusters.Enqueue(cluster);
        }

        while (maxClusterSize != slots.Count && clusters.Count != 0)
        {
            // Get the processing position
            foreach (Vector3 procPos in clusters.Dequeue())
            {
                // Get the node behind the key
                MeshNode procNode = slotClusterAssign[procPos];

                // Get all the positions inside the cluster (this nodes cluster)
                HashSet <Vector3> selfClusterPositions = new HashSet <Vector3>(procNode.GetPositions());

                // Find the neighboring cluster with the lowest size
                int     minClusterSize = 1000;
                Vector3 minClusterKey  = new Vector3(10000f, 10000f, 10000f);
                foreach (Vector3 n in basisvectors)
                {
                    // Get a neighbor key
                    Vector3 candidate = procPos + n;;

                    // Check if the candidate exists
                    if (!slots.ContainsKey(candidate))
                    {
                        continue;
                    }

                    // Check if the candidate is in the same cluster as current node
                    if (selfClusterPositions.Contains(candidate))
                    {
                        continue;
                    }

                    // Check the size of the cluster
                    MeshNode neigh = slotClusterAssign[candidate];
                    if (neigh.GetSize() < minClusterSize)
                    {
                        minClusterSize = neigh.GetSize();
                        minClusterKey  = candidate;
                    }
                }

                // No eligable neighbours
                if (minClusterSize == 1000)
                {
                    continue;
                }

                // Now we know the cluster we want to pair with
                // Get the node of the cluster
                MeshNode clusterNode = slotClusterAssign[minClusterKey];

                // Create a new cluster where the children are the current cluster and the neighbor cluster
                MeshNode newNode = new MeshNode(clusterNode.GetMesh(), procNode.GetMesh());
                newNode.AddChild(clusterNode);
                newNode.AddChild(procNode);

                // Get all the positions in the new cluster
                List <Vector3> clusterPositions = newNode.GetPositions();

                // Update the cluster assignment
                foreach (Vector3 position in clusterPositions)
                {
                    slotClusterAssign[position] = newNode;
                }

                // Add the cluster positions to the processing queue
                clusters.Enqueue(clusterPositions);


                // Get the cluster size
                if (newNode.GetSize() > maxClusterSize)
                {
                    maxClusterSize = newNode.GetSize();

                    // Early exit if task is already finished
                    if (maxClusterSize == slots.Count)
                    {
                        break;
                    }
                }
            }
        }

        // Return the topmost cluster
        return(slotClusterAssign[new Vector3(0f, 0f, 0f)]);
    }
Пример #21
0
        public frmNetworkInfo(MeshNode node)
        {
            InitializeComponent();

            _node = node;
        }
Пример #22
0
        public FacialAnimationSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            _graphicsScreen = new DeferredGraphicsScreen(Services)
            {
                DrawReticle = false
            };
            GraphicsService.Screens.Insert(0, _graphicsScreen);
            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

            // Add a game object which adds some GUI controls for the deferred graphics
            // screen to the Options window.
            GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

            // Use a fixed camera.
            var projection = new PerspectiveProjection();

            projection.SetFieldOfView(
                ConstantsF.PiOver4,
                GraphicsService.GraphicsDevice.Viewport.AspectRatio,
                0.1f,
                10);
            var cameraNode = new CameraNode(new Camera(projection));

            cameraNode.LookAt(new Vector3(0.15f, 0.15f, 0.5f), new Vector3(0.1f, 0.15f, 0), Vector3.Up);
            _graphicsScreen.Scene.Children.Add(cameraNode);
            _graphicsScreen.ActiveCameraNode = cameraNode;

            // Lighting setup:
            var keyLight = new LightNode(new Spotlight {
                DiffuseIntensity = 0.6f, SpecularIntensity = 0.4f
            });

            keyLight.LookAt(new Vector3(-2, 2, 2), new Vector3(), Vector3.Up);
            _graphicsScreen.Scene.Children.Add(keyLight);

            var backLight = new LightNode(new Spotlight {
                DiffuseIntensity = 0.3f, SpecularIntensity = 0.3f
            });

            backLight.LookAt(new Vector3(1, 0.5f, -2), new Vector3(), Vector3.Up);
            _graphicsScreen.Scene.Children.Add(backLight);

            var fillLight = new LightNode(new AmbientLight {
                HemisphericAttenuation = 1, Intensity = 0.1f
            });

            _graphicsScreen.Scene.Children.Add(fillLight);

            // The scene does not have a proper background. That's why the exposure is a
            // bit off. --> Reduce the max exposure.
            var hdrFilter = _graphicsScreen.PostProcessors.OfType <HdrFilter>().First();

            hdrFilter.MaxExposure = 6;

            // Load the customized "Sintel" model (original: Durian Open Movie Project - http://www.sintel.org/).
            var model = ContentManager.Load <ModelNode>("Sintel/Sintel-Head").Clone();

            model.PoseWorld = new Pose(new Vector3(0, 0, 0), Matrix.CreateRotationY(MathHelper.ToRadians(10)) * Matrix.CreateRotationX(-MathHelper.ToRadians(90)));
            _graphicsScreen.Scene.Children.Add(model);

            // The model consists of a root node and a mesh node.
            //  ModelNode "Sintel-Head"
            //    MeshNode "Sintel"
            _sintel = (MeshNode)model.Children[0];

            // The model contains two skeletal animations:
            // - "MOUTH-open" is just a single frame.
            // - "Test" is a short animation (250 frames).

            // In the Options window, we will add a slider to move the jaw.
            // Slider.Value = 0 ... mouth closed (default)
            _mouthClosedPose = SkeletonPose.Create(_sintel.Mesh.Skeleton);
            // Slider.Value = 1 ... mouth open (copied from the "MOUTH-open" animation)
            SkeletonKeyFrameAnimation mouthOpen = _sintel.Mesh.Animations["MOUTH-open"];

            _mouthOpenPose = SkeletonPose.Create(_sintel.Mesh.Skeleton);
            mouthOpen.GetValue(TimeSpan.Zero, ref _mouthOpenPose, ref _mouthOpenPose, ref _mouthOpenPose);

            // Turn the "Test" animation into an endless loop.
            _skeletalAnimation = new AnimationClip <SkeletonPose>(_sintel.Mesh.Animations["Test"])
            {
                Duration     = TimeSpan.MaxValue,
                LoopBehavior = LoopBehavior.Cycle
            };

            // Mesh has several morph targets for facial animation, which are imported
            // automatically via the content pipeline. Unfortunately, the XNA content
            // pipeline cannot import morph target animations automatically.
            // In this demo, we will create a morph target animation in code.
            _morphingAnimation = CreateMorphingAnimation();

            CreateGuiControls();
        }
Пример #23
0
    /** Exports the INavmesh graph to a file */
    public void ExportToFile(NavGraph target)
    {
        INavmesh graph = (INavmesh)target;

        if (graph == null)
        {
            return;
        }

        Int3[] vertices = graph.vertices;

        if (vertices == null || target.nodes == null)
        {
            if (EditorUtility.DisplayDialog("Scan graph before exporting?", "The graph does not contain any mesh data. Do you want to scan it?", "Ok", "Cancel"))
            {
                AstarPath.MenuScan();
            }
            else
            {
                return;
            }
        }

        vertices = graph.vertices;

        if (vertices == null || target.nodes == null)
        {
            Debug.LogError("Graph still does not contain any nodes or vertices. Canceling");
            return;
        }

        string path = EditorUtility.SaveFilePanel("Export .obj", "", "navmesh.obj", "obj");

        if (path == "")
        {
            return;
        }

        //Generate .obj
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        string name = System.IO.Path.GetFileNameWithoutExtension(path);

        sb.Append("g ").Append(name).AppendLine();

        //Write vertices
        for (int i = 0; i < vertices.Length; i++)
        {
            Vector3 v = (Vector3)vertices[i];
            sb.Append(string.Format("v {0} {1} {2}\n", -v.x, v.y, v.z));
        }

        //Define single texture coordinate to zero
        sb.Append("vt 0\n");

        //Write triangles
        for (int i = 0; i < target.nodes.Length; i++)
        {
            MeshNode node = target.nodes[i] as MeshNode;
            if (node == null)
            {
                Debug.LogError("Node could not be casted to MeshNode. Node was null or no MeshNode");
                return;
            }
            sb.Append(string.Format("f {0}/0 {1}/0 {2}/0\n", node.v1 + 1, node.v2 + 1, node.v3 + 1));
        }

        string obj = sb.ToString();

        using (System.IO.StreamWriter sw = new System.IO.StreamWriter(path))
        {
            sw.Write(obj);
        }
    }
Пример #24
0
		public void InternalOnPostScan () {

			if ( EndTransform == null || StartTransform == null ) return;

#if !ASTAR_NO_POINT_GRAPH
			if ( AstarPath.active.astarData.pointGraph == null ) {
				AstarPath.active.astarData.AddGraph ( new PointGraph () );
			}
#endif


			if ( startNode != null) {
				NodeLink2 tmp;
				if (reference.TryGetValue (startNode, out tmp) && tmp == this) reference.Remove (startNode);
			}
	
			if ( endNode != null) {
				NodeLink2 tmp;
				if (reference.TryGetValue (endNode, out tmp) && tmp == this) reference.Remove (endNode);
			}
	
#if !ASTAR_NO_POINT_GRAPH	
			//Get nearest nodes from the first point graph, assuming both start and end transforms are nodes
			startNode = AstarPath.active.astarData.pointGraph.AddNode ( (Int3)StartTransform.position );//AstarPath.active.astarData.pointGraph.GetNearest(StartTransform.position).node as PointNode;
			endNode = AstarPath.active.astarData.pointGraph.AddNode ( (Int3)EndTransform.position ); //AstarPath.active.astarData.pointGraph.GetNearest(EndTransform.position).node as PointNode;
#else
			throw new System.Exception ("Point graph is not included. Check your A* optimization settings.");
#endif

			connectedNode1 = null;
			connectedNode2 = null;
			
			if (startNode == null || endNode == null) {
				startNode = null;
				endNode = null;
				return;
			}
			
			postScanCalled = true;
			reference[startNode] = this;
			reference[endNode] = this;
			Apply( true );
		}
Пример #25
0
        public ParallaxMappingSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            _graphicsScreen             = new DeferredGraphicsScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);
            GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

            // Add gravity and damping to the physics Simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services);

            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
            GameObjectService.Objects.Add(new DynamicSkyObject(Services, false, false, true));
            GameObjectService.Objects.Add(new DynamicObject(Services, 1));
            GameObjectService.Objects.Add(new DynamicObject(Services, 1));
            GameObjectService.Objects.Add(new DynamicObject(Services, 1));
            GameObjectService.Objects.Add(new DynamicObject(Services, 2));
            GameObjectService.Objects.Add(new DynamicObject(Services, 2));
            GameObjectService.Objects.Add(new DynamicObject(Services, 2));

            // Add a few palm trees.
            Random random = new Random(12345);

            for (int i = 0; i < 10; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-3, -8), 0, random.NextFloat(0, -5));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                float     scale       = random.NextFloat(0.5f, 1.2f);
                GameObjectService.Objects.Add(new StaticObject(Services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
            }

            // Load ground model which uses normal mapping.
            var modelNode = ContentManager.Load <ModelNode>("Parallax/Ground");

            _meshNode            = modelNode.Children.OfType <MeshNode>().First().Clone();
            _meshNode.ScaleLocal = new Vector3F(0.1f);
            _meshNode.IsStatic   = true;

            Debug.Assert(_meshNode.Mesh.Materials.Count == 1, "Mesh should have only one material.");

            // Load materials with normal mapping, parallax mapping and parallax occlusion mapping.
            _normalMaterial                   = ContentManager.Load <Material>("Parallax/Normal").Clone();
            _parallaxMappingMaterial          = ContentManager.Load <Material>("Parallax/PM").Clone();
            _parallaxOcclusionMappingMaterial = ContentManager.Load <Material>("Parallax/POM").Clone();

            // Get default values from materials.
            var parameterBindings = _parallaxOcclusionMappingMaterial["Material"].ParameterBindings;

            _heightScale    = ((ConstParameterBinding <float>)parameterBindings["HeightScale"]).Value;
            _heightBias     = ((ConstParameterBinding <float>)parameterBindings["HeightBias"]).Value;
            _lodThreshold   = ((ConstParameterBinding <int>)parameterBindings["LodThreshold"]).Value;
            _maxSamples     = ((ConstParameterBinding <int>)parameterBindings["MaxSamples"]).Value;
            _shadowStrength = ((ConstParameterBinding <float>)parameterBindings["ShadowStrength"]).Value;

            // Start test with POM material.
            _currentMaterialIndex = 2;
            UpdateMesh();

            // Add nodes to scene graph.
            _graphicsScreen.Scene.Children.Add(_meshNode);

            // Create rigid body for ground plane.
            Simulation.RigidBodies.Add(new RigidBody(new PlaneShape(Vector3F.UnitY, 0))
            {
                MotionType = MotionType.Static,
            });
        }
Пример #26
0
    public static Vector3 GetNextTarget(Path path, Vector3 currPosition, float offset, float pickNextWaypointMargin)
    {
        if (path.error)
        {
            return currPosition;
        }

        Int3 currentPosition = (Int3)currPosition;

        int startIndex = 0;
        int endIndex = path.path.Length;

        //Int3 pos = (Int3)currentPosition;

        //int minDist = -1;
        //int minNode = -1;

        INavmesh navmeshGraph = AstarData.GetGraph(path.path[0]) as INavmesh;

        if (navmeshGraph == null)
        {
            Debug.LogError("Couldn't cast graph to the appropriate type (graph isn't a Navmesh type graph, it doesn't implement the INavmesh interface)");
            return currPosition;///Apply (path,start,end, startIndex, endIndex, graph);
        }

        Int3[] vertices = navmeshGraph.vertices;

        //float minDist2 = -1;
        //int minNode2 = -1;

        //Debug.Log (meshPath.Length + " "+path.Length +" "+startIndex+" "+endIndex);
        /*for (int i=startIndex;i< endIndex;i++) {
            MeshNode node = path.path[i] as MeshNode;

            if (node == null) {
                Debug.LogWarning ("Path could not be casted to Mesh Nodes");
                return currentPosition;//return base.Apply (path,start,end, startIndex, endIndex, graph);
            }

            //if (Polygon.TriangleArea2 (vertices[node.v1],vertices[node.v2],currentPosition) >= 0 || Polygon.TriangleArea2 (vertices[node.v2],vertices[node.v3],currentPosition) >= 0 || Polygon.TriangleArea2 (vertices[node.v3],vertices[node.v1],currentPosition) >= 0) {

            if (!Polygon.IsClockwise (vertices[node.v1],vertices[node.v2],pos) || !Polygon.IsClockwise (vertices[node.v2],vertices[node.v3],pos) || !Polygon.IsClockwise (vertices[node.v3],vertices[node.v1],pos)) {

                if (minDist == -1) {
                    float dist2 = (node.position-pos).sqrMagnitude;
                    if (minDist2 == -1 || dist2 < minDist2) {
                        minDist2 = dist2;
                        minNode2 = i;
                    }
                }
                continue;
            }

            Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.blue);
            Debug.DrawLine (vertices[node.v2],vertices[node.v3],Color.blue);
            Debug.DrawLine (vertices[node.v3],vertices[node.v1],Color.blue);

            int dist = node.position.y-pos.y;

            if (minDist == -1 || dist < minDist) {
                minDist = dist;
                minNode = i;
            }

        }*/

        MeshNode lastNode = path.path[endIndex - 1] as MeshNode;
        if (lastNode == null)
        {
            Debug.LogWarning("Path could not be casted to Mesh Nodes");
            return currentPosition;//return base.Apply (path,start,end, startIndex, endIndex, graph);
        }

        PathNNConstraint constraint = PathNNConstraint.Default;
        constraint.SetStart(lastNode);
        NNInfo nninfo = NavMeshGraph.GetNearestForce(path.path, vertices, currPosition, constraint);

        currentPosition = nninfo.clampedPosition;
        /*for (int i=startIndex;i< endIndex;i++) {
            if (nninfo.node == path.path[i]) {
                minNode = i;
            }
        }*/

        //Node minNode = nninfo.node;

        /*startIndex = minNode;
        if (startIndex == -1) {
            startIndex = minNode2;
            currentPosition = path.path[minNode2].position;
        }
        if (startIndex == -1) {
            Debug.Log ("Couldn't find current node");
            return currentPosition;
        }*/

        MeshNode[] meshPath = new MeshNode[endIndex - startIndex];

        for (int i = startIndex; i < endIndex; i++)
        {
            meshPath[i - startIndex] = path.path[i] as MeshNode;
        }
        //return Vector3.zero;

        //Vector3[] vertices = null;

        if (leftFunnel == null || leftFunnel.Length < meshPath.Length + 1)
        {
            leftFunnel = new Int3[meshPath.Length + 1];
        }
        if (rightFunnel == null || rightFunnel.Length < meshPath.Length + 1)
        {
            rightFunnel = new Int3[meshPath.Length + 1];
        }
        int leftFunnelLength = meshPath.Length + 1;
        //int rightFunnelLength = meshPath.Length+1;

        leftFunnel[0] = currentPosition;
        rightFunnel[0] = currentPosition;

        leftFunnel[meshPath.Length] = path.endPoint;
        rightFunnel[meshPath.Length] = path.endPoint;

        int lastLeftIndex = -1;
        int lastRightIndex = -1;

        for (int i = 0; i < meshPath.Length - 1; i++)
        {
            //Find the connection between the nodes

            MeshNode n1 = meshPath[i];
            MeshNode n2 = meshPath[i + 1];

            bool foundFirst = false;

            int first = -1;
            int second = -1;

            for (int x = 0; x < 3; x++)
            {
                //Vector3 vertice1 = vertices[n1.vertices[x]];
                //n1[x] gets the vertice index for vertex number 'x' in the node. Equal to n1.GetVertexIndex (x)
                int vertice1 = n1[x];
                for (int y = 0; y < 3; y++)
                {
                    //Vector3 vertice2 = vertices[n2.vertices[y]];
                    int vertice2 = n2[y];

                    if (vertice1 == vertice2)
                    {
                        if (foundFirst)
                        {
                            second = vertice2;
                            break;
                        }
                        else
                        {
                            first = vertice2;
                            foundFirst = true;
                        }
                    }
                }
            }

            //Debug.DrawLine ((Vector3)vertices[first]+Vector3.up*0.1F,(Vector3)vertices[second]+Vector3.up*0.1F,Color.cyan);
            //Debug.Log (first+" "+second);
            if (first == lastLeftIndex)
            {
                leftFunnel[i + 1] = vertices[first];
                rightFunnel[i + 1] = vertices[second];
                lastLeftIndex = first;
                lastRightIndex = second;

            }
            else if (first == lastRightIndex)
            {
                leftFunnel[i + 1] = vertices[second];
                rightFunnel[i + 1] = vertices[first];
                lastLeftIndex = second;
                lastRightIndex = first;

            }
            else if (second == lastLeftIndex)
            {
                leftFunnel[i + 1] = vertices[second];
                rightFunnel[i + 1] = vertices[first];
                lastLeftIndex = second;
                lastRightIndex = first;

            }
            else
            {
                leftFunnel[i + 1] = vertices[first];
                rightFunnel[i + 1] = vertices[second];
                lastLeftIndex = first;
                lastRightIndex = second;
            }
        }

        //Switch the arrays so the right funnel really is on the right side (and vice versa)
        if (!Polygon.IsClockwise(currentPosition, leftFunnel[1], rightFunnel[1]))
        {
            Int3[] tmp = leftFunnel;
            leftFunnel = rightFunnel;
            rightFunnel = tmp;
        }

        for (int i = 1; i < leftFunnelLength - 1; i++)
        {

            //float unitWidth = 2;
            Int3 normal = (rightFunnel[i] - leftFunnel[i]);

            float magn = normal.worldMagnitude;
            normal /= magn;
            normal *= Mathf.Clamp(offset, 0, (magn / 2F));
            leftFunnel[i] += normal;
            rightFunnel[i] -= normal;
            //Debug.DrawLine (rightFunnel[i],leftFunnel[i],Color.blue);
        }

        /*for (int i=0;i<path.Length-1;i++) {
            Debug.DrawLine (path[i].position,path[i+1].position,Color.blue);
        }*/

        /*for (int i=0;i<leftFunnel.Length-1;i++) {
            Debug.DrawLine (leftFunnel[i],leftFunnel[i+1],Color.red);
            Debug.DrawLine (rightFunnel[i],rightFunnel[i+1],Color.magenta);
        }*/

        if (tmpList == null)
        {
            tmpList = new List<Vector3>(3);
        }

        List<Vector3> funnelPath = tmpList;
        funnelPath.Clear();

        funnelPath.Add(currentPosition);

        Int3 portalApex = currentPosition;
        Int3 portalLeft = leftFunnel[0];
        Int3 portalRight = rightFunnel[0];

        int apexIndex = 0;
        int rightIndex = 0;
        int leftIndex = 0;

        //yield return 0;

        for (int i = 1; i < leftFunnelLength; i++)
        {

            Int3 left = leftFunnel[i];
            Int3 right = rightFunnel[i];

            /*Debug.DrawLine (portalApex,portalLeft,Color.red);
            Debug.DrawLine (portalApex,portalRight,Color.yellow);
            Debug.DrawLine (portalApex,left,Color.cyan);
            Debug.DrawLine (portalApex,right,Color.cyan);*/

            if (Polygon.TriangleArea2(portalApex, portalRight, right) >= 0)
            {

                if (portalApex == portalRight || Polygon.TriangleArea2(portalApex, portalLeft, right) <= 0)
                {
                    portalRight = right;
                    rightIndex = i;
                }
                else
                {
                    funnelPath.Add((Vector3)portalLeft);

                    //if (funnelPath.Count > 3)
                    //break;

                    portalApex = portalLeft;
                    apexIndex = leftIndex;

                    portalLeft = portalApex;
                    portalRight = portalApex;

                    leftIndex = apexIndex;
                    rightIndex = apexIndex;

                    i = apexIndex;

                    //yield return 0;
                    continue;
                }
            }

            if (Polygon.TriangleArea2(portalApex, portalLeft, left) <= 0)
            {

                if (portalApex == portalLeft || Polygon.TriangleArea2(portalApex, portalRight, left) >= 0)
                {
                    portalLeft = left;
                    leftIndex = i;

                }
                else
                {

                    funnelPath.Add((Vector3)portalRight);

                    //if (funnelPath.Count > 3)
                    //break;

                    portalApex = portalRight;
                    apexIndex = rightIndex;

                    portalLeft = portalApex;
                    portalRight = portalApex;

                    leftIndex = apexIndex;
                    rightIndex = apexIndex;

                    i = apexIndex;

                    //yield return 0;
                    continue;
                }
            }

            //yield return 0;
        }

        //yield return 0;

        funnelPath.Add(path.endPoint);

        Vector3[] p = funnelPath.ToArray();

        if (p.Length <= 1)
        {
            return currentPosition;
        }

        for (int i = 1; i < p.Length - 1; i++)
        {
            Vector3 closest = Mathfx.NearestPointStrict(p[i], p[i + 1], currentPosition);
            if ((closest - (Vector3)currentPosition).sqrMagnitude < pickNextWaypointMargin * pickNextWaypointMargin)
            {
                continue;
            }
            else
            {
                return p[i];
            }
        }
        return p[p.Length - 1];
    }
Пример #27
0
        public FurSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            SampleFramework.IsMouseVisible = false;

            _graphicsScreen             = new DeferredGraphicsScreen(Services);
            _graphicsScreen.DrawReticle = true;
            GraphicsService.Screens.Insert(0, _graphicsScreen);

            Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);
            Services.Register(typeof(IScene), null, _graphicsScreen.Scene);

            // Add gravity and damping to the physics Simulation.
            Simulation.ForceEffects.Add(new Gravity());
            Simulation.ForceEffects.Add(new Damping());

            // Add a custom game object which controls the camera.
            var cameraGameObject = new CameraObject(Services);

            GameObjectService.Objects.Add(cameraGameObject);
            _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

            // More standard objects.
            GameObjectService.Objects.Add(new GrabObject(Services));
            GameObjectService.Objects.Add(new ObjectCreatorObject(Services));
            GameObjectService.Objects.Add(new StaticSkyObject(Services));
            GameObjectService.Objects.Add(new GroundObject(Services));

            // Tell the engine how to interpret effect parameters with the name or semantic "FurDisplacement".
            // We could add our own effect interpreter instance, as it is done in the CloudQuadSample.
            // Or, we add the parameter description to the standard DefaultEffectInterpreter instance:
            var defaultEffectInterpreter = GraphicsService.EffectInterpreters.OfType <DefaultEffectInterpreter>().First();

            // If the effect parameter name or semantic in the .fx file is called "FurDisplacement", then
            // return an EffectParameterDescription. The hint "PerInstance" tells the engine that this
            // parameter needs to be updated for each scene node.
            defaultEffectInterpreter.ParameterDescriptions.Add(
                "FurDisplacement",
                (parameter, i) => new EffectParameterDescription(parameter, "FurDisplacement", i, EffectParameterHint.PerInstance));

            // Tell the engine how to create an effect parameter binding for "FurDisplacement".
            // We could add our own effect binder instance, as it is done in the CloudQuadSample.
            // Or, we add the parameter description to the standard DefaultEffectBinder instance:
            var defaultEffectBinder = GraphicsService.EffectBinders.OfType <DefaultEffectBinder>().First();

            // If the effect parameter represents "FurDisplacement", then create a DelegateParameterBinding
            // for the parameter. When an object is rendered using this effect the method ComputeFurDisplacement
            // is called to update the value of the effect parameter.
            defaultEffectBinder.Vector3Bindings.Add(
                "FurDisplacement",
                (effect, parameter, data) => new DelegateParameterBinding <Vector3>(effect, parameter, ComputeFurDisplacement));

            // Load model. (When the model and its effects are loaded, the engine will
            // check for the FurDisplacement parameter and create the appropriate parameter binding.)
            _meshNode  = (MeshNode)ContentManager.Load <ModelNode>("Fur/FurBall").Children[0].Clone();
            _rigidBody = new RigidBody(new SphereShape(0.5f));

            // Store a reference to the rigid body in SceneNode.UserData.
            _meshNode.UserData = _rigidBody;

            // Set a random pose.
            _rigidBody.Pose     = new Pose(new Vector3(0, 1, 0), RandomHelper.Random.NextQuaternion());
            _meshNode.PoseWorld = _rigidBody.Pose;

            // Add rigid body to physics simulation and model to scene.
            Simulation.RigidBodies.Add(_rigidBody);
            _graphicsScreen.Scene.Children.Add(_meshNode);
        }
Пример #28
0
 /// <summary>
 /// Exports the model.
 /// </summary>
 /// <param name="model">
 /// The model.
 /// </param>
 /// <param name="transform">
 /// The transform.
 /// </param>
 protected virtual void ExportModel(MeshNode model, Transform3D transform)
 {
 }
Пример #29
0
    public void RemoveEdgesWithSibling(MeshNode sibling)
    {
        int index = TargetNodes.IndexOf(sibling);
        if (index > -1)
        {
            if (index < TargetEdges.Count)
                RemoveEdge(TargetEdges[index]);

            TargetNodes.Remove(sibling);
        }
    }
Пример #30
0
		int RebuildFromInternal (MeshNode[] nodes, int from, int to, bool odd) {
			if (to - from <= 0) throw new ArgumentException();

			if (to - from == 1) {
				return GetBox(nodes[from]);
			}

			var rect = NodeBounds(nodes, from, to);
			int box = GetBox(rect);

			// Performance optimization for a common case
			if (to - from == 2) {
				arr[box].left = GetBox(nodes[from]);
				arr[box].right = GetBox(nodes[from+1]);
				return box;
			}

			int mx;
			if (odd) {
				// X
				int divider = (rect.xmin + rect.xmax)/2;
				mx = SplitByX (nodes, from, to, divider);
			} else {
				// Y/Z
				int divider = (rect.ymin + rect.ymax)/2;
				mx = SplitByZ (nodes, from, to, divider);
			}

			if (mx == from || mx == to) {
				// All nodes were on one side of the divider
				// Try to split along the other axis

				if (!odd) {
					// X
					int divider = (rect.xmin + rect.xmax)/2;
					mx = SplitByX (nodes, from, to, divider);
				} else {
					// Y/Z
					int divider = (rect.ymin + rect.ymax)/2;
					mx = SplitByZ (nodes, from, to, divider);
				}

				if (mx == from || mx == to) {
					// All nodes were on one side of the divider
					// Just pick one half
					mx = (from+to)/2;
				}
			}

			arr[box].left = RebuildFromInternal(nodes, from, mx, !odd);
			arr[box].right = RebuildFromInternal(nodes, mx, to, !odd);

			return box;
		}
Пример #31
0
        // OnLoad() is called when the GameObject is added to the IGameObjectService.
        protected override void OnLoad()
        {
            var graphicsService   = _services.GetInstance <IGraphicsService>();
            var gameObjectService = _services.GetInstance <IGameObjectService>();

            // Check if the game object manager has another ProceduralObject instance.
            var otherProceduralObject = gameObjectService.Objects
                                        .OfType <ProceduralObject>()
                                        .FirstOrDefault(o => o != this);
            Mesh mesh;

            if (otherProceduralObject != null)
            {
                // This ProceduralObject is not the first. We re-use rigid body data and
                // the mesh from the existing instance.
                var otherBody = otherProceduralObject._rigidBody;
                _rigidBody = new RigidBody(otherBody.Shape, otherBody.MassFrame, otherBody.Material);
                mesh       = otherProceduralObject._meshNode.Mesh;
            }
            else
            {
                // This is the first ProceduralObject instance. We create a new rigid body
                // and a new mesh.
                var shape = new MinkowskiSumShape(new GeometricObject(new SphereShape(0.05f)), new GeometricObject(new BoxShape(0.5f, 0.5f, 0.5f)));
                _rigidBody = new RigidBody(shape);

                // Create a DigitalRune.Geometry.Meshes.TriangleMesh from the RigidBody's
                // shape and convert this to a DigitalRune.Graphics.Mesh.
                var triangleMesh = _rigidBody.Shape.GetMesh(0.01f, 4);
                mesh = new Mesh {
                    Name = "ProceduralObject"
                };
                var submesh = CreateSubmeshWithTexCoords(graphicsService.GraphicsDevice, triangleMesh, MathHelper.ToRadians(70));
                mesh.Submeshes.Add(submesh);

                // Next, we need a material. We can load a predefined material (*.drmat file)
                // with the content manager.
                //var material = content.Load<Material>("Default");

                // Alternatively, we can load some effects and build the material here:
                Material material = new Material();

                // We need an EffectBinding for each render pass.
                // The "Default" pass uses a BasicEffectBinding (which is an EffectBinding
                // for the XNA BasicEffect).
                // Note: The "Default" pass is not used by the DeferredLightingScreen, so
                // we could ignore this pass in this sample project.
                BasicEffectBinding defaultEffectBinding = new BasicEffectBinding(graphicsService, null)
                {
                    LightingEnabled    = true,
                    TextureEnabled     = true,
                    VertexColorEnabled = false
                };
                defaultEffectBinding.Set("Texture", graphicsService.GetDefaultTexture2DWhite());
                defaultEffectBinding.Set("DiffuseColor", new Vector3(1, 1, 1));
                defaultEffectBinding.Set("SpecularColor", new Vector3(1, 1, 1));
                defaultEffectBinding.Set("SpecularPower", 100f);
                material.Add("Default", defaultEffectBinding);

                // EffectBinding for the "ShadowMap" pass.
                // Note: EffectBindings which are used in a Material must be marked with
                // the EffectParameterHint Material.
                var           content = _services.GetInstance <ContentManager>();
                EffectBinding shadowMapEffectBinding = new EffectBinding(
                    graphicsService,
                    content.Load <Effect>("DigitalRune\\Materials\\ShadowMap"),
                    null,
                    EffectParameterHint.Material);
                material.Add("ShadowMap", shadowMapEffectBinding);

                // EffectBinding for the "GBuffer" pass.
                EffectBinding gBufferEffectBinding = new EffectBinding(
                    graphicsService,
                    content.Load <Effect>("DigitalRune\\Materials\\GBuffer"),
                    null,
                    EffectParameterHint.Material);
                gBufferEffectBinding.Set("SpecularPower", 100f);
                material.Add("GBuffer", gBufferEffectBinding);

                // EffectBinding for the "Material" pass.
                EffectBinding materialEffectBinding = new EffectBinding(
                    graphicsService,
                    content.Load <Effect>("DigitalRune\\Materials\\Material"),
                    null,
                    EffectParameterHint.Material);
                materialEffectBinding.Set("DiffuseTexture", graphicsService.GetDefaultTexture2DWhite());
                materialEffectBinding.Set("DiffuseColor", new Vector3(1, 1, 1));
                materialEffectBinding.Set("SpecularColor", new Vector3(1, 1, 1));
                material.Add("Material", materialEffectBinding);

                // Assign this material to the submesh.
                submesh.SetMaterial(material);
            }

            // Create a scene graph node for the mesh.
            _meshNode = new MeshNode(mesh);

            // Set a random pose.
            var randomPosition = new Vector3F(
                RandomHelper.Random.NextFloat(-10, 10),
                RandomHelper.Random.NextFloat(2, 5),
                RandomHelper.Random.NextFloat(-20, 0));

            _rigidBody.Pose     = new Pose(randomPosition, RandomHelper.Random.NextQuaternionF());
            _meshNode.PoseWorld = _rigidBody.Pose;

            // Add mesh node to scene graph.
            var scene = _services.GetInstance <IScene>();

            scene.Children.Add(_meshNode);

            // Add rigid body to the physics simulation.
            var simulation = _services.GetInstance <Simulation>();

            simulation.RigidBodies.Add(_rigidBody);
        }
Пример #32
0
		/** Inserts a mesh node in the tree */
		public void Insert (MeshNode node) {
			int boxi = GetBox (node);

			// Was set to root
			if (boxi == 0) {
				return;
			}

			BBTreeBox box = arr[boxi];

			//int depth = 0;

			int c = 0;
			while (true) {

				BBTreeBox cb = arr[c];

				cb.rect = ExpandToContain (cb.rect,box.rect);
				if (cb.node != null) {
					//Is Leaf
					cb.left = boxi;

					int box2 = GetBox (cb.node);
					//BBTreeBox box2 = new BBTreeBox (this,c.node);

					//Console.WriteLine ("Inserted "+box.node+", rect "+box.rect.ToString ());
					cb.right = box2;


					cb.node = null;
					//cb.depth++;

					//c.rect = c.rect.
					arr[c] = cb;
					//Debug.Log (depth);
					return;
				} else {
					//depth++;
					//cb.depth++;
					arr[c] = cb;

					int e1 = ExpansionRequired (arr[cb.left].rect,box.rect);// * arr[cb.left].depth;
					int e2 =  ExpansionRequired (arr[cb.right].rect,box.rect);// * arr[cb.left].depth;

					//Choose the rect requiring the least expansion to contain box.rect
					if (e1 < e2) {
						c = cb.left;
					} else if (e2 < e1) {
						c = cb.right;
					} else {
						//Equal, Choose the one with the smallest area
						c = RectArea (arr[cb.left].rect) < RectArea (arr[cb.right].rect) ? cb.left : cb.right;
					}
				}
			}
		}
Пример #33
0
        public IKPhysicsSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            GraphicsScreen.DrawReticle = true;

            // Add game objects which allows to grab rigid bodies.
            _grabObject = new GrabObject(Services);
            GameObjectService.Objects.Add(_grabObject);

            // Add Dude model.
            var modelNode = ContentManager.Load <ModelNode>("Dude/Dude");

            _meshNode           = modelNode.GetSubtree().OfType <MeshNode>().First().Clone();
            _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0));
            SampleHelper.EnablePerPixelLighting(_meshNode);
            GraphicsScreen.Scene.Children.Add(_meshNode);

            // Create a ragdoll for the Dude model.
            _ragdoll = new Ragdoll();
            DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f);

            // Set the initial world space pose of the whole ragdoll. And copy the bone poses of the
            // current skeleton pose.
            _ragdoll.Pose = _meshNode.PoseWorld;
            _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose);

            // Enable constraints (joints and limits, no motors)
            _ragdoll.EnableJoints();
            _ragdoll.EnableLimits();
            _ragdoll.DisableMotors();

            foreach (var body in _ragdoll.Bodies)
            {
                if (body != null)
                {
                    // Disable rigid body sleeping. (If we leave it enabled, the simulation might
                    // disable slow bodies before they reach their IK goal.)
                    body.CanSleep = false;

                    // Disable collisions response.
                    body.CollisionResponseEnabled = false;
                }
            }

            // Add rigid bodies and the constraints of the ragdoll to the simulation.
            _ragdoll.AddToSimulation(Simulation);

            // Disable all force effects (default gravity and damping).
            Simulation.ForceEffects.Clear();

            // Create constraints which hold selected bodies at their current position
            // relative to the world.
            // To constrain the position + orientation, we use a FixedJoint.
            foreach (var boneName in new[] { "Pelvis" })
            {
                var ragdollBody = _ragdoll.Bodies[_meshNode.SkeletonPose.Skeleton.GetIndex(boneName)];
                var ikJoint     = new FixedJoint
                {
                    AnchorPoseALocal = ragdollBody.Pose,
                    BodyA            = Simulation.World,
                    AnchorPoseBLocal = Pose.Identity,
                    BodyB            = ragdollBody,
                    CollisionEnabled = false,
                    MaxForce         = 1000,
                };
                _ikJoints.Add(ikJoint);
                Simulation.Constraints.Add(ikJoint);
            }
            // To constrain only the position, we use a BallJoint.
            foreach (var boneName in new[] { "L_Hand", "R_Hand", "L_Ankle1", "R_Ankle" })
            {
                var ragdollBody = _ragdoll.Bodies[_meshNode.SkeletonPose.Skeleton.GetIndex(boneName)];
                var ikJoint     = new BallJoint
                {
                    AnchorPositionALocal = ragdollBody.Pose.Position,
                    BodyA = Simulation.World,
                    AnchorPositionBLocal = Vector3F.Zero,
                    BodyB            = ragdollBody,
                    CollisionEnabled = false,
                    MaxForce         = 1000,
                };
                _ikJoints.Add(ikJoint);
                Simulation.Constraints.Add(ikJoint);
            }
        }
Пример #34
0
			public BBTreeBox (IntRect rect) {
				node = null;
				this.rect = rect;
				left = right = -1;
			}
    /** Applies constrained movement from \a startPos to \a endPos.
     * The result is stored in \a clampedPos.
     * Returns the new current node */
    public Node ClampAlongNavmesh(Vector3 startPos, Node startNode, Vector3 endPos, out Vector3 clampedPos)
    {
        clampedPos = endPos;

        Stack <Node> stack  = tmpStack;         // Tiny stack
        List <Node>  closed = tmpClosed;        // Tiny closed list

        stack.Clear();
        closed.Clear();

        Vector3 bestPos, p;
        float   bestDist = float.PositiveInfinity;
        float   d;
        Node    bestRef = null;
        // Search constraint
        Vector3 searchPos    = (startPos + endPos) / 2;
        float   searchRadius = Mathfx.MagnitudeXZ(startPos, endPos) / 2;

        // Init
        bestPos = startPos;
        stack.Push(startNode);
        closed.Add(startNode);         // Self ref, start maker.

        INavmesh graph = AstarData.GetGraph(startNode) as INavmesh;

        if (graph == null)
        {
            //Debug.LogError ("Null graph, or the graph was no NavMeshGraph");
            return(startNode);
        }


        while (stack.Count > 0)
        {
            // Pop front.
            Node     cur  = stack.Pop();
            MeshNode poly = cur as MeshNode;

            // If target is inside the poly, stop search.
            if (NavMeshGraph.ContainsPoint(poly, endPos, graph.vertices))
            {
                bestRef = cur;
                bestPos = endPos;
                break;
            }
            // Follow edges or keep track of nearest point on blocking edge.
            for (int i = 0, j = 2; i < 3; j = i++)
            {
                int sp = poly.GetVertexIndex(j);
                int sq = poly.GetVertexIndex(i);

                bool     blocking = true;
                MeshNode conn     = null;

                for (int q = 0; q < cur.connections.Length; q++)
                {
                    conn = cur.connections[q] as MeshNode;
                    if (conn == null)
                    {
                        continue;
                    }

                    for (int i2 = 0, j2 = 2; i2 < 3; j2 = i2++)
                    {
                        int sp2 = conn.GetVertexIndex(j2);
                        int sq2 = conn.GetVertexIndex(i2);
                        if ((sp2 == sp && sq2 == sq) || (sp2 == sq && sq2 == sp))
                        {
                            blocking = false;
                            break;
                        }
                    }

                    if (!blocking)
                    {
                        break;
                    }
                }

                //Node neiRef = poly->nei[j];

                if (blocking)
                {
                    // Blocked edge, calc distance.
                    p = Mathfx.NearestPointStrictXZ((Vector3)graph.vertices[sp], (Vector3)graph.vertices[sq], endPos);

                    d = Mathfx.MagnitudeXZ(p, endPos);
                    if (d < bestDist)
                    {
                        // Update nearest distance.
                        bestPos  = p;
                        bestDist = d;
                        bestRef  = cur;
                    }
                }
                else
                {
                    // Skip already visited.
                    if (closed.Contains(conn))
                    {
                        continue;
                    }
                    // Store to closed with parent for trace back.
                    closed.Add(conn);

                    // Non-blocked edge, follow if within search radius.
                    p = Mathfx.NearestPointStrictXZ((Vector3)graph.vertices[sp], (Vector3)graph.vertices[sq], searchPos);

                    d = Mathfx.MagnitudeXZ(p, searchPos);
                    if (d <= searchRadius)
                    {
                        stack.Push(conn);
                    }
                }
            }
        }
        // Trace back and store visited polygons.

        /* followVisited(bestRef,visited,closed);
         * // Store best movement position.*/
        clampedPos = bestPos;
        // Return number of visited polys.
        return(bestRef);       //visited.size();
    }
Пример #36
0
        public KinematicRagdollSample(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            GraphicsScreen.DrawReticle = true;

            // Add game objects which allow to shoot balls and grab rigid bodies.
            _ballShooterObject = new BallShooterObject(Services)
            {
                Speed = 10
            };
            GameObjectService.Objects.Add(_ballShooterObject);
            _grabObject = new GrabObject(Services);
            GameObjectService.Objects.Add(_grabObject);

            var modelNode = ContentManager.Load <ModelNode>("Dude/Dude");

            _meshNode           = modelNode.GetSubtree().OfType <MeshNode>().First().Clone();
            _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
            SampleHelper.EnablePerPixelLighting(_meshNode);
            GraphicsScreen.Scene.Children.Add(_meshNode);

            var animations       = _meshNode.Mesh.Animations;
            var loopingAnimation = new AnimationClip <SkeletonPose>(animations.Values.First())
            {
                LoopBehavior = LoopBehavior.Cycle,
                Duration     = TimeSpan.MaxValue,
            };
            var animationController = AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose);

            animationController.UpdateAndApply();

            // Create a ragdoll for the Dude model.
            _ragdoll = new Ragdoll();
            DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f);

            // Set the world space pose of the whole ragdoll. And copy the bone poses of the
            // current skeleton pose.
            _ragdoll.Pose = _meshNode.PoseWorld;
            _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose);

            // Set all bodies to kinematic -  they should not be affected by forces.
            foreach (var body in _ragdoll.Bodies)
            {
                if (body != null)
                {
                    body.MotionType = MotionType.Kinematic;
                }
            }

            // Set all motors to velocity motors. Velocity motors change RigidBody.LinearVelocity
            // RigidBody.AngularVelocity to move the rigid bodies.
            foreach (RagdollMotor motor in _ragdoll.Motors)
            {
                if (motor != null)
                {
                    motor.Mode = RagdollMotorMode.Velocity;
                }
            }
            _ragdoll.EnableMotors();

            // In this sample, we do not need joints or limits.
            _ragdoll.DisableJoints();
            _ragdoll.DisableLimits();

            // Add ragdoll rigid bodies to the simulation.
            _ragdoll.AddToSimulation(Simulation);

            // Add a rigid body.
            var box = new RigidBody(new BoxShape(0.4f, 0.4f, 0.4f))
            {
                Name = "Box",
                Pose = new Pose(new Vector3F(0, 3, 0)),
            };

            Simulation.RigidBodies.Add(box);
        }
Пример #37
0
        // Creates a test scene with a lot of randomly placed objects.
        internal static void CreateScene(ServiceContainer services, ContentManager content, DeferredGraphicsScreen graphicsScreen)
        {
            var gameObjectService = services.GetInstance <IGameObjectService>();
            var graphicsService   = services.GetInstance <IGraphicsService>();

            gameObjectService.Objects.Add(new DynamicSkyObject(services, true, false, true)
            {
                EnableAmbientLight = false, // Disable ambient light of sky to make shadows more visible.
                EnableCloudShadows = false
            });

            gameObjectService.Objects.Add(new GroundObject(services));
            gameObjectService.Objects.Add(new DynamicObject(services, 1));
            gameObjectService.Objects.Add(new DynamicObject(services, 2));
            gameObjectService.Objects.Add(new DynamicObject(services, 3));
            gameObjectService.Objects.Add(new DynamicObject(services, 5));
            gameObjectService.Objects.Add(new DynamicObject(services, 6));
            gameObjectService.Objects.Add(new DynamicObject(services, 7));
            gameObjectService.Objects.Add(new ObjectCreatorObject(services));
            gameObjectService.Objects.Add(new LavaBallsObject(services));

            var random = new Random();

            // Spheres
            var sphereMesh = SampleHelper.CreateMesh(content, graphicsService, new SphereShape(1));

            for (int i = 0; i < 100; i++)
            {
                Vector3F position = new Vector3F(random.NextFloat(-100, 100), random.NextFloat(0, 3), random.NextFloat(-100, 100));
                float    scale    = random.NextFloat(0.5f, 3f);
                var      meshNode = new MeshNode(sphereMesh)
                {
                    PoseLocal  = new Pose(position),
                    ScaleLocal = new Vector3F(scale),
                    IsStatic   = true,
                };
                graphicsScreen.Scene.Children.Add(meshNode);
            }

            // Boxes
            var boxMesh = SampleHelper.CreateMesh(content, graphicsService, new BoxShape(1, 1, 1));

            for (int i = 0; i < 100; i++)
            {
                Vector3F    position    = new Vector3F(random.NextFloat(-100, 100), random.NextFloat(0, 3), random.NextFloat(-100, 100));
                QuaternionF orientation = random.NextQuaternionF();
                Vector3F    scale       = random.NextVector3F(0.1f, 4f);
                var         meshNode    = new MeshNode(boxMesh)
                {
                    PoseLocal  = new Pose(position, orientation),
                    ScaleLocal = scale,
                    IsStatic   = true,
                };
                graphicsScreen.Scene.Children.Add(meshNode);
            }

            // Height field with smooth hills.
            var numberOfSamplesX = 20;
            var numberOfSamplesZ = 20;
            var samples          = new float[numberOfSamplesX * numberOfSamplesZ];

            for (int z = 0; z < numberOfSamplesZ; z++)
            {
                for (int x = 0; x < numberOfSamplesX; x++)
                {
                    if (x == 0 || z == 0 || x == 19 || z == 19)
                    {
                        // Set this boundary elements to a low height, so that the height field is connected
                        // to the ground.
                        samples[z * numberOfSamplesX + x] = -1;
                    }
                    else
                    {
                        // A sine/cosine function that creates some interesting waves.
                        samples[z * numberOfSamplesX + x] = 1 + (float)(Math.Cos(z / 2f) * Math.Sin(x / 2f) * 1);
                    }
                }
            }
            var heightField         = new HeightField(0, 0, 20, 20, samples, numberOfSamplesX, numberOfSamplesZ);
            var heightFieldMesh     = SampleHelper.CreateMesh(content, graphicsService, heightField);
            var heightFieldMeshNode = new MeshNode(heightFieldMesh)
            {
                PoseLocal  = new Pose(new Vector3F(20, 0, -20)),
                ScaleLocal = new Vector3F(1, 2, 1),
                IsStatic   = true,
            };

            graphicsScreen.Scene.Children.Add(heightFieldMeshNode);

            // Dudes.
            for (int i = 0; i < 10; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-20, 20), 0, random.NextFloat(-20, 20));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                gameObjectService.Objects.Add(new DudeObject(services)
                {
                    Pose = new Pose(position, orientation)
                });
            }

            // Palm trees.
            for (int i = 0; i < 100; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-80, 80), 0, random.NextFloat(-100, 100));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                float     scale       = random.NextFloat(0.5f, 1.2f);
                gameObjectService.Objects.Add(new StaticObject(services, "PalmTree/palm_tree", scale, new Pose(position, orientation)));
            }

            // Rocks
            for (int i = 0; i < 100; i++)
            {
                Vector3F    position    = new Vector3F(random.NextFloat(-80, 80), 1, random.NextFloat(-100, 100));
                QuaternionF orientation = RandomHelper.Random.NextQuaternionF();
                float       scale       = random.NextFloat(0.5f, 1.2f);
                gameObjectService.Objects.Add(new StaticObject(services, "Rock/rock_05", scale, new Pose(position, orientation)));
            }

            // Grass
            for (int i = 0; i < 100; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-20, 20), 0, random.NextFloat(-20, 20));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                float     scale       = random.NextFloat(0.5f, 1.2f);
                gameObjectService.Objects.Add(new StaticObject(services, "Grass/Grass", scale, new Pose(position, orientation)));
            }

            // More plants
            for (int i = 0; i < 100; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(-20, 20), 0, random.NextFloat(-20, 20));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                float     scale       = random.NextFloat(0.5f, 1.2f);
                gameObjectService.Objects.Add(new StaticObject(services, "Parviflora/Parviflora", scale, new Pose(position, orientation)));
            }

            // "Skyscrapers"
            for (int i = 0; i < 20; i++)
            {
                Vector3F  position    = new Vector3F(random.NextFloat(90, 100), 0, random.NextFloat(-100, 100));
                Matrix33F orientation = Matrix33F.CreateRotationY(random.NextFloat(0, ConstantsF.TwoPi));
                Vector3F  scale       = new Vector3F(random.NextFloat(6, 20), random.NextFloat(10, 100), random.NextFloat(6, 20));
                var       meshNode    = new MeshNode(boxMesh)
                {
                    PoseLocal  = new Pose(position, orientation),
                    ScaleLocal = scale,
                    IsStatic   = true,
                    UserFlags  = 1, // Mark the distant huge objects. Used in render callbacks in the CompositeShadowSample.
                };
                graphicsScreen.Scene.Children.Add(meshNode);
            }

            // "Hills"
            for (int i = 0; i < 20; i++)
            {
                Vector3F position = new Vector3F(random.NextFloat(-90, -100), 0, random.NextFloat(-100, 100));
                Vector3F scale    = new Vector3F(random.NextFloat(10, 20), random.NextFloat(10, 30), random.NextFloat(10, 20));
                var      meshNode = new MeshNode(sphereMesh)
                {
                    PoseLocal  = new Pose(position),
                    ScaleLocal = scale,
                    IsStatic   = true,
                    UserFlags  = 1, // Mark the distant huge objects. Used in render callbacks in the CompositeShadowSample.
                };
                graphicsScreen.Scene.Children.Add(meshNode);
            }
        }
Пример #38
0
		static int SplitByX (MeshNode[] nodes, int from, int to, int divider) {
			int mx = to;
			for (int i = from; i < mx; i++) {
				if (nodes[i].position.x > divider) {
					// swap with mx
					mx--;
					var tmp = nodes[mx];
					nodes[mx] = nodes[i];
					nodes[i] = tmp;
					i--;
				}
			}
			return mx;
		}
Пример #39
0
        static void Main(string[] args)
        {
            if (args != null && args.Length > 0)
            {
                ParseArguments(args, out _Ip, out _Port, out _PeerIpPorts);
                _IpPort = _Ip + ":" + _Port;
            }
            else
            {
                _IpPort = InputString("Local IP:port:", "127.0.0.1:8000", false);
                ParseIpPort(_IpPort, out _Ip, out _Port);
            }

            _Settings = new MeshSettings();
            _Settings.AcceptInvalidCertificates = true;
            _Settings.AutomaticReconnect        = true;
            _Settings.MutuallyAuthenticate      = false;
            _Settings.PresharedKey        = null;
            _Settings.StreamBufferSize    = 65536;
            _Settings.ReconnectIntervalMs = 1000;

            _Mesh = new MeshNode(_Ip, _Port);
            _Mesh.PeerConnected      += PeerConnected;
            _Mesh.PeerDisconnected   += PeerDisconnected;
            _Mesh.MessageReceived    += MessageReceived;
            _Mesh.SyncMessageReceived = SyncMessageReceived;
            // _Mesh.Logger = Logger;

            _Mesh.Start();

            if (_PeerIpPorts != null && _PeerIpPorts.Count > 0)
            {
                Console.Write("Adding peers: ");
                foreach (string curr in _PeerIpPorts)
                {
                    Console.Write(curr + " ");
                    _Mesh.Add(new MeshPeer(curr, false));
                }
                Console.WriteLine("");
            }

            while (_RunForever)
            {
                string userInput = InputString("WatsonMesh [? for help] >", null, false);

                List <MeshPeer> peers;

                switch (userInput)
                {
                case "?":
                    Menu();
                    break;

                case "q":
                case "quit":
                    _RunForever = false;
                    break;

                case "c":
                case "cls":
                    Console.Clear();
                    break;

                case "list":
                    peers = _Mesh.GetPeers();
                    if (peers != null && peers.Count > 0)
                    {
                        Console.WriteLine("Configured peers: " + peers.Count);
                        foreach (MeshPeer curr in peers)
                        {
                            Console.WriteLine("  " + curr.ToString());
                        }
                    }
                    else
                    {
                        Console.WriteLine("None");
                    }
                    break;

                case "failed":
                    peers = _Mesh.GetDisconnectedPeers();
                    if (peers != null && peers.Count > 0)
                    {
                        Console.WriteLine("Failed peers: " + peers.Count);
                        foreach (MeshPeer currPeer in peers)
                        {
                            Console.WriteLine("  " + currPeer.ToString());
                        }
                    }
                    else
                    {
                        Console.WriteLine("None");
                    }
                    break;

                case "send":
                    Send();
                    break;

                case "send md":
                    SendMetadata();
                    break;

                case "sendsync":
                    SendSync();
                    break;

                case "sendsync md":
                    SendSyncMetadata();
                    break;

                case "bcast":
                    Broadcast();
                    break;

                case "add":
                    _Mesh.Add(
                        new MeshPeer(
                            InputString("IP:port:", "127.0.0.1:8000", false),
                            false));
                    break;

                case "del":
                    _Mesh.Remove(
                        new MeshPeer(
                            InputString("IP:port:", "127.0.0.1:8000", false),
                            false));
                    break;

                case "health":
                    Console.WriteLine("Healthy: " + _Mesh.IsHealthy);
                    break;

                case "nodehealth":
                    Console.WriteLine(
                        _Mesh.IsServerConnected(
                            InputString("IP:Port", "127.0.0.1:8000", false)));
                    break;
                }
            }
        }