コード例 #1
0
        public static Path spline2Path(AXSpline s)
        {
            Path path = new Path();

            for (int i = 0; i < s.vertCount; i++)
            {
                path.Add(Vec2_2_IntPt(s.verts[i]));
            }
            return(path);
        }
コード例 #2
0
        public static AXSpline path2AXSpline(Path path)
        {
            AXSpline s = new AXSpline();

            for (int i = 0; i < path.Count; i++)
            {
                s.Push(IntPt2Vec2(path[i]));
            }
            return(s);
        }
コード例 #3
0
        public static AXSpline curve2Spline(List <CurvePoint> curve)
        {
            AXSpline s = new AXSpline();

            for (int i = 0; i < curve.Count; i++)
            {
                s.Push(curve[i].position);
            }
            return(s);
        }
コード例 #4
0
        //bool drawingHole = false;

        public AXTurtle()
        {
            updateTrigs();
            dir(0);

            s = new AXSpline();

            paths = new Paths();
            clips = new Paths();

            polytree = new PolyTree();
        }
コード例 #5
0
    public static void DrawSplineFit(AXParameter p, Vector2 offset, float size, Color splineColor)
    {
        AXSpline s = p.spline.clone();

        s.rotate(p.Parent.floatValue("Rot_Z"));

        if (s == null)
        {
            return;
        }

        // scale the spline to fit in "size" in pixels
        AXSpline os = s.clone();

        os.calcStats();
        os.shift(-os.cenX, -os.cenY);

        float maxdim = (os.width > os.height) ? os.width : os.height;
        float scale  = size / maxdim;

        os.scale(scale);

        GUIDrawing.DrawSpline(os, offset, splineColor);
    }
コード例 #6
0
        // GENERATE PLAN_REPEATER
        public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool renderToOutputParameter)
        {
            if (parametricObject == null || !parametricObject.isActive)
            {
                return(null);
            }
            //Debug.Log("yo ******* makeGameObjects="+makeGameObjects);


            // RESULTING MESHES
            ax_meshes = new List <AXMesh>();

            paths_SubsplineIndices = new List <SubsplineIndices[]>();

            preGenerate();



            planSrc_p  = P_Plan.DependsOn;                         // getUpstreamSourceParameter(P_Plan);
            planSrc_po = (planSrc_p != null)                                                           ? planSrc_p.parametricObject    : null;

            //Debug.Log("planSrc_po = " + planSrc_po.Name+"."+planSrc_p.Name + " ... " + planSrc_p.DependsOn.PType + " ..... " + planSrc_p.getPaths());

            P_Plan.polyTree = null;
            AXShape.thickenAndOffset(ref P_Plan, planSrc_p);
            if (P_Plan.reverse)
            {
                P_Plan.doReverse();
            }


            planPaths = P_Plan.getPaths();

            if (planPaths == null || planPaths.Count == 0)
            {
                return(null);
            }



            // ** CREATE PLAN_SPLINES **

            if (planPaths != null && planPaths.Count > 0)
            {
                planSplines = new Spline[planPaths.Count];


                if (planSplines != null)
                {
                    for (int i = 0; i < planSplines.Length; i++)
                    {
                        planSplines[i] = new Spline(planPaths[i], (P_Plan.shapeState == ShapeState.Closed) ? true : false);
                    }
                }
            }



            //Debug.Log("controlVertices="+ planSplines[0].controlVertices.Count);



            // CORNER_MESH
            GameObject cornerPlugGO = null;

            if (cornerSrc_p != null)
            {
                cornerSrc_po = cornerSrc_p.parametricObject;
                if (makeGameObjects && !parametricObject.combineMeshes)
                {
                    cornerPlugGO = cornerSrc_po.generator.generate(true, initiator_po, renderToOutputParameter);
                }
            }



            // NODE_MESH

            GameObject nodePlugGO = null;

            if (nodeSrc_p != null)
            {
                nodeSrc_po = nodeSrc_p.parametricObject;
                //Debug.Log("yo makeGameObjects="+makeGameObjects+", parametricObject.combineMeshes="+parametricObject.combineMeshes);
                if (makeGameObjects && !parametricObject.combineMeshes)
                {
                    nodePlugGO = nodeSrc_po.generator.generate(true, initiator_po, renderToOutputParameter);
                }
            }



            // CELL_MESH

            GameObject cellPlugGO = null;

            if (cellSrc_p != null)
            {
                cellSrc_po = cellSrc_p.parametricObject;
                if (makeGameObjects && !parametricObject.combineMeshes)
                {
                    cellPlugGO = cellSrc_po.generator.generate(true, initiator_po, renderToOutputParameter);
                }
            }



            // Plan
            // This is the main spline used for the iteration



            //AXParameter plan_p = ip.DependsOn;



            // The section spline is used to provide the connective tissue around corners

            // SECTION

            // The plan may have multiple paths. Each may generate a separate GO.

            sectionSrc_p  = P_Section.DependsOn;              //getUpstreamSourceParameter(P_Section);
            sectionSrc_po = (sectionSrc_p != null) ? sectionSrc_p.parametricObject : null;

            if (sectionSrc_po != null)
            {
                P_Section.polyTree = null;
                AXShape.thickenAndOffset(ref P_Section, sectionSrc_p);
                if (P_Section.reverse)
                {
                    P_Section.doReverse();
                }
            }



            float bay_U = parametricObject.floatValue("bay_U");
            float bay_V = parametricObject.floatValue("bay_V");

            if (bay_U == 0)
            {
                bay_U = .1f;
            }
            if (bay_V == 0)
            {
                bay_V = 10f;
            }

            float margin_U = parametricObject.floatValue("margin_U");



            Vector2 prevV = new Vector2();

            //Vector3 scaler1   = Vector3.one;


            //float margin = 2.5f;

            Vector2 firstPM = new Vector2();
            Vector2 prevVM  = new Vector2();



            AXSpline secSpline = null;
            AXSplineExtrudeGenerator tmpEXSP = null;

            if (sectionSrc_p != null && sectionSrc_p.spline != null && sectionSrc_p.spline.vertCount > 0)
            {
                secSpline = sectionSrc_p.spline;
            }



            tmpEXSP = new AXSplineExtrudeGenerator();

            Material tmp_mat = parametricObject.axMat.mat;

            if (parametricObject.axTex != null)
            {
                tmpEXSP.uScale = parametricObject.axTex.scale.x;
                tmpEXSP.vScale = parametricObject.axTex.scale.y;
                tmpEXSP.uShift = -parametricObject.axTex.shift.x;
                tmpEXSP.vShift = parametricObject.axTex.shift.y;
            }



            float runningU = 0;



            //ip.spline.getAnglesArray();

            //Spline sectionSpline = null;
            //	= new Spline(sectionPath, sectionIsClosed,  sec_p.breakGeom, sec_p.breakNorm);



            GameObject go     = null;
            GameObject planGO = null;

            if (makeGameObjects && !parametricObject.combineMeshes)
            {
                go = ArchimatixUtils.createAXGameObject(parametricObject.Name, parametricObject);
            }



            // BOUNDING

            List <AXMesh> boundingMeshes = new List <AXMesh>();



            // FOR EACH PATH
            for (int path_i = 0; path_i < planPaths.Count; path_i++)
            {
                if (makeGameObjects && !parametricObject.combineMeshes)
                {
                    planGO = ArchimatixUtils.createAXGameObject(parametricObject.Name + "_" + path_i, parametricObject);
                }



                // **** PREPARE EACH SPLINE *** //

                Spline planSpline = planSplines[path_i];

                planSpline.breakAngleCorners = cornerBreakAngle;
                planSpline.shapeState        = P_Plan.shapeState;



                // Create subsplines between each break point
                planSpline.getSmoothSubsplineIndicies(0, maxSegmentLength);


                // ....... DEBUG
                //Pather.printPaths(planPaths);


                planSpline.groupNearBreakAngleVertices(inset * 2);

                if (planSpline.groupedCornerNodes == null || planSpline.groupedCornerNodes.Count == 0)
                {
                    inset = 0;
                }



                // **** PREPARE EACH SPLINE *** //



                Matrix4x4 localPlacement_mx = Matrix4x4.identity;



                //  INSET PLANSWEEPS
                GameObject plansweepGO = null;

                if (sectionSrc_p != null && inset > 0 && planSpline.insetSplines != null)
                {
                    // convert planSpline.insetSplines to Paths
                    Paths insetPaths = AXGeometryTools.Utilities.Splines2Paths(planSpline.insetSplines);

                    AXParameter tmpPlanP = new AXParameter();
                    tmpPlanP.parametricObject = parametricObject;
                    tmpPlanP.paths            = insetPaths;
                    tmpPlanP.Type             = AXParameter.DataType.Shape;
                    tmpPlanP.shapeState       = ShapeState.Open;
                    tmpPlanP.breakGeom        = 0;

                    if (planSpline.insetSplines.Count == 1)
                    {
                        tmpPlanP.shapeState = planSpline.insetSplines[0].shapeState;
                    }

                    topCap = false;
                    botCap = false;

                    plansweepGO = generateFirstPass(initiator_po, makeGameObjects, tmpPlanP, P_Section, Matrix4x4.identity, renderToOutputParameter, false);



                    if (makeGameObjects && !parametricObject.combineMeshes && plansweepGO != null)
                    {
                        plansweepGO.transform.parent = go.transform;
                    }
                }



                AXMesh tmpMesh = null;



                if (planSpline.insetSpanSplines != null && planSpline.insetSpanSplines.Count > 0)
                {
                    //Debug.Log(".....????>> spanSpline.subsplines.Count="+ planSpline.insetSpanSplines.Count + " --- " + planSpline.subsplines.Count );
                    for (int si = 0; si < planSpline.insetSpanSplines.Count; si++)
                    {
                        planSpline.insetSpanSplines[si].setRepeaterTransforms(si, inset, bay);
                    }


                    // SPAN NODES - MESHES ALONG SUBSPLINES
                    if (nodeSrc_p != null && nodeSrc_p.meshes != null)
                    {
                        //int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ?  planSpline.subsplines.Count-1 : planSpline.subsplines.Count;
                        int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ?  planSpline.insetSpanSplines.Count - 1 : planSpline.insetSpanSplines.Count;

                        for (int i = 0; i < endCount; i++)
                        {
                            //SubsplineIndices rsi = planSpline.subsplines[i];
                            Spline spanSpline = planSpline.insetSpanSplines[i];


                            //Debug.Log(i + "||||||||||> " + spanSpline.toString());

                            List <Matrix4x4> nodeMatrices = spanSpline.repeaterNodeTransforms;


                            // on each of these nodes, place a nodePlug instance.
                            bool spanNodesAtBreakCorners = true;

                            int starter = (inset > 0 || spanNodesAtBreakCorners) ? 0 : 1;
                            //Debug.Log("starter="+starter);

                            int ender = (inset > 0 || spanSpline.shapeState == ShapeState.Open || planSpline.subsplines.Count == 1) ? nodeMatrices.Count : nodeMatrices.Count - 1;


                            //Debug.Log("starter="+starter +", ender="+ender + ", nodeMatrices.Count=" + nodeMatrices.Count);

                            //Debug.Log("(inset > 0 && spanNodesAtBreakCorners)="+(inset > 0 && spanNodesAtBreakCorners)+", nodeMatrices.Length="+nodeMatrices.Length+", starter="+starter+", ender="+ender);

                            string this_address = "";

                            if (nodeMatrices != null)
                            {
                                for (int ii = starter; ii < ender; ii++)
                                {
                                    this_address = "node_" + path_i + "_" + i + "_" + ii;

                                    //Debug.Log("this_address="+this_address);
                                    // LOCAL_PLACEMENT

                                    localPlacement_mx = localMatrixFromAddress(RepeaterItem.Node, path_i, i, ii);


                                    // AX_MESHES

                                    for (int mi = 0; mi < nodeSrc_p.meshes.Count; mi++)
                                    {
                                        AXMesh dep_amesh = nodeSrc_p.meshes [mi];
                                        tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix);
                                        tmpMesh.subItemAddress = this_address;
                                        ax_meshes.Add(tmpMesh);
                                    }



                                    // BOUNDING
                                    boundingMeshes.Add(new AXMesh(nodeSrc_po.boundsMesh, localPlacement_mx * nodeSrc_po.generator.localMatrix));

                                    //Debug.Log("boundingMeshes: " + boundingMeshes.Count);

                                    // GAME_OBJECTS

                                    if (nodePlugGO != null && makeGameObjects && !parametricObject.combineMeshes)
                                    {
                                        Matrix4x4  mx     = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment;
                                        GameObject copyGO = (GameObject)GameObject.Instantiate(nodePlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx));


                                        Vector3 newJitterScale = jitterScale + Vector3.one;
                                        copyGO.transform.localScale  = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z);
                                        copyGO.transform.localScale += jitterScale;

                                        AXGameObject axgo = copyGO.GetComponent <AXGameObject>();


                                        if (axgo != null)
                                        {
                                            axgo.consumerAddress = this_address;
                                            //Debug.Log("ADD ADDRESS: " + this_address);
                                        }
                                        copyGO.name = copyGO.name + "_" + this_address;

                                        //Debug.Log("copyGO.name = "+copyGO.name);

                                        copyGO.transform.parent = planGO.transform;
                                    }
                                }
                            }
                        }
                    }                     // \NODE MESHES



                    // CELL NODES - MESHES ALONG SUBSPLINES
                    if (cellSrc_p != null && cellSrc_p.meshes != null)
                    {
                        //int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ?  planSpline.subsplines.Count-1 : planSpline.subsplines.Count;
                        int endCount = (P_Plan != null && P_Plan.shapeState == ShapeState.Open) ?  planSpline.insetSpanSplines.Count - 1 : planSpline.insetSpanSplines.Count;

                        for (int i = 0; i < endCount; i++)
                        {
                            //SubsplineIndices rsi = planSpline.subsplines[i];
                            Spline spanSpline = planSpline.insetSpanSplines[i];

                            spanSpline.setRepeaterTransforms(i, inset, bay);


                            List <Matrix4x4> cellMatrices = spanSpline.repeaterCellTransforms;



                            // on each of these cell, place a nodePlug instance.
                            //bool spanNodesAtBreakCorners = true;

                            int starter = 0;                            //spanNodesAtBreakCorners ? 0 : 1;


                            //int ender     = (inset > 0 || spanNodesAtBreakCorners) ? cellMatrices.Count : cellMatrices.Count-1;
                            int ender = cellMatrices.Count;

                            //Debug.Log("(inset > 0 && spanNodesAtBreakCorners)="+(inset > 0 && spanNodesAtBreakCorners)+", nodeMatrices.Length="+nodeMatrices.Length+", starter="+starter+", ender="+ender);

                            string this_address = "";

                            if (cellMatrices != null)
                            {
                                for (int ii = starter; ii < ender; ii++)
                                {
                                    // ADDRESS

                                    this_address = "cell_" + path_i + "_" + i + "_" + ii;


                                    // LOCAL_PLACEMENT

                                    localPlacement_mx = localMatrixFromAddress(RepeaterItem.Cell, path_i, i, ii);



                                    // AX_MESHES

                                    for (int mi = 0; mi < cellSrc_p.meshes.Count; mi++)
                                    {
                                        AXMesh dep_amesh = cellSrc_p.meshes [mi];
                                        tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix);
                                        tmpMesh.subItemAddress = this_address;
                                        ax_meshes.Add(tmpMesh);
                                    }



                                    // BOUNDING
                                    boundingMeshes.Add(new AXMesh(cellSrc_po.boundsMesh, localPlacement_mx * cellSrc_po.generator.localMatrix));


                                    // GAME_OBJECTS

                                    if (cellPlugGO != null && makeGameObjects && !parametricObject.combineMeshes)
                                    {
                                        Matrix4x4  mx     = localPlacement_mx * cellSrc_po.generator.localMatrixWithAxisRotationAndAlignment;
                                        GameObject copyGO = (GameObject)GameObject.Instantiate(cellPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx));


                                        Vector3 newJitterScale = jitterScale + Vector3.one;
                                        copyGO.transform.localScale  = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z);
                                        copyGO.transform.localScale += jitterScale;

                                        AXGameObject axgo = copyGO.GetComponent <AXGameObject>();


                                        if (axgo != null)
                                        {
                                            axgo.consumerAddress = this_address;
                                            //Debug.Log("ADD ADDRESS: " + this_address);
                                        }
                                        copyGO.name = copyGO.name + "_";                                      // + this_address;

                                        //Debug.Log("copyGO.name = "+copyGO.name);

                                        copyGO.transform.parent = planGO.transform;
                                    }
                                }
                            }
                        }
                    }             // \CELL MESHES
                }                 // \each spanSpline



                // BREAK CORNER MESHES

                if (cornerSrc_p != null && cornerSrc_p.meshes != null)
                {
                    for (int bi = 0; bi < planSpline.breakIndices.Count; bi++)
                    {
                        // ADDRESS

                        string this_address = "corner_" + path_i + "_" + planSpline.breakIndices[bi];

                        // LOCAL_PLACEMENT

                        localPlacement_mx = localMatrixFromAddress(RepeaterItem.Corner, path_i, planSpline.breakIndices[bi]);


                        // AX_MESHES

                        for (int mi = 0; mi < cornerSrc_p.meshes.Count; mi++)
                        {
                            AXMesh dep_amesh = cornerSrc_p.meshes [mi];
                            tmpMesh = dep_amesh.Clone(localPlacement_mx * dep_amesh.transMatrix);
                            tmpMesh.subItemAddress = this_address;
                            ax_meshes.Add(tmpMesh);
                        }



                        // BOUNDING
                        boundingMeshes.Add(new AXMesh(cornerSrc_po.boundsMesh, localPlacement_mx * cornerSrc_po.generator.localMatrix));



                        // GAME_OBJECTS

                        if (cornerPlugGO != null && makeGameObjects && !parametricObject.combineMeshes)
                        {
                            Matrix4x4  mx     = localPlacement_mx * cornerSrc_po.generator.localMatrixWithAxisRotationAndAlignment;
                            GameObject copyGO = (GameObject)GameObject.Instantiate(cornerPlugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx));


                            Vector3 newJitterScale = jitterScale + Vector3.one;
                            copyGO.transform.localScale  = new Vector3(copyGO.transform.localScale.x * newJitterScale.x, copyGO.transform.localScale.y * newJitterScale.y, copyGO.transform.localScale.z * newJitterScale.z);
                            copyGO.transform.localScale += jitterScale;

                            AXGameObject axgo = copyGO.GetComponent <AXGameObject>();
                            if (axgo != null)
                            {
                                axgo.consumerAddress = this_address;
                            }

                            copyGO.name             = copyGO.name + "_" + this_address;
                            copyGO.transform.parent = planGO.transform;
                        }
                    }
                }



                /*
                 * int cells = Mathf.CeilToInt( md/bay_U );
                 * int nby = Mathf.CeilToInt( height/bay_V );
                 *
                 * //Debug.Log ("d="+d+", md="+md);
                 *
                 * float actual_bayx = md/cells;
                 * float actual_bayy = height/nby;
                 *
                 * // CREATE VERSIONS OF INPUT BAY_CENTER MESH(ES) USING BOUNDING BOX
                 * // ******************************************************************************
                 * // someting similar shoud be added to griditerator, stepiterator, and where else?
                 *
                 * // instead of prev, would be better to create a dictionary of bounds and AXMeshes?
                 * if (bay_span_p != null && (prevActuralBayx != actual_bayx || prevActuralBayx != actual_bayy))
                 * {
                 *      // regnerate the input meshes using actual_bayx
                 *      bay_span_p.Parent.setParameterValueByName("uScale", parametricObject.floatValue("uScale"));
                 *      bay_span_p.Parent.setParameterValueByName("vScale", parametricObject.floatValue("vScale"));
                 *      bay_span_p.Parent.setParameterValueByName("uShift", parametricObject.floatValue("uShift"));
                 *      bay_span_p.Parent.setParameterValueByName("vShift", parametricObject.floatValue("vShift"));
                 *
                 *      //bay_span_p.Parent.generateOutputNow (makeGameObjects, parametricObject, true);//, new Vector3(actual_bayx, actual_bayy, margin_th));
                 *
                 * }
                 * // ******************************************************************************
                 *
                 *
                 * // CREATE VERSIONS OF INPUT BAY_CENTER MESH(ES) USING BOUNDING BOX
                 * // ******************************************************************************
                 * // someting similar shoud be added to griditerator, stepiterator, and where else?
                 *
                 * // instead of prev, would be better to create a dictionary of bounds and AXMeshes?
                 * if (node_p != null && (prevActuralBayx != actual_bayx || prevActuralBayx != actual_bayy))
                 * {
                 *      // regnerate the input meshes using actual_bayx
                 *      node_p.Parent.setParameterValueByName("uScale", parametricObject.floatValue("uScale"));
                 *      node_p.Parent.setParameterValueByName("vScale", parametricObject.floatValue("vScale"));
                 *      node_p.Parent.setParameterValueByName("uShift", parametricObject.floatValue("uShift"));
                 *      node_p.Parent.setParameterValueByName("vShift", parametricObject.floatValue("vShift"));
                 *
                 *      //node_p.Parent.generateOutputNow (makeGameObjects, parametricObject, true);//, new Vector3(actual_bayx, actual_bayy, margin_th));
                 *
                 * }
                 * // ******************************************************************************
                 */



                //margin_U = .5f;
                if (margin_U > 0 && planSpline.isClosed)
                {
                    AXSpline connSpline2 = new AXSpline();
                    connSpline2.Push(prevVM);
                    connSpline2.Push(prevV);
                    connSpline2.Push(firstPM);
                    connSpline2.isClosed = false;

                    tmpEXSP.uShift = parametricObject.floatValue("uShift") + (runningU) / tmpEXSP.uScale;

                    Mesh mesh = tmpEXSP.generate(connSpline2, secSpline);
                    ax_meshes.Add(new AXMesh(mesh, Matrix4x4.identity, tmp_mat));
                }


                if (makeGameObjects && !parametricObject.combineMeshes)
                {
                    planGO.transform.parent = go.transform;
                }
            }            // end paths



            //GameObject.DestroyImmediate(bay_spanPlugGO);
            GameObject.DestroyImmediate(cornerPlugGO);
            GameObject.DestroyImmediate(nodePlugGO);
            GameObject.DestroyImmediate(cellPlugGO);



            // FINISH AX_MESHES
            //Debug.Log("finish " + ax_meshes.Count);
            parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter);


            // FINISH BOUNDS

            CombineInstance[] boundsCombinator = new CombineInstance[boundingMeshes.Count];
            for (int bb = 0; bb < boundsCombinator.Length; bb++)
            {
                boundsCombinator[bb].mesh      = boundingMeshes[bb].mesh;
                boundsCombinator[bb].transform = boundingMeshes[bb].transMatrix;
            }
            setBoundsWithCombinator(boundsCombinator);



            // FINISH GAME_OBJECTS

            if (makeGameObjects)
            {
                if (parametricObject.combineMeshes)
                {
                    go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true);
                }

                Matrix4x4 tmx = parametricObject.getLocalMatrix();

                go.transform.rotation   = AXUtilities.QuaternionFromMatrix(tmx);
                go.transform.position   = AXUtilities.GetPosition(tmx);
                go.transform.localScale = parametricObject.getLocalScaleAxisRotated();                        //AXUtilities.GetScale(tmx);

                if (P_Plan.reverse)
                {
                    P_Plan.doReverse();
                }

                if (P_Section != null && P_Section.reverse)
                {
                    P_Section.doReverse();
                }

                return(go);
            }
            else
            {
                // Submit AXMeshes for realtime rendering
                //parametricObject.finishMultiAXMeshAndOutput(ax_meshes, renderToOutputParameter);
                //setBoundaryFromMeshes(ax_meshes);
            }



            if (P_Plan.reverse)
            {
                P_Plan.doReverse();
            }

            if (P_Section != null && P_Section.reverse)
            {
                P_Section.doReverse();
            }

            return(null);
        }
コード例 #7
0
    public static void DrawSpline(AXSpline _spline, Vector2 offset, Color splineColor)
    {
        Handles.BeginGUI();
        Handles.color = splineColor;


        if (_spline != null)
        {
            List <AXSpline> subs = _spline.getSubsplines();
            if (subs != null && subs.Count > 0)
            {
                foreach (AXSpline sub in subs)
                {
                    if (sub.verts == null || sub.vertCount == 0)
                    {
                        continue;
                    }

                    List <AXSpline> parts = sub.getSolidAndHoles();


                    AXSpline contour = parts[0];

                    Color closeColor = splineColor;
                    closeColor.a = splineColor.a / 3;

                    // origin
                    Handles.color = new Color(0, 1, 0, .5f);
                    GUIDrawing.drawSquare(new Vector2(contour.verts[0].x + offset.x, -contour.verts[0].y + offset.y), 2);

                    for (int i = 1; i < contour.vertCount; i++)
                    {
                        Handles.color = splineColor;
                        Handles.DrawLine(new Vector3(contour.verts[i - 1].x + offset.x, -contour.verts[i - 1].y + offset.y, 0), new Vector3(contour.verts[i].x + offset.x, -contour.verts[i].y + offset.y, 0));
                    }
                    Handles.color = closeColor;
                    if (contour.isClosed)
                    {
                        Handles.DrawLine(new Vector3(contour.verts[contour.vertCount - 1].x + offset.x, -contour.verts[contour.vertCount - 1].y + offset.y, 0), new Vector3(contour.verts[0].x + offset.x, -contour.verts[0].y + offset.y, 0));
                    }

                    Handles.color = Color.magenta;
                    for (int pc = 1; pc < parts.Count; pc++)
                    {
                        // origin
                        Handles.color = new Color(0, 1, 0, .5f);
                        GUIDrawing.drawSquare(new Vector2(parts[pc].verts[0].x + offset.x, -parts[pc].verts[0].y + offset.y), 2);


                        Handles.color = Color.cyan;
                        for (int i = 1; i < parts[pc].vertCount; i++)
                        {
                            Handles.DrawLine(new Vector3(parts[pc].verts[i - 1].x + offset.x, -parts[pc].verts[i - 1].y + offset.y, 0), new Vector3(parts[pc].verts[i].x + offset.x, -parts[pc].verts[i].y + offset.y, 0));
                        }
                        Handles.DrawLine(new Vector3(parts[pc].verts[parts[pc].vertCount - 1].x + offset.x, -parts[pc].verts[parts[pc].vertCount - 1].y + offset.y, 0), new Vector3(parts[pc].verts[0].x + offset.x, -parts[pc].verts[0].y + offset.y, 0));
                    }



                    //Debug.Log ("close= "+(contour.vertCount-1));
                }
            }
        }


        Handles.EndGUI();
    }
コード例 #8
0
        public static Mesh triangulate(AXSpline poly, float height, AXTexCoords tex)
        {
            // poly has verts that are delimeted by 8888888 for holes

            //Debug.Log ("F");
            // 1. transpose points to poly2tri structures
            // 2. create mesh
            Polygon _polygon = null;

            List <AXSpline> parts = poly.getSolidAndHoles();

            if (parts == null || parts.Count == 0)
            {
                return(null);
            }

            // CONTOUR
            AXSpline contour = parts[0];

            List <PolygonPoint> _points = new List <PolygonPoint>();

            for (int ii = 0; ii < contour.vertCount; ii++)
            {
                _points.Add(new PolygonPoint((double)contour.verts[ii].x, (double)contour.verts[ii].y));
            }


            // POLYGON
            if (_points.Count >= 3)
            {
                _polygon = new Polygon(_points);


                // HOLES?
                if (parts.Count > 1)
                {
                    for (int i = 1; i < parts.Count; i++)
                    {
                        List <PolygonPoint> _holepoints = new List <PolygonPoint>();
                        for (int ii = 0; ii < parts[i].vertCount; ii++)
                        {
                            _holepoints.Add(new PolygonPoint((double)parts[i].verts[ii].x, (double)parts[i].verts[ii].y));
                        }
                        if (_holepoints.Count >= 3)
                        {
                            Polygon _hole = new Polygon(_holepoints);
                            _polygon.AddHole(_hole);
                        }
                    }
                }
            }

            // populate the polygon triangles
            if (_polygon != null)
            {
                P2T.Triangulate(_polygon);

                return(polygon2mesh(_polygon, tex));
            }
            return(null);
        }
コード例 #9
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);
        }
コード例 #10
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);
        }
コード例 #11
0
 // Constructors
 public Mesh generate(AXSpline _planSpline, AXSpline _sectionSpline)
 {
     return(generate(_planSpline, _sectionSpline, 0f, 0f));
 }
コード例 #12
0
    public Mesh generate(AXSpline _sectionSpline, float radius, int segs, float begAng, float endAng)
    {
        if (_sectionSpline == null || _sectionSpline.verts == null || _sectionSpline.verts.Length == 0 || float.IsNaN(_sectionSpline.verts[0].x))
        {
            return(new Mesh());
        }

        if (radius <= 0)
        {
            radius = .01f;
        }

        //Debug.Log (float.IsNaN(_sectionSpline.verts[0].x));
        //return new Mesh();

        if (segs < 3)
        {
            segs = 3;
        }

        // section spline
        AXSpline sectionSpline;

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

        // Cap Splines
        AXSpline3 planSplineBegCap = new AXSpline3();
        AXSpline3 planSplineEndCap = new AXSpline3();

        AXSpline3 secSplineBegCap = new AXSpline3();
        AXSpline3 secSplineEndCap = new AXSpline3();


        int index = 0;


        float arcDegs  = endAng - begAng;
        float deltaAng = arcDegs / segs;


        Vector3 scaler = new Vector3((1 / Mathf.Cos(Mathf.Deg2Rad * deltaAng / 2)), 1, 1);

        bool circleIsClosed          = false;
        int  circleAdjustedVertCount = segs + 1;

        if (arcDegs == 360)
        {
            circleIsClosed = true;
        }

        bool circleIsAccute = false;

        if (deltaAng > breakAngle)
        {
            circleIsAccute           = true;
            circleAdjustedVertCount += (circleAdjustedVertCount - 2);
        }


        float segLength = 2 * radius * Mathf.Sin(Mathf.Deg2Rad * deltaAng / 2);
        //Debug.Log ("segLength = " + segLength);

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

        //float[] sec_Angles                    = sectionSpline.getAnglesArray();
        int sec_AdjustedVertsCount = sectionSpline.getAllocateVertsCt();


        int fabricVertCount = circleAdjustedVertCount * sec_AdjustedVertsCount;
        //Debug.Log ("fabricVertCount="+fabricVertCount);
        int begCapVertCount = 0;
        int endCapVertCount = 0;


        if (begCap)
        {
            if (circleIsClosed)
            {
                //if(circleIsAccute) fabricVertCount += circleAdjustedVertCount;
                begCapVertCount = segs;
            }
            else if (sectionSpline.isClosed)
            {
                //if(sectionSpline.closeJointIsAcute()) fabricVertCount += sec_AdjustedVertsCount;
                begCapVertCount = sectionSpline.vertCount;
            }
        }
        if (endCap)
        {
            if (circleIsClosed)
            {
                //if(circleIsAccute) fabricVertCount += circleAdjustedVertCount;
                endCapVertCount = segs;
            }
            else if (sectionSpline.isClosed)
            {
                //if(sectionSpline.closeJointIsAcute()) fabricVertCount += sec_AdjustedVertsCount;
                endCapVertCount = sectionSpline.vertCount;
            }
        }

        int totalVertCount = fabricVertCount + begCapVertCount + endCapVertCount;

        int faceCount = segs * (sectionSpline.vertCount - 1);

        int facesTriangleCount = 3 * 2 * faceCount;

        int begTriangleCount = (begCap) ? (3 * (begCapVertCount - 2)) : 0;
        int endTriangleCount = (endCap) ? (3 * (endCapVertCount - 2)) : 0;


        int totalTriangCount = facesTriangleCount + begTriangleCount + endTriangleCount;

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

        float u = 0.0f;
        float v = 0.0f;



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


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

        int ribCounter  = 0;
        int vertCursor  = 0;
        int vertCursor0 = 0;

        if (arcDegs == 360)
        {
            //endAng = 360-deltaAng;
        }

        // FOR EACH VERT IN ARC
        // For arc vert, find the transformation matrix withwhich to transform the section as a "rib"
        // Then traverse the section verts and mutiply them by the matrix.
        // If arc is open (less than 360 degs), then the first and last ribs make the caps.

        float theta_i = 0;

        for (int i = 0; i <= segs; i++)
        {
            theta_i = i * deltaAng + begAng;

            u = uShift + i * segLength / uScale;

            vertCursor = ribCounter * sec_AdjustedVertsCount;

            Vector2 arc_vert = new Vector2(radius * Mathf.Cos(Mathf.Deg2Rad * theta_i), radius * Mathf.Sin(Mathf.Deg2Rad * theta_i));

            Matrix4x4  transMatrix = Matrix4x4.identity;
            Vector3    translation = new Vector3(arc_vert.x, 0, arc_vert.y);
            Quaternion rotation    = Quaternion.Euler(new Vector3(0, -theta_i, 0));;

            transMatrix.SetTRS(translation, rotation, scaler);



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

            // FOR EACH POINT IN SECTION SPLINE (sectionSpline)

            int thisRibVertCursor = 0;

            Vector3 vert0 = Vector3.zero;
            Vector3 vert  = Vector3.zero;


            //u = 0.0f;
            v = 0.0f;

            int j;

            // **  A RIB  **
            // **  each spline vert
            // **       - transform by plan location, rotation and scale
            for (j = 0; j < sectionSpline.vertCount; j++)
            {
                /* **** VERT IS CREATED *** */
                vert = transMatrix.MultiplyPoint(new Vector3(-sectionSpline.verts[j].y, sectionSpline.verts[j].x, 0));

                if (j == 0)
                {
                    vert0 = vert;
                }
                //if (j>0)
                v = vShift + sectionSpline.curve_distances[j] / vScale;


                // BUILDUP CAP POLYGON VERTS everytime you start and finish a sec rib.
                Vector3 thisVert = new Vector3(vert.x, vert.y, vert.z);

                if (circleIsClosed)
                {
                    // circle is closed
                    if (begCap && j == 0)
                    {
                        planSplineBegCap.Push(thisVert);
                    }

                    if (endCap && j == (sectionSpline.vertCount - 1))
                    {
                        planSplineEndCap.Push(thisVert);
                    }
                }
                else if (sectionSpline.isClosed)
                {
                    // circle is open --  end caps
                    if (begCap && theta_i == begAng)
                    {
                        secSplineBegCap.Push(thisVert);
                    }

                    if (endCap && theta_i == endAng)
                    {
                        secSplineEndCap.Push(thisVert);
                    }
                }



                // ** ADD THIS VERT TO MESH VERTICES **
                vertices[vertCursor + thisRibVertCursor] = vert;
                uv[vertCursor + thisRibVertCursor]       = new Vector2(u, v);

                thisRibVertCursor++;

                if (sectionSpline.jointIsAcute(j))
                {
                    // ** ADD THIS VERT TO MESH VERTICES (AGAIN) **    (and restart the u?)
                    vertices[vertCursor + thisRibVertCursor] = vert;
                    uv[vertCursor + thisRibVertCursor]       = new Vector2(u, v);

                    thisRibVertCursor++;
                }
            }

            if (sectionSpline.isClosed)
            {
                if (sectionSpline.closeJointIsAcute())
                {
                    //float d = Vector3.Distance(preVert, vert0);
                    //Debug.Log (d);
                    //u += d/100.0f;
                    //Debug.Log ("u="+u);
                    vertices[vertCursor + thisRibVertCursor] = vert0;
                    uv[vertCursor + thisRibVertCursor]       = new Vector2(u, v);
                }
            }



            // GET READY FOR NEXT PLAN VERT, ie, RIB
            ribCounter++;

            if (i > 0 && i < segs && circleIsAccute)
            {
                // ADD RIB -----------------------------------------------------------------------------
                for (var n = 0; n < sec_AdjustedVertsCount; n++)
                {
                    vertices[vertCursor + n + sec_AdjustedVertsCount] = vertices[vertCursor + n];
                    uv[vertCursor + n + sec_AdjustedVertsCount]       = uv[vertCursor + n];
                }
                u = 0.0f;

                ribCounter++;
            }
        }



        vertCursor = ribCounter * sec_AdjustedVertsCount;

        //int tmp = vertCursor-1;

        /*
         * if (i == segs && circleIsClosed && circleIsAccute) {
         *      // ADD RIB ------------------------------------- DUPLICATE FIRST RIB --------------------
         *      for(int n=0; n<sec_AdjustedVertsCount; n++) {
         *              vertices[vertCursor+n]                                  = vertices[n];
         *              uv[vertCursor+n]                                        = new Vector2(uScale, uv[n].y);
         *      }
         *
         * }
         */



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

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

        int leftRib = 0;


        // FOREACH PLAN NODE.......
        for (int i = 0; i < segs; i++)
        {
            vertCursor  = leftRib * sec_AdjustedVertsCount;
            vertCursor0 = vertCursor;

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

                LRib_L = 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;
                }

                if (circleIsClosed && i == segs && !circleIsAccute)
                {
                    // use rib0
                    RRib_L = LRib_L - fabricVertCount + sec_AdjustedVertsCount;
                    RRib_U = LRib_U - fabricVertCount + sec_AdjustedVertsCount;;
                }
                else
                {
                    // use next rib's points
                    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;

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


            // GO TO NEXT SEGMENT
            leftRib++;
            if (i < (segs + 1) && circleIsAccute)
            {
                leftRib++;
            }
        }



        //for (int l = 0; l<vertices.Length; l++)
        //	Debug.Log (l+": " + vertices[l]);



        // CAPS ////////////////////////

        if (isCapped)
        {
            //int vertCount = fabricVertCount;


            //int[] indices;
            //Vector2[] vertices2D;



            if ((botCap || topCap) && circleIsClosed && !sectionSpline.isClosed)
            {
                // planSpline CAPS

                // BOT_CAP

                /*
                 * if (botCap) {
                 *      // BOT_CAP VERTS
                 *
                 *      for (int i=0; i<planSplineBegCap.vertCount; i++) {
                 *              vertices[vertCount+i] = new Vector3(planSplineBegCap.verts[i].x, planSplineBegCap.verts[i].y, planSplineBegCap.verts[i].z);
                 *              uv		[vertCount+i] = new Vector2 (uShift+planSplineBegCap.verts[i].x/uScale, vShift+planSplineBegCap.verts[i].z/vScale);
                 *      }
                 *
                 *      // INDICES
                 *
                 *      AXSpline begCapSlpine = new AXSpline(planSplineBegCap.getVertsAsVector2s());
                 *
                 *
                 *      vertices2D = begCapSlpine.getVertsAsVector2s();
                 *
                 *
                 *      tr = new Triangulator(vertices2D);
                 *      indices = tr.Triangulate();
                 *
                 *      // flip
                 *      int[] indicesFlipped = new int[indices.Length];
                 *      int c = 0;
                 *      for(int i=(indices.Length-1); i >= 0; i--)
                 *              indicesFlipped[c++] = indices[i];
                 *
                 *
                 *      for(int i=0; i<indicesFlipped.Length; i++)
                 *              triangles[index++] = indicesFlipped[i] + vertCount;
                 *
                 *
                 *      vertCount += planSplineBegCap.vertCount;
                 *
                 * }
                 *
                 *
                 *
                 * // TOP CAP
                 *
                 * if (topCap) {
                 *      // TOP CAP VERTS
                 *
                 *      for (int i=0; i<planSplineEndCap.vertCount; i++) {
                 *              vertices[vertCount+i] = new Vector3(planSplineEndCap.verts[i].x, planSplineEndCap.verts[i].y, planSplineEndCap.verts[i].z);
                 *              uv		[vertCount+i] = new Vector2 (planSplineEndCap.verts[i].x/uScale, planSplineEndCap.verts[i].z/vScale);
                 *      }
                 *
                 *      // INDICES
                 *      AXSpline endCapSlpine = new AXSpline(planSplineEndCap.getVertsAsVector2s());
                 *      vertices2D = endCapSlpine.getVertsAsVector2s();
                 *
                 *      tr = new Triangulator(vertices2D);
                 *      indices = tr.Triangulate();
                 *      for(int i=0; i<indices.Length; i++)
                 *      {
                 *              triangles[index++] = indices[i] + vertCount;
                 *      }
                 *      vertCount += planSplineEndCap.vertCount;
                 * }
                 *
                 *
                 *
                 *
                 */
            }
            else if (!circleIsClosed && sectionSpline.isClosed)
            {
                // SS CAPS
                // SEC BEG CAP VERTS

                // The indices are independent of where the sec points are in space
                //vertices2D = sectionSpline.getVertsAsVector2s();

                /*
                 * tr = new Triangulator(vertices2D);
                 * indices = tr.Triangulate();
                 *
                 *
                 *
                 * // SEC BEG CAP
                 * if (begCap)
                 * {
                 *      for (int i=0; i<secSplineBegCap.vertCount; i++) {
                 *              vertices[vertCount+i] = new Vector3(secSplineBegCap.verts[i].x, secSplineBegCap.verts[i].y, secSplineBegCap.verts[i].z);
                 *              uv		[vertCount+i] = new Vector2 (secSplineBegCap.verts[i].x/uScale, secSplineBegCap.verts[i].y/vScale);
                 *      }
                 *      for(int i=0; i<indices.Length; i++)
                 *              triangles[index++] = indices[i] + vertCount;
                 *
                 *      vertCount += secSplineBegCap.vertCount;
                 * }
                 *
                 *
                 * // SEC END CAP
                 * if (endCap)
                 * {
                 *      for (int i=0; i<secSplineEndCap.vertCount; i++) {
                 *              vertices[vertCount+i] = new Vector3(secSplineEndCap.verts[i].x, secSplineEndCap.verts[i].y, secSplineEndCap.verts[i].z);
                 *              uv		[vertCount+i] = new Vector2 (secSplineEndCap.verts[i].x/uScale, secSplineEndCap.verts[i].y/vScale);
                 *      }
                 *      for(int i=indices.Length-1; i>=0; i--)
                 *              triangles[index++] = indices[i] + vertCount;
                 *
                 *      vertCount += secSplineBegCap.vertCount;
                 * }
                 *
                 */
            }
        }



        Mesh mesh = new Mesh();

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

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



        // adjust normals for first and last vert
        if (!circleIsAccute)
        {
            //Debug.Log ("adjust normals");
            Vector3[] norms = mesh.normals;


            Quaternion rotation0 = Quaternion.Euler(0, deltaAng / 2, 0);
            Quaternion rotationN = Quaternion.Euler(0, -deltaAng / 2, 0);
            int        lastRibV0 = (circleAdjustedVertCount - 1) * sec_AdjustedVertsCount;

            for (int jj = 0; jj < sec_AdjustedVertsCount; jj++)
            {
                // first rib
                norms[jj] = rotation0 * norms[jj];

                // last rib
                norms[lastRibV0 + jj] = rotationN * norms[lastRibV0 + jj];
            }



            mesh.normals = norms;
        }



        return(mesh);
    }
コード例 #13
0
    // Constructors


    public Mesh generate(AXSpline _sectionSpline, float radius, int segs)
    {
        return(generate(_sectionSpline, radius, segs, 0, 360));
    }