Пример #1
0
 public Vertex(DataStructures.MapObjects.Vertex original)
 {
     OriginalVertex = original;
     Location       = new CoordinateF(original.Location);
     DiffU          = (float)original.TextureU; DiffV = (float)original.TextureV;
     LMU            = original.LMU; LMV = original.LMV;
 }
Пример #2
0
 public MeshVertex(CoordinateF location, CoordinateF normal, IEnumerable <BoneWeighting> boneWeightings, float textureU, float textureV)
 {
     Location       = location;
     Normal         = normal;
     BoneWeightings = boneWeightings;
     TextureU       = textureU;
     TextureV       = textureV;
 }
Пример #3
0
        public CoordinateF Transform(CoordinateF c)
        {
            var x = (float)Matrix[0] * c.X + (float)Matrix[1] * c.Y + (float)Matrix[2] * c.Z + (float)Matrix[3];
            var y = (float)Matrix[4] * c.X + (float)Matrix[5] * c.Y + (float)Matrix[6] * c.Z + (float)Matrix[7];
            var z = (float)Matrix[8] * c.X + (float)Matrix[9] * c.Y + (float)Matrix[10] * c.Z + (float)Matrix[11];

            return(new CoordinateF(x, y, z));
        }
Пример #4
0
 public MeshVertex(CoordinateF location, CoordinateF normal, Bone bone, float textureU, float textureV)
 {
     Location       = location;
     Normal         = normal;
     BoneWeightings = new List <BoneWeighting> {
         new BoneWeighting(bone, 1)
     };
     TextureU = textureU;
     TextureV = textureV;
 }
Пример #5
0
        public static CoordinateF[] ReadCoordinateFArray(this BinaryReader br, int num)
        {
            var arr = new CoordinateF[num];

            for (var i = 0; i < num; i++)
            {
                arr[i] = br.ReadCoordinateF();
            }
            return(arr);
        }
Пример #6
0
        public void SwapUV()
        {
            float maxSwap = maxTotalX.Value; float minSwap = minTotalX.Value;

            maxTotalX = maxTotalY; minTotalX = minTotalY;
            maxTotalY = maxSwap; minTotalY = minSwap;

            CoordinateF swapAxis = uAxis;

            uAxis = vAxis;
            vAxis = swapAxis;
        }
Пример #7
0
        public LMFace(Face face, Solid solid)
        {
            Plane = new PlaneF(face.Plane);

            Normal = Plane.Normal;

            Vertices = face.Vertices.Select(x => new Vertex(x)).ToList();

            CastsShadows = !(solid?.Parent?.GetEntityData()?.Name.Equals("noshadow", StringComparison.OrdinalIgnoreCase) ?? false);

            int i1 = 0;
            int i2 = 1;
            int i3 = 2;

            CoordinateF v1 = Vertices[i1].Location;
            CoordinateF v2 = Vertices[i2].Location;
            CoordinateF v3 = Vertices[i3].Location;

            float w1x = Vertices[i1].DiffU; float w1y = Vertices[i1].DiffV;
            float w2x = Vertices[i2].DiffU; float w2y = Vertices[i2].DiffV;
            float w3x = Vertices[i3].DiffU; float w3y = Vertices[i3].DiffV;

            float x1 = v2.X - v1.X;
            float x2 = v3.X - v1.X;
            float y1 = v2.Y - v1.Y;
            float y2 = v3.Y - v1.Y;
            float z1 = v2.Z - v1.Z;
            float z2 = v3.Z - v1.Z;

            float s1 = w2x - w1x;
            float s2 = w3x - w1x;
            float t1 = w2y - w1y;
            float t2 = w3y - w1y;

            float       r    = 1.0f / (s1 * t2 - s2 * t1);
            CoordinateF sdir = new CoordinateF((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
            CoordinateF tdir = new CoordinateF((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

            Tangent   = (sdir - Normal * Normal.Dot(sdir)).Normalise();
            Bitangent = (tdir - Normal * Normal.Dot(tdir)).Normalise();

            LightBasis0 = Tangent * (-1.0f / (float)Math.Sqrt(6.0)) + Bitangent * (-1.0f / (float)Math.Sqrt(2.0)) + Normal * (1.0f / (float)Math.Sqrt(3.0));
            LightBasis1 = Tangent * (-1.0f / (float)Math.Sqrt(6.0)) + Bitangent * (1.0f / (float)Math.Sqrt(2.0)) + Normal * (1.0f / (float)Math.Sqrt(3.0));
            LightBasis2 = Tangent * ((float)Math.Sqrt(2.0 / 3.0)) + Normal * (1.0f / (float)Math.Sqrt(3.0));

            Texture = face.Texture.Name;

            OriginalFace = face;

            UpdateBoundingBox();
        }
Пример #8
0
 public Bone(int boneIndex, int parentIndex, Bone parent, string name,
             CoordinateF defaultPosition, CoordinateF defaultAngles,
             CoordinateF defaultPositionScale, CoordinateF defaultAnglesScale)
 {
     BoneIndex            = boneIndex;
     ParentIndex          = parentIndex;
     Parent               = parent;
     Name                 = name;
     DefaultPosition      = defaultPosition;
     DefaultAngles        = defaultAngles;
     DefaultPositionScale = defaultPositionScale;
     DefaultAnglesScale   = defaultAnglesScale;
     Transform            = QuaternionF.EulerAngles(DefaultAngles).GetMatrix().Translate(defaultPosition);
     if (parent != null)
     {
         Transform *= parent.Transform;
     }
 }
Пример #9
0
        protected static CoordinateF GetIntersectionPoint(LMFace face, LineF line, bool ignoreDirection = false)
        {
            var plane     = face.Plane;
            var intersect = plane.GetIntersectionPoint(line, ignoreDirection);
            List <CoordinateF> coordinates = face.Vertices.Select(x => x.Location).ToList();

            if (intersect == null)
            {
                return(null);
            }
            BoxF bbox = new BoxF(face.BoundingBox.Start - new CoordinateF(0.5f, 0.5f, 0.5f), face.BoundingBox.End + new CoordinateF(0.5f, 0.5f, 0.5f));

            if (!bbox.CoordinateIsInside(intersect))
            {
                return(null);
            }

            CoordinateF centerPoint = face.BoundingBox.Center;

            for (var i = 0; i < coordinates.Count; i++)
            {
                var i1 = i;
                var i2 = (i + 1) % coordinates.Count;

                var lineMiddle     = (coordinates[i1] + coordinates[i2]) * 0.5f;
                var middleToCenter = centerPoint - lineMiddle;
                var v          = coordinates[i1] - coordinates[i2];
                var lineNormal = face.Plane.Normal.Cross(v);

                if ((middleToCenter - lineNormal).LengthSquared() > (middleToCenter + lineNormal).LengthSquared())
                {
                    lineNormal = -lineNormal;
                }

                if (lineNormal.Dot(intersect - lineMiddle) < 0.0f)
                {
                    return(null);
                }
            }
            return(intersect);
        }
Пример #10
0
        public CoordinateF Transform(CoordinateF c)
        {
            var p = c - new CoordinateF(Axis.Start);
            var r = new CoordinateF((Axis.End - Axis.Start).Normalise());

            var costheta = (float)Math.Cos((float)Rotation);
            var sintheta = (float)Math.Sin((float)Rotation);

            float x = 0, y = 0, z = 0;

            x += (costheta + (1 - costheta) * r.X * r.X) * p.X;
            x += ((1 - costheta) * r.X * r.Y - r.Z * sintheta) * p.Y;
            x += ((1 - costheta) * r.X * r.Z + r.Y * sintheta) * p.Z;

            y += ((1 - costheta) * r.X * r.Y + r.Z * sintheta) * p.X;
            y += (costheta + (1 - costheta) * r.Y * r.Y) * p.Y;
            y += ((1 - costheta) * r.Y * r.Z - r.X * sintheta) * p.Z;

            z += ((1 - costheta) * r.X * r.Z - r.Y * sintheta) * p.X;
            z += ((1 - costheta) * r.Y * r.Z + r.X * sintheta) * p.Y;
            z += (costheta + (1 - costheta) * r.Z * r.Z) * p.Z;

            return(new CoordinateF(x, y, z) + new CoordinateF(Axis.Start));
        }
Пример #11
0
        public static void Render(Document document, ExportForm exportForm, out List <LMFace> faces, out int lmCount)
        {
            var textureCollection = document.TextureCollection;

            var map = document.Map;

            faces = new List <LMFace>();
            var lightEntities = new List <Light>();

            threadExceptions = new List <LMThreadException>();

            List <LightmapGroup> lmGroups          = new List <LightmapGroup>();
            List <LMFace>        exclusiveBlockers = new List <LMFace>();

            //get faces
            UpdateProgress(exportForm, "Determining UV coordinates...", 0);
            LMFace.FindFacesAndGroups(map, out faces, out lmGroups);

            if (!lmGroups.Any())
            {
                throw new Exception("No lightmap groups!");
            }

            foreach (Solid solid in map.WorldSpawn.Find(x => x is Solid).OfType <Solid>())
            {
                foreach (Face tface in solid.Faces)
                {
                    LMFace face = new LMFace(tface, solid);
                    if (tface.Texture.Name.ToLower() != "tooltextures/block_light")
                    {
                        continue;
                    }
                    exclusiveBlockers.Add(face);
                }
            }

            for (int i = 0; i < lmGroups.Count; i++)
            {
                for (int j = i + 1; j < lmGroups.Count; j++)
                {
                    if ((lmGroups[i].Plane.Normal - lmGroups[j].Plane.Normal).LengthSquared() < 0.001f &&
                        lmGroups[i].BoundingBox.IntersectsWith(lmGroups[j].BoundingBox))
                    {
                        lmGroups[i].Faces.AddRange(lmGroups[j].Faces);
                        lmGroups[i].BoundingBox = new BoxF(new BoxF[] { lmGroups[i].BoundingBox, lmGroups[j].BoundingBox });
#if DEBUG
                        if (lmGroups[j].DebugBreakpoint)
                        {
                            lmGroups[i].DebugBreakpoint = true;
                        }
#endif
                        lmGroups.RemoveAt(j);
                        j = i + 1;
                    }
                }
            }

            //put the faces into the bitmap
            lmGroups.Sort((x, y) =>
            {
                if (x.Width == y.Width)
                {
                    if (x.Height == y.Height)
                    {
                        return(0);
                    }
                    if (x.Height < y.Height)
                    {
                        return(1);
                    }
                    return(-1);
                }

                if (x.Width < y.Width)
                {
                    return(1);
                }
                return(-1);
            });

            FaceRenderThreads = new List <Thread>();

            Light.FindLights(map, out lightEntities);

            List <LMFace> allBlockers = lmGroups.Select(q => q.Faces).SelectMany(q => q).Where(f => f.CastsShadows).Union(exclusiveBlockers).ToList();
            int           faceCount   = 0;

            List <LightmapGroup> uvCalcFaces = new List <LightmapGroup>(lmGroups);

            int totalTextureDims = LightmapConfig.TextureDims;
            lmCount = 0;
            for (int i = 0; i < 4; i++)
            {
                int x = 1 + ((i % 2) * LightmapConfig.TextureDims);
                int y = 1 + ((i / 2) * LightmapConfig.TextureDims);
                CalculateUV(uvCalcFaces, new Rectangle(x, y, LightmapConfig.TextureDims - 2, LightmapConfig.TextureDims - 2), out _, out _);
                lmCount++;
                if (uvCalcFaces.Count == 0)
                {
                    break;
                }
                totalTextureDims = LightmapConfig.TextureDims * 2;
            }

            if (uvCalcFaces.Count > 0)
            {
                throw new Exception("Could not fit lightmap into four textures; try increasing texture dimensions or downscale factor");
            }

            float[][] buffers = new float[4][];
            lock (textureCollection.Lightmaps)
            {
                for (int i = 0; i < 4; i++)
                {
                    textureCollection.Lightmaps[i]?.Dispose();
                    textureCollection.Lightmaps[i] = new Bitmap(totalTextureDims, totalTextureDims);
                    buffers[i] = new float[textureCollection.Lightmaps[i].Width * textureCollection.Lightmaps[i].Height * Bitmap.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8];
                }
            }

            foreach (LightmapGroup group in lmGroups)
            {
                foreach (LMFace face in group.Faces)
                {
                    faceCount++;
                    Thread newThread = CreateLightmapRenderThread(document, buffers, lightEntities, group, face, allBlockers);
                    FaceRenderThreads.Add(newThread);
                }
            }

            int faceNum = 0;
            UpdateProgress(exportForm, "Started calculating brightness levels...", 0.05f);
            while (FaceRenderThreads.Count > 0)
            {
                for (int i = 0; i < 8; i++)
                {
                    if (i >= FaceRenderThreads.Count)
                    {
                        break;
                    }
                    if (FaceRenderThreads[i].ThreadState == ThreadState.Unstarted)
                    {
                        FaceRenderThreads[i].Start();
                    }
                    else if (!FaceRenderThreads[i].IsAlive)
                    {
                        FaceRenderThreads.RemoveAt(i);
                        i--;
                        faceNum++;
                        UpdateProgress(exportForm, faceNum.ToString() + "/" + faceCount.ToString() + " faces complete", 0.05f + ((float)faceNum / (float)faceCount) * 0.85f);
                    }
                }

                if (threadExceptions.Count > 0)
                {
                    for (int i = 0; i < FaceRenderThreads.Count; i++)
                    {
                        if (FaceRenderThreads[i].IsAlive)
                        {
                            FaceRenderThreads[i].Abort();
                        }
                    }
                    throw new Exception(threadExceptions[0].Message + "\n" + threadExceptions[0].StackTrace);
                }
                Thread.Yield();
            }

            //blur the lightmap so it doesn't look too pixellated
            UpdateProgress(exportForm, "Blurring lightmap...", 0.95f);
            float[] blurBuffer = new float[buffers[0].Length];
            for (int k = 0; k < 4; k++)
            {
                foreach (LightmapGroup group in lmGroups)
                {
                    int downscaledWidth  = (int)Math.Ceiling(group.Width / LightmapConfig.DownscaleFactor);
                    int downscaledHeight = (int)Math.Ceiling(group.Height / LightmapConfig.DownscaleFactor);

                    CoordinateF ambientNormal = new CoordinateF(LightmapConfig.AmbientNormalX,
                                                                LightmapConfig.AmbientNormalY,
                                                                LightmapConfig.AmbientNormalZ).Normalise();
                    float       ambientMultiplier = (group.Plane.Normal.Dot(ambientNormal) + 1.5f) * 0.4f;
                    CoordinateF mAmbientColor     = new CoordinateF((LightmapConfig.AmbientColorB * ambientMultiplier / 255.0f),
                                                                    (LightmapConfig.AmbientColorG * ambientMultiplier / 255.0f),
                                                                    (LightmapConfig.AmbientColorR * ambientMultiplier / 255.0f));
                    for (int y = group.writeY; y < group.writeY + downscaledHeight; y++)
                    {
                        if (y < 0 || y >= totalTextureDims)
                        {
                            continue;
                        }
                        for (int x = group.writeX; x < group.writeX + downscaledWidth; x++)
                        {
                            if (x < 0 || x >= totalTextureDims)
                            {
                                continue;
                            }
                            int offset = (x + y * totalTextureDims) * System.Drawing.Image.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8;

                            float accumRed    = 0;
                            float accumGreen  = 0;
                            float accumBlue   = 0;
                            int   sampleCount = 0;
                            for (int j = -LightmapConfig.BlurRadius; j <= LightmapConfig.BlurRadius; j++)
                            {
                                if (y + j < 0 || y + j >= totalTextureDims)
                                {
                                    continue;
                                }
                                if (y + j < group.writeY || y + j >= group.writeY + downscaledHeight)
                                {
                                    continue;
                                }
                                for (int i = -LightmapConfig.BlurRadius; i <= LightmapConfig.BlurRadius; i++)
                                {
                                    if (i * i + j * j > LightmapConfig.BlurRadius * LightmapConfig.BlurRadius)
                                    {
                                        continue;
                                    }
                                    if (x + i < 0 || x + i >= totalTextureDims)
                                    {
                                        continue;
                                    }
                                    if (x + i < group.writeX || x + i >= group.writeX + downscaledWidth)
                                    {
                                        continue;
                                    }
                                    int sampleOffset = ((x + i) + (y + j) * totalTextureDims) * System.Drawing.Image.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8;
                                    if (buffers[k][sampleOffset + 3] < 1.0f)
                                    {
                                        continue;
                                    }
                                    sampleCount++;
                                    accumRed   += buffers[k][sampleOffset + 0];
                                    accumGreen += buffers[k][sampleOffset + 1];
                                    accumBlue  += buffers[k][sampleOffset + 2];
                                }
                            }

                            if (sampleCount < 1)
                            {
                                sampleCount = 1;
                            }
                            accumRed   /= sampleCount;
                            accumGreen /= sampleCount;
                            accumBlue  /= sampleCount;

                            accumRed   = mAmbientColor.X + (accumRed * (1.0f - mAmbientColor.X));
                            accumGreen = mAmbientColor.Y + (accumGreen * (1.0f - mAmbientColor.Y));
                            accumBlue  = mAmbientColor.Z + (accumBlue * (1.0f - mAmbientColor.Z));

                            if (accumRed > 1.0f)
                            {
                                accumRed = 1.0f;
                            }
                            if (accumGreen > 1.0f)
                            {
                                accumGreen = 1.0f;
                            }
                            if (accumBlue > 1.0f)
                            {
                                accumBlue = 1.0f;
                            }

                            blurBuffer[offset + 0] = accumRed;
                            blurBuffer[offset + 1] = accumGreen;
                            blurBuffer[offset + 2] = accumBlue;
                            blurBuffer[offset + 3] = 1.0f;
                        }
                    }
                }

                blurBuffer.CopyTo(buffers[k], 0);
            }

            for (int i = 0; i < buffers[0].Length; i++)
            {
                if (i % 4 == 3)
                {
                    buffers[0][i] = 1.0f;
                    buffers[1][i] = 1.0f;
                    buffers[2][i] = 1.0f;
                    buffers[3][i] = 1.0f;
                }
                else
                {
                    float brightnessAdd = (buffers[0][i] + buffers[1][i] + buffers[2][i]) / (float)Math.Sqrt(3.0);
                    if (brightnessAdd > 0.0f) //normalize brightness to remove artifacts when adding together
                    {
                        buffers[0][i] *= buffers[3][i] / brightnessAdd;
                        buffers[1][i] *= buffers[3][i] / brightnessAdd;
                        buffers[2][i] *= buffers[3][i] / brightnessAdd;
                    }
                }
            }

            UpdateProgress(exportForm, "Copying bitmap data...", 0.99f);
            for (int k = 0; k < 4; k++)
            {
                byte[] byteBuffer = new byte[buffers[k].Length];
                for (int i = 0; i < buffers[k].Length; i++)
                {
                    byteBuffer[i] = (byte)Math.Max(Math.Min(buffers[k][i] * 255.0f, 255.0f), 0.0f);
                }
                lock (textureCollection.Lightmaps)
                {
                    BitmapData bitmapData2 = textureCollection.Lightmaps[k].LockBits(new Rectangle(0, 0, totalTextureDims, totalTextureDims), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    Marshal.Copy(byteBuffer, 0, bitmapData2.Scan0, byteBuffer.Length);
                    textureCollection.Lightmaps[k].UnlockBits(bitmapData2);
                }
            }

            faces.Clear();
            faces.AddRange(lmGroups.SelectMany(g => g.Faces));

            lock (textureCollection.Lightmaps)
            {
                document.TextureCollection.LightmapTextureOutdated = true;
            }

            UpdateProgress(exportForm, "Lightmapping complete!", 1.0f);
        }
Пример #12
0
 public Waypoint(Entity ent)
 {
     Location    = new CoordinateF(ent.Origin);
     Connections = new List <int>();
 }
Пример #13
0
 public CoordinateF Transform(CoordinateF c)
 {
     return(c + new CoordinateF(Translation));
 }
Пример #14
0
 public static void WriteCoordinateF(this BinaryWriter bw, CoordinateF c)
 {
     bw.Write(c.X);
     bw.Write(c.Y);
     bw.Write(c.Z);
 }
Пример #15
0
 public CoordinateF Transform(CoordinateF c)
 {
     return((c - new CoordinateF(Origin)).ComponentMultiply(new CoordinateF(Scalar)) + new CoordinateF(Origin));
 }
Пример #16
0
        private static void RenderLightOntoFace(Document doc, float[][] bitmaps, List <Light> lights, LightmapGroup group, LMFace targetFace, IEnumerable <LMFace> blockerFaces)
        {
            Random rand = new Random();

            int writeX = group.writeX;
            int writeY = group.writeY;

            int textureDims;

            lock (doc.TextureCollection.Lightmaps)
            {
                textureDims = doc.TextureCollection.Lightmaps[0].Width;
            }

            lights = lights.FindAll(x =>
            {
                float range   = x.Range;
                BoxF lightBox = new BoxF(x.Origin - new CoordinateF(range, range, range), x.Origin + new CoordinateF(range, range, range));
                return(lightBox.IntersectsWith(targetFace.BoundingBox));
            });

            float?minX = null; float?maxX = null;
            float?minY = null; float?maxY = null;

            foreach (CoordinateF coord in targetFace.Vertices.Select(x => x.Location))
            {
                float x = coord.Dot(group.uAxis);
                float y = coord.Dot(group.vAxis);

                if (minX == null || x < minX)
                {
                    minX = x;
                }
                if (minY == null || y < minY)
                {
                    minY = y;
                }
                if (maxX == null || x > maxX)
                {
                    maxX = x;
                }
                if (maxY == null || y > maxY)
                {
                    maxY = y;
                }
            }

            CoordinateF leewayPoint = group.Plane.PointOnPlane + (group.Plane.Normal * Math.Max(LightmapConfig.DownscaleFactor * 0.25f, 1.5f));

            minX -= LightmapConfig.DownscaleFactor; minY -= LightmapConfig.DownscaleFactor;
            maxX += LightmapConfig.DownscaleFactor; maxY += LightmapConfig.DownscaleFactor;

            minX /= LightmapConfig.DownscaleFactor; minX = (float)Math.Ceiling(minX.Value); minX *= LightmapConfig.DownscaleFactor;
            minY /= LightmapConfig.DownscaleFactor; minY = (float)Math.Ceiling(minY.Value); minY *= LightmapConfig.DownscaleFactor;
            maxX /= LightmapConfig.DownscaleFactor; maxX = (float)Math.Ceiling(maxX.Value); maxX *= LightmapConfig.DownscaleFactor;
            maxY /= LightmapConfig.DownscaleFactor; maxY = (float)Math.Ceiling(maxY.Value); maxY *= LightmapConfig.DownscaleFactor;

            foreach (LMFace.Vertex vert in targetFace.Vertices)
            {
                float x = vert.Location.Dot(group.uAxis);
                float y = vert.Location.Dot(group.vAxis);

                float u = (writeX + 0.5f + (x - group.minTotalX.Value) / LightmapConfig.DownscaleFactor);
                float v = (writeY + 0.5f + (y - group.minTotalY.Value) / LightmapConfig.DownscaleFactor);

                targetFace.LmIndex = (u >= LightmapConfig.TextureDims ? 1 : 0) + (v >= LightmapConfig.TextureDims ? 2 : 0);

                u /= (float)textureDims;
                v /= (float)textureDims;

                vert.LMU = u; vert.LMV = v;
                vert.OriginalVertex.LMU = u; vert.OriginalVertex.LMV = v;
            }

            float centerX           = (maxX.Value + minX.Value) / 2;
            float centerY           = (maxY.Value + minY.Value) / 2;

            int iterX = (int)Math.Ceiling((maxX.Value - minX.Value) / LightmapConfig.DownscaleFactor);
            int iterY = (int)Math.Ceiling((maxY.Value - minY.Value) / LightmapConfig.DownscaleFactor);

            float[][,] r = new float[4][, ];
            r[0]         = new float[iterX, iterY];
            r[1]         = new float[iterX, iterY];
            r[2]         = new float[iterX, iterY];
            r[3]         = new float[iterX, iterY];
            float[][,] g = new float[4][, ];
            g[0]         = new float[iterX, iterY];
            g[1]         = new float[iterX, iterY];
            g[2]         = new float[iterX, iterY];
            g[3]         = new float[iterX, iterY];
            float[][,] b = new float[4][, ];
            b[0]         = new float[iterX, iterY];
            b[1]         = new float[iterX, iterY];
            b[2]         = new float[iterX, iterY];
            b[3]         = new float[iterX, iterY];

            foreach (Light light in lights)
            {
                CoordinateF lightPos   = light.Origin;
                float       lightRange = light.Range;
                CoordinateF lightColor = light.Color * (1.0f / 255.0f) * light.Intensity;

                BoxF          lightBox = new BoxF(new BoxF[] { targetFace.BoundingBox, new BoxF(light.Origin - new CoordinateF(30.0f, 30.0f, 30.0f), light.Origin + new CoordinateF(30.0f, 30.0f, 30.0f)) });
                List <LMFace> applicableBlockerFaces = blockerFaces.Where(x =>
                {
                    if (x == targetFace)
                    {
                        return(false);
                    }
                    if (group.Faces.Contains(x))
                    {
                        return(false);
                    }
                    //return true;
                    if (lightBox.IntersectsWith(x.BoundingBox))
                    {
                        return(true);
                    }
                    return(false);
                }).ToList();

                bool[,] illuminated = new bool[iterX, iterY];

                for (int y = 0; y < iterY; y++)
                {
                    for (int x = 0; x < iterX; x++)
                    {
                        illuminated[x, y] = true;
                    }
                }

                for (int y = 0; y < iterY; y++)
                {
                    for (int x = 0; x < iterX; x++)
                    {
                        int tX = (int)(writeX + x + (int)(minX - group.minTotalX) / LightmapConfig.DownscaleFactor);
                        int tY = (int)(writeY + y + (int)(minY - group.minTotalY) / LightmapConfig.DownscaleFactor);

                        if (tX >= 0 && tY >= 0 && tX < textureDims && tY < textureDims)
                        {
                            int offset = (tX + tY * textureDims) * Bitmap.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format32bppArgb) / 8;
                            bitmaps[0][offset + 3] = 1.0f;
                            bitmaps[1][offset + 3] = 1.0f;
                            bitmaps[2][offset + 3] = 1.0f;
                            bitmaps[3][offset + 3] = 1.0f;
                        }
                    }
                }

                for (int y = 0; y < iterY; y++)
                {
                    for (int x = 0; x < iterX; x++)
                    {
                        float       ttX          = minX.Value + (x * LightmapConfig.DownscaleFactor);
                        float       ttY          = minY.Value + (y * LightmapConfig.DownscaleFactor);
                        CoordinateF pointOnPlane = (ttX - centerX) * group.uAxis + (ttY - centerY) * group.vAxis + targetFace.BoundingBox.Center;

                        /*Entity entity = new Entity(map.IDGenerator.GetNextObjectID());
                         * entity.Colour = Color.Pink;
                         * entity.Origin = new Coordinate(pointOnPlane);
                         * entity.UpdateBoundingBox();
                         * entity.SetParent(map.WorldSpawn);*/

                        int tX = (int)(writeX + x + (int)(minX - group.minTotalX) / LightmapConfig.DownscaleFactor);
                        int tY = (int)(writeY + y + (int)(minY - group.minTotalY) / LightmapConfig.DownscaleFactor);

                        CoordinateF luxelColor0    = new CoordinateF(r[0][x, y], g[0][x, y], b[0][x, y]);
                        CoordinateF luxelColor1    = new CoordinateF(r[1][x, y], g[1][x, y], b[1][x, y]);
                        CoordinateF luxelColor2    = new CoordinateF(r[2][x, y], g[2][x, y], b[2][x, y]);
                        CoordinateF luxelColorNorm = new CoordinateF(r[3][x, y], g[3][x, y], b[3][x, y]);

                        float dotToLight0    = Math.Max((lightPos - pointOnPlane).Normalise().Dot(targetFace.LightBasis0), 0.0f);
                        float dotToLight1    = Math.Max((lightPos - pointOnPlane).Normalise().Dot(targetFace.LightBasis1), 0.0f);
                        float dotToLight2    = Math.Max((lightPos - pointOnPlane).Normalise().Dot(targetFace.LightBasis2), 0.0f);
                        float dotToLightNorm = Math.Max((lightPos - pointOnPlane).Normalise().Dot(targetFace.Normal), 0.0f);

                        if (illuminated[x, y] && (pointOnPlane - lightPos).LengthSquared() < lightRange * lightRange)
                        {
#if TRUE
                            LineF lineTester = new LineF(lightPos, pointOnPlane);
                            for (int i = 0; i < applicableBlockerFaces.Count; i++)
                            {
                                LMFace      otherFace = applicableBlockerFaces[i];
                                CoordinateF hit       = otherFace.GetIntersectionPoint(lineTester);
                                if (hit != null && ((hit - leewayPoint).Dot(group.Plane.Normal) > 0.0f || (hit - pointOnPlane).LengthSquared() > LightmapConfig.DownscaleFactor * 2f))
                                {
                                    applicableBlockerFaces.RemoveAt(i);
                                    applicableBlockerFaces.Insert(0, otherFace);
                                    illuminated[x, y] = false;
                                    i++;
                                    break;
                                }
                            }
#endif
                        }
                        else
                        {
                            illuminated[x, y] = false;
                        }

                        if (illuminated[x, y])
                        {
                            float brightness = (lightRange - (pointOnPlane - lightPos).VectorMagnitude()) / lightRange;

                            if (light.Direction != null)
                            {
                                float directionDot = light.Direction.Dot((pointOnPlane - lightPos).Normalise());

                                if (directionDot < light.innerCos)
                                {
                                    if (directionDot < light.outerCos)
                                    {
                                        brightness = 0.0f;
                                    }
                                    else
                                    {
                                        brightness *= (directionDot - light.outerCos.Value) / (light.innerCos.Value - light.outerCos.Value);
                                    }
                                }
                            }

                            float brightness0    = dotToLight0 * brightness * brightness;
                            float brightness1    = dotToLight1 * brightness * brightness;
                            float brightness2    = dotToLight2 * brightness * brightness;
                            float brightnessNorm = dotToLightNorm * brightness * brightness;

                            brightness0    += ((float)rand.NextDouble() - 0.5f) * 0.005f;
                            brightness1    += ((float)rand.NextDouble() - 0.5f) * 0.005f;
                            brightness2    += ((float)rand.NextDouble() - 0.5f) * 0.005f;
                            brightnessNorm += ((float)rand.NextDouble() - 0.5f) * 0.005f;

                            r[0][x, y] += lightColor.Z * brightness0; if (r[0][x, y] > 1.0f)
                            {
                                r[0][x, y] = 1.0f;
                            }
                            if (r[0][x, y] < 0)
                            {
                                r[0][x, y] = 0;
                            }
                            g[0][x, y] += lightColor.Y * brightness0; if (g[0][x, y] > 1.0f)
                            {
                                g[0][x, y] = 1.0f;
                            }
                            if (g[0][x, y] < 0)
                            {
                                g[0][x, y] = 0;
                            }
                            b[0][x, y] += lightColor.X * brightness0; if (b[0][x, y] > 1.0f)
                            {
                                b[0][x, y] = 1.0f;
                            }
                            if (b[0][x, y] < 0)
                            {
                                b[0][x, y] = 0;
                            }

                            r[1][x, y] += lightColor.Z * brightness1; if (r[1][x, y] > 1.0f)
                            {
                                r[1][x, y] = 1.0f;
                            }
                            if (r[1][x, y] < 0)
                            {
                                r[1][x, y] = 0;
                            }
                            g[1][x, y] += lightColor.Y * brightness1; if (g[1][x, y] > 1.0f)
                            {
                                g[1][x, y] = 1.0f;
                            }
                            if (g[1][x, y] < 0)
                            {
                                g[1][x, y] = 0;
                            }
                            b[1][x, y] += lightColor.X * brightness1; if (b[1][x, y] > 1.0f)
                            {
                                b[1][x, y] = 1.0f;
                            }
                            if (b[1][x, y] < 0)
                            {
                                b[1][x, y] = 0;
                            }

                            r[2][x, y] += lightColor.Z * brightness2; if (r[2][x, y] > 1.0f)
                            {
                                r[2][x, y] = 1.0f;
                            }
                            if (r[2][x, y] < 0)
                            {
                                r[2][x, y] = 0;
                            }
                            g[2][x, y] += lightColor.Y * brightness2; if (g[2][x, y] > 1.0f)
                            {
                                g[2][x, y] = 1.0f;
                            }
                            if (g[2][x, y] < 0)
                            {
                                g[2][x, y] = 0;
                            }
                            b[2][x, y] += lightColor.X * brightness2; if (b[2][x, y] > 1.0f)
                            {
                                b[2][x, y] = 1.0f;
                            }
                            if (b[2][x, y] < 0)
                            {
                                b[2][x, y] = 0;
                            }

                            r[3][x, y] += lightColor.Z * brightnessNorm; if (r[3][x, y] > 1.0f)
                            {
                                r[3][x, y] = 1.0f;
                            }
                            if (r[3][x, y] < 0)
                            {
                                r[3][x, y] = 0;
                            }
                            g[3][x, y] += lightColor.Y * brightnessNorm; if (g[3][x, y] > 1.0f)
                            {
                                g[3][x, y] = 1.0f;
                            }
                            if (g[3][x, y] < 0)
                            {
                                g[3][x, y] = 0;
                            }
                            b[3][x, y] += lightColor.X * brightnessNorm; if (b[3][x, y] > 1.0f)
                            {
                                b[3][x, y] = 1.0f;
                            }
                            if (b[3][x, y] < 0)
                            {
                                b[3][x, y] = 0;
                            }

                            luxelColor0    = new CoordinateF(r[0][x, y], g[0][x, y], b[0][x, y]);
                            luxelColor1    = new CoordinateF(r[1][x, y], g[1][x, y], b[1][x, y]);
                            luxelColor2    = new CoordinateF(r[2][x, y], g[2][x, y], b[2][x, y]);
                            luxelColorNorm = new CoordinateF(r[3][x, y], g[3][x, y], b[3][x, y]);

                            if (tX >= 0 && tY >= 0 && tX < textureDims && tY < textureDims)
                            {
                                int offset = (tX + tY * textureDims) * Bitmap.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format32bppArgb) / 8;
                                if (luxelColor0.X + luxelColor0.Y + luxelColor0.Z > bitmaps[0][offset + 2] + bitmaps[0][offset + 1] + bitmaps[0][offset + 0])
                                {
                                    bitmaps[0][offset + 0] = luxelColor0.X;
                                    bitmaps[0][offset + 1] = luxelColor0.Y;
                                    bitmaps[0][offset + 2] = luxelColor0.Z;
                                }
                                if (luxelColor1.X + luxelColor1.Y + luxelColor1.Z > bitmaps[1][offset + 2] + bitmaps[1][offset + 1] + bitmaps[1][offset + 0])
                                {
                                    bitmaps[1][offset + 0] = luxelColor1.X;
                                    bitmaps[1][offset + 1] = luxelColor1.Y;
                                    bitmaps[1][offset + 2] = luxelColor1.Z;
                                }
                                if (luxelColor2.X + luxelColor2.Y + luxelColor2.Z > bitmaps[2][offset + 2] + bitmaps[2][offset + 1] + bitmaps[2][offset + 0])
                                {
                                    bitmaps[2][offset + 0] = luxelColor2.X;
                                    bitmaps[2][offset + 1] = luxelColor2.Y;
                                    bitmaps[2][offset + 2] = luxelColor2.Z;
                                }
                                if (luxelColorNorm.X + luxelColorNorm.Y + luxelColorNorm.Z > bitmaps[3][offset + 2] + bitmaps[3][offset + 1] + bitmaps[3][offset + 0])
                                {
                                    bitmaps[3][offset + 0] = luxelColorNorm.X;
                                    bitmaps[3][offset + 1] = luxelColorNorm.Y;
                                    bitmaps[3][offset + 2] = luxelColorNorm.Z;
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #17
0
 public Waypoint(Entity ent)
 {
     Location = new CoordinateF(ent.Origin);
 }
Пример #18
0
 private static void GLCoordinate(Vertex v, CoordinateF normal)
 {
     GL.TexCoord2(v.DTextureU, v.DTextureV);
     GL.Normal3(normal.X, normal.Y, normal.Z);
     GLCoordinate(v.Location);
 }
Пример #19
0
 public BoneAnimationFrame(Bone bone, CoordinateF position, QuaternionF angles)
 {
     Bone     = bone;
     Position = position;
     Angles   = angles;
 }
Пример #20
0
        private void CalculateInitialUV()
        {
            if (uAxis == null || vAxis == null)
            {
                var direction = Plane.GetClosestAxisToNormal();
                var tempV     = direction == CoordinateF.UnitZ ? -CoordinateF.UnitY : -CoordinateF.UnitZ;
                uAxis = Plane.Normal.Cross(tempV).Normalise();
                vAxis = uAxis.Cross(Plane.Normal).Normalise();

                if (Plane.OnPlane(Plane.PointOnPlane + uAxis * 1000f) != 0)
                {
                    throw new Exception("uAxis is misaligned");
                }
                if (Plane.OnPlane(Plane.PointOnPlane + vAxis * 1000f) != 0)
                {
                    throw new Exception("vAxis is misaligned");
                }
            }

            if (minTotalX == null || minTotalY == null || maxTotalX == null || maxTotalY == null)
            {
                foreach (LMFace face in Faces)
                {
                    foreach (CoordinateF coord in face.Vertices.Select(x => x.Location))
                    {
                        float x = coord.Dot(uAxis);
                        float y = coord.Dot(vAxis);

                        if (minTotalX == null || x < minTotalX)
                        {
                            minTotalX = x;
                        }
                        if (minTotalY == null || y < minTotalY)
                        {
                            minTotalY = y;
                        }
                        if (maxTotalX == null || x > maxTotalX)
                        {
                            maxTotalX = x;
                        }
                        if (maxTotalY == null || y > maxTotalY)
                        {
                            maxTotalY = y;
                        }
                    }
                }

                minTotalX -= LightmapConfig.DownscaleFactor; minTotalY -= LightmapConfig.DownscaleFactor;
                maxTotalX += LightmapConfig.DownscaleFactor; maxTotalY += LightmapConfig.DownscaleFactor;

                minTotalX /= LightmapConfig.DownscaleFactor; minTotalX = (float)Math.Ceiling(minTotalX.Value); minTotalX *= LightmapConfig.DownscaleFactor;
                minTotalY /= LightmapConfig.DownscaleFactor; minTotalY = (float)Math.Ceiling(minTotalY.Value); minTotalY *= LightmapConfig.DownscaleFactor;
                maxTotalX /= LightmapConfig.DownscaleFactor; maxTotalX = (float)Math.Ceiling(maxTotalX.Value); maxTotalX *= LightmapConfig.DownscaleFactor;
                maxTotalY /= LightmapConfig.DownscaleFactor; maxTotalY = (float)Math.Ceiling(maxTotalY.Value); maxTotalY *= LightmapConfig.DownscaleFactor;

                if ((maxTotalX - minTotalX) < (maxTotalY - minTotalY))
                {
                    SwapUV();
                }
            }
        }