Ejemplo n.º 1
0
        public AIMesh(Stream stream)
        {
            buffer = new BinaryReader(stream);
            for (int i = 0; i < AIMESH_TEXTURE_SIZE; i++) // For every scanline for the triangle rendering
            {
                scanlineLowest[i] = new ScanLine { u = 1e10f, v = 1e10f, x = 1e10f, y = 1e10f, z = 1e10f };
                scanlineHighest[i] = new ScanLine { u = -1e10f, v = -1e10f, x = -1e10f, y = -1e10f, z = -1e10f };
            }
            heightMap = new float[AIMESH_TEXTURE_SIZE * AIMESH_TEXTURE_SIZE]; // Shows occupied or not
            xMap = new float[AIMESH_TEXTURE_SIZE * AIMESH_TEXTURE_SIZE]; // Shows x
            yMap = new float[AIMESH_TEXTURE_SIZE * AIMESH_TEXTURE_SIZE]; // Shows y

            fileStream = new __AIMESHFILE();
            fileStream.magic = buffer.ReadChars(8);
            fileStream.version = buffer.ReadInt32();
            fileStream.triangle_count = buffer.ReadInt32();
            fileStream.zero = new int[] { buffer.ReadInt32(), buffer.ReadInt32() };

            for (var i = 0; i < fileStream.triangle_count; i++)
            {
                var triangle = new Triangle();
                for (var j = 0; j < 3; j++)
                    triangle.Face.v1[j] = buffer.ReadSingle();
                for (var j = 0; j < 3; j++)
                    triangle.Face.v2[j] = buffer.ReadSingle();
                for (var j = 0; j < 3; j++)
                    triangle.Face.v3[j] = buffer.ReadSingle();
                triangle.unk1 = buffer.ReadInt16();
                triangle.unk2 = buffer.ReadInt16();
                triangle.triangle_reference = buffer.ReadInt16();

                fileStream.triangles[i] = triangle;
            }
            outputMesh(AIMESH_TEXTURE_SIZE, AIMESH_TEXTURE_SIZE);

            ////writeFile(AIMESH_TEXTURE_SIZE, AIMESH_TEXTURE_SIZE);

            loaded = true;
        }
Ejemplo n.º 2
0
        void drawTriangle(Triangle triangle, int width, int height)
        {
            // The heart of the rasterizer

            Vertex[] tempVertex = new Vertex[3];

            tempVertex[0] = new Vertex();
            tempVertex[0].x = triangle.Face.v1[0];
            tempVertex[0].y = triangle.Face.v1[2];
            tempVertex[0].z = triangle.Face.v1[1];

            tempVertex[1] = new Vertex();
            tempVertex[1].x = triangle.Face.v2[0];
            tempVertex[1].y = triangle.Face.v2[2];
            tempVertex[1].z = triangle.Face.v2[1];

            tempVertex[2] = new Vertex();
            tempVertex[2].x = triangle.Face.v3[0];
            tempVertex[2].y = triangle.Face.v3[2];
            tempVertex[2].z = triangle.Face.v3[1];

            fillScanLine(tempVertex[0], tempVertex[1]);
            fillScanLine(tempVertex[1], tempVertex[2]);
            fillScanLine(tempVertex[2], tempVertex[0]);

            float tempWidth = width;
            float tempHeight = height;
            // target width and width

            int startY = (int)Math.Min(tempVertex[0].y, Math.Min(tempVertex[1].y, tempVertex[2].y));
            int endY = (int)Math.Max(tempVertex[0].y, Math.Max(tempVertex[1].y, tempVertex[2].y));
            // Get the scanline where we start drawing and where we stop.

            endY = Math.Min(endY, height - 1);
            startY = Math.Max(0, startY);

            for (int y = startY; y <= endY; y++) // for each scanline
            {
                if (scanlineLowest[y].x < scanlineHighest[y].x) // If we actually have something filled in this scanline
                {
                    int yw = y * height;

                    float z = scanlineLowest[y].z;
                    float u = scanlineLowest[y].u;
                    float v = scanlineLowest[y].v;
                    // The start of the Z, U, and V coordinate.

                    float deltaX = 1.0f / (scanlineHighest[y].x - scanlineLowest[y].x);
                    // Interpolation over X (change in X between the two, then reverse it so it's usable as multiplication
                    // in divisions

                    float deltaZ = (scanlineHighest[y].z - scanlineLowest[y].z) * deltaX;
                    float deltaU = (scanlineHighest[y].u - scanlineLowest[y].u) * deltaX;
                    float deltaV = (scanlineHighest[y].v - scanlineLowest[y].v) * deltaX;
                    // The interpolation in Z, U and V in respect to the interpolation of X	

                    // Sub-texel correction
                    int x = (int)scanlineLowest[y].x;
                    int tx = x + 1;
                    int distInt = (int)(scanlineHighest[y].x) - (int)(scanlineLowest[y].x);
                    if (distInt > 0.0f)
                    {
                        u += (((float)(tx)) - tx) * deltaU;
                        v += (((float)(tx)) - tx) * deltaV;
                        z += (((float)(tx)) - tx) * deltaZ;
                    }

                    if (!(scanlineHighest[y].x < 0 || x >= height))
                        for (int i = 0; x < (int)scanlineHighest[y].x; i++, x++) // for each piece of the scanline
                        {
                            if (x >= height) break; // If we're out of screen, break out this loop

                            if (x < 0)
                            {
                                int inverseX = Math.Abs(x);
                                z += deltaZ * inverseX;
                                u += deltaU * inverseX;
                                v += deltaV * inverseX;
                                x = 0;
                            }


                            {
                                // Get the point on the texture that we need to draw. It basically picks a pixel based on the uv.

                                //a_Target->GetRenderTarget()->Plot(x, tempHeight - y, 255);
                                heightMap[x + (y) * height] = z;
                                xMap[x + (y) * height] = scanlineLowest[y].x + deltaX * i;
                                yMap[x + (y) * height] = scanlineLowest[y].y;
                                if (z < lowestZ) lowestZ = z;
                            }

                            z += deltaZ;
                            u += deltaU;
                            v += deltaV;
                            // interpolate
                        }
                }

                scanlineLowest[y].x = 1e10f;
                scanlineHighest[y].x = -1e10f;
            }
        }
Ejemplo n.º 3
0
        bool outputMesh(int width, int height)
        {
            mapHeight = mapWidth = 0;
            for (var i = 0; i < width * height; i++)
                heightMap[i] = -99999.99f; // Clear the map

            lowX = 9e9;
            lowY = 9e9;
            highX = 0;
            highY = 0;
            lowestZ = 9e9; // Init triangle

            for (var i = 0; i < fileStream.triangle_count; i++)
            // Need to find the absolute values.. So we can map it to AIMESH_TEXTURE_SIZExAIMESH_TEXTURE_SIZE instead of 13000x15000
            {
                // Triangle low X check
                if (fileStream.triangles[i].Face.v1[0] < lowX)
                    lowX = fileStream.triangles[i].Face.v1[0];
                if (fileStream.triangles[i].Face.v2[0] < lowX)
                    lowX = fileStream.triangles[i].Face.v2[0];
                if (fileStream.triangles[i].Face.v3[0] < lowX)
                    lowX = fileStream.triangles[i].Face.v3[0];

                // Triangle low Y check
                if (fileStream.triangles[i].Face.v1[2] < lowY)
                    lowY = fileStream.triangles[i].Face.v1[2];
                if (fileStream.triangles[i].Face.v2[2] < lowY)
                    lowY = fileStream.triangles[i].Face.v2[2];
                if (fileStream.triangles[i].Face.v3[2] < lowY)
                    lowY = fileStream.triangles[i].Face.v3[2];

                // Triangle high X check
                if (fileStream.triangles[i].Face.v1[0] > highX)
                    highX = fileStream.triangles[i].Face.v1[0];
                if (fileStream.triangles[i].Face.v2[0] > highX)
                    highX = fileStream.triangles[i].Face.v2[0];
                if (fileStream.triangles[i].Face.v3[0] > highX)
                    highX = fileStream.triangles[i].Face.v3[0];

                // Triangle high Y check
                if (fileStream.triangles[i].Face.v1[2] > highY)
                    highY = fileStream.triangles[i].Face.v1[2];
                if (fileStream.triangles[i].Face.v2[2] > highY)
                    highY = fileStream.triangles[i].Face.v2[2];
                if (fileStream.triangles[i].Face.v3[2] > highY)
                    highY = fileStream.triangles[i].Face.v3[2];
            }

            mapWidth = (float)(highX + lowX);
            mapHeight = (float)(highY + lowY);

            // If the width or width larger?
            if ((highY - lowY) < (highX - lowX))
            {
                highX = 1.0f / (highX - lowX) * width; // We're wider than we're high, map on width
                highY = highX; // Keep aspect ratio Basically, 1 y should be 1 x.
                lowY = 0; // Though we need to project this in the middle, no offset
            }
            else
            {
                highY = 1.0f / (highY - lowY) * height; // We're higher than we're wide, map on width
                highX = highY; // Keep aspect ratio Basically, 1 x should be 1 y.
                               // lowX = 0; // X is already in the middle? ??????
            }

            for (var i = 0; i < fileStream.triangle_count; i++) // For every triangle
            {
                Triangle t_Triangle = new Triangle();// Create a triangle that is warped to heightmap coordinates
                t_Triangle.Face.v1[0] = (float)((fileStream.triangles[i].Face.v1[0] - lowX) * highX);
                t_Triangle.Face.v1[1] = fileStream.triangles[i].Face.v1[1];
                t_Triangle.Face.v1[2] = (float)((fileStream.triangles[i].Face.v1[2] - lowY) * highY);

                t_Triangle.Face.v2[0] = (float)((fileStream.triangles[i].Face.v2[0] - lowX) * highX);
                t_Triangle.Face.v2[1] = fileStream.triangles[i].Face.v2[1];
                t_Triangle.Face.v2[2] = (float)((fileStream.triangles[i].Face.v2[2] - lowY) * highY);

                t_Triangle.Face.v3[0] = (float)((fileStream.triangles[i].Face.v3[0] - lowX) * highX);
                t_Triangle.Face.v3[1] = fileStream.triangles[i].Face.v3[1];
                t_Triangle.Face.v3[2] = (float)((fileStream.triangles[i].Face.v3[2] - lowY) * highY);

                /*
                // Draw just the wireframe.
                drawLine(t_Triangle.Face.v1[0], t_Triangle.Face.v1[2], t_Triangle.Face.v2[0], t_Triangle.Face.v2[2], t_Info, width, height);
                drawLine(t_Triangle.Face.v2[0], t_Triangle.Face.v2[2], t_Triangle.Face.v3[0], t_Triangle.Face.v3[2], t_Info, width, height);
                drawLine(t_Triangle.Face.v3[0], t_Triangle.Face.v3[2], t_Triangle.Face.v1[0], t_Triangle.Face.v1[2], t_Info, width, height);
                */

                // Draw this triangle onto the heightmap using an awesome triangle drawing function
                drawTriangle(t_Triangle, width, height);
            }

            //writeFile(t_Info, width, height);
            return true;
        }