Пример #1
0
        //-----------------------------------------------------------------------
        public static void _extrudeShape(ref TriangleBuffer buffer, Shape shape, Vector3 position, Quaternion orientationLeft, Quaternion orientationRight, float scale, float scaleCorrectionLeft, float scaleCorrectionRight, float totalShapeLength, float uTexCoord, bool joinToTheNextSection, Track shapeTextureTrack)
        {
            float lineicShapePos = 0.0f;
            int   numSegShape    = shape.getSegCount();

            // Insert new points
            for (uint j = 0; j <= numSegShape; ++j)
            {
                Vector2    vp2         = shape.getPoint((int)j);
                Quaternion orientation = (vp2.x > 0) ? orientationRight : orientationLeft;
                Vector2    vp2normal   = shape.getAvgNormal(j);
                Vector3    vp          = new Vector3();
                if (vp2.x > 0)
                {
                    vp = new Vector3(scaleCorrectionRight * vp2.x, vp2.y, 0);
                }
                else
                {
                    vp = new Vector3(scaleCorrectionLeft * vp2.x, vp2.y, 0);
                }
                Vector3 normal = new Vector3(vp2normal.x, vp2normal.y, 0);
                buffer.rebaseOffset();
                Vector3 newPoint = position + orientation * (scale * vp);
                if (j > 0)
                {
                    lineicShapePos += (vp2 - shape.getPoint((int)j - 1)).Length;
                }
                float vTexCoord = 0f;
                if (shapeTextureTrack != null)
                {
                    vTexCoord = shapeTextureTrack.getValue(lineicShapePos, lineicShapePos / totalShapeLength, j);
                }
                else
                {
                    vTexCoord = lineicShapePos / totalShapeLength;
                }

                buffer.vertex(newPoint, orientation * normal, new Vector2(uTexCoord, vTexCoord));

                if (j < numSegShape && joinToTheNextSection)
                {
                    if (shape.getOutSide() == Side.SIDE_LEFT)
                    {
                        buffer.triangle(numSegShape + 1, numSegShape + 2, 0);
                        buffer.triangle(0, numSegShape + 2, 1);
                    }
                    else
                    {
                        buffer.triangle(numSegShape + 2, numSegShape + 1, 0);
                        buffer.triangle(numSegShape + 2, 0, 1);
                    }
                }
            }
        }
Пример #2
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
        }
Пример #3
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++;
                }
            }
        }
Пример #4
0
        //-----------------------------------------------------------------------

        public static void _retriangulate(ref TriangleBuffer newMesh, TriangleBuffer inputMesh, std_vector <Intersect> intersectionList, bool first)
        {
            std_vector <TriangleBuffer.Vertex> vec = inputMesh.getVertices();
            std_vector <int> ind = inputMesh.getIndices();
            // Triangulate
            //  Group intersections by triangle indice
            std_map <int, std_vector <Segment3D> > meshIntersects = new std_map <int, std_vector <Segment3D> >();

            //for (List<Intersect>.Enumerator it = intersectionList.GetEnumerator(); it.MoveNext(); ++it)
            foreach (var it in intersectionList)
            {
                int it2_find;
                if (first)
                {
                    it2_find = meshIntersects.find(it.mTri1);
                }
                else
                {
                    it2_find = meshIntersects.find(it.mTri2);
                }
                if (it2_find != -1)
                {
                    std_pair <int, std_vector <Segment3D> > it2 = meshIntersects.get((uint)it2_find);
                    it2.second.push_back(it.mSeg);
                }
                else
                {
                    std_vector <Segment3D> vec2 = new std_vector <Segment3D>();
                    vec2.push_back(it.mSeg);
                    if (first)
                    {
                        meshIntersects[it.mTri1] = vec2;
                    }
                    else
                    {
                        meshIntersects[it.mTri2] = vec2;
                    }
                }
            }
            // Build a new TriangleBuffer holding non-intersected triangles and retriangulated-intersected triangles
            //for (List<TriangleBuffer.Vertex>.Enumerator it = vec.GetEnumerator(); it.MoveNext(); ++it)
            foreach (var it in vec)
            {
                newMesh.vertex(it);
            }
            //for (int i = 0; i < (int)ind.Count / 3; i++)
            //    if (meshIntersects.find(i) == meshIntersects.end())
            //        newMesh.triangle(ind[i * 3], ind[i * 3 + 1], ind[i * 3 + 2]);
            for (int i = 0; i < (int)ind.size() / 3; i++)
            {
                if (meshIntersects.find(i) == -1)
                {
                    newMesh.triangle(ind[i * 3], ind[i * 3 + 1], ind[i * 3 + 2]);
                }
            }

            int numNonIntersected1 = newMesh.getIndices().size();

            //for (std.map<int, List<Segment3D> >.Enumerator it = meshIntersects.begin(); it.MoveNext(); ++it)
            foreach (var it in meshIntersects)
            {
                std_vector <Segment3D> segments = it.Value;
                int     triIndex    = it.Key;
                Vector3 v1          = vec[ind[triIndex * 3]].mPosition;
                Vector3 v2          = vec[ind[triIndex * 3 + 1]].mPosition;
                Vector3 v3          = vec[ind[triIndex * 3 + 2]].mPosition;
                Vector3 triNormal   = ((v2 - v1).CrossProduct(v3 - v1)).NormalisedCopy;
                Vector3 xAxis       = triNormal.Perpendicular;
                Vector3 yAxis       = triNormal.CrossProduct(xAxis);
                Vector3 planeOrigin = vec[ind[triIndex * 3]].mPosition;

                // Project intersection segments onto triangle plane
                std_vector <Segment2D> segments2 = new std_vector <Segment2D>();

                //for (List<Segment3D>.Enumerator it2 = segments.GetEnumerator(); it2.MoveNext(); it2++)
                //    segments2.Add(projectOnAxis(it2.Current, planeOrigin, xAxis, yAxis));
                foreach (var it2 in segments)
                {
                    segments2.push_back(projectOnAxis(it2, planeOrigin, xAxis, yAxis));
                }
                //for (List<Segment2D>.Enumerator it2 = segments2.GetEnumerator(); it2.MoveNext();)
                int it2_c = segments2.Count;
                for (int j = it2_c - 1; j >= 0; j--)
                {
                    Segment2D it2 = segments2[j];
                    if ((it2.mA - it2.mB).SquaredLength < 1e-5)
                    {
                        //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent to the STL vector 'erase' method in C#:
                        //it2 = segments2.erase(it2);
                        segments2.RemoveAt(j);
                    }
                    //else
                }
                // Triangulate
                Triangulator t = new Triangulator();
                //Triangle2D[[]] tri = new Triangle2D[ind[triIndex * 3]](projectOnAxis(vec.mPosition, planeOrigin, xAxis, yAxis), projectOnAxis(vec[ind[triIndex * 3 + 1]].mPosition, planeOrigin, xAxis, yAxis), projectOnAxis(vec[ind[triIndex * 3 + 2]].mPosition, planeOrigin, xAxis, yAxis));
                Triangle2D tri = new Triangle2D(projectOnAxis(vec[ind[triIndex * 3]].mPosition, planeOrigin, xAxis, yAxis),
                                                projectOnAxis(vec[ind[triIndex * 3 + 1]].mPosition, planeOrigin, xAxis, yAxis),
                                                projectOnAxis(vec[ind[triIndex * 3 + 2]].mPosition, planeOrigin, xAxis, yAxis));
                std_vector <Vector2> outPointList = new std_vector <Vector2>();//PointList outPointList;
                std_vector <int>     outIndice    = new std_vector <int>();
                t.setManualSuperTriangle(tri).setRemoveOutside(false).setSegmentListToTriangulate(ref segments2).triangulate(outIndice, outPointList);

                // Deproject and add to triangleBuffer
                newMesh.rebaseOffset();
                //for (List<int>.Enumerator it = outIndice.GetEnumerator(); it.MoveNext(); ++it)
                //    newMesh.index(it.Current);
                foreach (var oindex in outIndice)
                {
                    newMesh.index(oindex);
                }
                float   x1  = tri.mPoints[0].x;
                float   y1  = tri.mPoints[0].y;
                Vector2 uv1 = vec[ind[triIndex * 3]].mUV;
                float   x2  = tri.mPoints[1].x;
                float   y2  = tri.mPoints[1].y;
                Vector2 uv2 = vec[ind[triIndex * 3 + 1]].mUV;
                float   x3  = tri.mPoints[2].x;
                float   y3  = tri.mPoints[2].y;
                Vector2 uv3 = vec[ind[triIndex * 3 + 2]].mUV;
                float   DET = x1 * y2 - x2 * y1 + x2 * y3 - x3 * y2 + x3 * y1 - x1 * y3;
                Vector2 A   = ((y2 - y3) * uv1 + (y3 - y1) * uv2 + (y1 - y2) * uv3) / DET;
                Vector2 B   = ((x3 - x2) * uv1 + (x1 - x3) * uv2 + (x2 - x1) * uv3) / DET;
                Vector2 C   = ((x2 * y3 - x3 * y2) * uv1 + (x3 * y1 - x1 * y3) * uv2 + (x1 * y2 - x2 * y1) * uv3) / DET;

                //for (List<Vector2>.Enumerator it = outPointList.GetEnumerator(); it.MoveNext(); ++it)
                foreach (var it2 in outPointList)
                {
                    Vector2 uv = A * it2.x + B * it2.y + C;
                    newMesh.position(deprojectOnAxis(it2, planeOrigin, xAxis, yAxis));
                    newMesh.normal(triNormal);
                    newMesh.textureCoord(uv);
                }
            }
        }
Пример #5
0
        //-----------------------------------------------------------------------

        public static void _recursiveAddNeighbour(ref TriangleBuffer result, TriangleBuffer source, int triNumber, ref TriLookup lookup, std_set <Segment3D> limits, bool inverted)
        {
            if (triNumber == -1)
            {
                return;
            }
            Utils.log("tri " + (triNumber.ToString()));
            std_vector <int> ind = source.getIndices();
            std_vector <TriangleBuffer.Vertex> vec = source.getVertices();

            result.rebaseOffset();
            if (inverted)
            {
                result.triangle(0, 2, 1);
                TriangleBuffer.Vertex v = vec[ind[triNumber * 3]];
                v.mNormal = -v.mNormal;
                result.vertex(v);
                v         = vec[ind[triNumber * 3 + 1]];
                v.mNormal = -v.mNormal;
                result.vertex(v);
                v         = vec[ind[triNumber * 3 + 2]];
                v.mNormal = -v.mNormal;
                result.vertex(v);
            }
            else
            {
                result.triangle(0, 1, 2);
                result.vertex(vec[ind[triNumber * 3]]);
                result.vertex(vec[ind[triNumber * 3 + 1]]);
                result.vertex(vec[ind[triNumber * 3 + 2]]);
            }

            //Utils::log("vertex " + StringConverter::toString(vec[ind[triNumber*3]].mPosition));
            //Utils::log("vertex " + StringConverter::toString(vec[ind[triNumber*3+1]].mPosition));
            //Utils::log("vertex " + StringConverter::toString(vec[ind[triNumber*3+2]].mPosition));

            std_pair <Segment3D, List <int> > it = null;

            int nextTriangle1 = -1;
            int nextTriangle2 = -1;
            int nextTriangle3 = -1;
            int it_find       = lookup.find(new Segment3D(vec[ind[triNumber * 3]].mPosition, vec[ind[triNumber * 3 + 1]].mPosition).orderedCopy());

            ////if (it != lookup.end() && limits.find(it->first.orderedCopy()) != limits.end())
            ////	Utils::log("Cross limit1");
            //if (it != lookup.end() && limits.find(it->first.orderedCopy()) == limits.end()) {
            //    nextTriangle1 = it->second;
            //    _removeFromTriLookup(nextTriangle1, lookup);
            //}
            if (it_find != -1)
            {
                it = lookup.get((uint)it_find);
                if (limits.find(it.first.orderedCopy()) == -1)
                {
                    nextTriangle1 = it.second[0];
                    GlobalMembersProceduralBoolean._removeFromTriLookup(nextTriangle1, ref lookup);
                }
            }
            //	it = lookup.find(Segment3D(vec[ind[triNumber * 3 + 1]].mPosition, vec[ind[triNumber * 3 + 2]].mPosition).orderedCopy());
            it_find = lookup.find(new Segment3D(vec[ind[triNumber * 3 + 1]].mPosition, vec[ind[triNumber * 3 + 2]].mPosition).orderedCopy());

            ////if (it != lookup.end() && limits.find(it->first.orderedCopy()) != limits.end())
            ////Utils::log("Cross limit2");
            //if (it != lookup.end() && limits.find(it->first.orderedCopy()) == limits.end()) {
            //    nextTriangle2 = it->second;
            //    _removeFromTriLookup(nextTriangle2, lookup);
            //}
            if (it_find != -1)
            {
                it = lookup.get((uint)it_find);
                if (limits.find(it.first.orderedCopy()) == -1)
                {
                    nextTriangle2 = it.second[0];
                    GlobalMembersProceduralBoolean._removeFromTriLookup(nextTriangle2, ref lookup);
                }
            }
            //it = lookup.find(Segment3D(vec[ind[triNumber * 3]].mPosition, vec[ind[triNumber * 3 + 2]].mPosition).orderedCopy());
            ////if (it != lookup.end() && limits.find(it->first.orderedCopy()) != limits.end())
            ////	Utils::log("Cross limit3");
            //if (it != lookup.end() && limits.find(it->first.orderedCopy()) == limits.end()) {
            //    nextTriangle3 = it->second;
            //    _removeFromTriLookup(nextTriangle3, lookup);
            //}
            it_find = lookup.find(new Segment3D(vec[ind[triNumber * 3]].mPosition, vec[ind[triNumber * 3 + 2]].mPosition).orderedCopy());
            if (it_find != -1)
            {
                it = lookup.get((uint)it_find);
                if (limits.find(it.first.orderedCopy()) == -1)
                {
                    nextTriangle3 = it.second[0];
                    GlobalMembersProceduralBoolean._removeFromTriLookup(nextTriangle3, ref lookup);
                }
            }

            //Utils::log("add " + StringConverter::toString(nextTriangle1) + " ," + StringConverter::toString(nextTriangle2) + " ,"+StringConverter::toString(nextTriangle3) );

            _recursiveAddNeighbour(ref result, source, nextTriangle1, ref lookup, limits, inverted);
            _recursiveAddNeighbour(ref result, source, nextTriangle2, ref lookup, limits, inverted);
            _recursiveAddNeighbour(ref result, source, nextTriangle3, ref lookup, limits, inverted);
        }