예제 #1
0
        //read in the positions of the bones
        public void UpdateTransforms(Transform[] boneTransforms, ReadOnlyArrayCollection <Transform> boneWorldTransforms)
        {
            Transform transform;

            //update previous positions
            for (int i = 0; i < previousPositions.Length; i++)
            {
                this.previousPositions[i] = this.positions[i];
            }

            Matrix matrix;

            for (int i = 0; i < boneTransforms.Length; i++)
            {
                //read each bone
                if (activeBones[i])
                {
                    transform = (boneWorldTransforms[i] * boneTransforms[i]);
                    transform.GetMatrix(out matrix);                     //as a matrix.

                    //work out the position each offset point from each bone should be, and output to the position value.
                    for (int p = 0; p < BonePointCount; p++)
                    {
                        Vector3.Transform(ref BoneOffsets[p], ref matrix, out this.positions[i * BonePointCount + p]);
                    }
                }
            }
        }
예제 #2
0
 //the final method in the interface,
 //when this method is called, the bones have been transformed into their final hierarchy.
 //modifying a bone here will only modify the transform of that bone (and not it's children).
 public void ProcessBonesPostTransform(Transform[] boneSpaceTransforms, ModelData modelData,
                                       ReadOnlyArrayCollection <Transform> boneWorldSpaceIdentityTransforms, ReadOnlyArrayCollection <Transform> boneWorldSpaceIdentityInverseTransforms)
 {
     //however, here, simply copy out the positions for each of the bones, and store them in the hacky verlet integrator
     //note: when the verlet system is active, neither this method or the second interface method will be called,
     //as it returns false in the first method.
     verletSolver.UpdateTransforms(boneSpaceTransforms, boneWorldSpaceIdentityTransforms);
 }
예제 #3
0
        //the actual integration step
        public void IntegrateBones(Transform[] boneTransforms, ReadOnlyArrayCollection <Transform> boneWorldSpaceIdentityTransforms, ReadOnlyArrayCollection <Transform> boneWorldSpaceIdentityInverseTransforms)
        {
            //perform the integration (constraints, verlet, etc)
            PerformIntegration();

            //new bone transfomrs will be written to boneTransforms

            Matrix    matrix = Matrix.Identity;
            Transform transform;

            for (int i = 0; i < boneTransforms.Length; i++)
            {
                if (activeBones[i])
                {
                    //for each bone..
                    //the centre point (first position)
                    Vector3 basis = this.positions[i * BonePointCount];
                    //the three positions offset from the centre
                    Vector3 x = this.positions[i * BonePointCount + 1];
                    Vector3 y = this.positions[i * BonePointCount + 2];
                    Vector3 z = this.positions[i * BonePointCount + 3];

                    //get the differences to the centre point...
                    x -= basis;
                    y -= basis;
                    z -= basis;

                    //these form the axis of the bone's rotation
                    //x-axis of the matrix
                    matrix.M11 = x.X;
                    matrix.M12 = x.Y;
                    matrix.M13 = x.Z;
                    //y-axis of the matrix
                    matrix.M21 = y.X;
                    matrix.M22 = y.Y;
                    matrix.M23 = y.Z;
                    //z-axis of the matrix
                    matrix.M31 = z.X;
                    matrix.M32 = z.Y;
                    matrix.M33 = z.Z;

                    //position
                    matrix.M41 = basis.X;
                    matrix.M42 = basis.Y;
                    matrix.M43 = basis.Z;

                    //work out the transform from the matrix...

                    transform = new Transform(ref matrix);

                    //set the transform (multiplied by the inverse of the bone->world transform)
                    //as the bones are in world space, needs to be in bone local space
                    boneTransforms[i] = (boneWorldSpaceIdentityInverseTransforms[i] * transform);
                }
            }
        }
        public bool ProcessBonesPreTransform(Transform[] boneSpaceTransforms, ModelData modelData,
            ReadOnlyArrayCollection<Transform> boneWorldSpaceTransforms, ReadOnlyArrayCollection<Transform> boneWorldSpaceInverseTransforms)
        {
            for (int i = 0; i < 5; i++)
            {
                Transform transform = Transform.Identity;
                Quaternion.CreateFromYawPitchRoll(_rotations[i], 0, 0, out transform.Rotation);
                transform.Translation.Z = _rotations[i] * 2;

                int parent1 = modelData.Skeleton.BoneData[_fingers[i, 0]].Parent;
                int parent2 = modelData.Skeleton.BoneData[_fingers[i, 1]].Parent;

                boneSpaceTransforms[_fingers[i, 0]] *= transform;
                boneSpaceTransforms[_fingers[i, 1]] *= transform;
            }

            return true;
        }
예제 #5
0
        public static CodeMemberMethod BuildCpuLogic(string name, ReadOnlyArrayCollection <ParticleSystemLogicStep> steps, bool addMethod)
        {
            //generate the a runtime method...

            if (memberTranslate == null)
            {
                memberTranslate = new Dictionary <string, CodeExpression>();
                BuildTranslate(memberTranslate);
            }

            CodeMemberMethod method = new CodeMemberMethod();

            method.Attributes = MemberAttributes.Public | MemberAttributes.Static | MemberAttributes.Final;
            method.Name       = name;

            //inputs
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(uint), "count"));
            if (addMethod)
            {
                method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(uint[]), "indices"));
            }
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(float), "time"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Random), "rand"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(float), "delta_time"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(float[]), "global"));

            //fill the logic tree
            BuildLogic(method.Statements, steps, addMethod);

            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector2[]), "life"));

            //pass in all members even if unused
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector4[]), "ps"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector4[]), "vr"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector4[]), "col"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector4[]), "user"));

            return(method);
        }
예제 #6
0
        static internal void SetParticleTypeDrawMask(ref uint mask, ParticleSystem system, string particleTypeName, bool draw)
        {
            if (system == null)
            {
                throw new InvalidOperationException("ParticleSystem == null");
            }
            if (system.ParticleSystemData == null)
            {
                throw new InvalidOperationException("ParticleSystem.ParticleSystemData == null");
            }
            ReadOnlyArrayCollection <Xen.Ex.Graphics.Content.ParticleSystemTypeData> array = system.ParticleSystemData.ParticleTypeData;

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i].Name == particleTypeName)
                {
                    SetParticleTypeDrawMask(ref mask, i, draw);
                    return;
                }
            }
            throw new ArgumentException(string.Format("ParticleSystem.ParticleSystemData.ParticleTypeData does not contain a particle type '{0}'", particleTypeName));
        }
예제 #7
0
        //the second method in the animation process.
        //At this point, the normal model animations have been generated.
        //However, the bones have not been transformed into a hierarchy yet.
        public bool ProcessBonesPreTransform(Transform[] boneSpaceTransforms, ModelData modelData,
                                             ReadOnlyArrayCollection <Transform> boneWorldSpaceTransforms, ReadOnlyArrayCollection <Transform> boneWorldSpaceInverseTransforms)
        {
            //spin the spine..?
            if (enableModifySingleBone)
            {
                //make a transform to rotate the bone
                Transform transform = Transform.Identity;

                //create a rotation
                Quaternion.CreateFromYawPitchRoll(0, this.rotationValue, 0, out transform.Rotation);

                //see the big comment at the top of this file
                transform = boneWorldSpaceInverseTransforms[spinBoneIndex] * (transform * boneWorldSpaceTransforms[spinBoneIndex]);

                //modify the bone transform (or you could replace it entirely)
                boneSpaceTransforms[spinBoneIndex] *= transform;
            }

            //returning true continues the animation process, so the hierarchy is transformed and ProcessBonesPostTransform is called
            //return false if animation is complete (for example, the animation has been transformed manually)
            return(true);
        }
		public static CodeMemberMethod BuildCpuLogic(string name, ReadOnlyArrayCollection<ParticleSystemLogicStep> steps, bool addMethod)
		{
			//generate the a runtime method...

			if (memberTranslate == null)
			{
				memberTranslate = new Dictionary<string, CodeExpression>();
				BuildTranslate(memberTranslate);
			}

			CodeMemberMethod method = new CodeMemberMethod();
			method.Attributes = MemberAttributes.Public | MemberAttributes.Static | MemberAttributes.Final;
			method.Name = name;

			//inputs
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(uint), "count"));
			if (addMethod)
				method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(uint[]), "indices"));
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(float), "time"));
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Random), "rand"));
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(float), "delta_time"));
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(float[]), "global"));

			//fill the logic tree
			BuildLogic(method.Statements, steps, addMethod);

			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector2[]), "life"));

			//pass in all members even if unused
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector4[]), "ps"));
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector4[]), "vr"));
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector4[]), "col"));
			method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Vector4[]), "user"));

			return method;
		}
예제 #9
0
        private static void BuildLogic(CodeStatementCollection statements, ReadOnlyArrayCollection <ParticleSystemLogicStep> steps, bool addMethod)
        {
            Dictionary <string, bool> argsUsed = new Dictionary <string, bool>();

            foreach (string arg in memberTranslate.Keys)
            {
                argsUsed.Add(arg, false);
            }
            argsUsed.Add("rand", false);

            CodeStatementCollection code = new CodeStatementCollection();

            BuildLogic(code, steps, argsUsed, 0);

            //rand requires a local variable
            if (argsUsed["rand"])
            {
                statements.Add(
                    new CodeVariableDeclarationStatement(
                        typeof(float), "_tmp", new CodePrimitiveExpression(0.0f)));
            }

            for (int i = 0; i < 4; i++)
            {
                if (argsUsed["local" + i])
                {
                    code.Insert(0,
                                new CodeVariableDeclarationStatement(
                                    typeof(float), "local" + i, new CodePrimitiveExpression(0.0f)));
                }
            }

            CodeVariableReferenceExpression ref_i = new CodeVariableReferenceExpression("i");

            if (addMethod)             // add methods have indices to update...
            {
                ref_i.VariableName = "_i";
            }

            CodeIterationStatement loop = new CodeIterationStatement();

            loop.InitStatement      = new CodeVariableDeclarationStatement(typeof(uint), ref_i.VariableName, new CodePrimitiveExpression(0));
            loop.IncrementStatement = new CodeAssignStatement(ref_i, new CodeBinaryOperatorExpression(ref_i, CodeBinaryOperatorType.Add, new CodePrimitiveExpression((uint)1)));
            loop.TestExpression     = new CodeBinaryOperatorExpression(ref_i, CodeBinaryOperatorType.LessThan, new CodeArgumentReferenceExpression("count"));

            // uint i = indices[_i];
            if (addMethod)
            {
                loop.Statements.Add(new CodeVariableDeclarationStatement(typeof(uint), "i", new CodeArrayIndexerExpression(new CodeArgumentReferenceExpression("indices"), ref_i)));
            }
            else
            {
                //put in velocity logic

                loop.Statements.Add(
                    new CodeAssignStatement(Arg("position.x"),
                                            new CodeBinaryOperatorExpression(Arg("position.x"), CodeBinaryOperatorType.Add,
                                                                             new CodeBinaryOperatorExpression(Arg("velocity.x"), CodeBinaryOperatorType.Multiply, Arg("delta_time")))));

                loop.Statements.Add(
                    new CodeAssignStatement(Arg("position.y"),
                                            new CodeBinaryOperatorExpression(Arg("position.y"), CodeBinaryOperatorType.Add,
                                                                             new CodeBinaryOperatorExpression(Arg("velocity.y"), CodeBinaryOperatorType.Multiply, Arg("delta_time")))));

                loop.Statements.Add(
                    new CodeAssignStatement(Arg("position.z"),
                                            new CodeBinaryOperatorExpression(Arg("position.z"), CodeBinaryOperatorType.Add,
                                                                             new CodeBinaryOperatorExpression(Arg("velocity.z"), CodeBinaryOperatorType.Multiply, Arg("delta_time")))));
            }

            loop.Statements.AddRange(code);

            statements.Add(loop);
        }
예제 #10
0
        //methods of the interface

        //this first method is called before any normal animation calculation takes place
        //the nonAnimatedBones Transforms are usualy still storing the previous frame's animation,
        //however, this is not guarenteed. They should be considered write-only.
        //returning true from this method stops the animation process early
        public bool PreProcessAnimation(Transform[] nonAnimatedBones, ModelData modelData, ReadOnlyArrayCollection <Transform> boneWorldSpaceIdentityTransforms, ReadOnlyArrayCollection <Transform> boneWorldSpaceIdentityInverseTransforms)
        {
            //is the hacky verlet example enabled?
            if (enableVerlet)
            {
                //if so, let the verlet integrator generate the bone transforms itself
                verletSolver.IntegrateBones(nonAnimatedBones, boneWorldSpaceIdentityTransforms, boneWorldSpaceIdentityInverseTransforms);

                //the bones are now entirely generated, so return false.

                //return false because the animation is complete (in this example, the animation has been transformed manually)
                return(false);
            }

            //returning true continues the animation process,
            //so the animations are generated, interpolated and ProcessBonesPreTransform is called.
            return(true);
        }
		private static void BuildLogic(CodeStatementCollection statements, ReadOnlyArrayCollection<ParticleSystemLogicStep> steps, Dictionary<string, bool> argUsed, int depth)
		{
			for (int i = 0; i < steps.Length; i++)
			{
				ParticleSystemLogicStep step = steps[i];

				CodeExpression arg0		= Arg(step.arg0);
				CodeExpression arg1		= Arg(step.arg1);
				CodeExpression argT		= Arg(step.target);
				CodeExpression target	= Arg(step.target);

				if (arg0 != null && arg0 is CodePrimitiveExpression == false)
					argUsed[step.arg0] = true;
				if (arg1 != null && arg1 is CodePrimitiveExpression == false)
					argUsed[step.arg1] = true;
				if (target != null && target is CodePrimitiveExpression == false)
					argUsed[step.target] = true;

				if (step.Children.Length > 0)
				{
					CodeVariableReferenceExpression local = new CodeVariableReferenceExpression("i" + depth);

					if (step.type == "loop")
					{
						CodeIterationStatement iteration = new CodeIterationStatement();

						iteration.InitStatement = new CodeVariableDeclarationStatement(typeof(uint), local.VariableName, new CodePrimitiveExpression((uint)0));
						iteration.TestExpression = new CodeBinaryOperatorExpression(local, CodeBinaryOperatorType.LessThan, arg0);
						iteration.IncrementStatement = new CodeAssignStatement(local, new CodeBinaryOperatorExpression(local, CodeBinaryOperatorType.Add, new CodePrimitiveExpression((uint)1)));

						BuildLogic(iteration.Statements, step.Children, argUsed, depth + 1);
						statements.Add(iteration);
					}
					else
					{
						CodeBinaryOperatorType op = CodeBinaryOperatorType.IdentityEquality;
						//if
						switch (step.type)
						{
							case "if_notequal":
								op = CodeBinaryOperatorType.IdentityInequality;
								break;
							case "if_lessequal":
								op = CodeBinaryOperatorType.LessThanOrEqual;
								break;
							case "if_greaterequal":
								op = CodeBinaryOperatorType.GreaterThanOrEqual;
								break;
							case "if_less":
								op = CodeBinaryOperatorType.LessThan;
								break;
							case "if_greater":
								op = CodeBinaryOperatorType.GreaterThan;
								break;
						}

						CodeConditionStatement condition = new CodeConditionStatement();
						condition.Condition = new CodeBinaryOperatorExpression(
							arg0, op, arg1);


						BuildLogic(condition.TrueStatements, step.Children, argUsed, depth + 1);

						statements.Add(condition);
					}
				}
				else
				{
					CodeExpression expression = null;

					switch (step.type)
					{
						case "set":
							expression = arg0;
							break;
						case "add":
							expression = Op(CodeBinaryOperatorType.Add, argT, arg0, arg1);
							break;
						case "sub":
							expression = Op(CodeBinaryOperatorType.Subtract, argT, arg0, arg1);
							break;
						case "mul":
							expression = Op(CodeBinaryOperatorType.Multiply, argT, arg0, arg1);
							break;
						case "div":
							expression = Op(CodeBinaryOperatorType.Divide, argT, arg0, arg1);
							break;
						case "abs":
						case "sign":
						case "cos":
						case "sin":
						case "acos":
						case "asin":
						case "tan":
						case "atan":
						case "sqrt":
							expression = MathOp1(step.type, arg0);
							break;
						case "atan2":
						case "min":
						case "max":
							expression = MathOp2(step.type, arg0, arg1);
							break;
						case "saturate":
							expression =
								MathOp2("max",
									new CodePrimitiveExpression(0.0f),
										MathOp2("min", new CodePrimitiveExpression(1.0f),
											arg0));
							break;
						case "rsqrt":
							expression =
									new CodeBinaryOperatorExpression(
										new CodePrimitiveExpression(1.0f), CodeBinaryOperatorType.Divide,
											MathOp1("sqrt", arg0));
							break;
						case "madd":
							expression =
									new CodeBinaryOperatorExpression(argT,
										CodeBinaryOperatorType.Add,
											new CodeBinaryOperatorExpression(arg0,
												CodeBinaryOperatorType.Multiply,
													arg1));
							break;
						case "rand":
							argUsed["rand"] = true;
							expression = Rand(arg0, arg1, statements);
							break;
						case "rand_smooth":
							argUsed["rand"] = true;
							expression = RandSmooth(arg0, arg1, statements);
							break;
					}

					if (expression == null)
						throw new ArgumentNullException("Unknown statement " + step.type);

					statements.Add(new CodeAssignStatement(target,
						expression));
				}
			}
		}
		private static void BuildLogic(CodeStatementCollection statements, ReadOnlyArrayCollection<ParticleSystemLogicStep> steps, bool addMethod)
		{
			Dictionary<string, bool> argsUsed = new Dictionary<string, bool>();
			foreach (string arg in memberTranslate.Keys)
				argsUsed.Add(arg, false);
			argsUsed.Add("rand", false);

			CodeStatementCollection code = new CodeStatementCollection();
			BuildLogic(code, steps, argsUsed, 0);

			//rand requires a local variable
			if (argsUsed["rand"])
				statements.Add(
					new CodeVariableDeclarationStatement(
						typeof(float), "_tmp", new CodePrimitiveExpression(0.0f)));

			for (int i = 0; i < 4; i++)
			{
				if (argsUsed["local" + i])
				{
					code.Insert(0,
						new CodeVariableDeclarationStatement(
							typeof(float), "local"+i, new CodePrimitiveExpression(0.0f)));
				}
			}

			CodeVariableReferenceExpression ref_i = new CodeVariableReferenceExpression("i");

			if (addMethod) // add methods have indices to update...
				ref_i.VariableName = "_i";

			CodeIterationStatement loop = new CodeIterationStatement();
			loop.InitStatement = new CodeVariableDeclarationStatement(typeof(uint), ref_i.VariableName, new CodePrimitiveExpression(0));
			loop.IncrementStatement = new CodeAssignStatement(ref_i,new CodeBinaryOperatorExpression(ref_i, CodeBinaryOperatorType.Add, new CodePrimitiveExpression((uint)1)));
			loop.TestExpression = new CodeBinaryOperatorExpression(ref_i, CodeBinaryOperatorType.LessThan, new CodeArgumentReferenceExpression("count"));

			// uint i = indices[_i];
			if (addMethod)
				loop.Statements.Add(new CodeVariableDeclarationStatement(typeof(uint), "i", new CodeArrayIndexerExpression(new CodeArgumentReferenceExpression("indices"), ref_i)));
			else
			{
				//put in velocity logic

				loop.Statements.Add(
					new CodeAssignStatement(Arg("position.x"),
						new CodeBinaryOperatorExpression(Arg("position.x"), CodeBinaryOperatorType.Add,
							new CodeBinaryOperatorExpression(Arg("velocity.x"), CodeBinaryOperatorType.Multiply, Arg("delta_time")))));

				loop.Statements.Add(
					new CodeAssignStatement(Arg("position.y"),
						new CodeBinaryOperatorExpression(Arg("position.y"), CodeBinaryOperatorType.Add,
							new CodeBinaryOperatorExpression(Arg("velocity.y"), CodeBinaryOperatorType.Multiply, Arg("delta_time")))));

				loop.Statements.Add(
					new CodeAssignStatement(Arg("position.z"),
						new CodeBinaryOperatorExpression(Arg("position.z"), CodeBinaryOperatorType.Add,
							new CodeBinaryOperatorExpression(Arg("velocity.z"), CodeBinaryOperatorType.Multiply, Arg("delta_time")))));
			}

			loop.Statements.AddRange(code);

			statements.Add(loop);
		}
		//the actual integration step
		public void IntegrateBones(Transform[] boneTransforms, ReadOnlyArrayCollection<Transform> boneWorldSpaceIdentityTransforms, ReadOnlyArrayCollection<Transform> boneWorldSpaceIdentityInverseTransforms)
		{
			//perform the integration (constraints, verlet, etc)
			PerformIntegration();

			//new bone transfomrs will be written to boneTransforms

			Matrix matrix = Matrix.Identity;
			Transform transform = Transform.Identity;

			for (int i = 0; i < boneTransforms.Length; i++)
			{
				if (activeBones[i])
				{
					//for each bone..
					//the centre point (first position)
					Vector3 basis = this.positions[i * BonePointCount];
					//the three positions offset from the centre
					Vector3 x = this.positions[i * BonePointCount + 1];
					Vector3 y = this.positions[i * BonePointCount + 2];
					Vector3 z = this.positions[i * BonePointCount + 3];

					//get the differences to the centre point... 
					x -= basis;
					y -= basis;
					z -= basis;

					//these form the axis of the bone's rotation
					//x-axis of the matrix
					matrix.M11 = x.X;
					matrix.M12 = x.Y;
					matrix.M13 = x.Z;
					//y-axis of the matrix
					matrix.M21 = y.X;
					matrix.M22 = y.Y;
					matrix.M23 = y.Z;
					//z-axis of the matrix
					matrix.M31 = z.X;
					matrix.M32 = z.Y;
					matrix.M33 = z.Z;

					//position
					matrix.M41 = basis.X;
					matrix.M42 = basis.Y;
					matrix.M43 = basis.Z;

					//work out the transform from the matrix...

					//do not perform a validity check in the transform constrctor,
					//as who cares if the matrix isn't orthoganal :-)
					//otherwise it can throw an exception if the matrix is skewed

					transform = new Transform(ref matrix, false);

					//set the transform (multiplied by the inverse of the bone->world transform)
					//as the bones are in world space, needs to be in bone local space
					boneTransforms[i] = (boneWorldSpaceIdentityInverseTransforms[i] * transform);
				}
			}
		}
		//the second method in the animation process.
		//At this point, the normal model animations have been generated.
		//However, the bones have not been transformed into a hierarchy yet.
		public bool ProcessBonesPreTransform(Transform[] boneSpaceTransforms, ModelData modelData, 
			ReadOnlyArrayCollection<Transform> boneWorldSpaceTransforms, ReadOnlyArrayCollection<Transform> boneWorldSpaceInverseTransforms)
		{
			//spin the spine..?
			if (enableModifySingleBone)
			{
				//make a transform to rotate the bone
				Transform transform = Transform.Identity;

				//create a rotation
				Quaternion.CreateFromYawPitchRoll(0, this.rotationValue, 0, out transform.Rotation);

				//modify the bone transform (or you could replace it entirely)
				boneSpaceTransforms[spinBoneIndex] *= transform;
			}

			//returning true continues the animation process, so the hierarchy is transformed and ProcessBonesPostTransform is called
			//return false if animation is complete (for example, the animation has been transformed manually)
			return true;
		}
		//methods of the interface

		//this first method is called before any normal animation calculation takes place
		//the nonAnimatedBones Transforms are usualy still storing the previous frame's animation,
		//however, this is not guarenteed. They should be considered write-only.
		//returning true from this method stops the animation process early
		public bool PreProcessAnimation(Transform[] nonAnimatedBones, ModelData modelData, ReadOnlyArrayCollection<Transform> boneWorldSpaceIdentityTransforms, ReadOnlyArrayCollection<Transform> boneWorldSpaceIdentityInverseTransforms)
		{
			//is the hacky verlet example enabled?
			if (enableVerlet)
			{
				//if so, let the verlet integrator generate the bone transforms itself
				verletSolver.IntegrateBones(nonAnimatedBones, boneWorldSpaceIdentityTransforms, boneWorldSpaceIdentityInverseTransforms);

				//the bones are now entirely generated, so return false.

				//return false because the animation is complete (in this example, the animation has been transformed manually)
				return false;
			}

			//returning true continues the animation process,
			//so the animations are generated, interpolated and ProcessBonesPreTransform is called.
			return true;
		}
예제 #16
0
        private static void BuildLogic(CodeStatementCollection statements, ReadOnlyArrayCollection <ParticleSystemLogicStep> steps, Dictionary <string, bool> argUsed, int depth)
        {
            for (int i = 0; i < steps.Length; i++)
            {
                ParticleSystemLogicStep step = steps[i];

                CodeExpression arg0   = Arg(step.arg0);
                CodeExpression arg1   = Arg(step.arg1);
                CodeExpression argT   = Arg(step.target);
                CodeExpression target = Arg(step.target);

                if (arg0 != null && arg0 is CodePrimitiveExpression == false)
                {
                    argUsed[step.arg0] = true;
                }
                if (arg1 != null && arg1 is CodePrimitiveExpression == false)
                {
                    argUsed[step.arg1] = true;
                }
                if (target != null && target is CodePrimitiveExpression == false)
                {
                    argUsed[step.target] = true;
                }

                if (step.Children.Length > 0)
                {
                    CodeVariableReferenceExpression local = new CodeVariableReferenceExpression("i" + depth);

                    if (step.type == "loop")
                    {
                        CodeIterationStatement iteration = new CodeIterationStatement();

                        iteration.InitStatement      = new CodeVariableDeclarationStatement(typeof(uint), local.VariableName, new CodePrimitiveExpression((uint)0));
                        iteration.TestExpression     = new CodeBinaryOperatorExpression(local, CodeBinaryOperatorType.LessThan, arg0);
                        iteration.IncrementStatement = new CodeAssignStatement(local, new CodeBinaryOperatorExpression(local, CodeBinaryOperatorType.Add, new CodePrimitiveExpression((uint)1)));

                        BuildLogic(iteration.Statements, step.Children, argUsed, depth + 1);
                        statements.Add(iteration);
                    }
                    else
                    {
                        CodeBinaryOperatorType op = CodeBinaryOperatorType.IdentityEquality;
                        //if
                        switch (step.type)
                        {
                        case "if_notequal":
                            op = CodeBinaryOperatorType.IdentityInequality;
                            break;

                        case "if_lessequal":
                            op = CodeBinaryOperatorType.LessThanOrEqual;
                            break;

                        case "if_greaterequal":
                            op = CodeBinaryOperatorType.GreaterThanOrEqual;
                            break;

                        case "if_less":
                            op = CodeBinaryOperatorType.LessThan;
                            break;

                        case "if_greater":
                            op = CodeBinaryOperatorType.GreaterThan;
                            break;
                        }

                        CodeConditionStatement condition = new CodeConditionStatement();
                        condition.Condition = new CodeBinaryOperatorExpression(
                            arg0, op, arg1);


                        BuildLogic(condition.TrueStatements, step.Children, argUsed, depth + 1);

                        statements.Add(condition);
                    }
                }
                else
                {
                    CodeExpression expression = null;

                    switch (step.type)
                    {
                    case "set":
                        expression = arg0;
                        break;

                    case "add":
                        expression = Op(CodeBinaryOperatorType.Add, argT, arg0, arg1);
                        break;

                    case "sub":
                        expression = Op(CodeBinaryOperatorType.Subtract, argT, arg0, arg1);
                        break;

                    case "mul":
                        expression = Op(CodeBinaryOperatorType.Multiply, argT, arg0, arg1);
                        break;

                    case "div":
                        expression = Op(CodeBinaryOperatorType.Divide, argT, arg0, arg1);
                        break;

                    case "abs":
                    case "sign":
                    case "cos":
                    case "sin":
                    case "acos":
                    case "asin":
                    case "tan":
                    case "atan":
                    case "sqrt":
                        expression = MathOp1(step.type, arg0);
                        break;

                    case "atan2":
                    case "min":
                    case "max":
                        expression = MathOp2(step.type, arg0, arg1);
                        break;

                    case "saturate":
                        expression =
                            MathOp2("max",
                                    new CodePrimitiveExpression(0.0f),
                                    MathOp2("min", new CodePrimitiveExpression(1.0f),
                                            arg0));
                        break;

                    case "rsqrt":
                        expression =
                            new CodeBinaryOperatorExpression(
                                new CodePrimitiveExpression(1.0f), CodeBinaryOperatorType.Divide,
                                MathOp1("sqrt", arg0));
                        break;

                    case "madd":
                        expression =
                            new CodeBinaryOperatorExpression(argT,
                                                             CodeBinaryOperatorType.Add,
                                                             new CodeBinaryOperatorExpression(arg0,
                                                                                              CodeBinaryOperatorType.Multiply,
                                                                                              arg1));
                        break;

                    case "rand":
                        argUsed["rand"] = true;
                        expression      = Rand(arg0, arg1, statements);
                        break;

                    case "rand_smooth":
                        argUsed["rand"] = true;
                        expression      = RandSmooth(arg0, arg1, statements);
                        break;
                    }

                    if (expression == null)
                    {
                        throw new ArgumentNullException("Unknown statement " + step.type);
                    }

                    statements.Add(new CodeAssignStatement(target,
                                                           expression));
                }
            }
        }
예제 #17
0
        //NEW CODE
        private void DrawBoundingBoxes(DrawState state)
        {
            //First, get the animated bone transforms of the model.
            //These transforms are in 'bone-space', not in world space.
            ReadOnlyArrayCollection <Transform> boneAnimationTransforms = model.GetAnimationController().GetTransformedBones(state);


            //Get a simple shader from Xen.Ex that fills a solid colour
            Xen.Ex.Shaders.FillSolidColour shader = state.GetShader <Xen.Ex.Shaders.FillSolidColour>();

            shader.FillColour = Color.White.ToVector4();

            shader.Bind(state);



            //push the render state...
            state.PushRenderState();

            //disable back face culling
            state.RenderState.DepthColourCull.CullMode = CullMode.None;
            //set to wireframe
            state.RenderState.DepthColourCull.FillMode = FillMode.WireFrame;

            //loop through all the geometry data in the model..
            //(note, the sample model has only 1 geometry instance)


            Xen.Ex.Graphics.Content.SkeletonData modelSkeleton = model.ModelData.Skeleton;
            Matrix matrix;
            int    boxIndex = 0;

            foreach (Xen.Ex.Graphics.Content.MeshData meshData in model.ModelData.Meshes)
            {
                foreach (Xen.Ex.Graphics.Content.GeometryData geometry in meshData.Geometry)
                {
                    //now loop through all bones used by this geometry

                    for (int geometryBone = 0; geometryBone < geometry.BoneIndices.Length; geometryBone++)
                    {
                        //index of the bone (a piece of geometry may not use all the bones in the model)
                        int boneIndex = geometry.BoneIndices[geometryBone];

                        //get the base transform of the bone (the transform when not animated)
                        Transform boneTransform = modelSkeleton.BoneWorldTransforms[boneIndex];

                        //multiply the transform with the animation bone-local transform

                        //it would be better to use Transform.Multiply() here to save data copying on the xbox
                        boneTransform *= boneAnimationTransforms[boneIndex];

                        //Get the transform as a matrix
                        boneTransform.GetMatrix(out matrix);

                        //push the matrix
                        state.PushWorldMatrix(ref matrix);

                        //draw the box
                        if (boundingBoxes[boxIndex].CullTest(state))
                        {
                            boundingBoxes[boxIndex].Draw(state);
                        }

                        boxIndex++;

                        //pop the world matrix
                        state.PopWorldMatrix();
                    }
                }
            }

            //pop the render state
            state.PopRenderState();
        }
 public bool PreProcessAnimation(Transform[] nonAnimatedBones, ModelData modelData, ReadOnlyArrayCollection<Transform> boneWorldSpaceIdentityTransforms, ReadOnlyArrayCollection<Transform> boneWorldSpaceIdentityInverseTransforms)
 {
     return true;
 }