Exemplo n.º 1
0
        /*
         * public void setElev(Vector3 a, Vector3 b, Vector3 c)
         * {
         *      _elev = new Plane(a, b, c);
         * }
         * public void setBase(Vector3 a, Vector3 b, Vector3 c)
         * {
         *      _base = new Plane(a, b, c);
         * }
         */

        public Mesh generate(AXSpline spline, float _height)
        {
            // If a GameObject is passed, just replace its mesh.

            Debug.Log("--- Extrude: " + spline.toString());

            height = _height;

            float[] angles = spline.getAnglesArray();

            int edgeLoopVertCt = spline.getAllocateVertsCt();

            if (spline.isClosed && !spline.closeJointIsAcute())              // add a close rib
            {
                edgeLoopVertCt++;
            }

            int totalVertCount   = 0;
            int totalTriangCount = 0;



            int vcount = spline.vertCount;

            if (!spline.isClosed)
            {
                vcount--;
            }

            totalVertCount   += ((segs + 1) * edgeLoopVertCt);
            totalTriangCount += 3 * (segs * (2 * vcount));

            //Debug.Log ("totalVertCount="+totalVertCount);

            spline.getAnglesArray();
            spline.getUValues();

            Vector3[] vertices  = new Vector3[totalVertCount];
            Vector2[] uv        = new Vector2[totalVertCount];
            int[]     triangles = new int[totalTriangCount * 2];

            int index     = 0;
            int vertCount = 0;
            int segThis   = 0;

            // Create the Geometry
            // Run around the outline
            float x = 0;
            float y = 0;
            float z = 0;

            float u = 0;
            float v = 0;

            int   i;
            float segHgt;

            int reps = spline.vertCount - 1;

            if (spline.isClosed)
            {
                reps++;
            }

            //Debug.Log ("reps="+reps);

            // SIDE VERTICES

            for (int seg = 0; seg <= segs; seg++)
            {
                // each vert on spline
                for (i = 0; i <= reps; i++)
                {
                    segHgt = getHeight(spline.verts[i].x, spline.verts[i].y, seg);

                    if (i == spline.vertCount)
                    {
                        x = spline.verts[0].x;
                        y = segHgt;
                        z = spline.verts[0].y;
                    }
                    else
                    {
                        x = spline.verts[i].x;
                        y = segHgt;
                        z = spline.verts[i].y;
                    }



                    if (rotSidesTex && axis != Axis.Y)
                    {
                        //Debug.Log ("use height of extrude for u, heigth of vert for v");

                        u = height * (seg / segs);
                        v = z;
                    }
                    else
                    {
                        // Y-Axis, use length along spline
                        if (i == 0)
                        {
                            u = 0;
                        }
                        else if (i == spline.vertCount)
                        {
                            u = spline.getLength();
                        }
                        else
                        {
                            u = spline.curve_distances[i];
                        }
                        v = height * (seg / segs);
                    }



                    u /= uScale;
                    v /= vScale;

                    u += uShift;
                    v += vShift;

                    vertices[vertCount] = new Vector3(x, y, z);                       // bottom
                    uv[vertCount]       = new Vector2(u, v);


                    vertCount++;

                    if (spline.jointIsAcute(i))
                    {
                        vertices[vertCount] = new Vector3(x, y, z);
                        uv[vertCount]       = new Vector2(u, v);

                        vertCount++;
                    }
                }                 // end edge loop


                // if first vertex is acute, close loop by addeding vert0

                /*
                 * if (angles[0] > spline.breakAngle) {
                 *      u = 1;
                 *
                 *      vertices[vertCount] = vert0;
                 *                uv[vertCount] = new Vector2(u,v);
                 *                       vertCount++;
                 * }
                 */


                // Added bottom, now jump to next horizontal....
                if (seg == 0)
                {
                    continue;
                }

                // skin between this edgeLoop and the previous
                segThis = seg;

                // TRIANGLES /////////////////////////////////////////////////////////////////////////////////////////
                // now make triangles

                var segPrev = segThis - 1;


                int this_L;
                int this_U;
                int next_L = -1;
                int next_U = -1;

                var edgeloop_cursor = 0;

                for (i = 0; i < reps; i++)
                {
                    if (angles[i] > spline.breakAngle && i > 0)
                    {
                        edgeloop_cursor++;
                    }

                    this_L = segPrev * edgeLoopVertCt + edgeloop_cursor;
                    next_L = segPrev * edgeLoopVertCt + ((edgeloop_cursor + 1) % edgeLoopVertCt);

                    this_U = segThis * edgeLoopVertCt + edgeloop_cursor;
                    next_U = segThis * edgeLoopVertCt + ((edgeloop_cursor + 1) % edgeLoopVertCt);

                    triangles[index++] = next_L;
                    triangles[index++] = this_L;
                    triangles[index++] = this_U;

                    triangles[index++] = next_U;
                    triangles[index++] = next_L;
                    triangles[index++] = this_U;

                    edgeloop_cursor++;
                }
            }
            // end segs



            Mesh mesh = new Mesh();


            mesh.vertices  = vertices;
            mesh.uv        = uv;
            mesh.triangles = triangles;

            mesh.RecalculateNormals();

            /*
             * // adjust normals for first and last vert
             * if (! spline.closeJointIsAcute())
             * {
             *      Vector3[] norms = mesh.normals;
             *      Quaternion rotation;
             *
             *      // first rib
             *      rotation = Quaternion.Euler(0, spline.angles[0], 0);
             *      norms[0]                = rotation * norms[0];
             *      norms[edgeLoopVertCt]   = rotation * norms[edgeLoopVertCt];
             *
             *      // last rib
             *      rotation = Quaternion.Euler(0, -spline.angles[0], 0);
             *      norms[spline.vertCount-1] = rotation * norms[spline.vertCount-1];
             *      norms[spline.vertCount-1+edgeLoopVertCt] = rotation * norms[spline.vertCount-1+edgeLoopVertCt];
             *
             *      mesh.normals = norms;
             * }
             */


            return(mesh);
        }
Exemplo n.º 2
0
        public Mesh generate(AXSpline _planSpline, AXSpline _sectionSpline, float uShiftNow, float vShiftNow)
        {
            _planSpline.removeLastVertIfIdenticalToFirst();
            //Debug.Log ("topCap="+topCap+",  planSpline.isClosed="+_planSpline.isClosed + " : sectionSpline.isClosed=" + _sectionSpline.isClosed);

            if (uShiftNow != 0)
            {
                uShift = uShiftNow;
            }

            if (vShiftNow != 0)
            {
                vShift = vShiftNow;
            }

            if (_planSpline == null || _planSpline.vertCount == 0 || _sectionSpline == null || _sectionSpline.vertCount == 0)
            {
                return(null);
            }

            // plan spline
            AXSpline planSpline = _planSpline;

            // LATER: calc this on whether vert 0 and n are the same.
            planSpline.isClosed = false;

            planSpline.calcStats();
            planSpline.getUValues();


            // section spline
            AXSpline sectionSpline;

            sectionSpline            = _sectionSpline.turnRight();
            sectionSpline.isClosed   = true;                    //_sectionSpline.isClosed;
            sectionSpline.breakAngle = _sectionSpline.breakAngle;



            int index = 0;



            if (!planSpline.isClosed && !sectionSpline.isClosed)
            {
                begCap = false;
                endCap = false;
            }

            // ALLOCATE ARRAYS ////////////////////////////////////////////////////////////

            // SECTION ALLOCATION
            int sec_AdjustedVertsCount = sectionSpline.getAllocateVertsCt();
            //if (sectionSpline.isClosed && ! sectionSpline.closeJointIsAcute()) // add a close rib
            //	sec_AdjustedVertsCount++;

            // PLAN ALLOCATION
            int plan_AdjustedVertsCount = planSpline.getAllocateVertsCt();

            if (planSpline.isClosed && !planSpline.closeJointIsAcute())              // add a close rib
            {
                plan_AdjustedVertsCount++;
            }


            int fabricVertCount = plan_AdjustedVertsCount * sec_AdjustedVertsCount + 2;

            //Debug.Log

            // use the count of sides to determine the quads count in the extrusion
            int planSides = planSpline.vertCount;

            if (!planSpline.isClosed)
            {
                planSides--;
            }

            int sectionSides = sectionSpline.vertCount;

            if (!sectionSpline.isClosed)
            {
                sectionSides--;
            }

            int quadCount = planSides * sectionSides;

            int totalVertCount   = fabricVertCount;
            int totalTriangCount = 3 * 2 * quadCount;

            Vector3[] vertices  = new Vector3[totalVertCount];
            Vector2[] uv        = new Vector2[totalVertCount];
            int[]     triangles = new int[totalTriangCount];



            //Debug.Log("plan_AdjustedVertsCount="+plan_AdjustedVertsCount+", sec_AdjustedVertsCount="+sec_AdjustedVertsCount+", fabricVertCount = "+ fabricVertCount);



            // 1. CREATE VERTICES //////////////////////////////////////////////////////////


            // i is current vert:
            //
            //					  (i-1)
            //						|
            //						|
            //						| edgeAfter
            //						|
            //						|
            //				       (i)
            //					   /
            //				      /
            //				     / edgeBefore
            //				    /
            //				   /
            //              (i-1)

            int ribCount           = 0;
            int planRib_VertCursor = 0;
            int vertCursor0        = 0;

            Vector2 edgeBefore      = Vector2.zero;
            Vector2 edgeBeforePerp  = Vector2.zero;
            Vector2 edgeBeforePerpN = Vector2.zero;

            Vector2 edgeAfter      = Vector2.zero;
            Vector2 edgeAfterPerp  = Vector2.zero;
            Vector2 edgeAfterPerpN = Vector2.zero;


            float uScalerAfter = 1f;

            float plan_u = 0f;

            // FOR EACH PLAN  VERT
            for (int i = 0; i < planSpline.vertCount; i++)
            {
                //Debug.Log ("New PLAN POINT: " + i + " :: ribCount=" + ribCount + ", sec_AdjustedVertsCount="+sec_AdjustedVertsCount);

                planRib_VertCursor = ribCount * sec_AdjustedVertsCount;
                Debug.Log("planRib_VertCursor[" + i + "] = " + planRib_VertCursor);

                plan_u = planSpline.curve_distances[i] / uScale;

                //Debug.Log (planSpline.angles[i]);

                // EACH Plan node

                // ASSUME: If spline is open then the first and last are perpendicular to the end segments.

                // For each plan point, find the transformation matrix withwhich to transform the section as a "rib"
                // Then traverse the section verts and mutiply them by the plan point matrix.

                Matrix4x4 transMatrix = Matrix4x4.identity;

                Vector3    translation = new Vector3(planSpline.verts[i].x, 0.0f, planSpline.verts[i].y);
                Quaternion rotation    = Quaternion.identity;
                Vector3    scaler      = Vector3.one;



                if (!planSpline.isClosed && (i == 0 || i == planSpline.vertCount - 1))
                {
                    // open plan has special treatment of first and last verts
                    if (i == 0)
                    {
                        edgeAfter      = planSpline.verts[i + 1] - planSpline.verts[i];
                        edgeAfterPerp  = new Vector2(edgeAfter.y, -edgeAfter.x);
                        edgeAfterPerpN = edgeAfterPerp.normalized;
                        rotation       = Quaternion.FromToRotation(Vector3.right, new Vector3(edgeAfterPerp.x, 0, edgeAfterPerp.y));
                    }
                    else
                    {
                        edgeBefore      = planSpline.verts[i] - planSpline.verts[i - 1];
                        edgeBeforePerp  = new Vector2(edgeAfter.y, -edgeAfter.x);
                        edgeBeforePerpN = edgeBeforePerp.normalized;
                        rotation        = Quaternion.FromToRotation(Vector3.right, new Vector3(edgeBeforePerp.x, 0, edgeBeforePerp.y));
                    }

                    // scaler remains one
                }
                else
                {
                    if (i == 0)
                    {
                        edgeBefore = planSpline.verts[i] - planSpline.verts[planSpline.vertCount - 1];
                    }
                    else
                    {
                        edgeBefore = planSpline.verts[i] - planSpline.verts[i - 1];
                    }

                    edgeBeforePerp  = new Vector2(edgeBefore.y, -edgeBefore.x);
                    edgeBeforePerpN = edgeBeforePerp.normalized;



                    if (i == planSpline.vertCount - 1)
                    {
                        edgeAfter = planSpline.verts[0] - planSpline.verts[i];
                    }
                    else
                    {
                        edgeAfter = planSpline.verts[i + 1] - planSpline.verts[i];
                    }

                    edgeAfterPerp  = new Vector2(edgeAfter.y, -edgeAfter.x);
                    edgeAfterPerpN = edgeAfterPerp.normalized;



                    // the addition of the normalized perpendicular vectors leads to a bisector
                    Vector2 bisector = edgeAfterPerpN + edgeBeforePerpN;
                    rotation = Quaternion.FromToRotation(Vector3.right, new Vector3(bisector.x, 0, bisector.y));

                    float biAngle = Vector2.Angle(bisector, edgeAfter);

                    // we can get the scaler from the dot product
                    float scalerVal = 1 / Vector2.Dot(edgeBeforePerpN, bisector.normalized);
                    scaler = new Vector3(scalerVal, 1, 1);

                    uScalerAfter = scalerVal * Mathf.Cos(Mathf.Deg2Rad * biAngle);

                    //Debug.Log ("biAngle="+biAngle + " :: " + Mathf.Cos (Mathf.Deg2Rad*biAngle) + ", scalerVal="+scalerVal + " -- " + scalerVal*Mathf.Cos (Mathf.Deg2Rad*biAngle));
                }

                //Debug.Log("["+i+"] " + translation + " :: " + rotation + " :: " + scaler);
                transMatrix.SetTRS(translation, rotation, scaler);



                // ADD RIB -----------------------------------------------------------------------------

                // FOR EACH POINT IN SECTION SPLINE (sectionSpline)

                int     section_VertCursor = 0;
                Vector3 vert = Vector3.zero;


                int j;

                float u  = 0;
                float nu = 0;
                float v  = 0;

                int ribEnd_vertIndex = 0;
                int ribBeg_vertIndex = 0;

                // **  A RIB  **
                // **  each spline vert
                // **       - transform by plan location, rotation and scale
                for (j = 0; j <= sectionSpline.vertCount; j++)
                {
                    if (!sectionSpline.isClosed && j == sectionSpline.vertCount)
                    {
                        break;
                    }

                    /* **** VERT IS CREATED *** */
                    if (j == sectionSpline.vertCount)                   // return to first vert
                    {
                        vert = transMatrix.MultiplyPoint(new Vector3(-sectionSpline.verts[0].y, sectionSpline.verts[0].x, 0));
                    }
                    else
                    {
                        vert = transMatrix.MultiplyPoint(new Vector3(-sectionSpline.verts[j].y, sectionSpline.verts[j].x, 0));
                    }



                    // THIS IS THE MAIN SECTION OF CODE //


                    // Determine UV coordinates


                    // THIS_U
                    if (i == 0 && !planSpline.closeJointIsAcute())
                    {
                        u = uShift + plan_u;
                    }
                    else
                    {
                        u = uShift + plan_u - (uScalerAfter * sectionSpline.verts[j].y / uScale);
                    }


                    // NEXT_U (AFTER BREAK BUT AT SAME LOCATION)
                    if (planSpline.jointIsAcute(i) || (i == 0 && planSpline.closeJointIsAcute()))
                    {
                        if (i == 0 && planSpline.isClosed)
                        {
                            nu = uShift + (planSpline.getLength() / uScale) + (uScalerAfter * sectionSpline.verts[j].y / uScale);
                        }
                        else
                        {
                            nu = uShift + plan_u + (uScalerAfter * sectionSpline.verts[j].y / uScale);
                        }
                    }
                    else
                    {
                        if (i == 0 && planSpline.isClosed)
                        {
                            nu = uShift + (planSpline.getLength() / uScale);
                        }
                        else
                        {
                            nu = uShift + plan_u;
                        }
                    }

                    // THIS_V
                    if (j == sectionSpline.vertCount)
                    {
                        v = vShift + sectionSpline.getLength() / vScale;
                    }
                    else
                    {
                        v = vShift + sectionSpline.curve_distances[j] / vScale;
                    }


                    // determine vertices address
                    if (i == 0 && planSpline.isClosed)
                    {
                        ribEnd_vertIndex = (fabricVertCount - sec_AdjustedVertsCount) + section_VertCursor;
                        ribBeg_vertIndex = planRib_VertCursor + section_VertCursor;
                    }
                    else
                    {
                        ribEnd_vertIndex = planRib_VertCursor + section_VertCursor;
                        ribBeg_vertIndex = planRib_VertCursor + section_VertCursor + sec_AdjustedVertsCount;
                    }


                    // ** ADD THIS VERT TO MESH VERTICES **
                    vertices[ribEnd_vertIndex] = vert;
                    uv[ribEnd_vertIndex]       = new Vector2(nu, v);

                    //Debug.Log ("Add ribEnd_vertIndex="+ribEnd_vertIndex + "    -- "+vertices[ribEnd_vertIndex]);



                    if ((i > 0 && planSpline.jointIsAcute(i)) || (i == 0 && planSpline.isClosed))
                    {
                        // add an additional vert in the next rib (in same location
                        vertices[ribBeg_vertIndex] = vert;
                        uv[ribBeg_vertIndex]       = new Vector2(u, v);
                        //Debug.Log ("Add ribBeg_vertIndex="+ribBeg_vertIndex + "    -- "+vertices[ribBeg_vertIndex]);
                    }


                    section_VertCursor++;

                    // SECTION BREAK?
                    if (j < sectionSpline.vertCount && sectionSpline.jointIsAcute(j))
                    {
                        // ** ADD THIS VERT TO MESH VERTICES (AGAIN) **    (and restart the u?)
                        // add an additional section point in the same location
                        if (i == 0 && planSpline.isClosed)
                        {
                            ribEnd_vertIndex = (fabricVertCount - sec_AdjustedVertsCount) + section_VertCursor;
                            ribBeg_vertIndex = planRib_VertCursor + section_VertCursor;
                        }
                        else
                        {
                            ribEnd_vertIndex = planRib_VertCursor + section_VertCursor;
                            ribBeg_vertIndex = planRib_VertCursor + section_VertCursor + sec_AdjustedVertsCount;
                        }
                        //Debug.Log ("ribEnd_vertIndex="+ribEnd_vertIndex+", ribBeg_vertIndex="+ribBeg_vertIndex + "   -- "+vertices[ribBeg_vertIndex]);

                        vertices[ribEnd_vertIndex] = vert;
                        uv[ribEnd_vertIndex]       = new Vector2(nu, v);
                        //Debug.Log ("Add ribEnd_vertIndex="+ribEnd_vertIndex + "    -- "+vertices[ribEnd_vertIndex]);

                        if ((i > 0 && planSpline.jointIsAcute(i)) || (i == 0 && planSpline.isClosed))
                        {
                            // add an additional vert in the next rib (in same location
                            vertices[ribBeg_vertIndex] = vert;
                            uv[ribBeg_vertIndex]       = new Vector2(u, v);
                            //Debug.Log ("Add ribBeg_vertIndex="+ribBeg_vertIndex + "    -- "+vertices[ribBeg_vertIndex]);
                        }

                        section_VertCursor++;
                    }
                }



                ribCount++;                                                                     // COUNT THIS RIB, ie, RIB
                if (planSpline.jointIsAcute(i))
                {
                    ribCount++;                                                                 // ADD ADDITIONAL RIB COUNT
                }
            }



            // 2. CREATE TRIANGLES //////////////////////////////////////////////////////////

            int LRib_L;
            int RRib_L;
            int LRib_U;
            int RRib_U;

            int leftRib = 0;


            // FOREACH PLAN NODE.......
            for (int i = 1; i <= planSpline.vertCount; i++)
            {
                if (i == planSpline.vertCount && !planSpline.isClosed)
                {
                    break;
                }
                // from left to right

                planRib_VertCursor = leftRib * sec_AdjustedVertsCount;


                vertCursor0 = planRib_VertCursor;

                // FOREACH SEC NODE.......
                for (int j = 1; j <= sectionSpline.vertCount; j++)
                {
                    if (j == sectionSpline.vertCount && !sectionSpline.isClosed)
                    {
                        break;
                    }

                    LRib_L = planRib_VertCursor;

                    if (j == sectionSpline.vertCount && sectionSpline.isClosed && !sectionSpline.closeJointIsAcute())
                    {
                        //Debug.Log ("GOING BACK TO SEC ORIGN...");
                        LRib_U = vertCursor0;
                    }
                    else
                    {
                        LRib_U = LRib_L + 1;
                    }



                    // use next rib's points ( Never loop back to use rib0)
                    RRib_L = LRib_L + sec_AdjustedVertsCount;
                    RRib_U = LRib_U + sec_AdjustedVertsCount;



                    triangles[index++] = LRib_L;
                    triangles[index++] = RRib_U;
                    triangles[index++] = RRib_L;

                    triangles[index++] = LRib_L;
                    triangles[index++] = LRib_U;
                    triangles[index++] = RRib_U;

                    planRib_VertCursor++;
                    if (j < sectionSpline.vertCount && sectionSpline.jointIsAcute(j))
                    {
                        planRib_VertCursor++;
                    }
                }


                // GO TO NEXT SEGMENT
                leftRib++;
                if (i < planSpline.vertCount && planSpline.jointIsAcute(i))
                {
                    leftRib++;
                }
            }



            Mesh mesh = new Mesh();

            mesh.vertices  = vertices;
            mesh.uv        = uv;
            mesh.triangles = triangles;



            // Auto-calculate vertex normals from the mesh
            mesh.RecalculateNormals();

            return(mesh);
        }