Пример #1
0
    // Construct a solid sphere. Optional parameters are `center`, `radius`,
    // `slices`, and `stacks`, which default to `[0, 0, 0]`, `1`, `16`, and `8`.
    // The `slices` and `stacks` parameters control the tessellation along the
    // longitude and latitude directions.
    //
    // Example usage:
    //
    //     var sphere = CSG.sphere({
    //       center: [0, 0, 0],
    //       radius: 1,
    //       slices: 16,
    //       stacks: 8
    //     });
    static public CSG sphere(CSGVector3 center, float radius, int slices, int stacks, CSGShared shared)
    {
        List <CSGPolygon> polygons = new List <CSGPolygon>();

        for (float i = 0; i < slices; i++)
        {
            for (float j = 0; j < stacks; j++)
            {
                List <CSGVertex> vertices = new List <CSGVertex>();
                sphereVertex(center, radius, i / slices, j / stacks, vertices);

                if (j > 0)
                {
                    sphereVertex(center, radius, (i + 1) / slices, j / stacks, vertices);
                }

                if (j < stacks - 1)
                {
                    sphereVertex(center, radius, (i + 1) / slices, (j + 1) / stacks, vertices);
                }

                sphereVertex(center, radius, i / slices, (j + 1) / stacks, vertices);

                polygons.Add(new CSGPolygon(vertices, shared));
            }
        }

        return(CSG.fromPolygons(polygons));
    }
Пример #2
0
    // Construct an axis-aligned solid cuboid. Optional parameters are `center` and
    // `radius`, which default to `[0, 0, 0]` and `[1, 1, 1]`. The radius can be
    // specified using a single number or a list of three numbers, one for each axis.
    static public CSG cube(CSGVector3 center, CSGVector3 halfSize, CSGShared shared)
    {
        int[][][] data = new int[][][] {
            new int[][] { new int[] { 0, 4, 6, 2 }, new int[] { -1, 0, 0 } },
            new int[][] { new int[] { 1, 3, 7, 5 }, new int[] { +1, 0, 0 } },
            new int[][] { new int[] { 0, 1, 5, 4 }, new int[] { 0, -1, 0 } },
            new int[][] { new int[] { 2, 6, 7, 3 }, new int[] { 0, +1, 0 } },
            new int[][] { new int[] { 0, 2, 3, 1 }, new int[] { 0, 0, -1 } },
            new int[][] { new int[] { 4, 5, 7, 6 }, new int[] { 0, 0, +1 } }
        };

        List <CSGPolygon> polygons = new List <CSGPolygon>();

        foreach (int[][] info in data)
        {
            List <CSGVertex> vertices = new List <CSGVertex>();

            foreach (int i in info[0])
            {
                CSGVector3 pos = new CSGVector3(
                    center.x + halfSize.x * (2 * ((i & 1) != 0 ? 1 : 0) - 1),
                    center.y + halfSize.y * (2 * ((i & 2) != 0 ? 1 : 0) - 1),
                    center.z + halfSize.z * (2 * ((i & 4) != 0 ? 1 : 0) - 1)
                    );

                vertices.Add(new CSGVertex(pos, new CSGVector3(info[1][0], info[1][1], info[1][2])));
            }

            polygons.Add(new CSGPolygon(vertices, shared));
        }

        return(CSG.fromPolygons(polygons));
    }
 public CSGVector3 cross(CSGVector3 a)
 {
     return(new CSGVector3(
                this.y * a.z - this.z * a.y,
                this.z * a.x - this.x * a.z,
                this.x * a.y - this.y * a.x
                ));
 }
Пример #4
0
    static private CSGVertex cylinderPoint(CSGVector3 s, CSGVector3 ray, float r, CSGVector3 axisX, CSGVector3 axisY, CSGVector3 axisZ, float stack, float slice, float normalBlend)
    {
        float      angle  = slice * ((float)Math.PI) * 2;
        CSGVector3 outv   = axisX.times((float)Math.Cos(angle)).plus(axisY.times((float)Math.Sin(angle)));
        CSGVector3 pos    = s.plus(ray.times(stack)).plus(outv.times(r));
        CSGVector3 normal = outv.times(1 - Math.Abs(normalBlend)).plus(axisZ.times(normalBlend));

        return(new CSGVertex(pos, normal));
    }
    // Affine transformation of vertex. Returns a new CSG.Vertex
    public CSGVertex transform(CSGMatrix4x4 matrix4x4)
    {
        CSGVector3 newpos           = this.pos.multiply4x4(matrix4x4);
        CSGVector3 posPlusNormal    = this.pos.plus(this.normal);
        CSGVector3 newPosPlusNormal = posPlusNormal.multiply4x4(matrix4x4);
        CSGVector3 newnormal        = newPosPlusNormal.minus(newpos).unit();

        return(new CSGVertex(newpos, newnormal));
    }
Пример #6
0
    static private void sphereVertex(CSGVector3 center, float radius, float theta, float phi, List <CSGVertex> vertices)
    {
        theta *= ((float)Math.PI) * 2;
        phi   *= ((float)Math.PI);
        CSGVector3 dir = new CSGVector3(
            (float)Math.Cos(theta) * (float)Math.Sin(phi),
            (float)Math.Cos(phi),
            (float)Math.Sin(theta) * (float)Math.Sin(phi)
            );

        vertices.Add(new CSGVertex(center.plus(dir.times(radius)), dir));
    }
Пример #7
0
    // Construct a solid cylinder. Optional parameters are `start`, `end`,
    // `radius`, and `slices`, which default to `[0, -1, 0]`, `[0, 1, 0]`, `1`, and
    // `16`. The `slices` parameter controls the tessellation.
    //
    // Example usage:
    //
    //     var cylinder = CSG.cylinder({
    //       start: [0, -1, 0],
    //       end: [0, 1, 0],
    //       radius: 1,
    //       slices: 16
    //     });
    static public CSG cylinder(CSGVector3 s, CSGVector3 e, float radius, int slices, CSGShared shared)
    {
        CSGVector3 ray   = e.minus(s);
        CSGVector3 axisZ = ray.unit();
        bool       isY   = (Math.Abs(axisZ.y) > 0.5f);

        CSGVector3 axisX = new CSGVector3(isY ? 1 : 0, !isY ? 1 : 0, 0).cross(axisZ).unit();
        CSGVector3 axisY = axisX.cross(axisZ).unit();

        CSGVertex start = new CSGVertex(s, axisZ.negated());
        CSGVertex end   = new CSGVertex(e, axisZ.unit());

        List <CSGPolygon> polygons = new List <CSGPolygon>();

        for (float i = 0; i < slices; i++)
        {
            float t0 = i / slices;
            float t1 = (i + 1) / slices;

            //cylinderPoint(s, ray, radius, axisX, axisY, axisZ,

            polygons.Add(
                new CSGPolygon(
                    new CSGVertex[] {
                start,
                cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 0, t0, -1),
                cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 0, t1, -1)
            }, shared));

            polygons.Add(
                new CSGPolygon(
                    new CSGVertex[] {
                cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 0, t1, 0),
                cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 0, t0, 0),
                cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 1, t0, 0),
                cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 1, t1, 0)
            }, shared));

            polygons.Add(
                new CSGPolygon(
                    new CSGVertex[] {
                end,
                cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 1, t1, 1),
                cylinderPoint(s, ray, radius, axisX, axisY, axisZ, 1, t0, 1)
            }, shared));
        }

        return(CSG.fromPolygons(polygons));
    }
Пример #8
0
    // Create an affine matrix for scaling:
    static public CSGMatrix4x4 scaling(CSGVector3 vec)
    {
        CSGMatrix4x4 result = new CSGMatrix4x4();

        result.this0  = vec.x;
        result.this5  = vec.y;
        result.this10 = vec.z;
        result.this15 = 1;

        /*
         * float[] els = new float[] {
         *      vec.x, 0, 0, 0,
         *      0, vec.y, 0, 0,
         *      0, 0, vec.z, 0,
         *      0, 0, 0, 1
         * };
         */

        return(result);
    }
Пример #9
0
    // Multiply a CSG.Vector (interpreted as 1 row, 3 column) by this matrix
    // Fourth element is taken as 1
    public CSGVector3 rightMultiply1x3Vector(CSGVector3 v)
    {
        float v0 = v.x;
        float v1 = v.y;
        float v2 = v.z;
        float v3 = 1;
        float x  = v0 * this0 + v1 * this1 + v2 * this2 + v3 * this3;
        float y  = v0 * this4 + v1 * this5 + v2 * this6 + v3 * this7;
        float z  = v0 * this8 + v1 * this9 + v2 * this10 + v3 * this11;
        float w  = v0 * this12 + v1 * this13 + v2 * this14 + v3 * this15;

        // scale such that fourth element becomes 1:
        if (w != 1)
        {
            float invw = 1.0f / w;
            x *= invw;
            y *= invw;
            z *= invw;
        }

        return(new CSGVector3(x, y, z));
    }
Пример #10
0
    // Create an affine matrix for translation:
    static public CSGMatrix4x4 translation(CSGVector3 vec)
    {
        CSGMatrix4x4 result = new CSGMatrix4x4();

        result.this0  = 1;
        result.this3  = vec.x;
        result.this5  = 1;
        result.this7  = vec.y;
        result.this10 = 1;
        result.this11 = vec.z;
        result.this15 = 1;

        /*
         * float[] els = new float[] {
         *      1, 0, 0, vec.x,
         *      0, 1, 0, vec.y,
         *      0, 0, 1, vec.z,
         *      0, 0, 0, 1
         * };
         */

        return(result);
    }
 public CSGVertex(CSGVector3 pos, CSGVector3 normal)
 {
     this.pos    = pos;
     this.normal = normal;
 }
 public CSGPlane(CSGVector3 normal, float w)
 {
     this.normal = normal;
     this.w      = w;
 }
 public void flip()
 {
     normal = normal.negated();
     w      = -w;
 }
    static public CSGPlane fromPoints(CSGVector3 a, CSGVector3 b, CSGVector3 c)
    {
        CSGVector3 n = b.minus(a).cross(c.minus(a)).unit();

        return(new CSGPlane(n, n.dot(a)));
    }
 public CSGVector3 plus(CSGVector3 a)
 {
     return(new CSGVector3(x + a.x, y + a.y, z + a.z));
 }
Пример #16
0
 public CSGShared(float r, float g, float b)
 {
     this.color = new CSGVector3(r, g, b);
 }
Пример #17
0
 public CSG scale(CSGVector3 v)
 {
     return(this.transform(CSGMatrix4x4.scaling(v)));
 }
Пример #18
0
 public CSG translate(CSGVector3 v)
 {
     return(this.transform(CSGMatrix4x4.translation(v)));
 }
 public CSGVector3 minus(CSGVector3 a)
 {
     return(new CSGVector3(x - a.x, y - a.y, z - a.z));
 }
 public CSGVector3 lerp(CSGVector3 a, float t)
 {
     return(this.plus(a.minus(this).times(t)));
 }
 public float dot(CSGVector3 a)
 {
     return(this.x * a.x + this.y * a.y + this.z * a.z);
 }