public LCC3VertexLocations(int tag, string name)
            : base(tag, name)
        {
            _firstVertex = 0;
            _centerOfGeometry = LCC3Vector.CC3VectorZero;
            _boundingBox = LCC3BoundingBox.CC3BoundingBoxZero;
            _radius = 0.0f;

            this.MarkBoundaryDirty();
        }
        private void BuildBoundingBox()
        {
            LCC3Vector vl, vlMin, vlMax;
            vl = (this.VertexCount > 0) ? this.LocationAt(0) : LCC3Vector.CC3VectorZero;
            vlMin = vl;
            vlMax = vl;

            for (uint i = 1; i < this.VertexCount; i++)
            {
                vl = this.LocationAt(i);
                vlMin = LCC3Vector.CC3VectorMinimize(vlMin, vl);
                vlMax = LCC3Vector.CC3VectorMaximize(vlMax, vl);
            }

            _boundingBox = new LCC3BoundingBox(vlMin, vlMax);
            _centerOfGeometry = _boundingBox.Center;
            _boundaryIsDirty = false;
        }
        private void PopulateAsSolidBox(LCC3BoundingBox box, CCPoint corner, bool useSoftEdges=true)
        {
            LCC3Vector boxMin = box.Minimum;
            LCC3Vector boxMax = box.Maximum;
            uint vertexCount = 24;
            uint triangleCount = 12;

            this.EnsureVertexContent();
            this.AllocatedVertexCapacity = vertexCount;
            this.AllocatedVertexIndexCapacity = (triangleCount * 3);
            LCC3VertexIndices indices = this.VertexIndices;

            // Front face, CCW winding:
            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMin.Y, boxMax.Z), 0);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitZPositive, 0);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(corner.X, (1.0f - corner.Y)), 0);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMin.Y, boxMax.Z), 1);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitZPositive, 1);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.5f, (1.0f - corner.Y)), 1);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMax.Y, boxMax.Z), 2);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitZPositive, 2);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.5f, corner.Y), 2);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMax.Y, boxMax.Z), 3);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitZPositive, 3);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(corner.X, corner.Y), 3);

            // Right face, CCW winding:
            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMin.Y, boxMax.Z), 4);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitXPositive, 4);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.5f, (1.0f - corner.Y)), 4);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMin.Y, boxMin.Z), 5);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitXPositive, 5);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F((0.5f + corner.X), (1.0f - corner.Y)), 5);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMax.Y, boxMin.Z), 6);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitXPositive, 6);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F((0.5f + corner.X), corner.Y), 6);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMax.Y, boxMax.Z), 7);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitXPositive, 7);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.5f, corner.Y), 7);

            // Back face, CCW winding:
            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMin.Y, boxMin.Z), 8);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitZNegative, 8);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F((0.5f + corner.X), (1.0f - corner.Y)), 8);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMin.Y, boxMin.Z), 9);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitZNegative, 9);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(1.0f, (1.0f - corner.Y)), 9);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMax.Y, boxMin.Z), 10);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitZNegative, 10);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(1.0f, corner.Y), 10);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMax.Y, boxMin.Z), 11);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitZNegative, 11);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F((0.5f + corner.X), corner.Y), 11);

            // Left face, CCW winding:
            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMin.Y, boxMin.Z), 12);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitXNegative, 12);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.0f, (1.0f - corner.Y)), 12);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMin.Y, boxMax.Z), 13);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitXNegative, 13);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(corner.X, (1.0f - corner.Y)), 13);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMax.Y, boxMax.Z),14);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitXNegative, 14);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(corner.X, corner.Y), 14);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMax.Y, boxMin.Z), 15);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitXNegative, 15);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.0f, corner.Y), 15);

            // Top face, CCW winding:
            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMax.Y, boxMin.Z), 16);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitYPositive, 16);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(corner.X, 0.0f), 16);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMax.Y, boxMax.Z), 17);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitYPositive, 17);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(corner.X, corner.Y), 17);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMax.Y, boxMax.Z), 18);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitYPositive, 18);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.5f, corner.Y), 18);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMax.Y, boxMin.Z), 19);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYPositive + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitYPositive, 19);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.5f, 0.0f), 19);

            // Bottom face, CCW winding:
            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMin.Y, boxMax.Z), 20);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitYNegative, 20);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(corner.X, (1.0f - corner.Y)), 20);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMin.X, boxMin.Y, boxMin.Z), 21);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXNegative + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitYNegative, 21);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(corner.X, 1.0f), 21);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMin.Y, boxMin.Z), 22);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZNegative) / 3 : LCC3Vector.CC3UnitYNegative, 22);
            this.SetVertexTexCoord2FAtIndex( new CCTex2F(0.5f, 1.0f), 22);

            this.SetVertexLocationAtIndex(new LCC3Vector(boxMax.X, boxMin.Y, boxMax.Z), 23);
            this.SetNormalAtIndex(useSoftEdges ? (LCC3Vector.CC3UnitXPositive + LCC3Vector.CC3UnitYNegative + LCC3Vector.CC3UnitZPositive) / 3 : LCC3Vector.CC3UnitYNegative, 23);
            this.SetVertexTexCoord2FAtIndex(new CCTex2F(0.5f, (1.0f - corner.Y)), 23);

            uint indxIndx = 0;
            uint vtxIndx = 0;
            for (int side = 0; side < 6; side++)
            {
                // First trangle of side - CCW from bottom left
                indices.SetIndex(vtxIndx++, indxIndx++);
                indices.SetIndex(vtxIndx++, indxIndx++);
                indices.SetIndex(vtxIndx, indxIndx++);

                // Second triangle of side - CCW from bottom left
                indices.SetIndex(vtxIndx++, indxIndx++);
                indices.SetIndex(vtxIndx++, indxIndx++);
                indices.SetIndex(vtxIndx - 4, indxIndx++);
            }
        }
        public void PopulateFrom(LCC3VertexLocations another)
        {
            base.PopulateFrom(another);

            _firstVertex = another._firstVertex;
            _boundingBox = another.BoundingBox;
            _centerOfGeometry = another.CenterOfGeometry;
            _radius = another.Radius;
            _boundaryIsDirty = another.BoundaryIsDirty;
            _radiusIsDirty = another.RadiusIsDirty;
        }
        public void PopulateAsSolidBox(LCC3BoundingBox box, bool useSoftEdges=true)
        {
            float w = box.Maximum.X - box.Minimum.X;
            float h = box.Maximum.Y - box.Minimum.Y;
            float d = box.Maximum.Z - box.Minimum.Z;
            float ufw = d + w + d + w;
            float ufh = d + h + d;

            this.PopulateAsSolidBox( box, new CCPoint((d / ufw), (d / ufh)));
        }