Exemplo n.º 1
0
        private int WriteVB(BspGeometry geometry, LevelVBWriter writer)
        {
            if (geometry == null)
                return -1;
            if (geometry.Faces.Count == 0)
                return -1;

            TessalateFaces(geometry);

            var clusterIndex = subclustersInCluster.Count;
            var cluster = new List<int>();
            subclustersInCluster.Add(cluster);

            writer.PrepareVertexBuffer(geometry.Faces.Count * 3);
            //cluster.VertexBuffer = level.VertexBuffers.Count - 1;
            Dictionary<int, bool> materialMap = new Dictionary<int, bool>();
            List<int> materialInices = new List<int>(geometry.Faces.Count);
            foreach (var f in geometry.Faces)
            {
                RegisterTexture(f.Texture);
                if (f.Lightmap != null && commonLightmap != f.Lightmap)
                    throw new ApplicationException("not atlased lightmap");
                RegisterTexture(f.Lightmap);
                int matIndex = writer.WriteMaterial(BuildMaterial(f));
                materialInices.Add(matIndex);
                materialMap[matIndex] = true;
            }
            foreach (int t in materialMap.Keys)
            {
                var sub = new Cb4aLevelVBSubcluster();
                sub.Material = t;
                sub.VertexBuffer = level.VertexBuffers.Count - 1;
                CIwVec3 mins = new CIwVec3(int.MaxValue, int.MaxValue, int.MaxValue);
                CIwVec3 maxs = new CIwVec3(int.MinValue, int.MinValue, int.MinValue);
                for (int i = 0; i < materialInices.Count; ++i)
                {
                    if (materialInices[i] == t)
                    {
                        var f = geometry.Faces[i];

                        //TODO: slice face into more faces
                        BuildFace(writer, sub, ref mins, ref maxs, f);
                    }
                }
                if (mins.x > maxs.x)
                {
                    mins = CIwVec3.g_Zero;
                    maxs = CIwVec3.g_Zero;
                }
                sub.Mins = mins;
                sub.Maxs = maxs;
                if (sub.Indices.Count > 0)
                {
                    cluster.Add(level.subclusters.Count);
                    level.subclusters.Add(sub);
                }
            }

            return clusterIndex;
        }
Exemplo n.º 2
0
        private void BuildFace(LevelVBWriter writer, Cb4aLevelVBSubcluster sub, ref CIwVec3 mins, ref CIwVec3 maxs, BspGeometryFace f)
        {
            while (f.Vertex0.UV0.X >= 8 || f.Vertex1.UV0.X >= 8 || f.Vertex2.UV0.X >= 8)
            {
                f.Vertex0.UV0.X -= 1;
                f.Vertex1.UV0.X -= 1;
                f.Vertex2.UV0.X -= 1;
            }
            while (f.Vertex0.UV0.Y >= 8 || f.Vertex1.UV0.Y >= 8 || f.Vertex2.UV0.Y >= 8)
            {
                f.Vertex0.UV0.Y -= 1;
                f.Vertex1.UV0.Y -= 1;
                f.Vertex2.UV0.Y -= 1;
            }
            if (f.Vertex0.UV0.X < -8) f.Vertex0.UV0.X = -8;
            if (f.Vertex1.UV0.X < -8) f.Vertex1.UV0.X = -8;
            if (f.Vertex2.UV0.X < -8) f.Vertex2.UV0.X = -8;
            if (f.Vertex0.UV0.Y < -8) f.Vertex0.UV0.Y = -8;
            if (f.Vertex1.UV0.Y < -8) f.Vertex1.UV0.Y = -8;
            if (f.Vertex2.UV0.Y < -8) f.Vertex2.UV0.Y = -8;

            if (f.Vertex0.Position.X < mins.x) mins.x = (int)f.Vertex0.Position.X;
            if (f.Vertex1.Position.X < mins.x) mins.x = (int)f.Vertex1.Position.X;
            if (f.Vertex2.Position.X < mins.x) mins.x = (int)f.Vertex2.Position.X;
            if (f.Vertex0.Position.Y < mins.y) mins.y = (int)f.Vertex0.Position.Y;
            if (f.Vertex1.Position.Y < mins.y) mins.y = (int)f.Vertex1.Position.Y;
            if (f.Vertex2.Position.Y < mins.y) mins.y = (int)f.Vertex2.Position.Y;
            if (f.Vertex0.Position.Z < mins.z) mins.z = (int)f.Vertex0.Position.Z;
            if (f.Vertex1.Position.Z < mins.z) mins.z = (int)f.Vertex1.Position.Z;
            if (f.Vertex2.Position.Z < mins.z) mins.z = (int)f.Vertex2.Position.Z;

            if (f.Vertex0.Position.X > maxs.x) maxs.x = (int)f.Vertex0.Position.X;
            if (f.Vertex1.Position.X > maxs.x) maxs.x = (int)f.Vertex1.Position.X;
            if (f.Vertex2.Position.X > maxs.x) maxs.x = (int)f.Vertex2.Position.X;
            if (f.Vertex0.Position.Y > maxs.y) maxs.y = (int)f.Vertex0.Position.Y;
            if (f.Vertex1.Position.Y > maxs.y) maxs.y = (int)f.Vertex1.Position.Y;
            if (f.Vertex2.Position.Y > maxs.y) maxs.y = (int)f.Vertex2.Position.Y;
            if (f.Vertex0.Position.Z > maxs.z) maxs.z = (int)f.Vertex0.Position.Z;
            if (f.Vertex1.Position.Z > maxs.z) maxs.z = (int)f.Vertex1.Position.Z;
            if (f.Vertex2.Position.Z > maxs.z) maxs.z = (int)f.Vertex2.Position.Z;

            var index0 = writer.Write(GetLevelVBItem(f.Vertex0));
            var index1 = writer.Write(GetLevelVBItem(f.Vertex1));
            var index2 = writer.Write(GetLevelVBItem(f.Vertex2));
            if ((index0 == index1) || (index0 == index2) || (index2 == index1))
                return;
            sub.Indices.Add(index2);
            sub.Indices.Add(index1);
            sub.Indices.Add(index0);
        }