Beispiel #1
0
        /// <summary>
        /// </summary>
        /// <param name="other">
        /// </param>
        public virtual void merge(VertexData other)
        {
            if (other.indices != null)
            {
                if (this.indices == null)
                {
                    this.indices = new Array <int>();
                }

                var offset = (this.positions != null) ? this.positions.Length / 3 : 0;
                for (var index = 0; index < other.indices.Length; index++)
                {
                    this.indices.Add(other.indices[index] + offset);
                }
            }

            if (other.positions != null)
            {
                if (this.positions == null)
                {
                    this.positions = new Array <double>();
                }

                for (var index = 0; index < other.positions.Length; index++)
                {
                    this.positions.Add(other.positions[index]);
                }
            }

            if (other.normals != null)
            {
                if (this.normals == null)
                {
                    this.normals = new Array <double>();
                }

                for (var index = 0; index < other.normals.Length; index++)
                {
                    this.normals.Add(other.normals[index]);
                }
            }

            if (other.uvs != null)
            {
                if (this.uvs == null)
                {
                    this.uvs = new Array <double>();
                }

                for (var index = 0; index < other.uvs.Length; index++)
                {
                    this.uvs.Add(other.uvs[index]);
                }
            }

            if (other.uv2s != null)
            {
                if (this.uv2s == null)
                {
                    this.uv2s = new Array <double>();
                }

                for (var index = 0; index < other.uv2s.Length; index++)
                {
                    this.uv2s.Add(other.uv2s[index]);
                }
            }

            if (other.matricesIndices != null)
            {
                if (this.matricesIndices == null)
                {
                    this.matricesIndices = new Array <double>();
                }

                for (var index = 0; index < other.matricesIndices.Length; index++)
                {
                    this.matricesIndices.Add(other.matricesIndices[index]);
                }
            }

            if (other.matricesWeights != null)
            {
                if (this.matricesWeights == null)
                {
                    this.matricesWeights = new Array <double>();
                }

                for (var index = 0; index < other.matricesWeights.Length; index++)
                {
                    this.matricesWeights.Add(other.matricesWeights[index]);
                }
            }

            if (other.colors != null)
            {
                if (this.colors == null)
                {
                    this.colors = new Array <double>();
                }

                for (var index = 0; index < other.colors.Length; index++)
                {
                    this.colors.Add(other.colors[index]);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// </summary>
        /// <param name="xmin">
        /// </param>
        /// <param name="zmin">
        /// </param>
        /// <param name="xmax">
        /// </param>
        /// <param name="zmax">
        /// </param>
        /// <param name="subdivisions">
        /// </param>
        /// <param name="precision">
        /// </param>
        /// <returns>
        /// </returns>
        public static VertexData CreateTiledGround(double xmin, double zmin, double xmax, double zmax, SizeI subdivisions, SizeI precision)
        {
            var indices   = new Array <int>();
            var positions = new Array <double>();
            var normals   = new Array <double>();
            var uvs       = new Array <double>();

            subdivisions.h = (subdivisions.w < 1) ? 1 : subdivisions.h;
            subdivisions.w = (subdivisions.w < 1) ? 1 : subdivisions.w;
            precision.w    = (precision.w < 1) ? 1 : precision.w;
            precision.h    = (precision.h < 1) ? 1 : precision.h;
            var tileSize = new SizeI {
                w = (int)((xmax - xmin) / subdivisions.w), h = (int)((zmax - zmin) / subdivisions.h)
            };

            for (var tileRow = 0; tileRow < subdivisions.h; tileRow++)
            {
                for (var tileCol = 0; tileCol < subdivisions.w; tileCol++)
                {
                    var xTileMin = xmin + tileCol * tileSize.w;
                    var zTileMin = zmin + tileRow * tileSize.h;
                    var xTileMax = xmin + (tileCol + 1) * tileSize.w;
                    var zTileMax = zmin + (tileRow + 1) * tileSize.h;

                    // Indices
                    var _base     = positions.Length / 3;
                    var rowLength = precision.w + 1;
                    for (var row = 0; row < precision.h; row++)
                    {
                        for (var col = 0; col < precision.w; col++)
                        {
                            var square = new Array <int>(
                                _base + col + row * rowLength,
                                _base + (col + 1) + row * rowLength,
                                _base + (col + 1) + (row + 1) * rowLength,
                                _base + col + (row + 1) * rowLength);

                            indices.Add(square[1]);
                            indices.Add(square[2]);
                            indices.Add(square[3]);
                            indices.Add(square[0]);
                            indices.Add(square[1]);
                            indices.Add(square[3]);
                        }
                    }

                    // Position, normals and uvs
                    var position = Vector3.Zero();
                    var normal   = new Vector3(0, 1.0, 0);
                    for (var row = 0; row <= precision.h; row++)
                    {
                        position.z = (row * (zTileMax - zTileMin)) / precision.h + zTileMin;
                        for (var col = 0; col <= precision.w; col++)
                        {
                            position.x = (col * (xTileMax - xTileMin)) / precision.w + xTileMin;
                            position.y = 0;

                            positions.Add(position.x, position.y, position.z);
                            normals.Add(normal.x, normal.y, normal.z);
                            uvs.Add(col / precision.w, row / precision.h);
                        }
                    }
                }
            }

            var vertexData = new VertexData();

            vertexData.indices   = indices;
            vertexData.positions = positions;
            vertexData.normals   = normals;
            vertexData.uvs       = uvs;
            return(vertexData);
        }
Beispiel #3
0
        /// <summary>
        /// </summary>
        /// <param name="radius">
        /// </param>
        /// <param name="tube">
        /// </param>
        /// <param name="radialSegments">
        /// </param>
        /// <param name="tubularSegments">
        /// </param>
        /// <param name="p">
        /// </param>
        /// <param name="q">
        /// </param>
        /// <returns>
        /// </returns>
        public static VertexData CreateTorusKnot(
            double radius = 2, double tube = 0.5, int radialSegments = 32, int tubularSegments = 32, double p = 2, double q = 3)
        {
            var indices   = new Array <int>();
            var positions = new Array <double>();
            var normals   = new Array <double>();
            var uvs       = new Array <double>();
            var getPos    = new Func <double, Vector3>(
                angle =>
            {
                var cu      = Math.Cos(angle);
                var su      = Math.Sin(angle);
                var quOverP = q / p * angle;
                var cs      = Math.Cos(quOverP);
                var tx      = radius * (2 + cs) * 0.5 * cu;
                var ty      = radius * (2 + cs) * su * 0.5;
                var tz      = radius * Math.Sin(quOverP) * 0.5;
                return(new Vector3(tx, ty, tz));
            });

            for (var i = 0; i <= radialSegments; i++)
            {
                var modI  = i % radialSegments;
                var u     = modI / radialSegments * 2 * p * Math.PI;
                var p1    = getPos(u);
                var p2    = getPos(u + 0.01);
                var tang  = p2.subtract(p1);
                var n     = p2.add(p1);
                var bitan = Vector3.Cross(tang, n);
                n = Vector3.Cross(bitan, tang);
                bitan.normalize();
                n.normalize();
                for (var j = 0; j < tubularSegments; j++)
                {
                    var modJ = j % tubularSegments;
                    var v    = modJ / tubularSegments * 2 * Math.PI;
                    var cx   = -tube *Math.Cos(v);

                    var cy = tube * Math.Sin(v);
                    positions.Add(p1.x + cx * n.x + cy * bitan.x);
                    positions.Add(p1.y + cx * n.y + cy * bitan.y);
                    positions.Add(p1.z + cx * n.z + cy * bitan.z);
                    uvs.Add(i / radialSegments);
                    uvs.Add(j / tubularSegments);
                }
            }

            for (var i = 0; i < radialSegments; i++)
            {
                for (var j = 0; j < tubularSegments; j++)
                {
                    var jNext = (j + 1) % tubularSegments;
                    var a     = i * tubularSegments + j;
                    var b     = (i + 1) * tubularSegments + j;
                    var c     = (i + 1) * tubularSegments + jNext;
                    var d     = i * tubularSegments + jNext;
                    indices.Add(d);
                    indices.Add(b);
                    indices.Add(a);
                    indices.Add(d);
                    indices.Add(c);
                    indices.Add(b);
                }
            }

            ComputeNormals(positions, indices, normals);
            var vertexData = new VertexData();

            vertexData.indices   = indices;
            vertexData.positions = positions;
            vertexData.normals   = normals;
            vertexData.uvs       = uvs;
            return(vertexData);
        }
Beispiel #4
0
 public override VertexData _regenerateVertexData()
 {
     return(VertexData.CreateTorusKnot(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q));
 }
Beispiel #5
0
        /// <summary>
        /// </summary>
        /// <param name="height">
        /// </param>
        /// <param name="diameterTop">
        /// </param>
        /// <param name="diameterBottom">
        /// </param>
        /// <param name="tessellation">
        /// </param>
        /// <param name="subdivisions">
        /// </param>
        /// <returns>
        /// </returns>
        public static VertexData CreateCylinder(
            double height = 1.0, double diameterTop = 0.5, double diameterBottom = 1.0, int tessellation = 16, int subdivisions = 1)
        {
            var radiusTop    = diameterTop / 2;
            var radiusBottom = diameterBottom / 2;
            var indices      = new Array <int>();
            var positions    = new Array <double>();
            var normals      = new Array <double>();
            var uvs          = new Array <double>();

            subdivisions = (subdivisions < 1) ? 1 : subdivisions;
            var getCircleVector = new Func <int, Vector3>(
                (i) =>
            {
                var angle = i * 2.0 * Math.PI / tessellation;
                var dx    = Math.Cos(angle);
                var dz    = Math.Sin(angle);
                return(new Vector3(dx, 0, dz));
            });
            Vector3 offset;
            var     createCylinderCap = new Action <bool>(
                (isTop) =>
            {
                var radius = isTop ? radiusTop : radiusBottom;
                if (radius == 0.0)
                {
                    return;
                }

                var vbase        = positions.Length / 3;
                offset           = new Vector3(0, height / 2, 0);
                var textureScale = new Vector2(0.5, 0.5);
                if (!isTop)
                {
                    offset.scaleInPlace(-1.0);
                    textureScale.x = -textureScale.x;
                }

                for (var i = 0; i < tessellation; i++)
                {
                    var circleVector      = getCircleVector(i);
                    var position          = circleVector.scale(radius).add(offset);
                    var textureCoordinate = new Vector2(circleVector.x * textureScale.x + 0.5, circleVector.z * textureScale.y + 0.5);
                    positions.Add(position.x, position.y, position.z);
                    uvs.Add(textureCoordinate.x, textureCoordinate.y);
                }

                for (var i = 0; i < tessellation - 2; i++)
                {
                    if (!isTop)
                    {
                        indices.Add(vbase);
                        indices.Add(vbase + (i + 2) % tessellation);
                        indices.Add(vbase + (i + 1) % tessellation);
                    }
                    else
                    {
                        indices.Add(vbase);
                        indices.Add(vbase + (i + 1) % tessellation);
                        indices.Add(vbase + (i + 2) % tessellation);
                    }
                }
            });
            var _base = new Vector3(0, -1, 0).scale(height / 2);

            offset = new Vector3(0, 1, 0).scale(height / subdivisions);
            var stride = tessellation + 1;

            for (var i = 0; i <= tessellation; i++)
            {
                var circleVector      = getCircleVector(i);
                var textureCoordinate = new Vector2(i / tessellation, 0);
                var radius            = radiusBottom;
                for (var s = 0; s <= subdivisions; s++)
                {
                    var position = circleVector.scale(radius);
                    position.addInPlace(_base.add(offset.scale(s)));
                    textureCoordinate.y += 1 / subdivisions;
                    radius += (radiusTop - radiusBottom) / subdivisions;
                    positions.Add(position.x, position.y, position.z);
                    uvs.Add(textureCoordinate.x, textureCoordinate.y);
                }
            }

            subdivisions += 1;
            for (var s = 0; s < subdivisions - 1; s++)
            {
                for (var i = 0; i <= tessellation; i++)
                {
                    indices.Add(i * subdivisions + s);
                    indices.Add((i * subdivisions + (s + subdivisions)) % (stride * subdivisions));
                    indices.Add(i * subdivisions + (s + 1));
                    indices.Add(i * subdivisions + (s + 1));
                    indices.Add((i * subdivisions + (s + subdivisions)) % (stride * subdivisions));
                    indices.Add((i * subdivisions + (s + subdivisions + 1)) % (stride * subdivisions));
                }
            }

            createCylinderCap(true);
            createCylinderCap(false);
            ComputeNormals(positions, indices, normals);
            var vertexData = new VertexData();

            vertexData.indices   = indices;
            vertexData.positions = positions;
            vertexData.normals   = normals;
            vertexData.uvs       = uvs;
            return(vertexData);
        }
Beispiel #6
0
 public Plane(int id, Scene scene, double size, bool canBeRegenerated = false, Mesh mesh = null)
     : base(id, scene, VertexData.CreatePlane(size), canBeRegenerated, mesh)
 {
     this.size = size;
 }
Beispiel #7
0
 public override VertexData _regenerateVertexData()
 {
     return(VertexData.CreatePlane(this.size));
 }
Beispiel #8
0
 public override VertexData _regenerateVertexData()
 {
     return(VertexData.CreateGround(this.width, this.height, this.subdivisions));
 }
Beispiel #9
0
 public override VertexData _regenerateVertexData()
 {
     return(VertexData.CreateTiledGround(this.xmin, this.zmin, this.xmax, this.zmax, this.subdivisions, this.precision));
 }
Beispiel #10
0
 public override VertexData _regenerateVertexData()
 {
     return(VertexData.CreateTorus(this.diameter, this.thickness, this.tessellation));
 }
Beispiel #11
0
 public override VertexData _regenerateVertexData()
 {
     return(VertexData.CreateCylinder(this.height, this.diameterTop, this.diameterBottom, this.tessellation, this.subdivisions));
 }
Beispiel #12
0
 public override VertexData _regenerateVertexData()
 {
     return(VertexData.CreateSphere(this.segments, this.diameter));
 }
Beispiel #13
0
 public Sphere(int id, Scene scene, int segments, double diameter, bool canBeRegenerated = false, Mesh mesh = null)
     : base(id, scene, VertexData.CreateSphere(segments, diameter), canBeRegenerated, mesh)
 {
     this.segments = segments;
     this.diameter = diameter;
 }
Beispiel #14
0
 /// <summary>
 /// </summary>
 /// <param name="vertexData">
 /// </param>
 /// <param name="updatable">
 /// </param>
 public virtual void setAllVerticesData(VertexData vertexData, bool updatable = false)
 {
     vertexData.applyToGeometry(this, updatable);
 }