Beispiel #1
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            buffer.rebaseOffset();
            buffer.estimateVertexCount((mNumSegHeight + 1) * (mNumSegBase + 1) + mNumSegBase + 2);
            buffer.estimateIndexCount(mNumSegHeight * mNumSegBase * 6 + 3 * mNumSegBase);

            float deltaAngle  = (Math.TWO_PI / mNumSegBase);
            float deltaHeight = mHeight / (float)mNumSegHeight;
            int   offset      = 0;

            Vector3    refNormal = new Vector3(mRadius, mHeight, 0.0f);
            Quaternion q         = new Quaternion();

            for (uint i = 0; i <= mNumSegHeight; i++)
            {
                float r0 = mRadius * (1 - i / (float)mNumSegHeight);
                for (uint j = 0; j <= mNumSegBase; j++)
                {
                    float x0 = r0 * cosf(j * deltaAngle);
                    float z0 = r0 * sinf(j * deltaAngle);

                    q.FromAngleAxis(new Radian(-deltaAngle * j), Vector3.UNIT_Y);

                    addPoint(ref buffer, new Vector3(x0, i * deltaHeight, z0), q * refNormal, new Vector2(j / (float)mNumSegBase, i / (float)mNumSegHeight));

                    if (i != mNumSegHeight && j != mNumSegBase)
                    {
                        buffer.index(offset + (int)mNumSegBase + 2);
                        buffer.index(offset);
                        buffer.index(offset + (int)mNumSegBase + 1);
                        buffer.index(offset + (int)mNumSegBase + +2);
                        buffer.index(offset + 1);
                        buffer.index(offset);
                    }

                    offset++;
                }
            }

            //low cap
            int centerIndex = offset;

            addPoint(ref buffer, Vector3.ZERO, Vector3.NEGATIVE_UNIT_Y, Vector2.UNIT_Y);
            offset++;
            for (uint j = 0; j <= mNumSegBase; j++)
            {
                float x0 = mRadius * cosf(j * deltaAngle);
                float z0 = mRadius * sinf(j * deltaAngle);

                addPoint(ref buffer, new Vector3(x0, 0.0f, z0), Vector3.NEGATIVE_UNIT_Y, new Vector2(j / (float)mNumSegBase, 0.0f));

                if (j != mNumSegBase)
                {
                    buffer.index(centerIndex);
                    buffer.index(offset);
                    buffer.index(offset + 1);
                }
                offset++;
            }
        }
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            buffer.rebaseOffset();
            buffer.estimateVertexCount((mNumSegCircle + 1) * (mNumSegSection + 1));
            buffer.estimateIndexCount((mNumSegCircle) * (mNumSegSection + 1) * 6);

            float deltaSection = (Math.TWO_PI / mNumSegSection);
            float deltaCircle  = (Math.TWO_PI / mNumSegCircle);
            int   offset       = 0;

            for (uint i = 0; i <= mNumSegCircle; i++)
            {
                for (uint j = 0; j <= mNumSegSection; j++)
                {
                    Vector3    c0 = new Vector3(mRadius, 0.0f, 0.0f);
                    Vector3    v0 = new Vector3(mRadius + mSectionRadius * cosf(j * deltaSection), mSectionRadius * sinf(j * deltaSection), 0.0f);
                    Quaternion q  = new Quaternion();
                    q.FromAngleAxis(new Radian(i * deltaCircle), Vector3.UNIT_Y);
                    Vector3 v = q * v0;
                    Vector3 c = q * c0;
                    addPoint(ref buffer, v, (v - c).NormalisedCopy, new Vector2(i / (float)mNumSegCircle, j / (float)mNumSegSection));

                    if (i != mNumSegCircle)
                    {
                        buffer.index(offset + (int)mNumSegSection + 1);
                        buffer.index(offset);
                        buffer.index(offset + (int)mNumSegSection);
                        buffer.index(offset + (int)mNumSegSection + 1);
                        buffer.index(offset + 1);
                        buffer.index(offset);
                    }
                    offset++;
                }
            }
        }
Beispiel #3
0
        /// Internal. Builds a "corner" of the rounded box, ie a 1/8th of a sphere
        //
        //ORIGINAL LINE: void _addCorner(TriangleBuffer& buffer, bool isXPositive, bool isYPositive, bool isZPositive) const
        private void _addCorner(ref TriangleBuffer buffer, bool isXPositive, bool isYPositive, bool isZPositive)
        {
            buffer.rebaseOffset();
            buffer.estimateVertexCount((uint)((mChamferNumSeg + 1) * (mChamferNumSeg + 1)));
            buffer.estimateIndexCount((uint)(mChamferNumSeg * mChamferNumSeg * 6));
            int offset = 0;

            Vector3 offsetPosition  = new Vector3((isXPositive ? 1 : -1) * .5f * mSizeX, (isYPositive ? 1 : -1) * .5f * mSizeY, (isZPositive ? 1 : -1) * .5f * mSizeZ);
            float   deltaRingAngle  = (Math.HALF_PI / mChamferNumSeg);
            float   deltaSegAngle   = (Math.HALF_PI / mChamferNumSeg);
            float   offsetRingAngle = isYPositive ? 0 : Math.HALF_PI;
            float   offsetSegAngle  = 0f;

            if (isXPositive && isZPositive)
            {
                offsetSegAngle = 0;
            }
            if ((!isXPositive) && isZPositive)
            {
                offsetSegAngle = 1.5f * Math.PI;
            }
            if (isXPositive && (!isZPositive))
            {
                offsetSegAngle = Math.HALF_PI;
            }
            if ((!isXPositive) && (!isZPositive))
            {
                offsetSegAngle = Math.PI;
            }

            // Generate the group of rings for the sphere
            for (ushort ring = 0; ring <= mChamferNumSeg; ring++)
            {
                float r0 = mChamferSize * sinf(ring * deltaRingAngle + offsetRingAngle);
                float y0 = mChamferSize * cosf(ring * deltaRingAngle + offsetRingAngle);

                // Generate the group of segments for the current ring
                for (ushort seg = 0; seg <= mChamferNumSeg; seg++)
                {
                    float x0 = r0 * sinf(seg * deltaSegAngle + offsetSegAngle);
                    float z0 = r0 * cosf(seg * deltaSegAngle + offsetSegAngle);

                    // Add one vertex to the strip which makes up the sphere
                    addPoint(ref buffer, new Vector3(x0 + offsetPosition.x, y0 + offsetPosition.y, z0 + offsetPosition.z), new Vector3(x0, y0, z0).NormalisedCopy, new Vector2((float)seg / (float)mChamferNumSeg, (float)ring / (float)mChamferNumSeg));

                    if ((ring != mChamferNumSeg) && (seg != mChamferNumSeg))
                    {
                        // each vertex (except the last) has six indices pointing to it
                        buffer.index(offset + mChamferNumSeg + 2);
                        buffer.index(offset);
                        buffer.index(offset + mChamferNumSeg + 1);
                        buffer.index(offset + mChamferNumSeg + 2);
                        buffer.index(offset + 1);
                        buffer.index(offset);
                    }

                    offset++;
                } // end for seg
            }     // end for ring
        }
Beispiel #4
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            buffer.rebaseOffset();
            buffer.estimateVertexCount((mNumSegX + 1) * (mNumSegY + 1));
            buffer.estimateIndexCount(mNumSegX * mNumSegY * 6);
            int offset = 0;

            Vector3 vX     = mNormal.Perpendicular;
            Vector3 vY     = mNormal.CrossProduct(vX);
            Vector3 delta1 = mSizeX / (float)mNumSegX * vX;
            Vector3 delta2 = mSizeY / (float)mNumSegY * vY;
            // build one corner of the square
            Vector3 orig = -0.5f * mSizeX * vX - 0.5f * mSizeY * vY;

            for (ushort i1 = 0; i1 <= mNumSegX; i1++)
            {
                for (ushort i2 = 0; i2 <= mNumSegY; i2++)
                {
                    addPoint(ref buffer, orig + i1 * delta1 + i2 * delta2, mNormal, new Vector2(i1 / (float)mNumSegX, i2 / (float)mNumSegY));
                }
            }

            bool reverse = false;

            if (delta1.CrossProduct(delta2).DotProduct(mNormal) > 0f)
            {
                reverse = true;
            }
            for (ushort n1 = 0; n1 < mNumSegX; n1++)
            {
                for (ushort n2 = 0; n2 < mNumSegY; n2++)
                {
                    if (reverse)
                    {
                        buffer.index(offset + 0);
                        buffer.index(offset + (int)(mNumSegY + 1));
                        buffer.index(offset + 1);
                        buffer.index(offset + 1);
                        buffer.index(offset + (int)(mNumSegY + 1));
                        buffer.index(offset + (int)(mNumSegY + 1) + 1);
                    }
                    else
                    {
                        buffer.index(offset + 0);
                        buffer.index(offset + 1);
                        buffer.index(offset + (int)(mNumSegY + 1));
                        buffer.index(offset + 1);
                        buffer.index(offset + (int)(mNumSegY + 1) + 1);
                        buffer.index(offset + (int)(mNumSegY + 1));
                    }
                    offset++;
                }
                offset++;
            }

            //return this;
        }
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            buffer.rebaseOffset();
            buffer.estimateVertexCount((uint)((mNumSegCircle * mP + 1) * (mNumSegSection + 1)));
            buffer.estimateIndexCount((uint)((mNumSegCircle * mP) * (mNumSegSection + 1) * 6));

            int offset = 0;

            for (uint i = 0; i <= mNumSegCircle * mP; i++)
            {
                float phi = Math.TWO_PI * i / (float)mNumSegCircle;
                float x0  = mRadius * (2 + cosf(mQ * phi / (float)mP)) * cosf(phi) / 3.0f;
                float y0  = mRadius * sinf(mQ * phi / (float)mP) / 3.0f;
                float z0  = mRadius * (2 + cosf(mQ * phi / (float)mP)) * sinf(phi) / 3.0f;

                float phi1 = Math.TWO_PI * (i + 1) / (float)mNumSegCircle;
                float x1   = mRadius * (2 + cosf(mQ * phi1 / (float)mP)) * cosf(phi1) / 3.0f;
                float y1   = mRadius * sinf(mQ * phi1 / mP) / 3.0f;
                float z1   = mRadius * (2 + cosf(mQ * phi1 / (float)mP)) * sinf(phi1) / 3.0f;

                Vector3 v0        = new Vector3(x0, y0, z0);
                Vector3 v1        = new Vector3(x1, y1, z1);
                Vector3 direction = ((v1 - v0).NormalisedCopy);

                Quaternion q = Utils._computeQuaternion(direction);

                for (uint j = 0; j <= mNumSegSection; j++)
                {
                    float   alpha = Math.TWO_PI * j / mNumSegSection;
                    Vector3 vp    = mSectionRadius * (q * new Vector3(cosf(alpha), sinf(alpha), 0));

                    addPoint(ref buffer, v0 + vp, vp.NormalisedCopy, new Vector2(i / (float)mNumSegCircle, j / (float)mNumSegSection));

                    if (i != mNumSegCircle * mP)
                    {
                        buffer.index(offset + (int)mNumSegSection + 1);
                        buffer.index(offset + (int)mNumSegSection);
                        buffer.index(offset);
                        buffer.index(offset + (int)mNumSegSection + 1);
                        buffer.index(offset);
                        buffer.index(offset + 1);
                    }
                    offset++;
                }
            }
        }
Beispiel #6
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            buffer.rebaseOffset();
            buffer.estimateVertexCount((mNumRings + 1) * (mNumSegments + 1));
            buffer.estimateIndexCount(mNumRings * (mNumSegments + 1) * 6);

            float fDeltaRingAngle = (Math.PI / mNumRings);
            float fDeltaSegAngle  = (Math.TWO_PI / mNumSegments);
            int   offset          = 0;

            // Generate the group of rings for the sphere
            for (uint ring = 0; ring <= mNumRings; ring++)
            {
                float r0 = mRadius * sinf(ring * fDeltaRingAngle);
                float y0 = mRadius * cosf(ring * fDeltaRingAngle);

                // Generate the group of segments for the current ring
                for (uint seg = 0; seg <= mNumSegments; seg++)
                {
                    float x0 = r0 * sinf(seg * fDeltaSegAngle);
                    float z0 = r0 * cosf(seg * fDeltaSegAngle);

                    // Add one vertex to the strip which makes up the sphere
                    addPoint(ref buffer, new Vector3(x0, y0, z0), new Vector3(x0, y0, z0).NormalisedCopy, new Vector2((float)seg / (float)mNumSegments, (float)ring / (float)mNumRings));

                    if (ring != mNumRings)
                    {
                        if (seg != mNumSegments)
                        {
                            // each vertex (except the last) has six indices pointing to it
                            if (ring != mNumRings - 1)
                            {
                                buffer.triangle(offset + (int)mNumSegments + 2, offset, offset + (int)mNumSegments + 1);
                            }
                            if (ring != 0)
                            {
                                buffer.triangle(offset + (int)mNumSegments + 2, offset + 1, offset);
                            }
                        }
                        offset++;
                    }
                } // end for seg
            }     // end for ring
        }
Beispiel #7
0
        //-----------------------------------------------------------------------
        //
        //ORIGINAL LINE: void _latheCapImpl(TriangleBuffer& buffer) const
        private void _latheCapImpl(ref TriangleBuffer buffer)
        {
            std_vector <int>     indexBuffer = new std_vector <int>();
            std_vector <Vector2> pointList   = new std_vector <Vector2>();

            buffer.rebaseOffset();

            Triangulator t              = new Triangulator();
            Shape        shapeCopy      = new Shape();
            MultiShape   multishapeCopy = new MultiShape();

            if (mShapeToExtrude != null)
            {
                //
                //ORIGINAL LINE: shapeCopy = *mShapeToExtrude;
                shapeCopy = (mShapeToExtrude);
                shapeCopy.close();
                t.setShapeToTriangulate(shapeCopy);
            }
            else
            {
                //
                //ORIGINAL LINE: multishapeCopy = *mMultiShapeToExtrude;
                multishapeCopy = (mMultiShapeToExtrude);
                multishapeCopy.close();
                t.setMultiShapeToTriangulate(mMultiShapeToExtrude);
            }
            t.triangulate(indexBuffer, pointList);
            buffer.estimateIndexCount(2 * (uint)indexBuffer.Count);
            buffer.estimateVertexCount(2 * (uint)pointList.Count);

            //begin cap
            buffer.rebaseOffset();
            Quaternion q = new Quaternion();

            q.FromAngleAxis(mAngleBegin, Vector3.UNIT_Y);
            for (int j = 0; j < pointList.size(); j++)
            {
                Vector2 vp2 = pointList[j];
                Vector3 vp  = new Vector3(vp2.x, vp2.y, 0);
                //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
                //ORIGINAL LINE: Vector3 normal = Vector3::UNIT_Z;
                Vector3 normal = (Vector3.UNIT_Z);

                addPoint(ref buffer, q * vp, q * normal, vp2);
            }

            for (int i = 0; i < indexBuffer.size() / 3; i++)
            {
                buffer.index(indexBuffer[i * 3]);
                buffer.index(indexBuffer[i * 3 + 1]);
                buffer.index(indexBuffer[i * 3 + 2]);
            }
            //end cap
            buffer.rebaseOffset();
            q.FromAngleAxis(mAngleEnd, Vector3.UNIT_Y);
            for (int j = 0; j < pointList.size(); j++)
            {
                Vector2 vp2    = pointList[j];
                Vector3 vp     = new Vector3(vp2.x, vp2.y, 0);
                Vector3 normal = -Vector3.UNIT_Z;

                addPoint(ref buffer, q * vp, q * normal, vp2);
            }

            for (int i = 0; i < indexBuffer.size() / 3; i++)
            {
                buffer.index(indexBuffer[i * 3]);
                buffer.index(indexBuffer[i * 3 + 2]);
                buffer.index(indexBuffer[i * 3 + 1]);
            }
        }
Beispiel #8
0
        //-----------------------------------------------------------------------
        //
        //ORIGINAL LINE: void _latheBodyImpl(TriangleBuffer& buffer, const Shape* shapeToExtrude) const
        private void _latheBodyImpl(ref TriangleBuffer buffer, Shape shapeToExtrude)
        {
            if (shapeToExtrude == null)
            {
                OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "Shape must not be null!", "Procedural::Lathe::_latheBodyImpl(Procedural::TriangleBuffer&, const Procedural::Shape*)");
            }
            int numSegShape = shapeToExtrude.getSegCount();

            if (numSegShape < 2)
            {
                OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "Shape must contain at least two points", "Procedural::Lathe::_latheBodyImpl(Procedural::TriangleBuffer&, const Procedural::Shape*)");
            }

            int offset = 0;

            //int numSeg = mClosed?mNumSeg+1:mNumSeg;
            int numSeg = (int)mNumSeg + 1;

            buffer.rebaseOffset();
            buffer.estimateIndexCount((uint)(numSeg * numSegShape * 6));
            buffer.estimateVertexCount((uint)((numSegShape + 1) * (numSeg + 1)));

            Radian angleEnd = new Radian(mAngleEnd);

            if (mAngleBegin > mAngleEnd)
            {
                angleEnd += (Radian)Math.TWO_PI;
            }

            for (int i = 0; i < numSeg; i++)
            {
                Radian angle = new Radian();
                if (mClosed)
                {
                    angle = i / (float)mNumSeg * Math.TWO_PI;
                }
                else
                {
                    angle = mAngleBegin + i / (float)mNumSeg * (angleEnd - mAngleBegin);
                }
                Quaternion q = new Quaternion();
                q.FromAngleAxis(angle, Vector3.UNIT_Y);

                for (int j = 0; j <= numSegShape; j++)
                {
                    Vector2 v0           = shapeToExtrude.getPoint(j);
                    Vector3 vp           = new Vector3(v0.x, v0.y, 0);
                    Vector2 vp2direction = shapeToExtrude.getAvgDirection((uint)j);
                    Vector2 vp2normal    = vp2direction.Perpendicular;
                    Vector3 normal       = new Vector3(vp2normal.x, vp2normal.y, 0);
                    normal.Normalise();
                    if (shapeToExtrude.getOutSide() == Side.SIDE_RIGHT)
                    {
                        normal = -normal;
                    }

                    addPoint(ref buffer, q * vp, q * normal, new Vector2(i / (float)mNumSeg, j / (float)numSegShape));

                    if (j < numSegShape && i < numSeg - 1)
                    {
                        if (shapeToExtrude.getOutSide() == Side.SIDE_RIGHT)
                        {
                            buffer.triangle(offset + numSegShape + 2, offset, offset + numSegShape + 1);
                            buffer.triangle(offset + numSegShape + 2, offset + 1, offset);
                        }
                        else
                        {
                            buffer.triangle(offset + numSegShape + 2, offset + numSegShape + 1, offset);
                            buffer.triangle(offset + numSegShape + 2, offset, offset + 1);
                        }
                    }
                    offset++;
                }
            }
        }
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            buffer.rebaseOffset();
            if (mCapped)
            {
                buffer.estimateVertexCount((mNumSegHeight + 1) * (mNumSegBase + 1) + 2 * (mNumSegBase + 1) + 2);
                buffer.estimateIndexCount(mNumSegHeight * (mNumSegBase + 1) * 6 + 6 * mNumSegBase);
            }
            else
            {
                buffer.estimateVertexCount((mNumSegHeight + 1) * (mNumSegBase + 1));
                buffer.estimateIndexCount(mNumSegHeight * (mNumSegBase + 1) * 6);
            }


            float deltaAngle  = (Math.TWO_PI / mNumSegBase);
            float deltaHeight = mHeight / (float)mNumSegHeight;
            int   offset      = 0;

            for (uint i = 0; i <= mNumSegHeight; i++)
            {
                for (uint j = 0; j <= mNumSegBase; j++)
                {
                    float x0 = mRadius * cosf(j * deltaAngle);
                    float z0 = mRadius * sinf(j * deltaAngle);

                    addPoint(ref buffer, new Vector3(x0, (float)i * deltaHeight, z0), new Vector3(x0, 0f, z0).NormalisedCopy, new Vector2((float)j / (float)mNumSegBase, (float)i / (float)mNumSegHeight));

                    if (i != mNumSegHeight)
                    {
                        buffer.index(offset + (int)mNumSegBase + 1);
                        buffer.index(offset);
                        buffer.index(offset + (int)mNumSegBase);
                        buffer.index(offset + (int)mNumSegBase + 1);
                        buffer.index(offset + 1);
                        buffer.index(offset);
                    }
                    offset++;
                }
            }
            if (mCapped)
            {
                //low cap
                int centerIndex = offset;
                addPoint(ref buffer, Vector3.ZERO, Vector3.NEGATIVE_UNIT_Y, Vector2.ZERO);
                offset++;
                for (uint j = 0; j <= mNumSegBase; j++)
                {
                    float x0 = cosf(j * deltaAngle);
                    float z0 = sinf(j * deltaAngle);

                    addPoint(ref buffer, new Vector3(mRadius * x0, 0.0f, mRadius * z0), Vector3.NEGATIVE_UNIT_Y, new Vector2(x0, z0));
                    if (j != mNumSegBase)
                    {
                        buffer.index(centerIndex);
                        buffer.index(offset);
                        buffer.index(offset + 1);
                    }
                    offset++;
                }
                // high cap
                centerIndex = offset;
                addPoint(ref buffer, new Vector3(0, mHeight, 0), Vector3.UNIT_Y, Vector2.ZERO);
                offset++;
                for (uint j = 0; j <= mNumSegBase; j++)
                {
                    float x0 = cosf(j * deltaAngle);
                    float z0 = sinf(j * deltaAngle);

                    addPoint(ref buffer, new Vector3(x0 * mRadius, mHeight, mRadius * z0), Vector3.UNIT_Y, new Vector2(x0, z0));
                    if (j != mNumSegBase)
                    {
                        buffer.index(centerIndex);
                        buffer.index(offset + 1);
                        buffer.index(offset);
                    }
                    offset++;
                }
            }
        }
        //-----------------------------------------------------------------------
        public static void _extrudeCapImpl(ref TriangleBuffer buffer, MultiShape multiShapeToExtrude, MultiPath extrusionMultiPath, TrackMap scaleTracks, TrackMap rotationTracks)
        {
            std_vector <int> indexBuffer = new std_vector <int>();
            // PointList pointList;
            std_vector <Vector2> pointList = new std_vector <Vector2>();

            Triangulator t = new Triangulator();

            t.setMultiShapeToTriangulate(multiShapeToExtrude);
            t.triangulate(indexBuffer, pointList);

            for (uint i = 0; i < extrusionMultiPath.getPathCount(); ++i)
            {
                Path  extrusionPath = extrusionMultiPath.getPath((int)i);
                Track scaleTrack    = null;
                Track rotationTrack = null;
                if (scaleTracks.find(i) != -1)         // scaleTracks.end())
                {
                    scaleTrack = scaleTracks[i];       //.find(i).second;
                }
                if (rotationTracks.find(i) != -1)      // rotationTracks.end())
                {
                    rotationTrack = rotationTracks[i]; //.find(i).second;
                }
                //begin cap
                //if (extrusionMultiPath.getIntersectionsMap().find(MultiPath.PathCoordinate(i, 0)) == extrusionMultiPath.getIntersectionsMap().end())
                if (extrusionMultiPath.getIntersectionsMap().find(new MultiPath.PathCoordinate(i, 0)) == -1)
                {
                    buffer.rebaseOffset();
                    buffer.estimateIndexCount((uint)indexBuffer.Count);
                    buffer.estimateVertexCount((uint)pointList.Count);

                    Quaternion qBegin = Utils._computeQuaternion(extrusionPath.getDirectionAfter(0));
                    if (rotationTrack != null)
                    {
                        float angle = rotationTrack.getFirstValue();
                        qBegin = qBegin * new Quaternion((Radian)angle, Vector3.UNIT_Z);
                    }
                    float scaleBegin = 1.0f;
                    if (scaleTrack != null)
                    {
                        scaleBegin = scaleTrack.getFirstValue();
                    }

                    for (int j = 0; j < pointList.size(); j++)
                    {
                        Vector2 vp2    = pointList[j];
                        Vector3 vp     = new Vector3(vp2.x, vp2.y, 0);
                        Vector3 normal = -Vector3.UNIT_Z;

                        Vector3 newPoint = extrusionPath.getPoint(0) + qBegin * (scaleBegin * vp);
                        buffer.vertex(newPoint, qBegin * normal, vp2);
                    }
                    for (int i2 = 0; i2 < indexBuffer.Count / 3; i2++)
                    {
                        buffer.index(indexBuffer[i2 * 3]);
                        buffer.index(indexBuffer[i2 * 3 + 2]);
                        buffer.index(indexBuffer[i2 * 3 + 1]);
                    }
                }

                //end cap
                //if (extrusionMultiPath.getIntersectionsMap().find(MultiPath.PathCoordinate(i, extrusionPath.getSegCount())) == extrusionMultiPath.getIntersectionsMap().end())
                if (extrusionMultiPath.getIntersectionsMap().find(new MultiPath.PathCoordinate(i, (uint)extrusionPath.getSegCount())) == -1)
                {
                    buffer.rebaseOffset();
                    buffer.estimateIndexCount((uint)indexBuffer.Count);
                    buffer.estimateVertexCount((uint)pointList.Count);

                    Quaternion qEnd = Utils._computeQuaternion(extrusionPath.getDirectionBefore(extrusionPath.getSegCount()));
                    if (rotationTrack != null)
                    {
                        float angle = rotationTrack.getLastValue();
                        qEnd = qEnd * new Quaternion((Radian)angle, Vector3.UNIT_Z);
                    }
                    float scaleEnd = 1.0f;
                    if (scaleTrack != null)
                    {
                        scaleEnd = scaleTrack.getLastValue();
                    }

                    for (int j = 0; j < pointList.Count; j++)
                    {
                        Vector2 vp2 = pointList[j];
                        Vector3 vp  = new Vector3(vp2.x, vp2.y, 0f);
                        //C++ TO C# CONVERTER WARNING: The following line was determined to be a copy constructor call - this should be verified and a copy constructor should be created if it does not yet exist:
                        //ORIGINAL LINE: Vector3 normal = Vector3::UNIT_Z;
                        Vector3 normal = (Vector3.UNIT_Z);

                        Vector3 newPoint = extrusionPath.getPoint(extrusionPath.getSegCount()) + qEnd * (scaleEnd * vp);
                        buffer.vertex(newPoint, qEnd * normal, vp2);
                    }
                    for (int ii = 0; ii < indexBuffer.Count / 3; ii++)
                    {
                        buffer.index(indexBuffer[ii * 3]);
                        buffer.index(indexBuffer[ii * 3 + 1]);
                        buffer.index(indexBuffer[ii * 3 + 2]);
                    }
                }
            }
        }
        //-----------------------------------------------------------------------
        public static void _extrudeBodyImpl(ref TriangleBuffer buffer, Shape shapeToExtrude, Path pathToExtrude, int pathBeginIndex, int pathEndIndex, Track shapeTextureTrack, Track rotationTrack, Track scaleTrack, Track pathTextureTrack)
        {
            if (pathToExtrude == null || shapeToExtrude == null)
            {
                OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "Shape and Path must not be null!", "Procedural::Extruder::_extrudeBodyImpl(Procedural::TriangleBuffer&, const Procedural::Shape*)");
            }
            ;

            uint numSegPath  = (uint)(pathEndIndex - pathBeginIndex);
            uint numSegShape = (uint)shapeToExtrude.getSegCount();

            if (numSegPath == 0 || numSegShape == 0)
            {
                OGRE_EXCEPT("Ogre::Exception::ERR_INVALID_STATE", "Shape and path must contain at least two points", "Procedural::Extruder::_extrudeBodyImpl(Procedural::TriangleBuffer&, const Procedural::Shape*)");
            }
            ;

            float totalPathLength  = pathToExtrude.getTotalLength();
            float totalShapeLength = shapeToExtrude.getTotalLength();

            // Merge shape and path with tracks
            float lineicPos = pathToExtrude.getLengthAtPoint(pathBeginIndex);
            Path  path      = pathToExtrude;

            numSegPath  = (uint)(pathEndIndex - pathBeginIndex);
            numSegShape = (uint)shapeToExtrude.getSegCount();

            // Estimate vertex and index count
            buffer.rebaseOffset();
            buffer.estimateIndexCount(numSegShape * numSegPath * 6);
            buffer.estimateVertexCount((numSegShape + 1) * (numSegPath + 1));

            Vector3 oldup = new Vector3();

            for (int i = pathBeginIndex; i <= pathEndIndex; ++i)
            {
                Vector3 v0        = path.getPoint(i);
                Vector3 direction = path.getAvgDirection(i);

                Quaternion q = Utils._computeQuaternion(direction);

                Radian angle = Utils.angleBetween((q * Vector3.UNIT_Y), (oldup));
                if (i > pathBeginIndex && angle > (Radian)Math.HALF_PI / 2.0f)
                {
                    q = Utils._computeQuaternion(direction, oldup);
                }
                oldup = q * Vector3.UNIT_Y;

                float scale = 1.0f;

                if (i > pathBeginIndex)
                {
                    lineicPos += (v0 - path.getPoint(i - 1)).Length;
                }

                // Get the values of angle and scale
                if (rotationTrack != null)
                {
                    float angle_2 = 0f;
                    angle_2 = rotationTrack.getValue(lineicPos, lineicPos / totalPathLength, (uint)i);

                    q = q * new Quaternion((Radian)angle_2, Vector3.UNIT_Z);
                }
                if (scaleTrack != null)
                {
                    scale = scaleTrack.getValue(lineicPos, lineicPos / totalPathLength, (uint)i);
                }
                float uTexCoord = 0f;
                if (pathTextureTrack != null)
                {
                    uTexCoord = pathTextureTrack.getValue(lineicPos, lineicPos / totalPathLength, (uint)i);
                }
                else
                {
                    uTexCoord = lineicPos / totalPathLength;
                }

                _extrudeShape(ref buffer, shapeToExtrude, v0, q, q, scale, 1.0f, 1.0f, totalShapeLength, uTexCoord, i < pathEndIndex, shapeTextureTrack);
            }
        }
Beispiel #12
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            std_vector <Vector3> vertices = new  std_vector <Vector3>();
            int offset = 0;

            /// Step 1 : Generate icosahedron
            float phi     = 0.5f * (1.0f + Math.Sqrt(5.0f));
            float invnorm = 1f / Math.Sqrt(phi * phi + 1f);

            vertices.push_back(invnorm * new Vector3(-1f, phi, 0f));  //0
            vertices.push_back(invnorm * new Vector3(1f, phi, 0f));   //1
            vertices.push_back(invnorm * new Vector3(0f, 1f, -phi));  //2
            vertices.push_back(invnorm * new Vector3(0f, 1f, phi));   //3
            vertices.push_back(invnorm * new Vector3(-phi, 0f, -1f)); //4
            vertices.push_back(invnorm * new Vector3(-phi, 0f, 1f));  //5
            vertices.push_back(invnorm * new Vector3(phi, 0f, -1f));  //6
            vertices.push_back(invnorm * new Vector3(phi, 0f, 1f));   //7
            vertices.push_back(invnorm * new Vector3(0f, -1f, -phi)); //8
            vertices.push_back(invnorm * new Vector3(0f, -1f, phi));  //9
            vertices.push_back(invnorm * new Vector3(-1f, -phi, 0f)); //10
            vertices.push_back(invnorm * new Vector3(1f, -phi, 0f));  //11

            int[] firstFaces = { 0,   1,  2,
                                 0,   3,  1,
                                 0,   4,  5,
                                 1,   7,  6,
                                 1,   6,  2,
                                 1,   3,  7,
                                 0,   2,  4,
                                 0,   5,  3,
                                 2,   6,  8,
                                 2,   8,  4,
                                 3,   5,  9,
                                 3,   9,  7,
                                 11,  6,  7,
                                 10,  5,  4,
                                 10,  4,  8,
                                 10,  9,  5,
                                 11,  8,  6,
                                 11,  7,  9,
                                 10,  8, 11,
                                 10, 11, 9 };

            //C++ TO C# CONVERTER WARNING: This 'sizeof' ratio was replaced with a direct reference to the array length:
            //ORIGINAL LINE: std::vector<int> faces(firstFaces, firstFaces + sizeof(firstFaces)/sizeof(*firstFaces));
            // 定义一个容纳100个int型数据的容器,初值赋为0
            //vector<int> vecMyHouse(100,0);
            std_vector <int> faces = new  std_vector <int>(firstFaces);//(firstFaces, firstFaces + firstFaces.Length);

            int size = 60;

            /// Step 2 : tessellate
            for (ushort iteration = 0; iteration < mNumIterations; iteration++)
            {
                size *= 4;
                std_vector <int> newFaces = new std_vector <int>();
                newFaces.Clear();
                //newFaces.resize(size);
                for (int i = 0; i < size / 12; i++)
                {
                    int     i1  = faces[i * 3];
                    int     i2  = faces[i * 3 + 1];
                    int     i3  = faces[i * 3 + 2];
                    int     i12 = vertices.Count;
                    int     i23 = i12 + 1;
                    int     i13 = i12 + 2;
                    Vector3 v1  = vertices[i1];
                    Vector3 v2  = vertices[i2];
                    Vector3 v3  = vertices[i3];
                    //make 1 vertice at the center of each edge and project it onto the sphere
                    vertices.push_back((v1 + v2).NormalisedCopy);
                    vertices.push_back((v2 + v3).NormalisedCopy);
                    vertices.push_back((v1 + v3).NormalisedCopy);
                    //now recreate indices
                    newFaces.push_back(i1);
                    newFaces.push_back(i12);
                    newFaces.push_back(i13);
                    newFaces.push_back(i2);
                    newFaces.push_back(i23);
                    newFaces.push_back(i12);
                    newFaces.push_back(i3);
                    newFaces.push_back(i13);
                    newFaces.push_back(i23);
                    newFaces.push_back(i12);
                    newFaces.push_back(i23);
                    newFaces.push_back(i13);
                }
                //faces.swap(newFaces);
                faces = newFaces;
            }

            /// Step 3 : generate texcoords
            std_vector <Vector2> texCoords = new std_vector <Vector2>();

            for (ushort i = 0; i < vertices.size(); i++)
            {
                Vector3 vec   = vertices[i];
                float   u     = 0f;
                float   v     = 0f;
                float   r0    = sqrtf(vec.x * vec.x + vec.z * vec.z);
                float   alpha = 0f;
                alpha = atan2f(vec.z, vec.x);
                u     = alpha / Math.TWO_PI + .5f;
                v     = atan2f(vec.y, r0) / Math.PI + .5f;
                texCoords.push_back(new Vector2(u, v));
            }

            /// Step 4 : fix texcoords
            // find vertices to split
            std_vector <int> indexToSplit = new  std_vector <int>();

            for (int i = 0; i < faces.size() / 3; i++)
            {
                Vector2 t0 = texCoords[faces[i * 3 + 0]];
                Vector2 t1 = texCoords[faces[i * 3 + 1]];
                Vector2 t2 = texCoords[faces[i * 3 + 2]];
                if (Math.Abs(t2.x - t0.x) > 0.5)
                {
                    if (t0.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 2]);
                    }
                }
                if (Math.Abs(t1.x - t0.x) > 0.5)
                {
                    if (t0.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 1]);
                    }
                }
                if (Math.Abs(t2.x - t1.x) > 0.5)
                {
                    if (t1.x < 0.5)
                    {
                        indexToSplit.push_back(faces[i * 3 + 1]);
                    }
                    else
                    {
                        indexToSplit.push_back(faces[i * 3 + 2]);
                    }
                }
            }

            //split vertices
            for (ushort i = 0; i < indexToSplit.size(); i++)
            {
                int index = indexToSplit[i];
                //duplicate vertex
                Vector3 v = vertices[index];
                Vector2 t = texCoords[index] + Vector2.UNIT_X;
                vertices.push_back(v);
                texCoords.push_back(t);
                int newIndex = vertices.size() - 1;
                //reassign indices
                for (ushort j = 0; j < faces.size(); j++)
                {
                    if (faces[j] == index)
                    {
                        int index1 = faces[(j + 1) % 3 + (j / 3) * 3];
                        int index2 = faces[(j + 2) % 3 + (j / 3) * 3];
                        if ((texCoords[index1].x > 0.5f) || (texCoords[index2].x > 0.5f))
                        {
                            faces[j] = newIndex;
                        }
                    }
                }
            }

            /// Step 5 : realize
            buffer.rebaseOffset();
            buffer.estimateVertexCount((uint)vertices.size());
            buffer.estimateIndexCount((uint)size);

            for (ushort i = 0; i < vertices.size(); i++)
            {
                addPoint(ref buffer, mRadius * vertices[i], vertices[i], new Vector2(texCoords[i].x, texCoords[i].y));
            }
            for (ushort i = 0; i < size; i++)
            {
                buffer.index(offset + faces[i]);
            }
            offset += vertices.size();
        }
Beispiel #13
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            buffer.rebaseOffset();
            buffer.estimateVertexCount((2 * mNumRings + 2) * (mNumSegments + 1) + (mNumSegHeight - 1) * (mNumSegments + 1));
            buffer.estimateIndexCount((2 * mNumRings + 1) * (mNumSegments + 1) * 6 + (mNumSegHeight - 1) * (mNumSegments + 1) * 6);

            float fDeltaRingAngle = (Math.HALF_PI / mNumRings);
            float fDeltaSegAngle  = (Math.TWO_PI / mNumSegments);

            float sphereRatio   = mRadius / (2 * mRadius + mHeight);
            float cylinderRatio = mHeight / (2 * mRadius + mHeight);
            int   offset        = 0;

            // Top half sphere

            // Generate the group of rings for the sphere
            for (uint ring = 0; ring <= mNumRings; ring++)
            {
                float r0 = mRadius * sinf(ring * fDeltaRingAngle);
                float y0 = mRadius * cosf(ring * fDeltaRingAngle);

                // Generate the group of segments for the current ring
                for (uint seg = 0; seg <= mNumSegments; seg++)
                {
                    float x0 = r0 * cosf(seg * fDeltaSegAngle);
                    float z0 = r0 * sinf(seg * fDeltaSegAngle);

                    // Add one vertex to the strip which makes up the sphere
                    addPoint(ref buffer, new Vector3(x0, 0.5f * mHeight + y0, z0), new Vector3(x0, y0, z0).NormalisedCopy, new Vector2((float)seg / (float)mNumSegments, (float)ring / (float)mNumRings * sphereRatio));

                    // each vertex (except the last) has six indices pointing to it
                    buffer.index(offset + (int)mNumSegments + 1);
                    buffer.index(offset + (int)mNumSegments);
                    buffer.index(offset);
                    buffer.index(offset + (int)mNumSegments + 1);
                    buffer.index(offset);
                    buffer.index(offset + 1);

                    offset++;
                } // end for seg
            }     // end for ring

            // Cylinder part
            float deltaAngle   = (Math.TWO_PI / mNumSegments);
            float deltamHeight = mHeight / (float)mNumSegHeight;

            for (ushort i = 1; i < mNumSegHeight; i++)
            {
                for (ushort j = 0; j <= mNumSegments; j++)
                {
                    float x0 = mRadius * cosf(j * deltaAngle);
                    float z0 = mRadius * sinf(j * deltaAngle);

                    addPoint(ref buffer, new Vector3(x0, 0.5f * mHeight - i * deltamHeight, z0), new Vector3(x0, 0, z0).NormalisedCopy, new Vector2(j / (float)mNumSegments, i / (float)mNumSegHeight * cylinderRatio + sphereRatio));

                    buffer.index(offset + (int)mNumSegments + 1);
                    buffer.index(offset + (int)mNumSegments);
                    buffer.index(offset);
                    buffer.index(offset + (int)mNumSegments + 1);
                    buffer.index(offset);
                    buffer.index(offset + 1);

                    offset++;
                }
            }

            // Bottom half sphere

            // Generate the group of rings for the sphere
            for (uint ring = 0; ring <= mNumRings; ring++)
            {
                float r0 = mRadius * sinf(Math.HALF_PI + ring * fDeltaRingAngle);
                float y0 = mRadius * cosf(Math.HALF_PI + ring * fDeltaRingAngle);

                // Generate the group of segments for the current ring
                for (uint seg = 0; seg <= mNumSegments; seg++)
                {
                    float x0 = r0 * cosf(seg * fDeltaSegAngle);
                    float z0 = r0 * sinf(seg * fDeltaSegAngle);

                    // Add one vertex to the strip which makes up the sphere
                    addPoint(ref buffer, new Vector3(x0, -0.5f * mHeight + y0, z0), new Vector3(x0, y0, z0).NormalisedCopy, new Vector2((float)seg / (float)mNumSegments, (float)ring / (float)mNumRings * sphereRatio + cylinderRatio + sphereRatio));

                    if (ring != mNumRings)
                    {
                        // each vertex (except the last) has six indices pointing to it
                        buffer.index(offset + (int)mNumSegments + 1);
                        buffer.index(offset + (int)mNumSegments);
                        buffer.index(offset);
                        buffer.index(offset + (int)mNumSegments + 1);
                        buffer.index(offset);
                        buffer.index(offset + 1);
                    }
                    offset++;
                } // end for seg
            }     // end for ring
        }
Beispiel #14
0
        //    *
        //	 * Builds the mesh into the given TriangleBuffer
        //	 * @param buffer The TriangleBuffer on where to append the mesh.
        //
        //
        //ORIGINAL LINE: void addToTriangleBuffer(TriangleBuffer& buffer) const
        public override void addToTriangleBuffer(ref TriangleBuffer buffer)
        {
            buffer.rebaseOffset();
            buffer.estimateVertexCount((mNumSegHeight + 1) * (mNumSegBase + 1) * 2 + (mNumSegBase + 1) * 4);
            buffer.estimateIndexCount(6 * (mNumSegBase + 1) * mNumSegHeight * 2 + 6 * mNumSegBase * 2);

            float deltaAngle  = (Math.TWO_PI / mNumSegBase);
            float deltaHeight = mHeight / (float)mNumSegHeight;
            int   offset      = 0;

            for (uint i = 0; i <= mNumSegHeight; i++)
            {
                for (uint j = 0; j <= mNumSegBase; j++)
                {
                    float x0 = mOuterRadius * cosf(j * deltaAngle);
                    float z0 = mOuterRadius * sinf(j * deltaAngle);
                    addPoint(ref buffer, new Vector3(x0, i * deltaHeight, z0), new Vector3(x0, 0, z0).NormalisedCopy, new Vector2(j / (float)mNumSegBase, i / (float)mNumSegHeight));

                    if (i != mNumSegHeight)
                    {
                        buffer.index(offset + (int)mNumSegBase + 1);
                        buffer.index(offset);
                        buffer.index(offset + (int)mNumSegBase);
                        buffer.index(offset + (int)mNumSegBase + 1);
                        buffer.index(offset + 1);
                        buffer.index(offset);
                    }
                    offset++;
                }
            }

            for (uint i = 0; i <= mNumSegHeight; i++)
            {
                for (uint j = 0; j <= mNumSegBase; j++)
                {
                    float x0 = mInnerRadius * cosf(j * deltaAngle);
                    float z0 = mInnerRadius * sinf(j * deltaAngle);
                    addPoint(ref buffer, new Vector3(x0, i * deltaHeight, z0), -new Vector3(x0, 0, z0).NormalisedCopy, new Vector2(j / (float)mNumSegBase, i / (float)mNumSegHeight));

                    if (i != mNumSegHeight)
                    {
                        buffer.index(offset + (int)mNumSegBase + 1);
                        buffer.index(offset + (int)mNumSegBase);
                        buffer.index(offset);
                        buffer.index(offset + (int)mNumSegBase + 1);
                        buffer.index(offset);
                        buffer.index(offset + 1);
                    }
                    offset++;
                }
            }


            //low cap
            for (uint j = 0; j <= mNumSegBase; j++)
            {
                float x0 = mInnerRadius * cosf(j * deltaAngle);
                float z0 = mInnerRadius * sinf(j * deltaAngle);

                addPoint(ref buffer, new Vector3(x0, 0.0f, z0), Vector3.NEGATIVE_UNIT_Y, new Vector2(j / (float)mNumSegBase, 1.0f));

                x0 = mOuterRadius * cosf(j * deltaAngle);
                z0 = mOuterRadius * sinf(j * deltaAngle);

                addPoint(ref buffer, new Vector3(x0, 0.0f, z0), Vector3.NEGATIVE_UNIT_Y, new Vector2(j / (float)mNumSegBase, 0.0f));

                if (j != mNumSegBase)
                {
                    buffer.index(offset);
                    buffer.index(offset + 1);
                    buffer.index(offset + 3);
                    buffer.index(offset + 2);
                    buffer.index(offset);
                    buffer.index(offset + 3);
                }
                offset += 2;
            }


            //high cap
            for (uint j = 0; j <= mNumSegBase; j++)
            {
                float x0 = mInnerRadius * cosf(j * deltaAngle);
                float z0 = mInnerRadius * sinf(j * deltaAngle);

                addPoint(ref buffer, new Vector3(x0, mHeight, z0), Vector3.UNIT_Y, new Vector2(j / (float)mNumSegBase, 0.0f));

                x0 = mOuterRadius * cosf(j * deltaAngle);
                z0 = mOuterRadius * sinf(j * deltaAngle);

                addPoint(ref buffer, new Vector3(x0, mHeight, z0), Vector3.UNIT_Y, new Vector2(j / (float)mNumSegBase, 1.0f));

                if (j != mNumSegBase)
                {
                    buffer.index(offset + 1);
                    buffer.index(offset);
                    buffer.index(offset + 3);
                    buffer.index(offset);
                    buffer.index(offset + 2);
                    buffer.index(offset + 3);
                }
                offset += 2;
            }
        }
Beispiel #15
0
        /// Internal. Builds an "edge" of the rounded box, ie a quarter cylinder

        //*
        // * xPos,yPos,zPos : 1 => positive
        //					-1 => negative
        //					0 => undefined
        //
        //
        //ORIGINAL LINE: void _addEdge(TriangleBuffer& buffer, short xPos, short yPos, short zPos) const
        private void _addEdge(ref TriangleBuffer buffer, short xPos, short yPos, short zPos)
        {
            int offset = 0;

            Vector3 centerPosition = 0.5f * xPos * mSizeX * Vector3.UNIT_X + .5f * yPos * mSizeY * Vector3.UNIT_Y + .5f * zPos * mSizeZ * Vector3.UNIT_Z;
            Vector3 vy0            = (1.0f - Math.Abs(xPos)) * Vector3.UNIT_X + (1.0f - Math.Abs(yPos)) * Vector3.UNIT_Y + (1.0f - Math.Abs(zPos)) * Vector3.UNIT_Z; //extrusion direction

            Vector3 vx0 = Utils.vectorAntiPermute(vy0);
            Vector3 vz0 = Utils.vectorPermute(vy0);

            if (vx0.DotProduct(centerPosition) < 0.0)
            {
                vx0 = -vx0;
            }
            if (vz0.DotProduct(centerPosition) < 0.0)
            {
                vz0 = -vz0;
            }
            if (vx0.CrossProduct(vy0).DotProduct(vz0) < 0.0)
            {
                vy0 = -vy0;
            }

            float   height         = (1 - Math.Abs(xPos)) * mSizeX + (1 - Math.Abs(yPos)) * mSizeY + (1 - Math.Abs(zPos)) * mSizeZ;
            Vector3 offsetPosition = centerPosition - .5f * height * vy0;
            int     numSegHeight   = 1;

            if (xPos == 0)
            {
                numSegHeight = mNumSegX;
            }
            else if (yPos == 0)
            {
                numSegHeight = mNumSegY;
            }
            else if (zPos == 0)
            {
                numSegHeight = mNumSegZ;
            }

            float deltaAngle  = (Math.HALF_PI / mChamferNumSeg);
            float deltaHeight = height / (float)numSegHeight;


            buffer.rebaseOffset();
            buffer.estimateIndexCount((uint)(6 * numSegHeight * mChamferNumSeg));
            buffer.estimateVertexCount((uint)((numSegHeight + 1) * (mChamferNumSeg + 1)));

            for (ushort i = 0; i <= numSegHeight; i++)
            {
                for (ushort j = 0; j <= mChamferNumSeg; j++)
                {
                    float x0 = mChamferSize * cosf(j * deltaAngle);
                    float z0 = mChamferSize * sinf(j * deltaAngle);
                    //addPoint(ref buffer, new Vector3(x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition), (x0 * vx0 + z0 * vz0).NormalisedCopy, new Vector2(j / (float)mChamferNumSeg, i / (float)numSegHeight));


                    //addPoint(buffer, Vector3(x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition),
                    // (x0 * vx0 + z0 * vz0).normalisedCopy(),
                    // Vector2(j / (Real)mChamferNumSeg, i / (Real)numSegHeight));

                    addPoint(ref buffer,
                             (x0 * vx0 + i * deltaHeight * vy0 + z0 * vz0 + offsetPosition),
                             (x0 * vx0 + z0 * vz0).NormalisedCopy,
                             new Vector2(j / (float)mChamferNumSeg, i / (float)numSegHeight)
                             );
                    if (i != numSegHeight && j != mChamferNumSeg)
                    {
                        buffer.index(offset + mChamferNumSeg + 2);
                        buffer.index(offset);
                        buffer.index(offset + mChamferNumSeg + 1);
                        buffer.index(offset + mChamferNumSeg + 2);
                        buffer.index(offset + 1);
                        buffer.index(offset);
                    }
                    offset++;
                }
            }
        }