예제 #1
0
		private void CalculateBounds(idJointMatrix[] entityJoints)
		{
			_bounds.Clear();

			foreach(idMD5Mesh mesh in _meshes)
			{
				_bounds.AddBounds(mesh.CalculateBounds(entityJoints));
			}
		}
예제 #2
0
        /// <summary>
        /// Compare, with epsilon.
        /// </summary>
        /// <param name="m"></param>
        /// <param name="epsilon"></param>
        /// <returns></returns>
        public bool Equals(idJointMatrix m, float epsilon)
        {
            for (int i = 0; i < 12; i++)
            {
                if (idMath.Abs(_m[i] - m._m[i]) > epsilon)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        /// <summary>
        /// Exact compare, no epsilon.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool Equals(idJointMatrix m)
        {
            for (int i = 0; i < 12; i++)
            {
                if (_m[i] != m._m[i])
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #4
0
        public static idJointMatrix Transform(idJointMatrix x, idJointMatrix y)
        {
            float[] m   = (float[])x._m.Clone();
            float[] dst = new float[3];

            dst[0]       = m[0 * 4 + 0] * y._m[0 * 4 + 0] + m[1 * 4 + 0] * y._m[0 * 4 + 1] + m[2 * 4 + 0] * y._m[0 * 4 + 2];
            dst[1]       = m[0 * 4 + 0] * y._m[1 * 4 + 0] + m[1 * 4 + 0] * y._m[1 * 4 + 1] + m[2 * 4 + 0] * y._m[1 * 4 + 2];
            dst[2]       = m[0 * 4 + 0] * y._m[2 * 4 + 0] + m[1 * 4 + 0] * y._m[2 * 4 + 1] + m[2 * 4 + 0] * y._m[2 * 4 + 2];
            m[0 * 4 + 0] = dst[0];
            m[1 * 4 + 0] = dst[1];
            m[2 * 4 + 0] = dst[2];

            dst[0]       = m[0 * 4 + 1] * y._m[0 * 4 + 0] + m[1 * 4 + 1] * y._m[0 * 4 + 1] + m[2 * 4 + 1] * y._m[0 * 4 + 2];
            dst[1]       = m[0 * 4 + 1] * y._m[1 * 4 + 0] + m[1 * 4 + 1] * y._m[1 * 4 + 1] + m[2 * 4 + 1] * y._m[1 * 4 + 2];
            dst[2]       = m[0 * 4 + 1] * y._m[2 * 4 + 0] + m[1 * 4 + 1] * y._m[2 * 4 + 1] + m[2 * 4 + 1] * y._m[2 * 4 + 2];
            m[0 * 4 + 1] = dst[0];
            m[1 * 4 + 1] = dst[1];
            m[2 * 4 + 1] = dst[2];

            dst[0]       = m[0 * 4 + 2] * y._m[0 * 4 + 0] + m[1 * 4 + 2] * y._m[0 * 4 + 1] + m[2 * 4 + 2] * y._m[0 * 4 + 2];
            dst[1]       = m[0 * 4 + 2] * y._m[1 * 4 + 0] + m[1 * 4 + 2] * y._m[1 * 4 + 1] + m[2 * 4 + 2] * y._m[1 * 4 + 2];
            dst[2]       = m[0 * 4 + 2] * y._m[2 * 4 + 0] + m[1 * 4 + 2] * y._m[2 * 4 + 1] + m[2 * 4 + 2] * y._m[2 * 4 + 2];
            m[0 * 4 + 2] = dst[0];
            m[1 * 4 + 2] = dst[1];
            m[2 * 4 + 2] = dst[2];

            dst[0]       = m[0 * 4 + 3] * y._m[0 * 4 + 0] + m[1 * 4 + 3] * y._m[0 * 4 + 1] + m[2 * 4 + 3] * y._m[0 * 4 + 2];
            dst[1]       = m[0 * 4 + 3] * y._m[1 * 4 + 0] + m[1 * 4 + 3] * y._m[1 * 4 + 1] + m[2 * 4 + 3] * y._m[1 * 4 + 2];
            dst[2]       = m[0 * 4 + 3] * y._m[2 * 4 + 0] + m[1 * 4 + 3] * y._m[2 * 4 + 1] + m[2 * 4 + 3] * y._m[2 * 4 + 2];
            m[0 * 4 + 3] = dst[0];
            m[1 * 4 + 3] = dst[1];
            m[2 * 4 + 3] = dst[2];

            m[0 * 4 + 3] += y._m[0 * 4 + 3];
            m[1 * 4 + 3] += y._m[1 * 4 + 3];
            m[2 * 4 + 3] += y._m[2 * 4 + 3];

            return(new idJointMatrix(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11]));
        }
예제 #5
0
		/// <summary>
		/// Compare, with epsilon.
		/// </summary>
		/// <param name="m"></param>
		/// <param name="epsilon"></param>
		/// <returns></returns>
		public bool Equals(idJointMatrix m, float epsilon)
		{
			for(int i = 0; i < 12; i++)
			{
				if(idMath.Abs(_m[i] - m._m[i]) > epsilon)
				{
					return false;
				}
			}

			return true;
		}
예제 #6
0
		/// <summary>
		/// Exact compare, no epsilon.
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public bool Equals(idJointMatrix m)
		{
			for(int i = 0; i < 12; i++)
			{
				if(_m[i] != m._m[i])
				{
					return false;
				}
			}

			return true;
		}
예제 #7
0
		public static idJointMatrix Transform(idJointMatrix x, idJointMatrix y)
		{
			float[] m = (float[]) x._m.Clone();
			float[] dst = new float[3];

			dst[0] = m[0 * 4 + 0] * y._m[0 * 4 + 0] + m[1 * 4 + 0] * y._m[0 * 4 + 1] + m[2 * 4 + 0] * y._m[0 * 4 + 2];
			dst[1] = m[0 * 4 + 0] * y._m[1 * 4 + 0] + m[1 * 4 + 0] * y._m[1 * 4 + 1] + m[2 * 4 + 0] * y._m[1 * 4 + 2];
			dst[2] = m[0 * 4 + 0] * y._m[2 * 4 + 0] + m[1 * 4 + 0] * y._m[2 * 4 + 1] + m[2 * 4 + 0] * y._m[2 * 4 + 2];
			m[0 * 4 + 0] = dst[0];
			m[1 * 4 + 0] = dst[1];
			m[2 * 4 + 0] = dst[2];

			dst[0] = m[0 * 4 + 1] * y._m[0 * 4 + 0] + m[1 * 4 + 1] * y._m[0 * 4 + 1] + m[2 * 4 + 1] * y._m[0 * 4 + 2];
			dst[1] = m[0 * 4 + 1] * y._m[1 * 4 + 0] + m[1 * 4 + 1] * y._m[1 * 4 + 1] + m[2 * 4 + 1] * y._m[1 * 4 + 2];
			dst[2] = m[0 * 4 + 1] * y._m[2 * 4 + 0] + m[1 * 4 + 1] * y._m[2 * 4 + 1] + m[2 * 4 + 1] * y._m[2 * 4 + 2];
			m[0 * 4 + 1] = dst[0];
			m[1 * 4 + 1] = dst[1];
			m[2 * 4 + 1] = dst[2];

			dst[0] = m[0 * 4 + 2] * y._m[0 * 4 + 0] + m[1 * 4 + 2] * y._m[0 * 4 + 1] + m[2 * 4 + 2] * y._m[0 * 4 + 2];
			dst[1] = m[0 * 4 + 2] * y._m[1 * 4 + 0] + m[1 * 4 + 2] * y._m[1 * 4 + 1] + m[2 * 4 + 2] * y._m[1 * 4 + 2];
			dst[2] = m[0 * 4 + 2] * y._m[2 * 4 + 0] + m[1 * 4 + 2] * y._m[2 * 4 + 1] + m[2 * 4 + 2] * y._m[2 * 4 + 2];
			m[0 * 4 + 2] = dst[0];
			m[1 * 4 + 2] = dst[1];
			m[2 * 4 + 2] = dst[2];

			dst[0] = m[0 * 4 + 3] * y._m[0 * 4 + 0] + m[1 * 4 + 3] * y._m[0 * 4 + 1] + m[2 * 4 + 3] * y._m[0 * 4 + 2];
			dst[1] = m[0 * 4 + 3] * y._m[1 * 4 + 0] + m[1 * 4 + 3] * y._m[1 * 4 + 1] + m[2 * 4 + 3] * y._m[1 * 4 + 2];
			dst[2] = m[0 * 4 + 3] * y._m[2 * 4 + 0] + m[1 * 4 + 3] * y._m[2 * 4 + 1] + m[2 * 4 + 3] * y._m[2 * 4 + 2];
			m[0 * 4 + 3] = dst[0];
			m[1 * 4 + 3] = dst[1];
			m[2 * 4 + 3] = dst[2];

			m[0 * 4 + 3] += y._m[0 * 4 + 3];
			m[1 * 4 + 3] += y._m[1 * 4 + 3];
			m[2 * 4 + 3] += y._m[2 * 4 + 3];

			return new idJointMatrix(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11]);
		}
예제 #8
0
		private void TransformVertices(Vertex[] verts, idJointMatrix[] entityJoints)
		{
			int j, i;
			int vertCount = verts.Length;

			for(j = i = 0; i < vertCount; i++)
			{
				Vector3 w = new Vector3(_scaledWeights[j].X, _scaledWeights[j].Y, _scaledWeights[j].Z);
				Vector3 v = entityJoints[_weightIndex[j * 2 + 0]].ToVector3() * w;

				while(_weightIndex[j * 2 + 1] == 0)
				{
					j++;
					v += entityJoints[_weightIndex[j * 2 + 0]].ToVector3() * w;
				}

				j++;
				verts[i].Position = v;
			}
		}
예제 #9
0
		public void Parse(idLexer lexer, idJointMatrix[] joints)
		{
			lexer.ExpectTokenString("{");

			//
			// parse name
			//
			if(lexer.CheckTokenString("name") == true)
			{
				lexer.ReadToken();
			}

			//
			// parse shader
			//
			lexer.ExpectTokenString("shader");

			idToken token = lexer.ReadToken();
			string materialName = token.ToString();

			_material = idE.DeclManager.FindMaterial(materialName);

			//
			// parse texture coordinates
			//
			lexer.ExpectTokenString("numverts");
			int count = lexer.ParseInt();

			if(count < 0)
			{
				lexer.Error("Invalid size: {0}", token.ToString());
			}

			_texCoords = new Vector2[count];

			int[] firstWeightForVertex = new int[count];
			int[] weightCountForVertex = new int[count];
			int maxWeight = 0;
			int coordCount = _texCoords.Length;

			_weightCount = 0;

			for(int i = 0; i < coordCount; i++)
			{
				lexer.ExpectTokenString("vert");
				lexer.ParseInt();

				float[] tmp = lexer.Parse1DMatrix(2);

				_texCoords[i] = new Vector2(tmp[0], tmp[1]);
				
				firstWeightForVertex[i] = lexer.ParseInt();
				weightCountForVertex[i] = lexer.ParseInt();

				if(weightCountForVertex[i] == 0)
				{
					lexer.Error("Vertex without any joint weights.");
				}

				_weightCount += weightCountForVertex[i];

				if((weightCountForVertex[i] + firstWeightForVertex[i]) > maxWeight)
				{
					maxWeight = weightCountForVertex[i] + firstWeightForVertex[i];
				}
			}

			//
			// parse tris
			//
			lexer.ExpectTokenString("numtris");
			_triangleCount = lexer.ParseInt();

			if(_triangleCount < 0)
			{
				lexer.Error("Invalid size: {0}", _triangleCount);
			}

			int[] tris = new int[_triangleCount * 3];

			for(int i = 0; i < _triangleCount; i++)
			{
				lexer.ExpectTokenString("tri");
				lexer.ParseInt();

				tris[i * 3 + 0] = lexer.ParseInt();
				tris[i * 3 + 1] = lexer.ParseInt();
				tris[i * 3 + 2] = lexer.ParseInt();
			}

			//
			// parse weights
			//
			lexer.ExpectTokenString("numweights");
			count = lexer.ParseInt();

			if(count < 0)
			{
				lexer.Error("Invalid size: {0}", count);
			}

			if(maxWeight > count)
			{
				lexer.Warning("Vertices reference out of range weights in model ({0} of {1} weights).", maxWeight, count);
			}

			VertexWeight[] tempWeights = new VertexWeight[count];

			for(int i = 0; i < count; i++)
			{
				lexer.ExpectTokenString("weight");
				lexer.ParseInt();

				int jointIndex = lexer.ParseInt();

				if((jointIndex < 0) || (jointIndex >= joints.Length))
				{
					lexer.Error("Joint index out of range({0}): {1}", joints.Length, jointIndex);
				}

				tempWeights[i].JointIndex = jointIndex;
				tempWeights[i].JointWeight = lexer.ParseFloat();

				float[] tmp = lexer.Parse1DMatrix(3);

				tempWeights[i].Offset = new Vector3(tmp[0], tmp[1], tmp[2]);
			}

			// create pre-scaled weights and an index for the vertex/joint lookup
			_scaledWeights = new Vector4[_weightCount];
			_weightIndex = new int[_weightCount * 2];

			count = 0;
			coordCount = _texCoords.Length;

			for(int i = 0; i < coordCount; i++)
			{
				int num = firstWeightForVertex[i];
				int weightCount = weightCountForVertex[i];

				for(int j = 0; j < weightCount; j++, num++, count++)
				{
					Vector3 tmp = tempWeights[num].Offset * tempWeights[num].JointWeight;

					_scaledWeights[count].X = tmp.X;
					_scaledWeights[count].Y = tmp.Y;
					_scaledWeights[count].Z = tmp.Z;
					_scaledWeights[count].W = tempWeights[num].JointWeight;

					_weightIndex[count * 2 + 0] = tempWeights[num].JointIndex;
				}

				_weightIndex[count * 2 - 1] = 1;
			}

			lexer.ExpectTokenString("}");

			// update counters
			idConsole.Warning("TODO: idRenderModel_MD5 update counters");

			/*c_numVerts += texCoords.Num();
			c_numWeights += numWeights;
			c_numWeightJoints++;
			for ( i = 0; i < numWeights; i++ ) {
				c_numWeightJoints += weightIndex[i*2+1];
			}*/

			//
			// build the information that will be common to all animations of this mesh:
			// silhouette edge connectivity and normal / tangent generation information
			//
			Vertex[] verts = new Vertex[_texCoords.Length];
			int vertCount = verts.Length;

			for(int i = 0; i < vertCount; i++)
			{
				verts[i].TextureCoordinates = _texCoords[i];
			}

			TransformVertices(verts, joints);

			idConsole.Warning("TODO: idMD5Mesh Deform");
			//_deformInfo = idE.RenderSystem.BuildDeformInformation(verts, tris, _material.UseUnsmoothedTangents);
		}
예제 #10
0
		public idBounds CalculateBounds(idJointMatrix[] joints)
		{
			Vertex[] verts = new Vertex[_texCoords.Length];
			idBounds bounds = idBounds.Zero;

			TransformVertices(verts, joints);

			idHelper.MinMax(ref bounds.Min, ref bounds.Max, verts, _texCoords.Length);

			return bounds;
		}
예제 #11
0
		/// <summary>
		/// Used for initial loads, reloadModel, and reloading the data of purged models.
		/// </summary>
		/// <remarks>
		/// Upon exit, the model will absolutely be valid, but possibly as a default model.
		/// </remarks>
		public override void Load()
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			if(_purged == false)
			{
				Purge();
			}

			_purged = false;

			idLexer lexer = new idLexer(LexerOptions.AllowPathNames | LexerOptions.NoStringEscapeCharacters);

			if(lexer.LoadFile(Name) == false)
			{
				MakeDefault();
				return;
			}

			lexer.ExpectTokenString(VersionString);

			int version = lexer.ParseInt();
			int count = 0;
			idToken token;

			if(version != Version)
			{
				lexer.Error("Invalid version {0}. Should be version {1}", version, Version);
			}

			//
			// skip commandline
			//
			lexer.ExpectTokenString("commandline");
			lexer.ReadToken();

			// parse num joints
			lexer.ExpectTokenString("numJoints");

			count = lexer.ParseInt();

			_joints = new idMD5Joint[count];
			_defaultPose = new idJointQuaternion[count];
			
			idJointMatrix[] poseMat3 = new idJointMatrix[count];

			// parse num meshes
			lexer.ExpectTokenString("numMeshes");
			count = lexer.ParseInt();

			if(count < 0)
			{
				lexer.Error("Invalid size: {0}", count);
			}

			_meshes = new idMD5Mesh[count];

			//
			// parse joints
			//
			lexer.ExpectTokenString("joints");
			lexer.ExpectTokenString("{");

			int jointCount = _joints.Length;

			for(int i = 0; i < jointCount; i++)
			{
				idMD5Joint joint = _joints[i] = new idMD5Joint();
				idJointQuaternion pose = new idJointQuaternion();

				ParseJoint(lexer, joint, ref pose);

				poseMat3[i] = idJointMatrix.Zero;
				poseMat3[i].Rotation = Matrix.CreateFromQuaternion(pose.Quaternion);
				poseMat3[i].Translation = pose.Translation;

				if(joint.Parent != null)
				{
					int parentIndex = GetJointIndex(joint.Parent);

					pose.Quaternion = Quaternion.CreateFromRotationMatrix(poseMat3[i].ToMatrix() 
										* Matrix.Transpose(poseMat3[parentIndex].ToMatrix()));
					pose.Translation = Vector3.Transform(poseMat3[i].ToVector3() - poseMat3[parentIndex].ToVector3(), 
										Matrix.Transpose(poseMat3[parentIndex].ToMatrix()));
				}

				_defaultPose[i] = pose;
			}

			lexer.ExpectTokenString("}");

			int meshCount = _meshes.Length;

			for(int i = 0; i < meshCount; i++)
			{
				lexer.ExpectTokenString("mesh");

				_meshes[i] = new idMD5Mesh();
				_meshes[i].Parse(lexer, poseMat3);
			}

			//
			// calculate the bounds of the model
			//
			CalculateBounds(poseMat3);

			// set the timestamp for reloadmodels
			idConsole.Warning("TODO: fileSystem->ReadFile( name, NULL, &timeStamp );");
		}
예제 #12
0
		public void SetupJoints(idJointMatrix[] joints, ref idBounds frameBounds, bool removeOriginOffset)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			if((_model == null) || (_model.IsDefault == true))
			{
				joints = null;
				frameBounds.Clear();
			}

			// get the number of joints
			int count = _model.JointCount;

			if(count == 0)
			{
				idConsole.Error("model '{0}' has no joints", _model.Name);
			}
			
			// set up initial pose for model (with no pose, model is just a jumbled mess)
			joints = new idJointMatrix[count];
			idJointQuaternion[] pose = this.DefaultPose;
			
			// convert the joint quaternions to joint matrices
			idHelper.ConvertJointQuaternionsToJointMatrices(joints, pose);

			// check if we offset the model by the origin joint
			if(removeOriginOffset == true)
			{
#if VELOCITY_MOVE
				joints[0].Translation(new Vector3(_offset.X, _offset.Y + pose[0].Translation.Y, _offset.Z + pose[0].Translation.Z));
#else
				joints[0].Translation = _offset;
#endif
			} 
			else 
			{
				joints[0].Translation = pose[0].Translation + _offset;
			}

			// transform the joint hierarchy
			idHelper.TransformJoints(joints, _jointParents, 1, joints.Length - 1);
			
			// get the bounds of the default pose
			frameBounds = _model.GetBounds(null);
		}