예제 #1
0
        /// <summary>
        /// Create collections of groups sharing same Material ID. Also ensures collection's MaterialID is valid!
        /// </summary>
        /// <param name="groups"></param>
        /// <returns></returns>
        List <SamplePointsMaterialGroupCollection> getMaterialIDGroups(CGVolume volume)
        {
            var matCollections = new Dictionary <int, SamplePointsMaterialGroupCollection>();

            SamplePointsMaterialGroupCollection col;

            for (int g = 0; g < volume.CrossMaterialGroups.Count; g++)
            {
                int matID = Mathf.Min(volume.CrossMaterialGroups[g].MaterialID, MaterialCount - 1);
                if (!matCollections.TryGetValue(matID, out col))
                {
                    col            = new SamplePointsMaterialGroupCollection();
                    col.MaterialID = matID;
                    matCollections.Add(matID, col);
                }
                col.Add(volume.CrossMaterialGroups[g]);
            }

            var res = new List <SamplePointsMaterialGroupCollection>();

            foreach (var item in matCollections.Values)
            {
                item.CalculateAspectCorrection(volume, MaterialSetttings[item.MaterialID]);
                res.Add(item);
            }
            return(res);
        }
예제 #2
0
        void build(CGVMesh vmesh, CGVolume vol, IntRegion subset)
        {
            // Because each Material ID forms a submesh
            // Do we need to calculate localU?
            if (GenerateUV)
            {
                System.Array.Resize <Vector2>(ref vmesh.UV, vmesh.Count);
            }
            // Prepare Submeshes
            prepareSubMeshes(vmesh, groupsByMatID, subset.Length, ref m_Material);
            //prepareSubMeshes(vmesh, groupsByMatID, vol.Count - 1, ref m_Material);

            SamplePointsMaterialGroupCollection col;
            SamplePointsMaterialGroup           grp;

            int vtIdx = 0;

            int[] triIdx = new int[groupsByMatID.Count]; // triIdx for each submesh
            // for all sample segments (except the last) along the path, create Triangles to the next segment
            for (int sample = subset.From; sample < subset.To; sample++)
            {
                // for each submesh (collection)
                for (int subMeshIdx = 0; subMeshIdx < groupsByMatID.Count; subMeshIdx++)
                {
                    col = groupsByMatID[subMeshIdx];
                    // create UV and triangles for all groups in submesh
                    for (int g = 0; g < col.Count; g++)
                    {
                        grp = col[g];
                        if (GenerateUV)
                        {
                            createMaterialGroupUV(ref vmesh, ref vol, ref grp, col.MaterialID, col.AspectCorrection, sample, vtIdx);
                        }
                        for (int p = 0; p < grp.Patches.Count; p++)
                        {
                            createPatchTriangles(ref vmesh.SubMeshes[subMeshIdx].Triangles, ref triIdx[subMeshIdx], vtIdx + grp.Patches[p].Start, grp.Patches[p].Count, vol.CrossSize, ReverseTriOrder);
                        }
                    }
                }
                vtIdx += vol.CrossSize;
            }

            // UV for last path segment
            if (GenerateUV)
            {
                // for each submesh (collection)
                for (int subMeshIdx = 0; subMeshIdx < groupsByMatID.Count; subMeshIdx++)
                {
                    col = groupsByMatID[subMeshIdx];
                    // create triangles
                    for (int g = 0; g < col.Count; g++)
                    {
                        grp = col[g];
                        createMaterialGroupUV(ref vmesh, ref vol, ref grp, col.MaterialID, col.AspectCorrection, subset.To, vtIdx);
                    }
                }
            }
        }
예제 #3
0
 public void GetLengths(CGVolume volume, out float worldLength, out float uLength)
 {
     worldLength = 0;
     for (int v = StartVertex; v < EndVertex; v++)
     {
         worldLength += (volume.Vertex[v + 1] - volume.Vertex[v]).magnitude;
     }
     uLength = volume.CrossMap[EndVertex] - volume.CrossMap[StartVertex];
 }
예제 #4
0
        /*! \cond PRIVATE */

        Matrix4x4 getMat(CGVolume vol, int index, bool inverse)
        {
            if (inverse)
            {
                var Q = Quaternion.LookRotation(vol.Direction[index], vol.Normal[index]);
                return(Matrix4x4.TRS(vol.Position[index], Q, Vector3.one));
            }
            else
            {
                var Q = Quaternion.Inverse(Quaternion.LookRotation(vol.Direction[index], vol.Normal[index]));
                return(Matrix4x4.TRS(-(Q * vol.Position[index]), Q, Vector3.one));
            }
        }
예제 #5
0
        /// <summary>
        /// trs vertices to eliminate Z and eleminate duplicates
        /// </summary>
        ContourVertex[] make2DSegment(CGVolume vol, int index)
        {
            Matrix4x4 m   = getMat(vol, index, false);
            int       idx = vol.GetSegmentIndex(index);

            ContourVertex[] res = new ContourVertex[vol.CrossSize];
            for (int i = 0; i < vol.CrossSize; i++)
            {
                res[i] = m.MultiplyPoint(vol.Vertex[idx + i]).ContourVertex();
            }

            return(res);
        }
예제 #6
0
파일: CGClasses.cs 프로젝트: ATL3Y/Ded_Game
        public void CalculateAspectCorrection(CGVolume volume, CGMaterialSettingsEx matSettings)
        {
            float totalLength = 0;
            float totalULength = 0;
            float l, u;

            for (int g = 0; g < Count; g++)
            {
                this[g].GetLengths(volume, out l, out u);
                totalLength  += l;
                totalULength += u;
            }

            AspectCorrection = volume.Length / (totalLength / totalULength);

            /*
             * float crossLength = volume.GetCrossLength(0);
             * for (int g = 0; g < Count; g++)
             * {
             *  // Calculate local U
             *  if (matSettings.LocalU)
             *      this[g].CalculateLocalINTERNAL(volume);
             *  // Aspect correction
             *  this[g].AspectCorrectionU = 1;
             *  this[g].AspectCorrectionV = 1;
             *  switch (matSettings.KeepAspect)
             *  {
             *      case CGKeepAspectMode.ScaleU:
             *          if (matSettings.LocalU)
             *               this[g].AspectCorrectionU = this[g].LocalLength / volume.Length;
             *          else
             *              this[g].AspectCorrectionU = crossLength / volume.Length;
             *          break;
             *      case CGKeepAspectMode.ScaleV:
             *          if (matSettings.LocalU)
             *              this[g].AspectCorrectionV = volume.Length / this[g].LocalLength;
             *          else
             *              this[g].AspectCorrectionV = volume.Length / crossLength;
             *          break;
             *  }
             * }
             *
             *
             */
        }
예제 #7
0
 public void CalculateAspectCorrection(CGVolume volume, CGMaterialSettingsEx matSettings)
 {
     if (matSettings.KeepAspect == CGKeepAspectMode.Off)
     {
         AspectCorrection = 1;
     }
     else
     {
         float totalLength = 0;
         float totalULength = 0;
         float l, u;
         for (int g = 0; g < Count; g++)
         {
             this[g].GetLengths(volume, out l, out u);
             totalLength  += l;
             totalULength += u;
         }
         AspectCorrection = volume.Length / (totalLength / totalULength);
     }
 }
예제 #8
0
        // OPTIMIZE: Store array of U values and just copy them
        void createMaterialGroupUV(ref CGVMesh vmesh, ref CGVolume vol, ref SamplePointsMaterialGroup grp, int matIndex, float grpAspectCorrection, int sample, int baseVertex)
        {
            var mat = m_MaterialSettings[matIndex];

            float v = mat.UVOffset.y + vol.F[sample] * mat.UVScale.y * grpAspectCorrection;
            float u;
            int   hi = grp.EndVertex;

            for (int c = grp.StartVertex; c <= hi; c++)
            {
                u = mat.UVOffset.x + vol.CrossMap[c] * mat.UVScale.x;

                if (mat.SwapUV)
                {
                    vmesh.UV[baseVertex + c] = new Vector2(v, u);
                }
                else
                {
                    vmesh.UV[baseVertex + c] = new Vector2(u, v);
                }
            }
        }
예제 #9
0
        /// <summary>
        /// trs vertices to eliminate Z and eleminate duplicates
        /// </summary>
        Vector3[] make2DSegment(CGVolume vol, int index)
        {
            Matrix4x4 m = getMat(vol, index, false);

            Vector3[]         vertices = vol.GetSegmentVertices(index);
            HashSet <Vector3> hash     = new HashSet <Vector3>();
            List <Vector3>    res      = new List <Vector3>(vertices.Length);

            Vector3 v;
            Vector3 l = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

            for (int i = 0; i < vertices.Length; i++)
            {
                v = m.MultiplyPoint(vertices[i]);
                if ((v - l).sqrMagnitude > 0.001f && hash.Add(v))
                {
                    res.Add(v);
                }
                l = v;
            }

            return(res.ToArray());
        }
예제 #10
0
 Matrix4x4 getMat(CGVolume vol, int index, bool inverse)
 {
     if (inverse)
     {
         var Q = Quaternion.LookRotation(vol.Direction[index], vol.Normal[index]);
         return Matrix4x4.TRS(vol.Position[index], Q, Vector3.one);
     }
     else
     {
         var Q = Quaternion.Inverse(Quaternion.LookRotation(vol.Direction[index], vol.Normal[index]));
         return Matrix4x4.TRS(-(Q * vol.Position[index]), Q, Vector3.one);
     }
 }
예제 #11
0
        // OPTIMIZE: Store array of U values and just copy them
        void createMaterialGroupUV(ref CGVMesh vmesh, ref CGVolume vol, ref SamplePointsMaterialGroup grp, int matIndex, float grpAspectCorrection, int sample, int baseVertex)
        {
            var mat = m_MaterialSettings[matIndex];

            float v = mat.UVOffset.y + vol.F[sample] * mat.UVScale.y * grpAspectCorrection;
            float u;
            int hi = grp.EndVertex;

            for (int c = grp.StartVertex; c <= hi; c++)
            {
                u = mat.UVOffset.x + vol.CrossMap[c] * mat.UVScale.x;

                if (mat.SwapUV)
                    vmesh.UV[baseVertex+c] = new Vector2(v, u);
                else
                    vmesh.UV[baseVertex+c] = new Vector2(u, v);
            }
        }
예제 #12
0
        /// <summary>
        /// Create collections of groups sharing same Material ID. Also ensures collection's MaterialID is valid!
        /// </summary>
        /// <param name="groups"></param>
        /// <returns></returns>
        List<SamplePointsMaterialGroupCollection> getMaterialIDGroups(CGVolume volume)
        {
            
            var matCollections = new Dictionary<int, SamplePointsMaterialGroupCollection>();

            SamplePointsMaterialGroupCollection col;

            for (int g = 0; g < volume.CrossMaterialGroups.Count;g++)
            {
                int matID = Mathf.Min(volume.CrossMaterialGroups[g].MaterialID,MaterialCount-1);
                if (!matCollections.TryGetValue(matID,out col))
                {
                    col = new SamplePointsMaterialGroupCollection();
                    col.MaterialID = matID;
                    matCollections.Add(matID,col);
                }
                col.Add(volume.CrossMaterialGroups[g]);
            }

            var res = new List<SamplePointsMaterialGroupCollection>();
            
            foreach (var item in matCollections.Values)
            {
                item.CalculateAspectCorrection(volume, MaterialSetttings[item.MaterialID]);
                res.Add(item);
            }
            return res;
            
        }
예제 #13
0
        /*! \endcond */
        #endregion

        #region ### Public Methods ###

        public override void Refresh()
        {
            base.Refresh();
            CGVolume vol   = InVolume.GetData <CGVolume>();
            var      holes = InVolumeHoles.GetAllData <CGVolume>();

            if (vol)
            {
                bool genStart = (StartCap == CGYesNoAuto.Yes || (StartCap == CGYesNoAuto.Auto && !vol.Seamless));
                bool genEnd   = (EndCap == CGYesNoAuto.Yes || (EndCap == CGYesNoAuto.Auto && !vol.Seamless));

                if (!genStart && !genEnd)
                {
                    OutVMesh.SetData(null);
                    return;
                }

                var       vmesh   = new CGVMesh();
                Vector3[] vtStart = new Vector3[0];
                Vector3[] vtEnd   = new Vector3[0];



                Polygon pOuter;

                vmesh.AddSubMesh(new CGVSubMesh());
                CGVSubMesh submesh = vmesh.SubMeshes[0];
                Vector3[]  points;

                if (genStart)
                {
                    #region --- Start Cap ---
                    points = make2DSegment(vol, 0);
                    if (points.Length < 3)
                    {
                        OutVMesh.SetData(null);
                        UIMessages.Add("Cross has <3 Vertices: Can't create Caps!");
                        return;
                    }

                    pOuter = new Polygon(points);

                    for (int h = 0; h < holes.Count; h++)
                    {
                        points = make2DSegment(holes[h], 0);
                        if (points.Length < 3)
                        {
                            OutVMesh.SetData(null);
                            UIMessages.Add("Hole Cross has <3 Vertices: Can't create Caps!");
                            return;
                        }
                        pOuter.AddHole(new Polygon(points));
                    }

                    try
                    {
                        P2T.Triangulate(pOuter);
                    }
                    catch (System.Exception e)
                    {
                        Debug.LogException(e);
                        OutVMesh.SetData(null);
                        return;
                    }

                    submesh.Material = StartMaterial;
                    pOuter.GetResults(out vtStart, out submesh.Triangles, ReverseTriOrder);
                    vmesh.Vertex = applyMat(vtStart, getMat(vol, 0, true));
                    if (GenerateUV)
                    {
                        vmesh.UV = new Vector2[vtStart.Length];
                        applyUV(vtStart, ref vmesh.UV, 0, vtStart.Length, pOuter.Bounds.Bounds, StartMaterialSettings);
                    }



                    #endregion
                }

                if (genEnd)
                {
                    #region --- End Cap ---

                    points = make2DSegment(vol, vol.Count - 1);
                    if (points.Length < 3)
                    {
                        OutVMesh.SetData(null);
                        UIMessages.Add("Cross has <3 Vertices: Can't create Caps!");
                        return;
                    }
                    pOuter = new Polygon(points);

                    for (int h = 0; h < holes.Count; h++)
                    {
                        points = make2DSegment(holes[h], holes[h].Count - 1);
                        if (points.Length < 3)
                        {
                            OutVMesh.SetData(null);
                            UIMessages.Add("Hole Cross has <3 Vertices: Can't create Caps!");
                            return;
                        }
                        pOuter.AddHole(new Polygon(points));
                    }

                    try
                    {
                        P2T.Triangulate(pOuter);
                    }
                    catch (System.Exception e)
                    {
                        Debug.LogException(e);
                        OutVMesh.SetData(null);
                        return;
                    }

                    int[] tris;
                    pOuter.GetResults(out vtEnd, out tris, !ReverseTriOrder, vtStart.Length);

                    vmesh.Vertex = vmesh.Vertex.AddRange <Vector3>(applyMat(vtEnd, getMat(vol, vol.Count - 1, true)));

                    if (!CloneStartCap && StartMaterial != EndMaterial)
                    {
                        vmesh.AddSubMesh(new CGVSubMesh(tris, EndMaterial));
                    }
                    else
                    {
                        submesh.Material  = StartMaterial;
                        submesh.Triangles = submesh.Triangles.AddRange <int>(tris);
                    }

                    if (GenerateUV)
                    {
                        System.Array.Resize <Vector2>(ref vmesh.UV, vmesh.UV.Length + vtEnd.Length);
                        applyUV(vtEnd, ref vmesh.UV, vtStart.Length, vtEnd.Length, pOuter.Bounds.Bounds, (CloneStartCap) ? StartMaterialSettings : EndMaterialSettings);
                    }


                    #endregion
                }


                OutVMesh.SetData(vmesh);
            }
        }
예제 #14
0
        /*! \cond PRIVATE */

        void prepare(CGVolume vol)
        {
            // We have groups (different MaterialID) of patches (e.g. by Hard Edges).
            // Create Collection of groups sharing the same material ID
            groupsByMatID = getMaterialIDGroups(vol);
        }
예제 #15
0
        /// <summary>
        /// trs vertices to eliminate Z and eleminate duplicates
        /// </summary>
        Vector3[] make2DSegment(CGVolume vol, int index)
        {
            Matrix4x4 m = getMat(vol, index, false);
            Vector3[] vertices = vol.GetSegmentVertices(index);
            HashSet<Vector3> hash = new HashSet<Vector3>();
            List<Vector3> res = new List<Vector3>(vertices.Length);

            Vector3 v;
            Vector3 l = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            for (int i = 0; i < vertices.Length; i++)
            {
                v = m.MultiplyPoint(vertices[i]);
                if ((v - l).sqrMagnitude > 0.001f && hash.Add(v))
                    res.Add(v);
                l = v;
            }
            
            return res.ToArray();
        }
예제 #16
0
        void build(CGVMesh vmesh, CGVolume vol, IntRegion subset)
        {

            // Because each Material ID forms a submesh
            // Do we need to calculate localU?
            if (GenerateUV)
            {
                System.Array.Resize<Vector2>(ref vmesh.UV, vmesh.Count);

            }
            // Prepare Submeshes
            prepareSubMeshes(vmesh, groupsByMatID, subset.Length, ref m_Material);
            //prepareSubMeshes(vmesh, groupsByMatID, vol.Count - 1, ref m_Material);

            SamplePointsMaterialGroupCollection col;
            SamplePointsMaterialGroup grp;

            int vtIdx = 0;
            int[] triIdx = new int[groupsByMatID.Count]; // triIdx for each submesh
            // for all sample segments (except the last) along the path, create Triangles to the next segment 
            for (int sample = subset.From; sample < subset.To; sample++)
            {
                // for each submesh (collection)
                for (int subMeshIdx = 0; subMeshIdx < groupsByMatID.Count; subMeshIdx++)
                {
                    col = groupsByMatID[subMeshIdx];
                    // create UV and triangles for all groups in submesh
                    for (int g = 0; g < col.Count; g++)
                    {
                        grp = col[g];
                        if (GenerateUV)
                            createMaterialGroupUV(ref vmesh, ref vol, ref grp, col.MaterialID, col.AspectCorrection, sample, vtIdx);
                        for (int p = 0; p < grp.Patches.Count; p++)
                            createPatchTriangles(ref vmesh.SubMeshes[subMeshIdx].Triangles, ref triIdx[subMeshIdx], vtIdx+grp.Patches[p].Start, grp.Patches[p].Count, vol.CrossSize, ReverseTriOrder);

                    }
                }
                vtIdx += vol.CrossSize;
            }

            // UV for last path segment
            if (GenerateUV)
            {
                // for each submesh (collection)
                for (int subMeshIdx = 0; subMeshIdx < groupsByMatID.Count; subMeshIdx++)
                {
                    col = groupsByMatID[subMeshIdx];
                    // create triangles
                    for (int g = 0; g < col.Count; g++)
                    {
                        grp = col[g];
                        createMaterialGroupUV(ref vmesh, ref vol, ref grp, col.MaterialID, col.AspectCorrection, subset.To, vtIdx);
                        
                    }
                }
            }
        }
예제 #17
0
        /*! \endcond */
        #endregion

        #region ### Public Methods ###

        public override void Refresh()
        {
            base.Refresh();
            if (Length == 0)
            {
                Reset();
            }
            else
            {
                var req = new List <CGDataRequestParameter>();
                req.Add(new CGDataRequestRasterization(this.From, this.Length, CGUtility.CalculateSamplePointsCacheSize(Resolution, InPath.SourceSlot().OnRequestPathModule.PathLength *this.Length), AngleThreshold, (Optimize) ? CGDataRequestRasterization.ModeEnum.Optimized : CGDataRequestRasterization.ModeEnum.Even));
                var path = InPath.GetData <CGPath>(req.ToArray());
                req.Clear();
                req.Add(new CGDataRequestRasterization(this.CrossFrom, this.CrossLength, CGUtility.CalculateSamplePointsCacheSize(CrossResolution, InCross.SourceSlot().OnRequestPathModule.PathLength *this.CrossLength), CrossAngleThreshold, (CrossOptimize) ? CGDataRequestRasterization.ModeEnum.Optimized : CGDataRequestRasterization.ModeEnum.Even));

                if (CrossIncludeControlPoints || CrossHardEdges || CrossMaterials)
                {
                    req.Add(new CGDataRequestMetaCGOptions(CrossHardEdges, CrossMaterials, CrossIncludeControlPoints, CrossExtendedUV));
                }

                var cross = InCross.GetData <CGShape>(req.ToArray());

                if (!path || !cross || path.Count == 0 || cross.Count == 0)
                {
                    OutVolume.ClearData();
                    OutVolumeHollow.ClearData();
                    return;
                }


                var vol       = CGVolume.Get(OutVolume.GetData <CGVolume>(), path, cross);
                var volHollow = (OutVolumeHollow.IsLinked) ? CGVolume.Get(OutVolumeHollow.GetData <CGVolume>(), path, cross) : null;

                PathSamples   = path.Count;
                CrossSamples  = cross.Count;
                CrossGroups   = cross.MaterialGroups.Count;
                CrossPosition = vol.Position[0];
                CrossRotation = Quaternion.LookRotation(vol.Direction[0], vol.Normal[0]);



                Vector3 baseScale = (ScaleUniform) ? new Vector3(ScaleX, ScaleX, 1) : new Vector3(ScaleX, ScaleY, 1);
                Vector3 scl       = baseScale;
                int     vtIdx     = 0;

                float[] scaleFArray = (ScaleReference == CGReferenceMode.Source) ? path.SourceF : path.F;

                Matrix4x4 mat;
                Matrix4x4 matHollow;

                Quaternion R;
                int        crossNormalMul  = (CrossReverseNormals) ? -1 : 1;
                int        hollowNormalMul = (HollowReverseNormals) ? -1 : 1;
                for (int sample = 0; sample < path.Count; sample++)
                {
                    R = Quaternion.LookRotation(path.Direction[sample], path.Normal[sample]);

                    getScaleInternal(scaleFArray[sample], baseScale, ref scl);
                    mat = Matrix4x4.TRS(path.Position[sample], R, scl);

                    if (volHollow == null)
                    {
                        for (int c = 0; c < cross.Count; c++)
                        {
                            vol.Vertex[vtIdx]         = mat.MultiplyPoint(cross.Position[c]);
                            vol.VertexNormal[vtIdx++] = R * cross.Normal[c] * crossNormalMul;
                        }
                    }
                    else
                    {
                        matHollow = Matrix4x4.TRS(path.Position[sample], R, scl * (1 - HollowInset));
                        for (int c = 0; c < cross.Count; c++)
                        {
                            vol.Vertex[vtIdx]             = mat.MultiplyPoint(cross.Position[c]);
                            vol.VertexNormal[vtIdx]       = R * cross.Normal[c];
                            volHollow.Vertex[vtIdx]       = matHollow.MultiplyPoint(cross.Position[c]);
                            volHollow.VertexNormal[vtIdx] = vol.VertexNormal[vtIdx++] * hollowNormalMul;
                        }
                    }
                }



                switch (CrossShiftMode)
                {
                case CrossShiftModeEnum.ByOrientation:
                    // shift CrossF to match Path Orientation
                    Vector2 hit;
                    float   frag;
                    for (int i = 0; i < cross.Count - 1; i++)
                    {
                        if (DTMath.RayLineSegmentIntersection(vol.Position[0], vol.VertexNormal[0], vol.Vertex[i], vol.Vertex[i + 1], out hit, out frag))
                        {
                            vol.CrossFShift = DTMath.SnapPrecision(vol.CrossF[i] + (vol.CrossF[i + 1] - vol.CrossF[i]) * frag, 2);
                            break;
                        }
                    }
                    if (vol.CrossClosed && DTMath.RayLineSegmentIntersection(vol.Position[0], vol.VertexNormal[0], vol.Vertex[cross.Count - 1], vol.Vertex[0], out hit, out frag))
                    {
                        vol.CrossFShift = DTMath.SnapPrecision(vol.CrossF[cross.Count - 1] + (vol.CrossF[0] - vol.CrossF[cross.Count - 1]) * frag, 2);
                    }
                    break;

                case CrossShiftModeEnum.Custom:
                    vol.CrossFShift = CrossShiftValue;
                    break;

                default:
                    vol.CrossFShift = 0;
                    break;
                }

                if (volHollow != null)
                {
                    volHollow.CrossFShift = vol.CrossFShift;
                }

                OutVolume.SetData(vol);
                OutVolumeHollow.SetData(volHollow);
            }
        }
예제 #18
0
        /*! \endcond */
        #endregion

        #region ### Public Methods ###

        public override void Refresh()
        {
            base.Refresh();
            CGVolume vol   = InVolume.GetData <CGVolume>();
            var      holes = InVolumeHoles.GetAllData <CGVolume>();

            if (vol)
            {
                bool genStart = (StartCap == CGYesNoAuto.Yes || (StartCap == CGYesNoAuto.Auto && !vol.Seamless));
                bool genEnd   = (EndCap == CGYesNoAuto.Yes || (EndCap == CGYesNoAuto.Auto && !vol.Seamless));

                if (!genStart && !genEnd)
                {
                    OutVMesh.SetData(null);
                    return;
                }

                var       vmesh   = new CGVMesh();
                Vector3[] vtStart = new Vector3[0];
                Vector3[] vtEnd   = new Vector3[0];

                vmesh.AddSubMesh(new CGVSubMesh());
                CGVSubMesh submesh = vmesh.SubMeshes[0];

                if (genStart)
                {
                    #region --- Start Cap ---

                    var tess = new Tess();
                    tess.UsePooling = true;
                    tess.AddContour(make2DSegment(vol, 0));

                    for (int h = 0; h < holes.Count; h++)
                    {
                        if (holes[h].Count < 3)
                        {
                            OutVMesh.SetData(null);
                            UIMessages.Add("Hole Cross has <3 Vertices: Can't create Caps!");
                            return;
                        }
                        tess.AddContour(make2DSegment(holes[h], 0));
                    }
                    tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
                    vtStart = UnityLibTessUtility.FromContourVertex(tess.Vertices);
                    Bounds b;
                    vmesh.Vertex      = applyMat(vtStart, getMat(vol, 0, true), out b);
                    submesh.Material  = StartMaterial;
                    submesh.Triangles = tess.Elements;
                    if (ReverseTriOrder)
                    {
                        flipTris(ref submesh.Triangles, 0, submesh.Triangles.Length);
                    }
                    if (GenerateUV)
                    {
                        vmesh.UV = new Vector2[vtStart.Length];
                        applyUV(vtStart, ref vmesh.UV, 0, vtStart.Length, StartMaterialSettings, b);
                    }
                    #endregion
                }

                if (genEnd)
                {
                    #region --- End Cap ---

                    var tess = new Tess();
                    tess.UsePooling = true;
                    tess.AddContour(make2DSegment(vol, 0));

                    for (int h = 0; h < holes.Count; h++)
                    {
                        if (holes[h].Count < 3)
                        {
                            OutVMesh.SetData(null);
                            UIMessages.Add("Hole Cross has <3 Vertices: Can't create Caps!");
                            return;
                        }
                        tess.AddContour(make2DSegment(holes[h], 0));
                    }
                    tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3);
                    vtEnd = UnityLibTessUtility.FromContourVertex(tess.Vertices);
                    Bounds b;
                    int    l = vmesh.Vertex.Length;
                    vmesh.Vertex = vmesh.Vertex.AddRange <Vector3>(applyMat(vtEnd, getMat(vol, vol.Count - 1, true), out b));
                    int[] tris = tess.Elements;
                    if (!ReverseTriOrder)
                    {
                        flipTris(ref tris, 0, tris.Length);
                    }
                    for (int i = 0; i < tris.Length; i++)
                    {
                        tris[i] += l;
                    }
                    if (!CloneStartCap && StartMaterial != EndMaterial)
                    {
                        vmesh.AddSubMesh(new CGVSubMesh(tris, EndMaterial));
                    }
                    else
                    {
                        submesh.Material  = StartMaterial;
                        submesh.Triangles = submesh.Triangles.AddRange <int>(tris);
                    }

                    if (GenerateUV)
                    {
                        System.Array.Resize <Vector2>(ref vmesh.UV, vmesh.UV.Length + vtEnd.Length);
                        applyUV(vtEnd, ref vmesh.UV, vtStart.Length, vtEnd.Length, (CloneStartCap) ? StartMaterialSettings : EndMaterialSettings, b);
                    }


                    #endregion
                }


                OutVMesh.SetData(vmesh);
            }
        }
예제 #19
0
        public override void OnModuleSceneDebugGUI()
        {
            base.OnModuleSceneDebugGUI();
            CGVolume vol = Target.InData.GetData <CGVolume>();

            if (vol)
            {
                Handles.matrix = Target.Generator.transform.localToWorldMatrix;

                if (Target.ShowPathSamples)
                {
                    CGEditorUtility.SceneGUIPlot(vol.Position, 0.1f, Target.PathColor);
                    if (Target.ShowIndex)
                    {
                        var labels = Enumerable.Range(0, vol.Count).Select(i => i.ToString()).ToArray <string>();
                        CGEditorUtility.SceneGUILabels(vol.Position, labels, Color.black, Vector2.zero);
                    }
                }
                if (Target.ShowCrossSamples)
                {
                    int vtLo = Target.LimitCross.From * vol.CrossSize;
                    int vtHi = vtLo + vol.CrossSize;
                    if (!Target.LimitCross.SimpleValue)
                    {
                        vtLo = Target.LimitCross.Low * vol.CrossSize;
                        vtHi = (Target.LimitCross.High + 1) * vol.CrossSize;
                    }

                    vtLo = Mathf.Clamp(vtLo, 0, vol.VertexCount);
                    vtHi = Mathf.Clamp(vtHi, vtLo, vol.VertexCount);
                    var range = vol.Vertex.SubArray <Vector3>(vtLo, vtHi - vtLo);
                    CGEditorUtility.SceneGUIPlot(range, 0.1f, Color.white);

                    if (Target.ShowIndex)
                    {
                        var labels = Enumerable.Range(vtLo, vtHi).Select(i => i.ToString()).ToArray <string>();
                        CGEditorUtility.SceneGUILabels(range, labels, Color.black, Vector2.zero);
                    }

                    if (Target.ShowMap)
                    {
                        var labels = Enumerable.Range(vtLo, vtHi).Select(i => DTMath.SnapPrecision(vol.CrossMap[i], 3).ToString()).ToArray <string>();
                        CGEditorUtility.SceneGUILabels(range, labels, new Color(1, 0, 1), new Vector2(10, 20));
                    }

                    if (Target.ShowNormals)
                    {
                        DTHandles.PushHandlesColor(Target.NormalColor);

                        for (int i = vtLo; i < vtHi; i++)
                        {
                            Handles.DrawLine(vol.Vertex[i], vol.Vertex[i] + vol.VertexNormal[i] * 2);
                        }

                        DTHandles.PopHandlesColor();
                    }
                }
                if (Target.Interpolate)
                {
                    Vector3 pos;
                    Vector3 tan;
                    Vector3 up;
                    vol.InterpolateVolume(Target.InterpolatePathF, Target.InterpolateCrossF, out pos, out tan, out up);
                    Handles.ConeCap(0, pos, Quaternion.LookRotation(up, tan), 1f);
                }
                Handles.matrix = Matrix4x4.identity;
            }
        }
예제 #20
0
        /*! \cond PRIVATE */

        void prepare(CGVolume vol)
        {
            // We have groups (different MaterialID) of patches (e.g. by Hard Edges).
            // Create Collection of groups sharing the same material ID
            groupsByMatID = getMaterialIDGroups(vol);
        }