Пример #1
0
		private void BuildFace(ref SourceFace face, BspSubmeshStreams subMesh)
		{
			Vertex[] faceVertices = new Vertex[face.numedges];

			var plane = this.planes[face.planenum];
			var texture_id = this.texInfo[face.texinfo].texdata;

			Float2 minUV0 = new Float2(float.MaxValue, float.MaxValue);
			Float2 minUV1 = new Float2(float.MaxValue, float.MaxValue);
			Float2 maxUV1 = new Float2(float.MinValue, float.MinValue);
			int nextShouldBe = -1;
			for (int index = 0; index < faceVertices.Length; index++)
			{
				var listOfEdgesIndex = face.firstedge + index;
				if (listOfEdgesIndex >= this.listOfEdges.Length)
				{
					throw new BspFormatException(
						string.Format("Edge list index {0} is out of range [0..{1}]", listOfEdgesIndex, this.listOfEdges.Length - 1));
				}

				var edgeIndex = this.listOfEdges[listOfEdgesIndex];
				if (edgeIndex >= this.edges.Length)
				{
					throw new BspFormatException(
						string.Format("Edge index {0} is out of range [0..{1}]", edgeIndex, this.edges.Length - 1));
				}

				SourceEdge edge;
				if (edgeIndex >= 0)
				{
					edge = this.edges[edgeIndex];
				}
				else
				{
					var flippedEdge = this.edges[-edgeIndex];
					edge = new SourceEdge { vertex0 = flippedEdge.vertex1, vertex1 = flippedEdge.vertex0 };
				}
				var edgesvertex0 = edge.vertex0;
				if (edgesvertex0 >= this.vertices.Length)
				{
					throw new BspFormatException(
						string.Format("Vertex index {0} is out of range [0..{1}]", edgesvertex0, this.vertices.Length - 1));
				}
				var edgesvertex1 = edge.vertex1;
				if (edgesvertex1 >= this.vertices.Length)
				{
					throw new BspFormatException(
						string.Format("Vertex index {0} is out of range [0..{1}]", edgesvertex1, this.vertices.Length - 1));
				}
				if (nextShouldBe >= 0 && nextShouldBe != edgesvertex0)
				{
					throw new BspFormatException(string.Format("Wrong edge order"));
				}
				nextShouldBe = edgesvertex1;
				Vertex vertex;
				this.BuildVertex(
					this.vertices[(short)edgesvertex0],
					plane.normal,
					//(face.side == 0) ? plane.normal : -plane.normal,
					face,
					ref this.texInfo[face.texinfo],
					out vertex);
				faceVertices[index] = vertex;
				if (minUV0.X > vertex.UV0.X)
				{
					minUV0.X = vertex.UV0.X;
				}
				if (minUV0.Y > vertex.UV0.Y)
				{
					minUV0.Y = vertex.UV0.Y;
				}
				if (minUV1.X > vertex.UV1.X)
				{
					minUV1.X = vertex.UV1.X;
				}
				if (minUV1.Y > vertex.UV1.Y)
				{
					minUV1.Y = vertex.UV1.Y;
				}
				if (maxUV1.X < vertex.UV1.X)
				{
					maxUV1.X = vertex.UV1.X;
				}
				if (maxUV1.Y < vertex.UV1.Y)
				{
					maxUV1.Y = vertex.UV1.Y;
				}
			}
			if (this.textures[texture_id].name == "TOOLS/TOOLSSKYBOX")
			{
				minUV0.X = 0;
				minUV0.Y = 0;
				for (int j = 0; j < (int)face.numedges; ++j)
				{
					faceVertices[j].UV0 = new Float3(0, 0, 0);
				}
			}

			int[] indices = new int[faceVertices.Length];
			for (int j = 0; j < faceVertices.Length; ++j)
			{
				meshStreams.Positions.Add(faceVertices[j].Position);
				meshStreams.Normals.Add(faceVertices[j].Normal);
				meshStreams.Colors.Add(faceVertices[j].Color);
				meshStreams.TexCoord0.Add(new Float2(faceVertices[j].UV0.X, faceVertices[j].UV0.Y));
				meshStreams.TexCoord1.Add(new Float2(faceVertices[j].UV1.X, faceVertices[j].UV1.Y));
			}
			for (int j = 1; j < faceVertices.Length - 1; ++j)
			{
				subMesh.AddToAllStreams(indices[0]);
				subMesh.AddToAllStreams(indices[j]);
				subMesh.AddToAllStreams(indices[j + 1]);
			}
		}
Пример #2
0
		private void BuildPatch(Quake3Face quake3Face, BspSubmeshStreams submesh)
		{
			var width = quake3Face.sizeX;
			var height = quake3Face.sizeY;
			if (width * height != quake3Face.numOfVerts)
			{
				throw new BspFormatException("wrong patch point count");
			}
			for (int i = 0; i < width - 1; i += 1)
			{
				for (int j = 0; j < height - 1; j += 1)
				{
					AddVertexToMesh(quake3Face.vertexIndex + (i) + (j) * width, submesh);
					AddVertexToMesh(quake3Face.vertexIndex + (i + 1) + (j + 1) * width, submesh);
					AddVertexToMesh(quake3Face.vertexIndex + (i + 1) + (j) * width, submesh);

					AddVertexToMesh(quake3Face.vertexIndex + (i) + (j) * width, submesh);
					AddVertexToMesh(quake3Face.vertexIndex + (i) + (j + 1) * width, submesh);
					AddVertexToMesh(quake3Face.vertexIndex + (i + 1) + (j + 1) * width, submesh);
				}
			}
		}
Пример #3
0
		protected override void BuildScene()
		{
			this.CollectLeafsInCluster();
			//BuildVisibilityList();

			var node = new Node();
			this.Scene.Nodes.Add(node);

			if (this.buildBsp)
			{
				this.Scene.Geometries.Add(streamMesh);
				var meshBuilder = new MeshBuilder(streamMesh, this);
				node.Mesh = streamMesh;

				var vsdNodes = new BspVsdTreeNode[this.nodes.Length];
				for (int index = 0; index < this.nodes.Length; index++)
				{
					var sourceNode = this.nodes[index];
					vsdNodes[index] = new BspVsdTreeNode
						{
							Min = new Float3(sourceNode.box.boxMinX, sourceNode.box.boxMinY, sourceNode.box.boxMinZ),
							Max = new Float3(sourceNode.box.boxMaxX, sourceNode.box.boxMaxY, sourceNode.box.boxMaxZ),
							PositiveNodeIndex = sourceNode.front,
							NegativeNodeIndex = sourceNode.back,
							N = this.planes[sourceNode.planenum].normal,
							D = this.planes[sourceNode.planenum].dist,
						};
					if (sourceNode.face_num > 0)
					{
						//TODO: put this faces into geometry
						sourceNode.face_num = sourceNode.face_num;
					}
				}

				List<int> visibleClustersLookup = new List<int>();
				List<int> visibleMeshesLookup = new List<int>();
				var vsdLeaves = new BspVsdTreeLeaf[this.leaves.Length];
				var vsdClusters = new BspVsdTreeCluster[this.clusters.Length];
				//int nodesMeshId;
				//var nodesMesh = meshBuilder.EnsureSubMesh(new BspSubmeshKey(-1, new BspMaterialKey(0, 0)), out nodesMeshId);
				//for (int index = 0; index < this.nodes.Length; index++)
				//{
				//    for (int j = nodes[index].face_id; j < nodes[index].face_id + nodes[index].face_num;++j )
				//        this.BuildFace(ref this.faces[j], nodesMesh, streamMesh);
				//}
				for (int index = 0; index < this.leaves.Length; index++)
				{
					var sourceLeaf = this.leaves[index];
					vsdLeaves[index] = new BspVsdTreeLeaf
						{
							Min = new Float3(sourceLeaf.box.boxMinX, sourceLeaf.box.boxMinY, sourceLeaf.box.boxMinZ),
							Max = new Float3(sourceLeaf.box.boxMaxX, sourceLeaf.box.boxMaxY, sourceLeaf.box.boxMaxZ),
							Cluster = sourceLeaf.cluster,
						};
				}
				for (int index = 0; index < this.clusters.Length; index++)
				{
					Dictionary<int, bool> uniqueSubmeshes = new Dictionary<int, bool>();
					var sourceCluster = this.clusters[index];
					vsdClusters[index] = new BspVsdTreeCluster
						{
							VisibleClustersCount = sourceCluster.visiblity.Count,
							VisibleClustersOffset = visibleClustersLookup.Count,
							VisibleMeshesOffset = visibleMeshesLookup.Count,
						};

					visibleClustersLookup.AddRange(sourceCluster.visiblity);

					Dictionary<int, bool> uniqueFaces = new Dictionary<int, bool>();

					foreach (var leafIndex in sourceCluster.leaves)
					{
						var sourceLeaf = this.leaves[leafIndex];
						var faceBegin = sourceLeaf.firstleafface;
						var faceEnd = faceBegin + sourceLeaf.numleaffaces;
						for (int f = faceBegin; f < faceEnd; ++f)
						{
							uniqueFaces[this.leafFaces[f]] = true;
						}
					}
					foreach (var uniqueFace in uniqueFaces)
					{
						int texIndex = 0; // this.texInfo[this.faces[faceIndex].texinfo].texdata;
						int lightmapIndex = 0; //this.faces[faceIndex].lightmap;

						int meshIndex;
						SeparateStreamsSubmesh subMesh =
							meshBuilder.EnsureSubMesh(new BspSubmeshKey(index, new BspMaterialKey(texIndex, lightmapIndex)), out meshIndex);
						if (!uniqueSubmeshes.ContainsKey(meshIndex))
						{
							visibleMeshesLookup.Add(meshIndex);
							uniqueSubmeshes[meshIndex] = true;
						}
						BspSubmeshStreams submeshStreams= new BspSubmeshStreams(subMesh, meshStreams,StreamConverterFactory);
						this.BuildFace(ref this.faces[uniqueFace.Key], submeshStreams);
					}
					vsdClusters[index].VisibleMeshesCount = visibleMeshesLookup.Count - vsdClusters[index].VisibleMeshesOffset;
				}

				//for (int index = 0; index < usedFaces.Length; index++)
				//{
				//    if (!usedFaces[index])
				//    {
				//        for (int i = 0; i < this.models.Length; i++)
				//        {
				//            if (this.models[i].firstface <= index && this.models[i].firstface+this.models[i].numfaces > index)
				//            {
				//                Trace.WriteLine(string.Format("Lost face {0} belongs to model {1}", index, i));
				//                break;
				//            }
				//        }
				//        for (int i = 0; i < this.nodes.Length; i++)
				//        {
				//            if (this.nodes[i].face_id <= index && this.nodes[i].face_id + this.nodes[i].face_num > index)
				//            {
				//                Trace.WriteLine(string.Format("Lost face {0} belongs to node {1}", index, i));
				//                break;
				//            }
				//        }
				//        for (int i = 0; i < this.leaves.Length; i++)
				//        {
				//            var begin = this.leaves[i].firstleafface;
				//            var end = begin+this.leaves[i].numleaffaces;
				//            while (begin<end)
				//            {
				//                if (leafFaces[begin] == index)
				//                {
				//                    Trace.WriteLine(string.Format("Lost face {0} belongs to leaf {1}", index, i));
				//                    break;
				//                }
				//                ++begin;
				//            }
				//        }
				//    }
				//}

				this.Scene.VsdProvider = new BspVsdProvider
					{
						VisibleClustersLookupTable = visibleClustersLookup.ToArray(),
						VisibleMeshesLookupTable = visibleMeshesLookup.ToArray(),
						Clusters = vsdClusters,
						Leaves = vsdLeaves,
						Models = (from model in this.models select new BspVsdTreeModel { RootNode = model.headnode }).ToArray(),
						Level = streamMesh,
						Nodes = vsdNodes
					};

				this.BuildAdditionalNodes();
			}
			else
			{
				this.BuildAdditionalNodes();
				node.Mesh = this.Scene.Geometries[0];
			}

			this.BuildEntityNodes(this.entitiesInfo);
		}
Пример #4
0
		private static void AddVertexToMesh(int index, BspSubmeshStreams subMesh)
		{
			subMesh.AddToAllStreams(index);
		}