Quantcast
Channel: Community | MonoGame - Latest topics
Viewing all articles
Browse latest Browse all 6821

[Code]Cube Sphere SkyBox Sphere From IndexedPrimitives.

$
0
0

@willmotil wrote:

The below class generates a cube or sphere with the specified number of vertices per face.
It creates smooth normals on the sphere as well as tangents for normal mapping.
It has a switch to create it as either a cube or sphere or to create it as a sky cube or sphere.
It has switches to use it with a standard cross type image or a blender block type image or with 6 seperate images per face. This is so it can be used for a RenderTargetCube.
It was created and tested to perform depth mapping or reflection but i extended it a bit and polished it up.

    /// <summary>
    /// This is a sphere or a sky sphere. 
    /// It can use 6 seperate images on 6 faces or a cross or blender block type texture..
    /// Both Sphere and skyShere Uses CCW culling in regular operation.
    /// It generates positions normals texture and tangents for normal maping.
    /// It tesselates face points into sphereical coordinates on creation.
    /// A face resolution of 2 is also a cube or sky cube.
    /// It can also switch tangent or normal directions or u v that shouldn't be needed though.
    /// </summary>
    public class SpherePNTT
    {
        bool changeToSkySphere = false;
        bool changeToSingleImageTexture = true;
        bool blenderStyleElseCross = false;
        bool flipTangentSign = false;
        bool flipNormalDirection = false;
        bool flipU = false;
        bool flipV = false;
        int verticeFaceResolution = 3;

        int verticeFaceDrawOffset = 0;
        int indiceFaceDrawOffset = 0;
        int verticesPerFace = 0;
        int indicesPerFace = 0;
        int primitivesPerFace = 0;

        // face identifiers
        const int FaceFront = 0;
        const int FaceBack = 1;
        const int FaceLeft = 2;
        const int FaceRight = 3;
        const int FaceTop = 4;
        const int FaceBottom = 5;

        VertexPositionNormalTextureTangent[] vertices = new VertexPositionNormalTextureTangent[24];
        int[] indices = new int[36];

        /// <summary>
        /// Defaults to a seperate image hexahedron. 
        /// Use the other overloads if you want something more specific like a sphere.
        /// The spheres are counter clockwise wound.
        /// The skySphere is clockwise wound.
        /// </summary>
        public SpherePNTT()
        {
            CreateSixFaceSphere(true, false, false, false, false, false, false, verticeFaceResolution);
        }
        // seperate faces
        public SpherePNTT(bool changeToSkySphere)
        {
            CreateSixFaceSphere(changeToSkySphere, false, false, false, false, false, false, verticeFaceResolution);
        }
        // seperate faces at resolution
        public SpherePNTT(bool changeToSkySphere, int vertexResolutionPerFace)
        {
            CreateSixFaceSphere(changeToSkySphere, false, false, false, false, false, false, vertexResolutionPerFace);
        }
        /// <summary>
        /// Set the type, if the faces are in a single image or six seperate images and if the single image is a cross or blender type image.
        /// Additionally specify the number of vertices per face this value is squared as it is used for rows and columns.
        /// </summary>
        public SpherePNTT(bool changeToSkySphere, bool changeToSingleImageTexture, bool blenderStyleSkyBox, int vertexResolutionPerFace)
        {
            CreateSixFaceSphere(changeToSkySphere, changeToSingleImageTexture, blenderStyleSkyBox, false, false, false, false, vertexResolutionPerFace);
        }
        public SpherePNTT(bool changeToSkySphere, bool changeToSingleImageTexture, bool blenderStyleSkyBox, bool flipNormalDirection, bool flipTangentDirection, bool flipTextureDirectionU, bool flipTextureDirectionV , int vertexResolutionPerFace)
        {
            CreateSixFaceSphere(changeToSkySphere, changeToSingleImageTexture, blenderStyleSkyBox, flipNormalDirection, flipTangentDirection, flipTextureDirectionU, flipTextureDirectionV, vertexResolutionPerFace);
        }

        void CreateSixFaceSphere(bool changeToSkySphere, bool changeToSingleImageTexture, bool blenderStyleElseCross, bool flipNormalDirection, bool flipTangentDirection, bool flipU, bool flipV, int vertexResolutionPerFace)
        {
            this.changeToSkySphere = changeToSkySphere;
            this.changeToSingleImageTexture = changeToSingleImageTexture;
            this.blenderStyleElseCross = blenderStyleElseCross;
            this.flipNormalDirection = flipNormalDirection;
            this.flipTangentSign = flipTangentDirection;
            this.flipU = flipU;
            this.flipV = flipV;
            if (vertexResolutionPerFace < 2)
                vertexResolutionPerFace = 2;
            this.verticeFaceResolution = vertexResolutionPerFace;
            Vector3 offset = new Vector3(.5f, .5f, .5f);
            // 8 vertice points ill label them, then reassign them for clarity.
            Vector3 LT_f = new Vector3(0, 1, 0) - offset; Vector3 A = LT_f;
            Vector3 LB_f = new Vector3(0, 0, 0) - offset; Vector3 B = LB_f;
            Vector3 RT_f = new Vector3(1, 1, 0) - offset; Vector3 C = RT_f;
            Vector3 RB_f = new Vector3(1, 0, 0) - offset; Vector3 D = RB_f;
            Vector3 LT_b = new Vector3(0, 1, 1) - offset; Vector3 E = LT_b;
            Vector3 LB_b = new Vector3(0, 0, 1) - offset; Vector3 F = LB_b;
            Vector3 RT_b = new Vector3(1, 1, 1) - offset; Vector3 G = RT_b;
            Vector3 RB_b = new Vector3(1, 0, 1) - offset; Vector3 H = RB_b;

            // Six faces to a cube or sphere
            // each face of the cube wont actually share vertices as each will use its own texture.
            // unless it is actually using single skybox texture

            // we will need to precalculate the grids size now
            int vw = vertexResolutionPerFace;
            int vh = vertexResolutionPerFace;
            int vlen = vw * vh * 6; // the extra six here is the number of faces
            int iw = vw - 1;
            int ih = vh - 1;
            int ilen = iw * ih * 6  * 6; // the extra six here is the number of faces
            vertices = new VertexPositionNormalTextureTangent[vlen];
            indices = new int[ilen];
            verticeFaceDrawOffset = vlen = vw * vh;
            indiceFaceDrawOffset = ilen = iw * ih * 6;
            verticesPerFace = vertexResolutionPerFace * vertexResolutionPerFace;
            indicesPerFace = iw * ih * 6;
            primitivesPerFace = iw * ih * 2; // 2 triangles per quad

            if (changeToSkySphere)
            {
                // passed uv texture coordinates.
                Vector2 uv0 = new Vector2(1f, 1f);
                Vector2 uv1 = new Vector2(0f, 1f);
                Vector2 uv2 = new Vector2(1f, 0f);
                Vector2 uv3 = new Vector2(0f, 0f);
                SetFaceGrid(FaceFront, D, B, C, A, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceBack, F, H, E, G, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceLeft, B, F, A, E, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceRight, H, D, G, C, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceTop, C, A, G, E, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceBottom, H, F, D, B, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
            }
            else // regular cube 
            {
                Vector2 uv0 = new Vector2(0f, 0f);
                Vector2 uv1 = new Vector2(0f, 1f);
                Vector2 uv2 = new Vector2(1f, 0f);
                Vector2 uv3 = new Vector2(1f, 1f);
                SetFaceGrid(FaceFront, A, B, C, D, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceBack, G, H, E, F, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceLeft, E, F, A, B, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceRight, C, D, G, H, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceTop, E, A, G, C, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
                SetFaceGrid(FaceBottom, B, F, D, H, uv0, uv1, uv2, uv3, vertexResolutionPerFace);
            }
        }

        void SetFaceGrid(int faceMultiplier, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, Vector2 uv0, Vector2 uv1, Vector2 uv2, Vector2 uv3, int vertexResolution)
        {
            if (changeToSingleImageTexture)
                UvSkyTextureReassignment(faceMultiplier, ref uv0, ref uv1, ref uv2, ref uv3);
            int vw = vertexResolution;
            int vh = vertexResolution;
            int vlen = vw * vh;
            int iw = vw -1;
            int ih = vh - 1;
            int ilen = iw * ih * 6;
            // actual start index's
            int vIndex = faceMultiplier * vlen;
            int iIndex = faceMultiplier * ilen;
            // we now must build the grid/
            float ratio = 1f / (float)(vertexResolution -1);
            // well do it all simultaneously no point in spliting it up
            for (int y = 0; y < vertexResolution; y++)
            {
                float ratioY = (float)y * ratio;
                for (int x = 0; x < vertexResolution; x++)
                {
                    // index
                    int index = vIndex + (y * vertexResolution + x);
                    float ratioX = (float)x * ratio;
                    // calculate uv_n_p tangent comes later
                    var uv = InterpolateUv(uv0, uv1, uv2, uv3, ratioX, ratioY);
                    var n = InterpolateToNormal(v0, v1, v2, v3, ratioX, ratioY);
                    var p = n * .5f; // displace to distance
                    if (changeToSkySphere)
                        n = -n;
                    if (flipNormalDirection)
                        n = -n;
                    // handle u v fliping if its desired.
                    if (flipU)
                        uv.X = 1.0f - uv.X;
                    if (flipV)
                        uv.Y = 1.0f - uv.Y;
                    // assign
                    vertices[index].Position = p;
                    vertices[index].TextureCoordinate = uv;
                    vertices[index].Normal = n;
                }
            }

            // ToDo... 
            // We could loop all the vertices which are nearly the exact same and make sure they are the same place but seperate.
            // sort of redundant but floating point errors happen under interpolation, well get back to that later on.
            // not sure i really need to it looks pretty spot on.

            // ok so now we have are positions our normal and uv per vertice we need to loop again and handle the tangents
            for (int y = 0; y < (vertexResolution -1); y++)
            {
                for (int x = 0; x < (vertexResolution -1); x++)
                {
                    //
                    int indexV0 = vIndex + (y * vertexResolution + x);
                    int indexV1 = vIndex + ( (y + 1) * vertexResolution + x);
                    int indexV2 = vIndex + (y * vertexResolution + (x +1));
                    int indexV3 = vIndex + ((y + 1) * vertexResolution + (x+1));
                    var p0 = vertices[indexV0].Position; 
                    var p1 = vertices[indexV1].Position;
                    var p2 = vertices[indexV2].Position;
                    var p3 = vertices[indexV3].Position;
                    var t = -(p0 - p1);
                    if (changeToSkySphere)
                        t = -t;
                    t.Normalize();
                    if (flipTangentSign)
                        t = -t;
                    vertices[indexV0].Tangent = t; vertices[indexV1].Tangent = t; vertices[indexV2].Tangent = t; vertices[indexV3].Tangent = t;
                    //
                    // set our indices while were at it.
                    int indexI = iIndex + ((y * (vertexResolution - 1) + x) * 6);
                    int via = indexV0, vib = indexV1, vic = indexV2, vid = indexV3;
                    indices[indexI + 0] = via; indices[indexI + 1] = vib; indices[indexI + 2] = vic;
                    indices[indexI + 3] = vic; indices[indexI + 4] = vib; indices[indexI + 5] = vid;
                }
            }
        }

        // this allows for the use of a single texture skybox.
        void UvSkyTextureReassignment(int faceMultiplier, ref Vector2 uv0, ref Vector2 uv1, ref Vector2 uv2, ref Vector2 uv3)
        {
            if (changeToSingleImageTexture)
            {
                Vector2 tupeBuvwh = new Vector2(.250000000f, .333333333f); // this is a 8 square left sided skybox
                Vector2 tupeAuvwh = new Vector2(.333333333f, .500000000f); // this is a 6 square blender type skybox
                Vector2 currentuvWH = tupeBuvwh;
                Vector2 uvStart = Vector2.Zero;
                Vector2 uvEnd = Vector2.Zero;

                // crossstyle
                if (blenderStyleElseCross == false)
                {
                    currentuvWH = tupeBuvwh;
                    switch (faceMultiplier)
                    {
                        case FaceFront:
                            uvStart = new Vector2(currentuvWH.X * 1f, currentuvWH.Y * 1f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceBack:
                            uvStart = new Vector2(currentuvWH.X * 3f, currentuvWH.Y * 1f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceRight:
                            uvStart = new Vector2(currentuvWH.X * 2f, currentuvWH.Y * 1f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceLeft:
                            uvStart = new Vector2(currentuvWH.X * 0f, currentuvWH.Y * 1f);
                            uvEnd = uvStart + currentuvWH;
                            //uvStart = new Vector2(currentuvWH.X * 1f, currentuvWH.Y * 0f);
                            //uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceTop:
                            uvStart = new Vector2(currentuvWH.X * 1f, currentuvWH.Y * 0f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceBottom:
                            uvStart = new Vector2(currentuvWH.X * 1f, currentuvWH.Y * 2f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                    }
                    if (changeToSkySphere)
                    {
                        uv0 = new Vector2(uvEnd.X, uvEnd.Y); uv1 = new Vector2(uvStart.X, uvEnd.Y); uv2 = new Vector2(uvEnd.X, uvStart.Y); uv3 = new Vector2(uvStart.X, uvStart.Y);
                    }
                    else
                    {
                        uv0 = new Vector2(uvStart.X, uvStart.Y); uv1 = new Vector2(uvStart.X, uvEnd.Y); uv2 = new Vector2(uvEnd.X, uvStart.Y); uv3 = new Vector2(uvEnd.X, uvEnd.Y);
                    }
                }
                else 
                {
                    currentuvWH = tupeAuvwh;
                    switch (faceMultiplier)
                    {
                        case FaceLeft:
                            uvStart = new Vector2(currentuvWH.X * 0f, currentuvWH.Y * 0f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceBack:
                            uvStart = new Vector2(currentuvWH.X * 1f, currentuvWH.Y * 0f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceRight:
                            uvStart = new Vector2(currentuvWH.X * 2f, currentuvWH.Y * 0f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceBottom:
                            uvStart = new Vector2(currentuvWH.X * 0f, currentuvWH.Y * 1f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceTop:
                            uvStart = new Vector2(currentuvWH.X * 1f, currentuvWH.Y * 1f);
                            uvEnd = uvStart + currentuvWH;
                            break;
                        case FaceFront:
                            uvStart = new Vector2(currentuvWH.X * 2f, currentuvWH.Y * 1f);
                            uvEnd = uvStart + currentuvWH;
                            break;                       
                    }
                    if (changeToSkySphere)
                    {
                        uv0 = new Vector2(uvEnd.X, uvEnd.Y); uv2 = new Vector2(uvEnd.X, uvStart.Y); uv1 = new Vector2(uvStart.X, uvEnd.Y); uv3 = new Vector2(uvStart.X, uvStart.Y);
                    }
                    else
                    {
                        uv0 = new Vector2(uvStart.X, uvStart.Y); uv1 = new Vector2(uvStart.X, uvEnd.Y); uv2 = new Vector2(uvEnd.X, uvStart.Y); uv3 = new Vector2(uvEnd.X, uvEnd.Y);
                    }
                }
            }
        }

        Vector3 InterpolateToNormal(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, float timeX, float timeY)
        {
            var y0 = ((v1 - v0) * timeY + v0);
            var y1 = ((v3 - v2) * timeY + v2);
            var n = ((y1 - y0) * timeX + y0) *10f; // * 10f ensure its sufficiently denormalized.
            n.Normalize();
            return n;
        }
        Vector2 InterpolateUv(Vector2 v0, Vector2 v1, Vector2 v2, Vector2 v3, float timeX, float timeY)
        {
            var y0 = ((v1 - v0) * timeY + v0);
            var y1 = ((v3 - v2) * timeY + v2);
            return ((y1 - y0) * timeX + y0); 
        }

        public void Draw(GraphicsDevice gd, Effect effect)
        {
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                gd.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, (indices.Length / 3), VertexPositionNormalTextureTangent.VertexDeclaration);
            }
        }

        /// <summary>
        /// Seperate faced cube or sphere or sky
        /// This method is pretty dependant on being able to pass to textureA not good but....
        /// </summary>
        public void Draw(GraphicsDevice gd, Effect effect, Texture2D front, Texture2D back, Texture2D left, Texture2D right, Texture2D top, Texture2D bottom)
        {
            int FaceFront = 0;
            int FaceBack = 1;
            int FaceLeft = 2;
            int FaceRight = 3;
            int FaceTop = 4;
            int FaceBottom = 5;
            for (int t = 0; t < 6; t++)
            {
                if (t == FaceFront) effect.Parameters["TextureA"].SetValue(front);
                if (t == FaceBack) effect.Parameters["TextureA"].SetValue(back);
                if (t == FaceLeft) effect.Parameters["TextureA"].SetValue(left);
                if (t == FaceRight) effect.Parameters["TextureA"].SetValue(right);
                if (t == FaceTop) effect.Parameters["TextureA"].SetValue(top);
                if (t == FaceBottom) effect.Parameters["TextureA"].SetValue(bottom);
                int ifoffset = t * indicesPerFace;
                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    gd.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, ifoffset, primitivesPerFace, VertexPositionNormalTextureTangent.VertexDeclaration);
                }
            }
        }

        /// <summary>
        /// Single texture multi faced cube or sphere or sky
        /// This method is pretty dependant on being able to pass to textureA not good but....
        /// </summary>
        public void Draw(GraphicsDevice gd, Effect effect, Texture2D cubeTexture)
        {
            effect.Parameters["TextureA"].SetValue(cubeTexture);
            for (int t = 0; t < 6; t++)
            {
                int ifoffset = t * indicesPerFace;
                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    gd.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, ifoffset, primitivesPerFace, VertexPositionNormalTextureTangent.VertexDeclaration);
                }
            }
        }

        /// <summary>
        /// This method is pretty dependant on being able to pass to textureA not good but....
        /// </summary>
        public void DrawWithBasicEffect(GraphicsDevice gd, BasicEffect effect, Texture2D front, Texture2D back, Texture2D left, Texture2D right, Texture2D top, Texture2D bottom)
        {
            int FaceFront = 0;
            int FaceBack = 1;
            int FaceLeft = 2;
            int FaceRight = 3;
            int FaceTop = 4;
            int FaceBottom = 5;
            for (int t = 0; t < 6; t++)
            {
                if (t == FaceFront) effect.Texture = front;
                if (t == FaceBack) effect.Texture = back;
                if (t == FaceLeft) effect.Texture = left;
                if (t == FaceRight) effect.Texture = right;
                if (t == FaceTop) effect.Texture = top;
                if (t == FaceBottom) effect.Texture = bottom;
                int vi = t * 4;
                int ii = t * indicesPerFace;
                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    gd.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, ii, primitivesPerFace, VertexPositionNormalTextureTangent.VertexDeclaration);
                }
            }
        }

        /// <summary>
        /// Single texture multi faced cube or sphere or sky
        /// This method is pretty dependant on being able to pass to textureA not good but....
        /// </summary>
        public void DrawWithBasicEffect(GraphicsDevice gd, BasicEffect effect, Texture2D cubeTexture)
        {
            effect.Texture = cubeTexture;
            for (int t = 0; t < 6; t++)
            {
                int ifoffset = t * indicesPerFace;
                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    gd.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, ifoffset, primitivesPerFace, VertexPositionNormalTextureTangent.VertexDeclaration);
                }
            }
        }

        public Vector3 Norm(Vector3 n)
        {
            return Vector3.Normalize(n);
        }

        /// <summary>
        /// Positional cross product, Counter Clock wise positive.
        /// </summary>
        public static Vector3 CrossVectors3d(Vector3 a, Vector3 b, Vector3 c)
        {
            // no point in doing reassignments the calculation is straight forward.
            return new Vector3
                (
                ((b.Y - a.Y) * (c.Z - b.Z)) - ((c.Y - b.Y) * (b.Z - a.Z)),
                ((b.Z - a.Z) * (c.X - b.X)) - ((c.Z - b.Z) * (b.X - a.X)),
                ((b.X - a.X) * (c.Y - b.Y)) - ((c.X - b.X) * (b.Y - a.Y))
                );
        }

        /// <summary>
        /// use the vector3 cross
        /// </summary>
        public static Vector3 CrossXna(Vector3 a, Vector3 b, Vector3 c)
        {
            var v1 = a - b;
            var v2 = c - b;

            return Vector3.Cross(v1, v2);
        }

        // vertex structure data.
        public struct VertexPositionNormalTextureTangent : IVertexType
        {
            public Vector3 Position;
            public Vector3 Normal;
            public Vector2 TextureCoordinate;
            public Vector3 Tangent;

            public static VertexDeclaration VertexDeclaration = new VertexDeclaration
            (
                  new VertexElement(VertexElementByteOffset.PositionStartOffset(), VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
                  new VertexElement(VertexElementByteOffset.OffsetVector3(), VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
                  new VertexElement(VertexElementByteOffset.OffsetVector2(), VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
                  new VertexElement(VertexElementByteOffset.OffsetVector3(), VertexElementFormat.Vector3, VertexElementUsage.Normal, 1)
            );
            VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } }
        }
        /// <summary>
        /// This is a helper struct for tallying byte offsets
        /// </summary>
        public struct VertexElementByteOffset
        {
            public static int currentByteSize = 0;
            [STAThread]
            public static int PositionStartOffset() { currentByteSize = 0; var s = sizeof(float) * 3; currentByteSize += s; return currentByteSize - s; }
            public static int Offset(float n) { var s = sizeof(float); currentByteSize += s; return currentByteSize - s; }
            public static int Offset(Vector2 n) { var s = sizeof(float) * 2; currentByteSize += s; return currentByteSize - s; }
            public static int Offset(Color n) { var s = sizeof(int); currentByteSize += s; return currentByteSize - s; }
            public static int Offset(Vector3 n) { var s = sizeof(float) * 3; currentByteSize += s; return currentByteSize - s; }
            public static int Offset(Vector4 n) { var s = sizeof(float) * 4; currentByteSize += s; return currentByteSize - s; }

            public static int OffsetFloat() { var s = sizeof(float); currentByteSize += s; return currentByteSize - s; }
            public static int OffsetColor() { var s = sizeof(int); currentByteSize += s; return currentByteSize - s; }
            public static int OffsetVector2() { var s = sizeof(float) * 2; currentByteSize += s; return currentByteSize - s; }
            public static int OffsetVector3() { var s = sizeof(float) * 3; currentByteSize += s; return currentByteSize - s; }
            public static int OffsetVector4() { var s = sizeof(float) * 4; currentByteSize += s; return currentByteSize - s; }
        }
    }

Posts: 1

Participants: 1

Read full topic


Viewing all articles
Browse latest Browse all 6821

Trending Articles