Ejemplo n.º 1
0
		public void CombineMeshes(CombineInstance[] combine, bool mergeSubMeshes){}
Ejemplo n.º 2
0
    public void Combine()
    {
        if (!forceDuplicateCombine && transform.Find("Combined mesh") != null)
        {
            completed = true;
            return;
        }

        if (DEBUG)
        {
            //print("START called on: " + gameObject.name + "in hex: " + transform.parent.gameObject.name);
            StartCoroutine(wait());
        }
        completed = false;

        Matrix4x4 myTransform = transform.worldToLocalMatrix;
        Dictionary <Material, List <CombineInstance> > combines = new Dictionary <Material, List <CombineInstance> >();

        MeshRenderer[] meshRenderers = GetComponentsInChildren <MeshRenderer>();
        foreach (var meshRenderer in meshRenderers)
        {
            foreach (var material in meshRenderer.sharedMaterials)
            {
                if (material != null && !combines.ContainsKey(material))
                {
                    combines.Add(material, new List <CombineInstance>());
                }
            }
        }

        MeshFilter[] meshFilters = GetComponentsInChildren <MeshFilter>();
        //if(DEBUG) print("Number of filters: " + meshFilters.Length);
        foreach (var filter in meshFilters)
        {
            if (filter.sharedMesh == null)
            {
                continue;
            }
            CombineInstance ci = new CombineInstance();
            ci.mesh      = filter.sharedMesh;
            ci.transform = myTransform * filter.transform.localToWorldMatrix;
            combines[filter.GetComponent <Renderer>().sharedMaterial].Add(ci);
            if (DEBUG)
            {
                filter.GetComponent <Renderer>().enabled = true;
            }
            else
            {
                filter.GetComponent <Renderer>().enabled = false;
            }
        }

        int counter = 0;

        //if(DEBUG) print("Number of materials: " + combines.Keys.Count);
        foreach (Material m in combines.Keys)
        {
            if (counter < 3)
            {
                var go = new GameObject("Combined mesh");                // + counter);
                go.transform.parent        = transform;
                go.transform.localPosition = Vector3.zero;
                go.transform.localRotation = Quaternion.identity;
                go.transform.localScale    = Vector3.one;

                var filter = go.AddComponent <MeshFilter>();
                filter.mesh.CombineMeshes(combines[m].ToArray(), true, true);

                var renderer = go.AddComponent <MeshRenderer>();
                renderer.material = m;
            }
            if (DEBUG)
            {
                counter++;
            }
        }


        completed = true;
    }
Ejemplo n.º 3
0
    void Start()
    {
        //stage情報初期化
        stage = variables.stage;

        //法線初期化
        normalVector   = new Vector3[variables.trapezoidDivisionNum + 1, 6];
        normalBasicVec = new Vector3[variables.trapezoidDivisionNum + 1, 6];

        if (myParent == null)
        {
            createSorce = GameObject.Find("central").GetComponent <createTrapezoidPole>();
            //現在のTextSetの段数を取得
            poleSum = variables.poleSum;
        }
        else
        {
            createSorce = myParent.GetComponent <createTrapezoidPole>();
            //自分の親の名前から該当TextSetの行からアイテム数を取得
            //Debug.Log(myParent.name.Substring(9));
            poleSum = GameObject.Find("central").GetComponent <centralSystem>().GetTextSetItemNum(int.Parse(myParent.name.Substring(9)));
        }

        systemScript = GameObject.Find("central").GetComponent <centralSystem>();

        //自分の番号を名前から取得し初期化
        poleNum = int.Parse(transform.name) - 1;

        //LineVertex初期化  最初の面4頂点+中間面4頂点+最後の面4頂点
        LineVertex = new Vector3[4 + variables.trapezoidDivisionNum * 4 + 4];
        //格納先も初期化
        lineVertecies = new Vector3[8 + 4 * variables.trapezoidDivisionNum + 8];

        // CombineMeshes()する時に使う配列   始端と終端も含めるので+3
        CombineInstance[] combineInstanceAry = new CombineInstance[variables.trapezoidDivisionNum + 3];

        //メッシュ作成
        for (DivisionNum = 0; DivisionNum <= variables.trapezoidDivisionNum; DivisionNum++)
        {
            //頂点計算
            CalcVertices();

            if (DivisionNum == 0)
            {
                //最初の一枚だけ別計算
                //メッシュ作成
                Mesh meshFirst = new Mesh();
                //メッシュリセット
                meshFirst.Clear();
                //メッシュへの頂点情報の追加
                meshFirst.vertices = StartVertex;
                //メッシュへの面情報の追加
                meshFirst.triangles = EndFace;

                // 合成するMesh(同じMeshを円形に並べたMesh)
                combineInstanceAry[0].mesh      = meshFirst;
                combineInstanceAry[0].transform = Matrix4x4.Translate(transform.position);
            }
            Mesh mesh = new Mesh();
            //メッシュリセット
            mesh.Clear();
            //メッシュへの頂点情報の追加
            mesh.vertices = SideVertex;
            //メッシュへの面情報の追加
            mesh.triangles = SideFace;

            //合成するMesh(同じMeshを円形に並べたMesh)
            combineInstanceAry[DivisionNum + 1].mesh      = mesh;
            combineInstanceAry[DivisionNum + 1].transform = Matrix4x4.Translate(transform.position);

            if (DivisionNum == variables.trapezoidDivisionNum)
            {
                //最後の一枚だけ別計算
                //メッシュ作成
                Mesh meshLast = new Mesh();
                //メッシュリセット
                meshLast.Clear();
                //メッシュへの頂点情報の追加
                meshLast.vertices = EndVertex;
                //メッシュへの面情報の追加
                meshLast.triangles = EndFace;

                // 合成するMesh(同じMeshを円形に並べたMesh)
                combineInstanceAry[DivisionNum + 2].mesh      = meshLast;
                combineInstanceAry[DivisionNum + 2].transform = Matrix4x4.Translate(transform.position);
            }
        }
        //合成した(する)メッシュ
        Mesh combinedMesh = new Mesh();

        combinedMesh.name = transform.name;
        combinedMesh.CombineMeshes(combineInstanceAry);
        //内向き法線の計算
        culcNormal(combinedMesh.vertices);

        //メッシュフィルター追加
        MeshFilter mesh_filter = new MeshFilter();

        mesh_filter = this.gameObject.AddComponent <MeshFilter>();
        //メッシュアタッチ
        mesh_filter.mesh = combinedMesh;
        //レンダラー追加 + マテリアルアタッチ
        meshRenderer          = this.gameObject.AddComponent <MeshRenderer>();
        meshRenderer.material = variables.material_TrapezoidPole_Normal;
        //コライダーアタッチ
        meshCollider            = this.gameObject.AddComponent <MeshCollider>();
        meshCollider.sharedMesh = mesh_filter.mesh;
        meshCollider.convex     = true;
        meshCollider.isTrigger  = true;

        //NormalMapの再計算
        mesh_filter.mesh.RecalculateNormals();

        //XRじゃないなら
        if (!variables.isOnXR)
        {
            //暫定当たり判定用Event Trigger
            //イベントトリガーのアタッチと初期化
            EventTrigger currentTrigger = this.gameObject.AddComponent <EventTrigger>();
            currentTrigger.triggers = new List <EventTrigger.Entry>();

            //侵入イベント用
            //侵入時に色を変える
            //イベントトリガーのトリガーイベント作成
            EventTrigger.Entry entry1 = new EventTrigger.Entry();
            entry1.eventID = EventTriggerType.PointerEnter;
            entry1.callback.AddListener((x) => OnMouseEnterOwnMade());  //ラムダ式の右側は追加するメソッド
            //トリガーイベントのアタッチ
            currentTrigger.triggers.Add(entry1);
            //侵入終了時に色を戻す
            EventTrigger.Entry entry2 = new EventTrigger.Entry();
            entry2.eventID = EventTriggerType.PointerExit;
            entry2.callback.AddListener((x) => OnMouseExitOwnMade());
            currentTrigger.triggers.Add(entry2);
        }

        //テキスト表示
        make3Dtext();

        //縁取り
        lineRenderer = this.gameObject.AddComponent <LineRenderer>();
        //ローカルで描画
        lineRenderer.useWorldSpace = false;
        //頂点数
        lineRenderer.positionCount = lineVertecies.Length;
        //幅
        lineRenderer.startWidth = variables.lineRendererWidth;
        //順番の格納
        SetLineVertecies();
        lineRenderer.SetPositions(lineVertecies);
        //線の折れる部分の丸み具合
        lineRenderer.numCornerVertices = 20;
        //線の端の丸み具合
        lineRenderer.numCapVertices = 20;
        //線の色
        lineRenderer.material = variables.material_LineRenderer;
        //影を発生させない
        lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
        //影の影響を受けない
        lineRenderer.receiveShadows = false;

        //クリエイト元を親にする
        transform.parent = createSorce.gameObject.transform;
    }
Ejemplo n.º 4
0
    public Mesh GenerateMesh()
    {
        List <CombineInstance> cisOpaque      = new List <CombineInstance>();
        List <CombineInstance> cisTransparent = new List <CombineInstance>();

        List <IBlock> blocks = new List <IBlock>(blocksInChunk.Values);


        for (int i = 0; i < blocks.Count; i++)
        {
            CombineInstance ci = new CombineInstance {
                mesh      = blocks[i].GetMesh(),
                transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one)
            };
            if (blocks[i] is ITransparentBlock)
            {
                cisTransparent.Add(ci);
            }
            else
            {
                cisOpaque.Add(ci);
            }
        }

        /*
         * Mesh meshOpaque = new Mesh();
         * meshOpaque.CombineMeshes(cisOpaque.ToArray());
         * Mesh meshTransparent = new Mesh();
         * meshOpaque.CombineMeshes(cisTransparent.ToArray());
         *
         * Mesh finalMesh = new Mesh();
         * CombineInstance[] cis = new CombineInstance[] {
         *  new CombineInstance() { mesh = meshOpaque },
         *  new CombineInstance() { mesh = meshTransparent }
         * };
         */
        Mesh opaqueMesh      = new Mesh();
        Mesh transparentMesh = new Mesh();

        opaqueMesh.CombineMeshes(cisOpaque.ToArray());
        transparentMesh.CombineMeshes(cisTransparent.ToArray());

        Mesh finalMesh = new Mesh();

        CombineInstance[] cis = new CombineInstance[] {
            new CombineInstance()
            {
                mesh      = opaqueMesh,
                transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one)
            },
            new CombineInstance()
            {
                mesh      = transparentMesh,
                transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one)
            },
        };

        finalMesh.CombineMeshes(cis, false);

        if (finalMesh.subMeshCount == 1)
        {
            finalMesh.subMeshCount = 2;
        }

        return(finalMesh);
    }
Ejemplo n.º 5
0
        public override List <Model> Modify(List <Model> input)
        {
            List <Model> output = new List <Model>();

            /*if (spline) {
             *  if (fit == Fit.Spline && updateOnSpline) spline.OnRefresh.AddListenerOnce(OnSplineRefreshEvent);
             *  else spline.OnRefresh.RemoveListener(OnSplineRefreshEvent);
             * }*/

            //int count = GetCount(inputMesh);

            //Loop through input models
            for (int i = 0; i < input.Count; i++)
            {
                CombineInstance[] finalCombines = new CombineInstance[input[i].mesh.subMeshCount];

                //Loop through model submeshes
                for (int g = 0; g < input[i].mesh.subMeshCount; g++)
                {
                    //Create a CombineInstance array for the submesh
                    CombineInstance[] submeshCombines = new CombineInstance[count];

                    //Perform the array modifier
                    for (int k = 0; k < count; k++)
                    {
                        Vector3 pos   = posOffset * k;
                        Vector3 rot   = rotOffset * k;
                        Vector3 scale = Vector3.one;

                        /*if (fit != Fit.Count && scaleToFit) {
                         *  float segmentWidth = GetSegmentWidth(inputMesh); //eg 4
                         *  float lengthToFit = GetLength(); //eg 11.12041
                         *  float fitScale = lengthToFit / (segmentWidth * count); //eg 1.390052
                         *  Vector3 fitAxis = posOffset / segmentWidth; //eg (0,0,1)
                         *  Vector3 fitScaleOffset = fitAxis * fitScale; //eg (0,0,1.390052)
                         *
                         *  scale.x *= Mathf.Lerp(1f, fitScaleOffset.x, fitAxis.x);
                         *  scale.y *= Mathf.Lerp(1f, fitScaleOffset.y, fitAxis.y);
                         *  scale.z *= Mathf.Lerp(1f, fitScaleOffset.z, fitAxis.z);
                         *  pos.x *= Mathf.Lerp(1f, fitScaleOffset.x, fitAxis.x);
                         *  pos.y *= Mathf.Lerp(1f, fitScaleOffset.y, fitAxis.y);
                         *  pos.z *= Mathf.Lerp(1f, fitScaleOffset.z, fitAxis.z);
                         *
                         * }*/
                        //scale += (scaleOffset * k);

                        //Setup CombineInstance
                        submeshCombines[k] = new CombineInstance()
                        {
                            mesh         = input[i].mesh,
                            transform    = Matrix4x4.TRS(pos, Quaternion.Euler(rot), scale),
                            subMeshIndex = g
                        };
                    }
                    Mesh arrayedSubmesh = new Mesh();
                    arrayedSubmesh.CombineMeshes(submeshCombines, true);
                    finalCombines[g] = new CombineInstance()
                    {
                        mesh      = arrayedSubmesh,
                        transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one),
                    };
                }
                Mesh finalMesh = new Mesh();
                finalMesh.CombineMeshes(finalCombines, false);
                output.Add(new Model(finalMesh, input[i].materials));
            }
            return(output);
        }
Ejemplo n.º 6
0
    public IEnumerator GenerateHLOD(bool propagateUpwards = true)
    {
        var mergeChildrenVolumes         = false;
        HashSet <Renderer> hlodRenderers = new HashSet <Renderer>();

        var rendererMaterials = renderers.SelectMany(r => r.sharedMaterials);

        yield return(null);

        foreach (Transform child in transform)
        {
            var childLODVolume = child.GetComponent <LODVolume>();
            if (childLODVolume && childLODVolume.renderers.Count > 0)
            {
                if (rendererMaterials.Except(childLODVolume.renderers.SelectMany(r => r.sharedMaterials)).Any())
                {
                    hlodRenderers.Clear();
                    mergeChildrenVolumes = false;
                    break;
                }

                var childHLODRoot = childLODVolume.hlodRoot;
                if (childHLODRoot)
                {
                    var childHLODRenderer = childHLODRoot.GetComponent <Renderer>();
                    if (childHLODRenderer)
                    {
                        mergeChildrenVolumes = true;
                        hlodRenderers.Add(childHLODRenderer);
                        continue;
                    }
                }

                hlodRenderers.Clear();
                mergeChildrenVolumes = false;
                break;
            }

            yield return(null);
        }

        if (!mergeChildrenVolumes)
        {
            foreach (var r in renderers)
            {
                var mr = r as MeshRenderer;
                if (mr)
                {
                    // Use the coarsest LOD if it exists
                    var mrLODGroup = mr.GetComponentInParent <LODGroup>();
                    if (mrLODGroup)
                    {
                        var mrLODs = mrLODGroup.GetLODs();
                        var maxLOD = mrLODGroup.GetMaxLOD();
                        var mrLOD  = mrLODs[maxLOD];
                        foreach (var lr in mrLOD.renderers)
                        {
                            if (lr && lr.GetComponent <MeshFilter>())
                            {
                                hlodRenderers.Add(lr);
                            }
                        }
                    }
                    else if (mr.GetComponent <MeshFilter>())
                    {
                        hlodRenderers.Add(mr);
                    }
                }

                yield return(null);
            }
        }

        var lodRenderers = new List <Renderer>();

        CleanupHLOD();

        GameObject hlodRootContainer = null;

        yield return(ObjectUtils.FindGameObject(k_HLODRootContainer, root =>
        {
            if (root)
            {
                hlodRootContainer = root;
            }
        }));

        if (!hlodRootContainer)
        {
            hlodRootContainer = new GameObject(k_HLODRootContainer);
        }

        var hlodLayer = LayerMask.NameToLayer(HLODLayer);

        hlodRoot                  = new GameObject("HLOD");
        hlodRoot.layer            = hlodLayer;
        hlodRoot.transform.parent = hlodRootContainer.transform;

        if (mergeChildrenVolumes)
        {
            Material sharedMaterial = null;

            CombineInstance[] combine = new CombineInstance[hlodRenderers.Count];
            var i = 0;
            foreach (var r in hlodRenderers)
            {
                var mf = r.GetComponent <MeshFilter>();
                var ci = new CombineInstance();
                ci.transform = r.transform.localToWorldMatrix;
                ci.mesh      = mf.sharedMesh;
                combine[i]   = ci;

                if (sharedMaterial == null)
                {
                    sharedMaterial = r.sharedMaterial;
                }

                i++;
            }

            var sharedMesh = new Mesh();
#if UNITY_2017_3_OR_NEWER
            sharedMesh.indexFormat = IndexFormat.UInt32;
#endif
            sharedMesh.CombineMeshes(combine, true, true);
            sharedMesh.RecalculateBounds();
            var meshFilter = hlodRoot.AddComponent <MeshFilter>();
            meshFilter.sharedMesh = sharedMesh;

            var meshRenderer = hlodRoot.AddComponent <MeshRenderer>();
            meshRenderer.sharedMaterial = sharedMaterial;
        }
        else
        {
            var parent = hlodRoot.transform;
            foreach (var r in hlodRenderers)
            {
                var rendererTransform = r.transform;

                var child = new GameObject(r.name, typeof(MeshFilter), typeof(MeshRenderer));
                child.layer = hlodLayer;
                var childTransform = child.transform;
                childTransform.SetPositionAndRotation(rendererTransform.position, rendererTransform.rotation);
                childTransform.localScale = rendererTransform.lossyScale;
                childTransform.SetParent(parent, true);

                var mr = child.GetComponent <MeshRenderer>();
                EditorUtility.CopySerialized(r.GetComponent <MeshFilter>(), child.GetComponent <MeshFilter>());
                EditorUtility.CopySerialized(r.GetComponent <MeshRenderer>(), mr);

                lodRenderers.Add(mr);
            }
        }
        LOD lod = new LOD();

        var lodGroup = GetComponent <LODGroup>();
        if (!lodGroup)
        {
            lodGroup = gameObject.AddComponent <LODGroup>();
        }
        this.lodGroup.lodGroup = lodGroup;

        if (!mergeChildrenVolumes)
        {
            var batcher = (IBatcher)Activator.CreateInstance(batcherType);
            yield return(batcher.Batch(hlodRoot));
        }

        lod.renderers = hlodRoot.GetComponentsInChildren <Renderer>(false);
        lodGroup.SetLODs(new LOD[] { lod });

        if (propagateUpwards)
        {
            var lodVolumeParent = transform.parent;
            var parentLODVolume = lodVolumeParent ? lodVolumeParent.GetComponentInParent <LODVolume>() : null;
            if (parentLODVolume)
            {
                yield return(parentLODVolume.GenerateHLOD());
            }
        }
    }
Ejemplo n.º 7
0
        // Merge meshes together for faster drawing.
        public void MergeMeshes()
        {
            if (AreMeshesMerged)
            {
                return;
            }

            // First make a list of all top-level child meshes that don't
            // have animators attached.
            Dictionary <Material, List <MeshRenderer> > staticMeshes =
                new Dictionary <Material, List <MeshRenderer> >();

            mergedMeshHolder      = new GameObject();
            mergedMeshHolder.name = "MergedMeshHolder";

            foreach (GameObject obj in sceneObjects.Values)
            {
                foreach (Transform child in obj.transform)
                {
                    bool hasAnimator = child.GetComponentsInChildren <Animator>().Length > 0;
                    if (!hasAnimator)
                    {
                        foreach (MeshRenderer meshRenderer in child.GetComponentsInChildren <MeshRenderer>())
                        {
                            if (meshRenderer.enabled)
                            {
                                int materialHash = meshRenderer.sharedMaterial.GetHashCode();
                                if (!staticMeshes.ContainsKey(meshRenderer.sharedMaterial))
                                {
                                    staticMeshes.Add(meshRenderer.sharedMaterial, new List <MeshRenderer>());
                                }
                                staticMeshes[meshRenderer.sharedMaterial].Add(meshRenderer);
                                Destroy(meshRenderer);
                            }
                        }
                    }
                }
            }
            foreach (Material mat in staticMeshes.Keys)
            {
                List <MeshRenderer> meshList     = staticMeshes[mat];
                CombineInstance[]   combineArray = new CombineInstance[meshList.Count];
                int i = 0;
                foreach (MeshRenderer meshRenderer in meshList)
                {
                    MeshFilter meshFilter = meshRenderer.gameObject.GetComponent <MeshFilter>();
                    if (meshFilter != null)
                    {
                        combineArray[i].mesh      = meshFilter.mesh;
                        combineArray[i].transform = meshFilter.transform.localToWorldMatrix;
                        i++;
                    }
                }
                GameObject meshHolder = new GameObject();
                meshHolder.name = "MeshHolder";

                meshHolder.transform.SetParent(mergedMeshHolder.transform, false);
                MeshRenderer newRenderer = meshHolder.AddComponent <MeshRenderer>();
                MeshFilter   newFilter   = meshHolder.AddComponent <MeshFilter>();
                newFilter.mesh = new Mesh();
                newFilter.mesh.CombineMeshes(combineArray, true);
                newRenderer.material = mat;
            }
        }
        public void CollectMesh(Armature armature, List <CombineMeshInfo> combineSlots)
        {
            if (armature == null)
            {
                return;
            }

            var slots = new List <Slot>(armature.GetSlots());

            if (slots.Count == 0)
            {
                return;
            }
            //
            var       isBreakCombineMesh = false;
            var       isSameMaterial     = false;
            var       isChildAramture    = false;
            UnitySlot slotMeshProxy      = null;

            GameObject slotDisplay = null;

            for (var i = 0; i < slots.Count; i++)
            {
                var slot = slots[i] as UnitySlot;

                slot.CancelCombineMesh();

                isChildAramture = slot.childArmature != null;
                slotDisplay     = slot.renderDisplay;

                if (slotMeshProxy != null)
                {
                    if (slot._meshBuffer.name == string.Empty)
                    {
                        isSameMaterial = true;
                    }
                    else
                    {
                        isSameMaterial = slotMeshProxy._meshBuffer.name == slot._meshBuffer.name;
                    }
                }
                else
                {
                    isSameMaterial = slotMeshProxy == null;
                }

                //先检查这个slot会不会打断网格合并
                isBreakCombineMesh = isChildAramture ||
                                     slot._isIgnoreCombineMesh ||
                                     slot._blendMode != BlendMode.Normal ||
                                     !isSameMaterial;

                //如果会打断,那么先合并一次
                if (isBreakCombineMesh)
                {
                    if (combineSlots.Count > 0)
                    {
                        if (combineSlots[combineSlots.Count - 1].combines.Count == 1)
                        {
                            combineSlots.RemoveAt(combineSlots.Count - 1);
                        }
                    }

                    slotMeshProxy = null;
                }
                //
                if (slotMeshProxy == null && !isBreakCombineMesh && slotDisplay != null && slotDisplay.activeSelf)
                {
                    CombineMeshInfo combineSlot = new CombineMeshInfo();
                    combineSlot.proxySlot = slot;
                    combineSlot.combines  = new List <CombineInstance>();
                    combineSlot.slots     = new List <UnitySlot>();
                    combineSlots.Add(combineSlot);

                    slotMeshProxy = slot;
                }

                //如果不会合并,检查一下是否是子骨架
                if (isChildAramture)
                {
                    continue;
                }

                if (slotMeshProxy != null && slotDisplay != null && slotDisplay.activeSelf && !slot._isIgnoreCombineMesh)
                {
                    var             parentTransfrom = (slot._armature.proxy as UnityArmatureComponent).transform;
                    CombineInstance com             = new CombineInstance();
                    com.mesh = slot._meshBuffer.sharedMesh;

                    com.transform = slotMeshProxy._renderDisplay.transform.worldToLocalMatrix * slotDisplay.transform.localToWorldMatrix;

                    combineSlots[combineSlots.Count - 1].combines.Add(com);
                    combineSlots[combineSlots.Count - 1].slots.Add(slot);
                }
                if (i != slots.Count - 1)
                {
                    continue;
                }
                //
                if (combineSlots.Count > 0)
                {
                    if (combineSlots[combineSlots.Count - 1].combines.Count == 1)
                    {
                        combineSlots.RemoveAt(combineSlots.Count - 1);
                    }
                }
                slotMeshProxy = null;
            }
        }
Ejemplo n.º 9
0
        private void PreprocessInputMesh()
        {
            if (deformedMesh == null)
            {
                deformedMesh      = new Mesh();
                deformedMesh.name = "deformedMesh";
                deformedMesh.MarkDynamic();
                GetComponent <MeshFilter>().mesh = deformedMesh;
            }

            deformedMesh.Clear();

            if (mesh == null)
            {
                orderedVertices = new int[0];
                return;
            }

            // Clamp instance count to a positive value.
            instances = Mathf.Max(0, instances);

            // combine all mesh instances into a single mesh:
            Mesh combinedMesh = new Mesh();

            CombineInstance[] meshInstances = new CombineInstance[instances];
            Vector3           pos           = Vector3.zero;

            // initial offset for the combined mesh is half the size of its bounding box in the swept axis:
            pos[(int)axis] = mesh.bounds.extents[(int)axis];

            for (int i = 0; i < instances; ++i)
            {
                meshInstances[i].mesh      = mesh;
                meshInstances[i].transform = Matrix4x4.TRS(pos, Quaternion.identity, Vector3.one);
                pos[(int)axis]             = mesh.bounds.extents[(int)axis] + (i + 1) * mesh.bounds.size[(int)axis] * instanceSpacing;
            }
            combinedMesh.CombineMeshes(meshInstances, true, true);

            // get combined mesh data:
            inputVertices = combinedMesh.vertices;
            inputNormals  = combinedMesh.normals;
            inputTangents = combinedMesh.tangents;

            // sort vertices along curve axis:
            float[] keys = new float[inputVertices.Length];
            orderedVertices = new int[inputVertices.Length];

            for (int i = 0; i < keys.Length; ++i)
            {
                keys[i]            = inputVertices[i][(int)axis];
                orderedVertices[i] = i;
            }

            Array.Sort(keys, orderedVertices);

            // Copy the combined mesh data to deform it:
            deformedMesh.vertices  = combinedMesh.vertices;
            deformedMesh.normals   = combinedMesh.normals;
            deformedMesh.tangents  = combinedMesh.tangents;
            deformedMesh.uv        = combinedMesh.uv;
            deformedMesh.uv2       = combinedMesh.uv2;
            deformedMesh.uv3       = combinedMesh.uv3;
            deformedMesh.uv4       = combinedMesh.uv4;
            deformedMesh.colors    = combinedMesh.colors;
            deformedMesh.triangles = combinedMesh.triangles;

            vertices = deformedMesh.vertices;
            normals  = deformedMesh.normals;
            tangents = deformedMesh.tangents;

            // Calculate scale along swept axis so that the mesh spans the entire lenght of the rope if required.
            meshSizeAlongAxis = combinedMesh.bounds.size[(int)axis];

            // destroy combined mesh:
            GameObject.DestroyImmediate(combinedMesh);
        }
Ejemplo n.º 10
0
    public void Generate()
    {
        float startTime = Time.realtimeSinceStartup;

        #region Create Mesh Data

        List <CombineInstance> blockData = new List <CombineInstance>();                                                                      //this will contain the data for the final mesh
        MeshFilter             blockMesh = Instantiate(blockPrefab, Vector3.zero, Quaternion.identity).GetComponentInChildren <MeshFilter>(); //create a unit cube and store the mesh from it

        //go through each block position
        for (int x = 0; x < chunkSize; x++)
        {
            for (int y = 0; y < chunkSize; y++)
            {
                for (int z = 0; z < chunkSize; z++)
                {
                    float noiseValue = Perlin3D(x * noiseScale, y * noiseScale, z * noiseScale, seed); //get value of the noise at given x, y, and z.
                    if (noiseValue >= threshold)
                    {                                                                                  //is noise value above the threshold for placing a block?
                        //ignore this block if it's a sphere and it's outside of the radius (ex: in the corner of the chunk, outside of the sphere)
                        //distance between the current point with the center point. if it's larger than the radius, then it's not inside the sphere.
                        float radius = chunkSize / 2;
                        if (sphere && Vector3.Distance(new Vector3(x, y, z), Vector3.one * radius) > radius)
                        {
                            continue;
                        }
                        if (cube && Vector3.Distance(new Vector3(x, y, z), Vector3.one * radius) < radius * 0.6f)
                        {
                            continue;
                        }
                        if (rhombus && Vector3.Distance(new Vector3(x, y, z), Vector3.one * radius) > radius * 0.8f && Vector3.Distance(new Vector3(x, y, z), Vector3.one * radius) < radius)
                        {
                            continue;
                        }

                        blockMesh.transform.position = new Vector3(x, y, z); //move the unit cube to the intended position
                        CombineInstance ci = new CombineInstance
                        {                                                    //copy the data off of the unit cube
                            mesh      = blockMesh.sharedMesh,
                            transform = blockMesh.transform.localToWorldMatrix,
                        };
                        blockData.Add(ci);//add the data to the list
                    }
                }
            }
        }

        Destroy(blockMesh.gameObject);//original unit cube is no longer needed. we copied all the data we need to the block list.

        #endregion

        #region Separate Mesh Data

        //divide meshes into groups of 65536 vertices. Meshes can only have 65536 vertices so we need to divide them up into multiple block lists.

        List <List <CombineInstance> > blockDataLists = new List <List <CombineInstance> >(); //we will store the meshes in a list of lists. each sub-list will contain the data for one mesh. same data as blockData, different format.
        int vertexCount = 0;
        blockDataLists.Add(new List <CombineInstance>());                                     //initial list of mesh data
        for (int i = 0; i < blockData.Count; i++)
        {                                                                                     //go through each element in the previous list and add it to the new list.
            vertexCount += blockData[i].mesh.vertexCount;                                     //keep track of total vertices
            if (vertexCount > 65536)
            {                                                                                 //if the list has reached it's capacity. if total vertex count is more then 65536, reset counter and start adding them to a new list.
                vertexCount = 0;
                blockDataLists.Add(new List <CombineInstance>());
                i--;
            }
            else
            {                                            //if the list hasn't yet reached it's capacity. safe to add another block data to this list
                blockDataLists.Last().Add(blockData[i]); //the newest list will always be the last one added
            }
        }

        #endregion

        #region Create Mesh

        //the creation of the final mesh from the data.

        Transform container = new GameObject("Meshys").transform;//create container object
        container.transform.position = new Vector3(Random.Range(0, 1024), Random.Range(50, 500), Random.Range(0, 1024));
        foreach (List <CombineInstance> data in blockDataLists)
        {                                                      //for each list (of block data) in the list (of other lists)
            GameObject g = new GameObject("Meshy");            //create gameobject for the mesh
            g.transform.parent = container;                    //set parent to the container we just made
            MeshFilter   mf = g.AddComponent <MeshFilter>();   //add mesh component
            MeshRenderer mr = g.AddComponent <MeshRenderer>(); //add mesh renderer component
            MeshCollider mc = g.AddComponent <MeshCollider>(); //add mesh collider component
            mr.material = material;                            //set material to avoid evil pinkness of missing texture
            mf.mesh.CombineMeshes(data.ToArray());             //set mesh to the combination of all of the blocks in the list
            mc.sharedMesh = mf.mesh;                           //derive colllider from the combined mesh
            meshes.Add(mf.mesh);                               //keep track of mesh so we can destroy it when it's no longer needed
            //g.AddComponent<MeshCollider>().sharedMesh = mf.sharedMesh;//setting colliders takes more time. disabled for testing.
            meshObjects.Add(g);
        }

        PositionOnTerrain();

        #endregion

        Debug.Log("Loaded in " + (Time.realtimeSinceStartup - startTime) + " Seconds.");
    }
Ejemplo n.º 11
0
    /// <summary>
    /// Primary recursive function used to grow segments of the body, and attached stems
    /// </summary>
    /// <param name="firstSegment">special modifier for the 'head' or first segment of the body</param>
    /// <param name="number">number of segments to grow, counts down to 0</param>
    /// <param name="meshes">reference to list of combine instances</param>
    /// <param name="pos">where to spawn the segment</param>
    /// <param name="rot">rotation of the segment</param>
    /// <param name="bodyScale">how much to scale each segment</param>
    /// <param name="switchDirection">used to change direction the segment grows in</param>
    /// <param name="stems">reference to list of combine instances for stems and leaves</param>
    void GrowBody(bool firstSegment, int number, List <CombineInstance> meshes, Vector3 pos, Quaternion rot, float bodyScale, bool switchDirection, List <CombineInstance> stems)
    {
        if (number <= 0)
        {
            return;
        }

        CombineInstance inst = new CombineInstance();

        inst.mesh      = MeshTools.MakeCylinder(5);
        inst.transform = Matrix4x4.TRS(pos, rot, new Vector3(bodyWidth, bodyScale, bodyWidth) * scale);

        meshes.Add(inst);


        //scale

        //rotation
        ;
        Vector3 stemRotation = new Vector3();

        //calculate which way to grow the next segment
        if (switchDirection)
        {//top side
            rot = Quaternion.Euler(-90, 0, 0);
            if (!firstSegment)
            {
                stemRotation.Set(-45, 0, 0);
            }
        }
        else
        {//bottom side
            rot = Quaternion.Euler(-180, 0, 0);
            if (!firstSegment)
            {
                stemRotation.Set(135, 0, 0);
            }
        }
        //don't spawn stems from the first segment
        if (!firstSegment)
        {
            //random chance for 2 stems
            if (Random.Range(0, 100) < chanceForMoreStems)
            {
                stemRotation = new Vector3(stemRotation.x, stemRotation.y, -45);
                GrowStem(stemSize, stems, pos, Quaternion.Euler(stemRotation), switchDirection);
                stemRotation = new Vector3(stemRotation.x, stemRotation.y, 45);
            }
            GrowStem(stemSize, stems, pos, Quaternion.Euler(stemRotation), switchDirection);
        }

        switchDirection = !switchDirection;

        pos = inst.transform.MultiplyPoint(new Vector3(0, 1, 0));

        //de increment iterations
        number--;

        //grow another segment
        GrowBody(false, number, meshes, pos, rot, bodyScale, switchDirection, stems);
    }
Ejemplo n.º 12
0
    // FIXME: This most of this method is horrendously unoptimized, optimize it later
    // Combines meshes with differing materials into a parent mesh subdivided into submeshes
    public void MultiMaterialCombine()
    {
        // Caches frequently used references and components
        CacheReferences();

        // The output mesh where all other final submeshes are combined
        Mesh outputMesh = new Mesh();

        // Creates a new list to store the materials
        List <Material> materials = new List <Material>();

        // Creates an array of submeshes. Each submesh will contain a material
        Mesh[] subMeshes;
        // Creates a list of sublists of combine instances for each material
        // FIXME: Doing this is horrendous for performance
        List <List <CombineInstance> > combineInstanceLists = new List <List <CombineInstance> >();

        // HACK: To avoid annoying matrix math, we instead are resetting the position and restoring it later
        Quaternion rotation = transform.rotation;
        Vector3    position = transform.position;

        // For each of the children mesh filters
        foreach (MeshFilter meshFilter in childrenMeshFilters)
        {
            // Gets the mesh renderer attached to the mesh filter
            MeshRenderer meshRenderer = meshFilter.GetComponent <MeshRenderer>();

            // Skips if it is the container
            if (meshFilter == containerMeshFilter)
            {
                continue;
            }
            // Skips if the mesh renderer is null or the meshfilter's shared mesh is null or the mesh renderer's material count is different from the mesh filter's submesh count
            // This is important because each submesh is a material; therefore, if there are more materials than submeshes, the mesh combine will fail
            if (!meshRenderer || !meshFilter.sharedMesh || meshRenderer.sharedMaterials.Length != meshFilter.sharedMesh.subMeshCount)
            {
                continue;
            }

            // For each submesh in the meshfilter's mesh
            for (int sharedMaterialIndex = 0; sharedMaterialIndex < meshFilter.sharedMesh.subMeshCount; sharedMaterialIndex++)
            {
                // If the material does not exist in the materials list
                if (!materials.Contains(meshRenderer.sharedMaterials[sharedMaterialIndex]))
                {
                    // Add the material to the materials list
                    materials.Add(meshRenderer.sharedMaterials[sharedMaterialIndex]);
                }

                // Instantiates the material sublist
                combineInstanceLists.Add(new List <CombineInstance>());

                // Creates a new combine instance to store data about the mesh
                CombineInstance combineInstance = new CombineInstance();

                // Populates combineInstance with data
                combineInstance.transform    = meshRenderer.transform.localToWorldMatrix;
                combineInstance.subMeshIndex = sharedMaterialIndex;
                combineInstance.mesh         = meshFilter.sharedMesh;

                // Adds the combine instance to the material sublist
                combineInstanceLists[sharedMaterialIndex].Add(combineInstance);
            }

            // Disables the child's meshrenderer
            meshRenderer.enabled = false;
        }

        // Combine material index into a per-material mesh
        // Initializes the submesh array
        subMeshes = new Mesh[materials.Count];
        // Creates a new combine instance for each material
        CombineInstance[] finalCombineInstances = new CombineInstance[materials.Count];

        // For each material in materials
        for (int sharedMaterialIndex = 0; sharedMaterialIndex < materials.Count; sharedMaterialIndex++)
        {
            // Generates an array of combine instances that will be used to generate each submesh
            CombineInstance[] subfinalCombineInstances = combineInstanceLists[sharedMaterialIndex].ToArray();

            // Assigns a new mesh to the submesh array entry
            subMeshes[sharedMaterialIndex] = new Mesh();
            // Combines the meshes in the sub combine instances array
            subMeshes[sharedMaterialIndex].CombineMeshes(subfinalCombineInstances);

            // Assigns a new combine index to the final combine instances array
            finalCombineInstances[sharedMaterialIndex] = new CombineInstance();
            // Gives it the combined mesh of the subcombiners
            finalCombineInstances[sharedMaterialIndex].mesh = subMeshes[sharedMaterialIndex];
            // Set submesh index to 0, since we no longer need to worry about each submesh containing a material
            finalCombineInstances[sharedMaterialIndex].subMeshIndex = 0;
        }

        // Combine submeshes into output mesh
        // mergeSubMeshes submeshes is set to false, because we need them to display individual materials
        // useMatrices is set to false because we want to ignore the transform of the submeshes
        outputMesh.CombineMeshes(finalCombineInstances, false, false);

        // Sets the container's mesh to the output mesh
        containerMeshFilter.sharedMesh      = outputMesh;
        containerMeshFilter.sharedMesh.name = "Combined mesh";

        // Assigns materials to container mesh renderer
        containerRenderer.sharedMaterials = materials.ToArray();

        // Warns the developer the combined mesh exceeds unity's vertex limit
        if (outputMesh.vertexCount >= 65535)
        {
            Debug.LogError("The combined mesh exceeds Unity's limit of 65,535 vertices per mesh! Try combining fewer meshes!");
            Debug.Log("Automatically uncombined meshes.");
            Uncombine();
        }

        // Resets rotation and position
        transform.rotation = Quaternion.identity;
        transform.position = transform.position;

        // Marks meshes as combined
        meshesAreCombined = true;
    }
Ejemplo n.º 13
0
    public void CombineFromNet()
    {
        SkinnedMeshRenderer[]  smRenderers      = GetComponentsInChildren <SkinnedMeshRenderer>();
        List <Transform>       bones            = new List <Transform>();
        List <BoneWeight>      boneWeights      = new List <BoneWeight>();
        List <CombineInstance> combineInstances = new List <CombineInstance>();
        List <Texture2D>       textures         = new List <Texture2D>();
        int numSubs = 0;

        foreach (SkinnedMeshRenderer smr in smRenderers)
        {
            numSubs += smr.sharedMesh.subMeshCount;
        }

        int[] meshIndex  = new int[numSubs];
        int   boneOffset = 0;

        for (int s = 0; s < smRenderers.Length; s++)
        {
            SkinnedMeshRenderer smr = smRenderers[s];

            BoneWeight[] meshBoneweight = smr.sharedMesh.boneWeights;

            // May want to modify this if the renderer shares bones as unnecessary bones will get added.
            foreach (BoneWeight bw in meshBoneweight)
            {
                BoneWeight bWeight = bw;

                bWeight.boneIndex0 += boneOffset;
                bWeight.boneIndex1 += boneOffset;
                bWeight.boneIndex2 += boneOffset;
                bWeight.boneIndex3 += boneOffset;

                boneWeights.Add(bWeight);
            }
            boneOffset += smr.bones.Length;

            Transform[] meshBones = smr.bones;
            foreach (Transform bone in meshBones)
            {
                bones.Add(bone);
            }

            if (smr.material.mainTexture != null)
            {
                textures.Add(smr.GetComponent <Renderer>().material.mainTexture as Texture2D);
            }

            CombineInstance ci = new CombineInstance();
            ci.mesh      = smr.sharedMesh;
            meshIndex[s] = ci.mesh.vertexCount;
            ci.transform = smr.transform.localToWorldMatrix;
            combineInstances.Add(ci);

            Object.Destroy(smr.gameObject);
        }

        List <Matrix4x4> bindposes = new List <Matrix4x4>();

        for (int b = 0; b < bones.Count; b++)
        {
            bindposes.Add(bones[b].worldToLocalMatrix * transform.worldToLocalMatrix);
        }

        SkinnedMeshRenderer r = gameObject.AddComponent <SkinnedMeshRenderer>();

        r.sharedMesh = new Mesh();
        r.sharedMesh.CombineMeshes(combineInstances.ToArray(), true, true);

        Texture2D skinnedMeshAtlas = new Texture2D(128, 128);

        Rect[]    packingResult = skinnedMeshAtlas.PackTextures(textures.ToArray(), 0);
        Vector2[] originalUVs   = r.sharedMesh.uv;
        Vector2[] atlasUVs      = new Vector2[originalUVs.Length];

        int rectIndex   = 0;
        int vertTracker = 0;

        for (int i = 0; i < atlasUVs.Length; i++)
        {
            atlasUVs[i].x = Mathf.Lerp(packingResult[rectIndex].xMin, packingResult[rectIndex].xMax, originalUVs[i].x);
            atlasUVs[i].y = Mathf.Lerp(packingResult[rectIndex].yMin, packingResult[rectIndex].yMax, originalUVs[i].y);

            if (i >= meshIndex[rectIndex] + vertTracker)
            {
                vertTracker += meshIndex[rectIndex];
                rectIndex++;
            }
        }

        Material combinedMat = new Material(Shader.Find("Diffuse"));

        combinedMat.mainTexture = skinnedMeshAtlas;
        r.sharedMesh.uv         = atlasUVs;
        r.sharedMaterial        = combinedMat;

        r.bones = bones.ToArray();
        r.sharedMesh.boneWeights = boneWeights.ToArray();
        r.sharedMesh.bindposes   = bindposes.ToArray();
        r.sharedMesh.RecalculateBounds();
    }
Ejemplo n.º 14
0
    private void RedrawRenderer(MeshVisualizeInfo mvi)
    {
        GameObject g;

        renderers.TryGetValue(mvi, out g);
        if (g != null)
        {
            int n = blockVisualizersList.Count;
            if (n > 0)
            {
                var indexes = new List <int>();
                for (int i = 0; i < n; i++)
                {
                    if (blockVisualizersList[i].meshInfo == mvi)
                    {
                        indexes.Add(i);
                    }
                }

                n = indexes.Count;
                if (n > 0)
                {
                    CombineInstance[]      cir = new CombineInstance[n], cic = new CombineInstance[n];
                    BlockpartVisualizeInfo bvi;
                    Mesh      cm;
                    Matrix4x4 mtr;
                    for (int i = 0; i < n; i++)
                    {
                        bvi              = blockVisualizersList[indexes[i]];
                        cm               = MeshMaster.GetMesh(bvi.meshType, bvi.materialID);
                        cir[i].mesh      = cm;
                        mtr              = bvi.GetPositionMatrix();
                        cir[i].transform = mtr;
                        cic[i].mesh      = bvi.meshType == MeshType.Quad ? cm : MeshMaster.GetMeshColliderLink(bvi.meshType);
                        cic[i].transform = mtr;
                    }
                    cm = new Mesh();
                    cm.CombineMeshes(cir);
                    g.GetComponent <MeshFilter>().sharedMesh = cm;
                    cm = new Mesh();
                    cm.CombineMeshes(cic);
                    g.GetComponent <MeshCollider>().sharedMesh = cm;
                    if (PoolMaster.useIlluminationSystem)
                    {
                        g.GetComponent <MeshRenderer>().sharedMaterial = PoolMaster.GetMaterial(mvi.materialType, mvi.illumination);
                    }
                    else
                    {
                        g.GetComponent <MeshRenderer>().sharedMaterial = PoolMaster.GetMaterial(mvi.materialType);
                    }
                }
                else
                {
                    renderers.Remove(mvi);
                    Destroy(g);
                }
            }
        }
        else
        {
            CreateBlockpartsRenderer(mvi);
        }
    }
Ejemplo n.º 15
0
    private void CreateBlockpartsRenderer(MeshVisualizeInfo mvi)
    {
        if (renderers.ContainsKey(mvi))
        {
            return;
        }
        var processingIndexes = new List <int>();

        for (int i = 0; i < blockVisualizersList.Count; i++)
        {
            if (blockVisualizersList[i].meshInfo == mvi)
            {
                processingIndexes.Add(i);
            }
        }

        int pcount = processingIndexes.Count;

        if (pcount > 0)
        {
            var  ci = new CombineInstance[pcount];
            Mesh m;
            BlockpartVisualizeInfo cdata;
            for (int j = 0; j < pcount; j++)
            {
                cdata           = blockVisualizersList[processingIndexes[j]];
                m               = MeshMaster.GetMesh(cdata.meshType, cdata.materialID);
                ci[j].mesh      = m;
                ci[j].transform = cdata.GetPositionMatrix();
            }

            GameObject g = new GameObject();
            m = new Mesh();
            m.CombineMeshes(ci, true); // все подмеши используют один материал

            //удаление копий вершин на стыках - отменено из-за uv

            var mf = g.AddComponent <MeshFilter>();
            mf.sharedMesh = m;

            var mr = g.AddComponent <MeshRenderer>();
            mr.shadowCastingMode    = UnityEngine.Rendering.ShadowCastingMode.Off;
            mr.receiveShadows       = PoolMaster.shadowCasting;
            mr.lightProbeUsage      = UnityEngine.Rendering.LightProbeUsage.Off;
            mr.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
            if (!PoolMaster.useIlluminationSystem)
            {
                mr.sharedMaterial = PoolMaster.GetMaterial(mvi.materialType);
            }
            else
            {
                mr.sharedMaterial = PoolMaster.GetMaterial(mvi.materialType, mvi.illumination);
            }

            g.transform.parent = renderersHolders[mvi.faceIndex].transform;
            g.AddComponent <MeshCollider>().sharedMesh = m;
            g.tag = BLOCK_COLLIDER_TAG;

            renderers.Add(mvi, g);
        }
    }
    private IEnumerator display(int lod)
    {
        this.manager.displayingRegions.Add(this);
        this.computingDisplay = true;

        MeshFilter filter = this.gameObject.GetComponent <MeshFilter>();

        if (filter != null)
        {
            Destroy(filter.mesh);
            filter.mesh = null;
        }

        int pointsBuffer = 0;

        for (int i = 0; i < REGIONSIZE - lod; i = i + lod)
        {
            for (int j = 0; j < REGIONSIZE - lod; j = j + lod)
            {
                float[] pointHeightmap = new float[] {
                    this.heightmap[i, j],
                    this.heightmap[i + lod, j],
                    this.heightmap[i, j + lod],
                    this.heightmap[i + lod, j + lod]
                };

                this.points[i, j].display(lod, pointHeightmap);

                pointsBuffer++;
                if (pointsBuffer >= WorldRegionManager.REGIONSPOINTSDISPLAYBUFFERSIZE)
                {
                    pointsBuffer = 0;
                    yield return(new WaitForEndOfFrame());
                }
            }
        }

        List <MeshFilter> meshFilters = new List <MeshFilter>();

        for (int i = 0; i < REGIONSIZE; i++)
        {
            for (int j = 0; j < REGIONSIZE; j++)
            {
                if (this.points[i, j].gameObject.GetComponent <MeshFilter>() != null)
                {
                    meshFilters.Add(this.points[i, j].gameObject.GetComponent <MeshFilter>());
                }
            }
        }
        CombineInstance[] combineInstances = new CombineInstance[meshFilters.Count];
        for (int i = 0; i < combineInstances.Length; i++)
        {
            if (meshFilters[i] != null)
            {
                combineInstances[i].mesh      = meshFilters[i].mesh;
                combineInstances[i].transform = Matrix4x4.TRS(this.gameObject.transform.InverseTransformPoint(meshFilters[i].gameObject.transform.position), Quaternion.Inverse(meshFilters[i].gameObject.transform.rotation), Vector3.one);
            }
        }

        MeshRenderer renderer = this.gameObject.GetComponent <MeshRenderer>();

        if (renderer == null)
        {
            renderer = this.gameObject.AddComponent <MeshRenderer>();
        }

        filter = this.gameObject.GetComponent <MeshFilter>();
        if (filter == null)
        {
            filter = this.gameObject.AddComponent <MeshFilter>();
            Mesh mesh = new Mesh();
            filter.mesh = mesh;
        }
        filter.mesh.CombineMeshes(combineInstances);
        filter.mesh.RecalculateBounds();
        filter.mesh.RecalculateNormals();

        switch (this.manager.regionsType)
        {
        case WorldRegionManager.RegionsType.Sand:
            renderer.material       = (Material)Instantiate(this.level.resources[61]);
            renderer.sharedMaterial = (Material)Instantiate(this.level.resources[61]);
            break;

        case WorldRegionManager.RegionsType.Rock:
            renderer.material       = (Material)Instantiate(this.level.resources[62]);
            renderer.sharedMaterial = (Material)Instantiate(this.level.resources[62]);
            break;
        }

        for (int i = 0; i < REGIONSIZE; i++)
        {
            for (int j = 0; j < REGIONSIZE; j++)
            {
                Destroy(this.points[i, j].gameObject);
                this.points[i, j] = null;
            }
        }

        this.manager.displayingRegions.Remove(this);
        this.computingDisplay = false;
        this.status           = Status.Displayed;
        //Debug.Log("WorldRegion " + this.ToString() + " displayed");
    }
Ejemplo n.º 17
0
    private void CombineWalls()
    {
        Vector3    basePosition = transform.position;
        Quaternion baseRotation = transform.rotation;

        transform.position = Vector3.zero;
        transform.rotation = Quaternion.identity;



        ArrayList materials             = new ArrayList();
        ArrayList combineInstanceArrays = new ArrayList();

        MeshFilter[] meshFilters = wallMesh.GetComponentsInChildren <MeshFilter>();

        //Linq solution to make sure we don't combine any of the doors(a door is easily identifiable by it's rigidbody component, so we look for that).
        meshFilters = meshFilters.Where((source, index) => !(source.transform.name == "FloorMesh" || source.transform.name == "WallMesh" || source.transform.GetComponent <Rigidbody>() || source.transform.GetComponentInParent <Rigidbody>())).ToArray();
        foreach (MeshFilter meshFilter in meshFilters)
        {
            MeshRenderer meshRenderer = meshFilter.GetComponent <MeshRenderer>();
            if (!meshRenderer ||
                !meshFilter.sharedMesh ||
                meshRenderer.sharedMaterials.Length != meshFilter.sharedMesh.subMeshCount)
            {
                print(meshFilter.gameObject.name);
                continue;
            }

            for (int s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
            {
                if (meshRenderer.sharedMaterials[s])
                {
                    int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[s].name);
                    if (materialArrayIndex == -1)
                    {
                        materials.Add(meshRenderer.sharedMaterials[s]);
                        materialArrayIndex = materials.Count - 1;
                    }
                    combineInstanceArrays.Add(new ArrayList());

                    CombineInstance combineInstance = new CombineInstance();
                    combineInstance.transform    = meshRenderer.transform.localToWorldMatrix;
                    combineInstance.subMeshIndex = s;
                    combineInstance.mesh         = meshFilter.sharedMesh;
                    (combineInstanceArrays[materialArrayIndex] as ArrayList).Add(combineInstance);
                }
            }
        }

        // Get / Create mesh filter & renderer
        MeshFilter meshFilterCombine = wallMesh.GetComponent <MeshFilter>();

        if (meshFilterCombine == null)
        {
            meshFilterCombine = wallMesh.AddComponent <MeshFilter>();
        }
        MeshRenderer meshRendererCombine = gameObject.GetComponent <MeshRenderer>();

        if (meshRendererCombine == null)
        {
            meshRendererCombine = wallMesh.AddComponent <MeshRenderer>();
        }

        // Combine by material index into per-material meshes
        // also, Create CombineInstance array for next step
        Mesh[]            meshes           = new Mesh[materials.Count];
        CombineInstance[] combineInstances = new CombineInstance[materials.Count];

        for (int m = 0; m < materials.Count; m++)
        {
            CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[];
            meshes[m] = new Mesh();
            meshes[m].CombineMeshes(combineInstanceArray, true, true);

            combineInstances[m]              = new CombineInstance();
            combineInstances[m].mesh         = meshes[m];
            combineInstances[m].subMeshIndex = 0;
        }

        // Combine into one
        meshFilterCombine.sharedMesh = new Mesh();
        meshFilterCombine.sharedMesh.CombineMeshes(combineInstances, false, false);

        // Destroy other meshes
        foreach (Mesh oldMesh in meshes)
        {
            oldMesh.Clear();
            DestroyImmediate(oldMesh);
        }

        // Assign materials
        Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[];
        meshRendererCombine.materials = materialsArray;

        foreach (MeshFilter meshFilter in meshFilters)
        {
            if (!meshFilter || meshFilter.transform.GetComponent <Rigidbody>() || meshFilter.transform.GetComponentInParent <Rigidbody>() || meshFilter.transform.GetComponentInChildren <Rigidbody>())
            {
                continue;
            }
            print(meshFilter.gameObject.transform.parent.name);
            DestroyImmediate(meshFilter.gameObject.transform.parent.gameObject);
        }
        wallMesh.transform.position = basePosition;
        wallMesh.transform.rotation = baseRotation;
        wallMesh.AddComponent <MeshCollider>().sharedMesh = wallMesh.GetComponent <MeshFilter>().sharedMesh;
    }
Ejemplo n.º 18
0
        // GENERATE PAIR_REPEATER
        public override GameObject generate(bool makeGameObjects, AXParametricObject initiator_po, bool isReplica)
        {
            //Debug.Log ("PairRepeater::Generate ");
            if (parametricObject == null || !parametricObject.isActive)
            {
                return(null);
            }

            preGenerate();

            if ((nodeSrc_p == null || nodeSrc_p.meshes == null || nodeSrc_p.meshes.Count == 0) && (nodeSrc_po != null && !(nodeSrc_po.generator is PrefabInstancer)))
            {
                return(null);
            }


            if (P_Node == null || P_Node.DependsOn == null)
            {
                return(null);
            }

            GameObject go = null;

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


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

            GameObject plugGO = null;

            if (makeGameObjects && !parametricObject.combineMeshes)
            {
                plugGO = nodeSrc_po.generator.generate(true, initiator_po, isReplica);


                if (plugGO == null)
                {
                    return(null);
                }
            }



            float separationX = zAxis ? 0 : separation;
            float separationZ = zAxis ? -separation : 0;


            CombineInstance[] boundsCombinator = new CombineInstance[2];



            // * RIGHT INSTANCE	*
            // --------------------------------------------------------------------


            // Right Instance is at Address 0...
            Matrix4x4 localPlacement_mx = localNodeMatrixFromAddress(0);

            // use submeshes for right instance

            // AX_MESHES

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


            // BOUNDING MESHES

            boundsCombinator[0].mesh      = nodeSrc_po.boundsMesh;
            boundsCombinator[0].transform = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment;



            // GAME_OBJECTS

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

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


                copyGO.name             = copyGO.name + "_node_right";
                copyGO.transform.parent = go.transform;
            }



            // * INVERSE (LEFT) INSTANCE
            // --------------------------------------------------------------------

            // ***--- AX_MESHES - INVERSE (LEFT) ---***



            translate = new Vector3(-separationX / 2, 0, -separationZ / 2);

            // LOCAL PLACEMENT
            localPlacement_mx = localNodeMatrixFromAddress(1);

            // use submeshes for left instance
            for (int mi = 0; mi < P_Node.DependsOn.meshes.Count; mi++)
            {
                // CLONE
                AXMesh dep_amesh = P_Node.DependsOn.meshes [mi];
                AXMesh clone     = dep_amesh.Clone();
                // SYMETRICAL?
                if (symmetrical)
                {
                    clone.mesh        = AXMesh.freezeWithMatrix(dep_amesh.mesh, symmetryM * dep_amesh.transMatrix);
                    clone.transMatrix = localPlacement_mx * symmetryM.inverse;
                }
                else
                {
                    clone = dep_amesh.Clone(localPlacement_mx * symmetryM.inverse * dep_amesh.transMatrix);
                }
                // ADD TO AX_MESHES
                ax_meshes.Add(clone);
            }



            // BOUNDING MESHES

            boundsCombinator[1].mesh      = nodeSrc_po.boundsMesh;
            boundsCombinator[1].transform = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment;



            //   *** --- INVERSE (LEFT) - GAME_OBJECT ---**
            if (plugGO != null && makeGameObjects && !parametricObject.combineMeshes)
            {
                // LOCAL PLACEMENT
                //Matrix4x4 mx = localPlacement_mx  * symmetryM * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment;
                Matrix4x4 mx = localPlacement_mx * nodeSrc_po.generator.localMatrixWithAxisRotationAndAlignment;



                // GAME_OBJECT
                GameObject copyGO = (GameObject)GameObject.Instantiate(plugGO, AXUtilities.GetPosition(mx), AXUtilities.QuaternionFromMatrix(mx));
                copyGO.transform.localScale = nodeSrc_po.getLocalScaleAxisRotated();

                // SYMETRICAL?
                if (symmetrical)
                {
                    copyGO.transform.localScale = copyGO.transform.localScale * -1;
                    if (zAxis)
                    {
                        copyGO.transform.Rotate(0, 180, 180);
                    }
                    else
                    {
                        copyGO.transform.Rotate(180, 0, 0);
                    }
                }


                // Force a refreshing of the colliders down the instatiatined hierachy
                // Based on a solution provided by pkamat here:http://forum.unity3d.com/threads/how-to-update-a-mesh-collider.32467/

                foreach (MeshCollider mc in copyGO.GetComponentsInChildren <MeshCollider>())
                {
                    mc.sharedMesh = null;
                    mc.sharedMesh = mc.gameObject.GetComponent <MeshFilter>().sharedMesh;
                }


                // ADD GAME_OBJECT
                AXGameObject axgo = copyGO.GetComponent <AXGameObject>();
                if (axgo != null)
                {
                    axgo.consumerAddress = "node_1";
                }

                copyGO.name             = copyGO.name + "_node_left";
                copyGO.transform.parent = go.transform;
            }



            GameObject.DestroyImmediate(plugGO);



            // COMBINE ALL THE MESHES
            CombineInstance[] combine = new CombineInstance[ax_meshes.Count];

            int combineCt = 0;

            for (int i = 0; i < ax_meshes.Count; i++)
            {
                AXMesh _amesh = ax_meshes [i];
                combine [combineCt].mesh      = _amesh.mesh;
                combine [combineCt].transform = _amesh.transMatrix;
                combineCt++;
            }
            Mesh combinedMesh = new Mesh();

            combinedMesh.CombineMeshes(combine);
            combinedMesh.RecalculateBounds();

            // BOUNDARY - Use combined meshes for boundary
            setBoundsWithCombinator(boundsCombinator);

            /*
             * // BOUNDS & CENTER
             *
             * Vector3 margin = new Vector3(source_po.bounds.size.x, source_po.bounds.size.y, source_po.bounds.size.z);
             * Bounds b = new Bounds();
             * b.size = new Vector3(separationX + margin.x, margin.y, separationZ + margin.z);
             * b.extents = b.size/2;
             * b.center = source_po.bounds.center;// + new Vector3(0, b.extents.y, 0);
             *
             * parametricObject.margin = margin;
             * parametricObject.bounds = b;
             */

            // FINISH
            parametricObject.finishMultiAXMeshAndOutput(ax_meshes, isReplica);


            // Turn ax_meshes into GameObjects
            if (makeGameObjects)
            {
                if (parametricObject.combineMeshes)
                {
                    go = parametricObject.makeGameObjectsFromAXMeshes(ax_meshes, true, false);

                    // If combine, use combined mesh as invisible collider
                    MeshFilter mf = (MeshFilter)go.GetComponent(typeof(MeshFilter));
                    if (mf == null)
                    {
                        mf = (MeshFilter)go.AddComponent(typeof(MeshFilter));
                    }
                    if (mf != null)
                    {
                        mf.sharedMesh = combinedMesh;

                        parametricObject.addCollider(go);
                    }
                }

                //Matrix4x4 tmx = parametricObject.generator.localMatrix;
                Matrix4x4 tmx = parametricObject.getLocalMatrix();

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



                return(go);
            }


            return(null);
        }
Ejemplo n.º 19
0
    void Start()
    {
        Matrix4x4 myTransform = transform.worldToLocalMatrix;

        combines       = new Dictionary <string, List <CombineInstance> >();
        namedMaterials = new Dictionary <string, Material>();

        //For each mesh renderer within all children attached to this gameobject
        MeshRenderer[] meshRenderers = GetComponentsInChildren <MeshRenderer>();
        foreach (var meshRenderer in meshRenderers)
        {
            //Grab each material in shared materials for the current mesh renderer
            foreach (var material in meshRenderer.sharedMaterials)
            {
                if (material != null && !combines.ContainsKey(material.name))
                {
                    combines.Add(material.name, new List <CombineInstance>());
                    namedMaterials.Add(material.name, material);
                }
            }
        }

        MeshFilter[] meshFilters = GetComponentsInChildren <MeshFilter>();
        foreach (var filter in meshFilters)
        {
            if (filter.sharedMesh == null)
            {
                continue;
            }
            var filterRenderer = filter.GetComponent <Renderer>();
            if (filterRenderer.sharedMaterial == null)
            {
                continue;
            }
            if (filterRenderer.sharedMaterials.Length > 1)
            {
                continue;
            }
            CombineInstance ci = new CombineInstance
            {
                mesh      = filter.sharedMesh,
                transform = myTransform * filter.transform.localToWorldMatrix
            };
            combines[filterRenderer.sharedMaterial.name].Add(ci);

            Destroy(filterRenderer);
        }

        foreach (Material m in namedMaterials.Values)
        {
            var go = new GameObject("Combined mesh");
            go.transform.parent        = transform;
            go.transform.localPosition = Vector3.zero;
            go.transform.localRotation = Quaternion.identity;
            go.transform.localScale    = Vector3.one;

            var filter = go.AddComponent <MeshFilter>();
            filter.mesh.CombineMeshes(combines[m.name].ToArray(), true, true);

            var arenderer = go.AddComponent <MeshRenderer>();
            arenderer.material = m;
        }

        turnOnLightsAfterMeshCombine();
    }
Ejemplo n.º 20
0
    public void Combine()
    {
        Transform[] childTransforms = gameObject.GetComponentsInChildren <Transform> ();
        foreach (Transform childTransform in childTransforms)
        {
            Objects.Add(childTransform.gameObject);
        }

        // Find all mesh filter submeshes and separate them by their cooresponding materials
        ArrayList materials             = new ArrayList();
        ArrayList combineInstanceArrays = new ArrayList();

        foreach (GameObject obj in Objects)
        {
            if (!obj)
            {
                continue;
            }

            MeshFilter[] meshFilters = obj.GetComponentsInChildren <MeshFilter>();

            foreach (MeshFilter meshFilter in meshFilters)
            {
                MeshRenderer meshRenderer = meshFilter.GetComponent <MeshRenderer>();

                // Handle bad input
                if (!meshRenderer)
                {
                    Debug.LogError("MeshFilter does not have a coresponding MeshRenderer.");
                    continue;
                }
                if (meshRenderer.materials.Length != meshFilter.sharedMesh.subMeshCount)
                {
                    Debug.LogError("Mismatch between material count and submesh count. Is this the correct MeshRenderer?");
                    continue;
                }

                for (int s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
                {
                    int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials [s].name);
                    if (materialArrayIndex == -1)
                    {
                        materials.Add(meshRenderer.sharedMaterials [s]);
                        materialArrayIndex = materials.Count - 1;
                    }
                    combineInstanceArrays.Add(new ArrayList());

                    CombineInstance combineInstance = new CombineInstance();
                    combineInstance.transform    = meshRenderer.transform.localToWorldMatrix;
                    combineInstance.subMeshIndex = s;
                    combineInstance.mesh         = meshFilter.sharedMesh;
                    (combineInstanceArrays [materialArrayIndex] as ArrayList).Add(combineInstance);
                }
            }
        }

        // For MeshFilter
        {
            // Get / Create mesh filter
            MeshFilter meshFilterCombine = gameObject.GetComponent <MeshFilter>();
            if (!meshFilterCombine)
            {
                meshFilterCombine = gameObject.AddComponent <MeshFilter>();
            }

            // Combine by material index into per-material meshes
            // also, Create CombineInstance array for next step
            Mesh[]            meshes           = new Mesh[materials.Count];
            CombineInstance[] combineInstances = new CombineInstance[materials.Count];

            for (int m = 0; m < materials.Count; m++)
            {
                CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[];
                meshes[m] = new Mesh();
                meshes[m].CombineMeshes(combineInstanceArray, true, true);

                combineInstances[m]              = new CombineInstance();
                combineInstances[m].mesh         = meshes[m];
                combineInstances[m].subMeshIndex = 0;
            }

            // Combine into one
            meshFilterCombine.sharedMesh = new Mesh();
            meshFilterCombine.sharedMesh.CombineMeshes(combineInstances, false, false);

            // Destroy other meshes
            foreach (Mesh mesh in meshes)
            {
                mesh.Clear();
                DestroyImmediate(mesh);
            }
        }

        // For MeshRenderer
        {
            // Get / Create mesh renderer
            MeshRenderer meshRendererCombine = gameObject.GetComponent <MeshRenderer>();
            if (!meshRendererCombine)
            {
                meshRendererCombine = gameObject.AddComponent <MeshRenderer>();
            }

            // Assign materials
            Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[];
            meshRendererCombine.materials = materialsArray;
        }
    }
Ejemplo n.º 21
0
        void CreatePickingMesh()
        {
            var renderer = GetComponent <MeshRenderer>();
            var filter   = GetComponent <MeshFilter>();

            if (!renderer)
            {
                var brick = GetComponent <Brick>();

                var combineInstances = new List <CombineInstance>();

                if (brick)
                {
                    // Get all shells from parts and combine them.
                    foreach (var part in brick.parts)
                    {
                        if (part.legacy)
                        {
                            var partRenderer = part.GetComponent <MeshRenderer>();
                            if (partRenderer)
                            {
                                var mesh            = partRenderer.GetComponent <MeshFilter>().sharedMesh;
                                var combineInstance = new CombineInstance();
                                combineInstance.mesh      = mesh;
                                combineInstance.transform = transform.worldToLocalMatrix * part.transform.localToWorldMatrix;

                                combineInstances.Add(combineInstance);
                            }
                        }
                        else
                        {
                            var shell = part.transform.Find("Shell");
                            if (shell)
                            {
                                var mesh            = shell.GetComponent <MeshFilter>().sharedMesh;
                                var combineInstance = new CombineInstance();
                                combineInstance.mesh      = mesh;
                                combineInstance.transform = transform.worldToLocalMatrix * shell.localToWorldMatrix;

                                combineInstances.Add(combineInstance);
                            }

                            var colourChangeSurfaces = part.transform.Find("ColourChangeSurfaces");
                            if (colourChangeSurfaces)
                            {
                                foreach (Transform colourChangeSurface in colourChangeSurfaces)
                                {
                                    var mesh            = colourChangeSurface.GetComponent <MeshFilter>().sharedMesh;
                                    var combineInstance = new CombineInstance();
                                    combineInstance.mesh      = mesh;
                                    combineInstance.transform = transform.worldToLocalMatrix * colourChangeSurface.localToWorldMatrix;

                                    combineInstances.Add(combineInstance);
                                }
                            }
                        }
                    }
                }

                Mesh combinedMesh = null;
                if (combineInstances.Count == 1)
                {
                    // If there is just one mesh, simply use a reference to that rather than combining.
                    // We know that the one mesh will not be transformed, so it's safe to ignore the transform on the CombineInstance.
                    combinedMesh = combineInstances[0].mesh;
                }
                else if (combineInstances.Count > 1)
                {
                    // Otherwise, if there's more than one, create and save a mesh asset (if it does not exist already).
                    // Then reference that mesh asset.
                    if (!PickingMeshUtils.CheckIfPickingMeshExists(name))
                    {
                        var newMesh = new Mesh();
                        newMesh.CombineMeshes(combineInstances.ToArray(), true, true, false);

                        PickingMeshUtils.SavePickingMesh(name, newMesh);
                        combinedMesh = PickingMeshUtils.LoadPickingMesh(name);
                    }
                    else
                    {
                        combinedMesh = PickingMeshUtils.LoadPickingMesh(name);
                    }
                }
                else
                {
                    // If there were no meshes, we assume it is a minifig and use a box mesh.
                    combinedMesh = PickingMeshUtils.LoadMinifigPickingMesh();
                }

                renderer = gameObject.AddComponent <MeshRenderer>();
                renderer.sharedMaterial = AssetDatabase.LoadAssetAtPath <Material>("Packages/com.unity.lego.modelimporter/Materials/LEGO_AssetPicking.mat");
                filter            = gameObject.AddComponent <MeshFilter>();
                filter.sharedMesh = combinedMesh;
            }

            // Need to hide the renderer, filter and material every time as they do not stay hidden when reloading the scene.
            renderer.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable;
            renderer.sharedMaterial.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable;
            filter.hideFlags = HideFlags.HideInInspector | HideFlags.NotEditable;
        }
Ejemplo n.º 22
0
    void Start()
    {
        MeshFilter[]      meshFilters   = GetComponentsInChildren <MeshFilter>();
        MeshRenderer[]    meshRenderers = GetComponentsInChildren <MeshRenderer>();
        CombineInstance[] combine       = new CombineInstance[meshFilters.Length];
        //Material[] SharedMats = meshRenderers[1].sharedMaterials;
        Material MainMaterial = meshRenderers[1].materials[0];

        Material[]             SubMaterial = new Material[meshRenderers[1].materials.Length - 1];
        List <CombineInstance> combine2    = new List <CombineInstance>();

        // gotta get this big enough
        SubMaterial = new Material[2];

        for (int i = 0; i < meshFilters.Length; i++)
        {
            Mesh mShared = meshFilters[i].sharedMesh;

            combine[i].mesh      = mShared;
            combine[i].transform = meshFilters[i].transform.localToWorldMatrix;

            if (mShared.subMeshCount > 1)
            {
                // combine submeshes
                for (int j = 0; j < mShared.subMeshCount; j++)
                {
                    if (j < mShared.subMeshCount - 1)
                    {
                        SubMaterial[i] = meshRenderers[1].materials[0];
                    }
                    CombineInstance ci = new CombineInstance();

                    ci.mesh         = mShared;
                    ci.subMeshIndex = j;
                    ci.transform    = meshFilters[i].transform.localToWorldMatrix;

                    combine2.Add(ci);
                }
            }

            meshFilters[i].gameObject.SetActive(false);
        }
        GameObject go = new GameObject(gameObject.name);

        go.AddComponent <MeshFilter>();
        go.AddComponent <MeshRenderer>();

        var goFilter   = go.GetComponent <MeshFilter>();
        var goRenderer = go.GetComponent <MeshRenderer>();

        go.SetActive(false);
        goFilter.mesh = new Mesh();
        goFilter.mesh.CombineMeshes(combine);
        go.SetActive(true);

        //goRenderer.materials = Mats;
        goRenderer.material = MainMaterial;

        if (SubMaterial.Length >= 1)
        {
            GameObject go2 = new GameObject(gameObject.name + "Sub");
            go2.AddComponent <MeshFilter>();
            go2.AddComponent <MeshRenderer>();

            var goFilter2   = go2.GetComponent <MeshFilter>();
            var goRenderer2 = go2.GetComponent <MeshRenderer>();

            go2.SetActive(false);
            goFilter2.mesh = new Mesh();
            goFilter2.mesh.CombineMeshes(combine2.ToArray(), false);
            go2.SetActive(true);

            //goRenderer.materials = Mats;
            goRenderer2.materials = SubMaterial;
        }

        Destroy(gameObject);
    }
Ejemplo n.º 23
0
        void Start()
        {
            // Create an array of CombineInstances to hold tube meshes temporarily.
            CombineInstance[] combineInstances = new CombineInstance[HAIR_COUNT];

            // Temporary variables for calculating positions.
            float revolutions    = 0;
            float positionRadius = HAIR_RADIUS;

            // Create tubes.
            for (int h = 0; h < HAIR_COUNT; h++)
            {
                // Create game object and add TubeRenderer component.
                TubeRenderer tube = new GameObject().AddComponent <TubeRenderer>();

                // Position object.
                revolutions            += (HAIR_RADIUS * 2) / (positionRadius * Mathf.PI * 2);
                positionRadius          = revolutions * (HAIR_RADIUS * 2);
                tube.transform.position = Quaternion.Euler(0, revolutions * 360, 0) * Vector3.forward * positionRadius;

                // No caps please.
                tube.caps = TubeRenderer.CapMode.None;

                // Toggle between two different uv mappings.
                tube.uvRect = h % 2 == 0 ? new Rect(0.01f, 0.01f, 0.48f, 0.48f) : new Rect(0, 0.51f, 0.48f, 0.48f);

                // Create points and radiuses arrays.
                tube.points   = new Vector3[POINT_COUNT];
                tube.radiuses = new float[POINT_COUNT];

                // Calculate height.
                float hairNorm = h / (HAIR_COUNT - 1f);
                float height   = Mathf.Pow(1 - hairNorm, 0.8f) * 0.5f;

                // Define points and radiuses.
                tube.points[0]   = Vector3.zero;
                tube.radiuses[0] = HAIR_RADIUS;
                for (int p = 1; p < POINT_COUNT; p++)
                {
                    float norm  = (p - 1) / (POINT_COUNT - 2f);
                    float angle = norm * Mathf.PI * 0.5f;
                    tube.radiuses[p] = Mathf.Cos(angle) * HAIR_RADIUS;
                    float y = height + Mathf.Sin(angle) * HAIR_RADIUS;
                    tube.points[p] = new Vector3(0, y, 0);
                }

                // Force update to generate the tube mesh immediately.
                tube.ForceUpdate();

                // Add the tube mesh to the combine instances.
                combineInstances[h].mesh      = tube.mesh;
                combineInstances[h].transform = tube.transform.localToWorldMatrix;

                // Destroy the TubeRenderer we just used to build the mesh.
                Destroy(tube.gameObject);
            }

            // Add mesh rendering components and combine tubes.
            gameObject.AddComponent <MeshRenderer>();
            MeshFilter filter = gameObject.AddComponent <MeshFilter>();

            filter.mesh.CombineMeshes(combineInstances);

            // Add a material and a texture.
            GetComponent <Renderer>().material             = new Material(Shader.Find("Diffuse"));
            GetComponent <Renderer>().material.mainTexture = Helpers.CreateTileTexture(2);
        }
Ejemplo n.º 24
0
    static void CombineCollider()
    {
        if (Selection.activeGameObject == null)
        {
            return;
        }

        MeshFilter[] meshFilters = Selection.activeGameObject.GetComponentsInChildren <MeshFilter>();

        if (meshFilters.Length == 0)
        {
            return;
        }

        List <CombineInstance> combine = new List <CombineInstance>();

        var delete = EditorUtility.DisplayDialog("Collider Generator", "Delete Child Collider?", "Yes", "No");

        var hadFilter = true;

        if (Selection.activeGameObject.GetComponent <MeshFilter>() == null)
        {
            hadFilter = false;
            Selection.activeGameObject.AddComponent <MeshFilter>();
        }

        var prevMesh = Selection.activeGameObject.GetComponent <MeshFilter>().sharedMesh;

        var count = 0;

        if (Selection.activeGameObject.GetComponent <MeshCollider>())
        {
            DestroyImmediate(Selection.activeGameObject.GetComponent <MeshCollider>());
        }

        for (int i = 0; i < meshFilters.Length; i++)
        {
            if (meshFilters[i].sharedMesh == null)
            {
                if (delete)
                {
                    DestroyImmediate(meshFilters[i]);
                    continue;
                }
            }

            var c = new CombineInstance();
            c.mesh      = meshFilters[i].sharedMesh;
            c.transform = Selection.activeGameObject.transform.worldToLocalMatrix * meshFilters[i].transform.localToWorldMatrix;
            combine.Add(c);
            if (meshFilters[i].GetComponent <Collider>() && delete)
            {
                DestroyImmediate(meshFilters[i].GetComponent <Collider>());
            }

            count += meshFilters[i].sharedMesh.vertexCount;

            if (i + 1 == meshFilters.Length || meshFilters[i + 1].sharedMesh.vertexCount + count > MAXTRISCOUNT)
            {
                if (Selection.activeGameObject.GetComponent <MeshFilter>() == null)
                {
                    Selection.activeGameObject.AddComponent <MeshFilter>();
                }
                Selection.activeGameObject.transform.GetComponent <MeshFilter>().sharedMesh = new Mesh();
                Selection.activeGameObject.transform.GetComponent <MeshFilter>().sharedMesh.CombineMeshes(combine.ToArray());

                Selection.activeGameObject.AddComponent <MeshCollider>();

                combine.Clear();
                count = 0;
            }
        }

        if (hadFilter)
        {
            Selection.activeGameObject.GetComponent <MeshFilter>().sharedMesh = prevMesh;
        }
        else
        {
            DestroyImmediate(Selection.activeGameObject.GetComponent <MeshFilter>());
        }
    }
        // Update is called once per frame
        public override void Update()
        {
            base.Update();
            if (Input.GetMouseButtonDown(0) & !Input.GetKey(KeyCode.LeftControl))
            {
                RaycastHit hit;

                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

                bool canHit = Physics.Raycast(ray, out hit, 100f);

                if (canHit)
                {
                    this.ExtrudeMesh();
                }

                if (Physics.Raycast(ray, out hit, 100f))
                {
                    this.pos    = hit.transform.position;
                    this.normal = hit.normal;

                    hit.transform.position += hit.normal * this.extrusionSenstivity;

                    RaycastHit u;

                    if (Physics.Raycast(hit.point, -hit.normal, out u))
                    {
                        Debug.LogError(u.transform.gameObject);
                        this.ScaleSiblingParts(hit.transform.gameObject, u.transform.gameObject, hit.normal, this.scaleSenstivity, this.positionSenstivity);
                    }

                    CombineInstance[] instances = new CombineInstance[this.triangles.Count];

                    for (int i = 0; i < instances.Length; i++)
                    {
                        instances[i].mesh      = this.triangles[i].GetComponent <MeshFilter>().mesh;
                        instances[i].transform = this.triangles[i].GetComponent <MeshRenderer>().transform.localToWorldMatrix;
                    }

                    for (int i = 0; i < this.triangles.Count; i++)
                    {
                        Destroy(this.triangles[i]);
                    }


                    Mesh m = new Mesh();
                    m.CombineMeshes(instances, true, true);

                    UnityEditor.MeshUtility.Optimize(m);

                    this.meshFilter.mesh = m;

                    this.meshCollider.sharedMesh = m;

                    this.meshRenderer.enabled = true;
                    this.meshCollider.enabled = true;
                }
            }

            if (this.normal != Vector3.zero)
            {
                Debug.DrawRay(this.pos, this.normal * 10f, Color.red);
            }
        }
Ejemplo n.º 26
0
    /// Создание модели лабиринта
    Mesh BuildModel()
    {
        Mesh wallMesh   = Wall(Vector2.zero, new Vector2(.5f, 0), Vector2.up);      // половина текстуры
        Mesh groundMesh = Quad(Vector3.up, Vector3.right, Vector3.forward,
                               new Vector2(.5f, 0), Vector2.right, new Vector2(.5f, .5f));
        Mesh roofMesh = Quad(Vector3.down, Vector3.forward, Vector3.right,
                             new Vector2(.5f, .5f), new Vector2(1, .5f), new Vector2(.5f, 1));
        Vector3 scale     = new Vector3(widthCount, 1, widthCount);
        Quaternion bottom = Quaternion.identity;
        Quaternion left   = Quaternion.Euler(0, 90, 0);
        Quaternion top    = Quaternion.Euler(0, 180, 0);
        Quaternion right  = Quaternion.Euler(0, -90, 0);

        CombineInstance[] meshes = new CombineInstance[getMeshesNumber()];
        int faceOffset = 0, sX, sZ, lastRow = size * widthCount;

        // Строим модель лабиринта на основе элементов массива m
        for (int z = 0; z < size; z++)
        {
            for (int x = 0; x < size; x++)
            {
                sX = x * widthCount;               // scale X
                sZ = z * widthCount;               // scale Y
                if (m[x, z] == boundary)
                {
                    if (z > 0 && m[x, z - 1] > boundary)                        // снизу от текущей клетки
                    {
                        meshes[faceOffset].mesh      = wallMesh;
                        meshes[faceOffset].transform = Matrix4x4.TRS(new Vector3(sX, 0, sZ), bottom, Vector3.one);
                        faceOffset++;
                    }
                    if (x > 0 && m[x - 1, z] > boundary)                        // слева от текущей клетки
                    {
                        meshes[faceOffset].mesh      = wallMesh;
                        meshes[faceOffset].transform = Matrix4x4.TRS(
                            new Vector3(sX, 0, sZ + widthCount), left, Vector3.one);
                        faceOffset++;
                    }
                    if (z < size && m[x, z + 1] > boundary)                     // сверху от текущей клетки
                    {
                        meshes[faceOffset].mesh      = wallMesh;
                        meshes[faceOffset].transform = Matrix4x4.TRS(
                            new Vector3(sX + widthCount, 0, sZ + widthCount), top, Vector3.one);
                        faceOffset++;
                    }
                    if (x < size && m[x + 1, z] > boundary)                     // справа от текущей клетки
                    {
                        meshes[faceOffset].mesh      = wallMesh;
                        meshes[faceOffset].transform = Matrix4x4.TRS(
                            new Vector3(sX + widthCount, 0, sZ), right, Vector3.one);
                        faceOffset++;
                    }
                }
                else
                {
                    meshes[faceOffset].mesh      = groundMesh;                  // пол
                    meshes[faceOffset].transform = Matrix4x4.TRS(new Vector3(sX, 0, sZ), bottom, scale);
                    faceOffset++;
                    meshes[faceOffset].mesh      = roofMesh;                            // крыша
                    meshes[faceOffset].transform = Matrix4x4.TRS(new Vector3(sX, heightCount, sZ), bottom, scale);
                    faceOffset++;
                }
            }
            // Наружные стенки
            sZ = z * widthCount;                     // scale Z
            sX = sZ + widthCount;                    // scale X
            meshes[faceOffset].mesh      = wallMesh; // "нижняя" стенка
            meshes[faceOffset].transform = Matrix4x4.TRS(new Vector3(sX, 0, 0), top, Vector3.one);
            faceOffset++;
            meshes[faceOffset].mesh      = wallMesh;        // "левая" стенка
            meshes[faceOffset].transform = Matrix4x4.TRS(new Vector3(0, 0, sZ), right, Vector3.one);
            faceOffset++;
            meshes[faceOffset].mesh      = wallMesh;        // "верхняя" стенка
            meshes[faceOffset].transform = Matrix4x4.TRS(new Vector3(sZ, 0, lastRow), bottom, Vector3.one);
            faceOffset++;
            meshes[faceOffset].mesh      = wallMesh;        // "правая" стенка
            meshes[faceOffset].transform = Matrix4x4.TRS(new Vector3(lastRow, 0, sX), left, Vector3.one);
            faceOffset++;
        }

        Mesh mesh = new Mesh();

        mesh.CombineMeshes(meshes, true, true);
        mesh.Optimize();
        return(mesh);
    }
Ejemplo n.º 27
0
        static RuntimeHandles()
        {
            LinesMaterial       = new Material(Shader.Find("Battlehub/RTHandles/VertexColor"));
            LinesMaterial.color = Color.white;

            LinesClipMaterial       = new Material(Shader.Find("Battlehub/RTHandles/VertexColorClip"));
            LinesClipMaterial.color = Color.white;

            LinesBillboardMaterial       = new Material(Shader.Find("Battlehub/RTHandles/VertexColorBillboard"));
            LinesBillboardMaterial.color = Color.white;

            ShapesMaterial       = new Material(Shader.Find("Battlehub/RTHandles/Shape"));
            ShapesMaterial.color = Color.white;

            ShapesMaterialZTest       = new Material(Shader.Find("Battlehub/RTHandles/Shape"));
            ShapesMaterialZTest.color = new Color(1, 1, 1, 0);
            ShapesMaterialZTest.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
            ShapesMaterialZTest.SetFloat("_ZWrite", 1.0f);

            ShapesMaterialZTestOffset       = new Material(Shader.Find("Battlehub/RTHandles/Shape"));
            ShapesMaterialZTestOffset.color = new Color(1, 1, 1, 1);
            ShapesMaterialZTestOffset.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
            ShapesMaterialZTestOffset.SetFloat("_ZWrite", 1.0f);
            ShapesMaterialZTestOffset.SetFloat("_OFactors", -1.0f);
            ShapesMaterialZTestOffset.SetFloat("_OUnits", -1.0f);

            ShapesMaterialZTest2       = new Material(Shader.Find("Battlehub/RTHandles/Shape"));
            ShapesMaterialZTest2.color = new Color(1, 1, 1, 0);
            ShapesMaterialZTest2.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
            ShapesMaterialZTest2.SetFloat("_ZWrite", 1.0f);

            ShapesMaterialZTest3       = new Material(Shader.Find("Battlehub/RTHandles/Shape"));
            ShapesMaterialZTest3.color = new Color(1, 1, 1, 0);
            ShapesMaterialZTest3.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
            ShapesMaterialZTest3.SetFloat("_ZWrite", 1.0f);

            ShapesMaterialZTest4       = new Material(Shader.Find("Battlehub/RTHandles/Shape"));
            ShapesMaterialZTest4.color = new Color(1, 1, 1, 0);
            ShapesMaterialZTest4.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
            ShapesMaterialZTest4.SetFloat("_ZWrite", 1.0f);

            XMaterial             = new Material(Shader.Find("Battlehub/RTHandles/Billboard"));
            XMaterial.color       = Color.white;
            XMaterial.mainTexture = Resources.Load <Texture>("Battlehub.RuntimeHandles.x");
            YMaterial             = new Material(Shader.Find("Battlehub/RTHandles/Billboard"));
            YMaterial.color       = Color.white;
            YMaterial.mainTexture = Resources.Load <Texture>("Battlehub.RuntimeHandles.y");
            ZMaterial             = new Material(Shader.Find("Battlehub/RTHandles/Billboard"));
            ZMaterial.color       = Color.white;
            ZMaterial.mainTexture = Resources.Load <Texture>("Battlehub.RuntimeHandles.z");

            GridMaterial       = new Material(Shader.Find("Battlehub/RTHandles/Grid"));
            GridMaterial.color = Color.white;

            Mesh selectionArrowMesh = CreateConeMesh(SelectionColor);

            CombineInstance yArrow = new CombineInstance();

            yArrow.mesh      = selectionArrowMesh;
            yArrow.transform = Matrix4x4.TRS(Vector3.up, Quaternion.identity, Vector3.one);
            SelectionArrowY  = new Mesh();
            SelectionArrowY.CombineMeshes(new[] { yArrow }, true);
            SelectionArrowY.RecalculateNormals();

            CombineInstance xArrow = new CombineInstance();

            xArrow.mesh      = selectionArrowMesh;
            xArrow.transform = Matrix4x4.TRS(Vector3.right, Quaternion.AngleAxis(-90, Vector3.forward), Vector3.one);
            SelectionArrowX  = new Mesh();
            SelectionArrowX.CombineMeshes(new[] { xArrow }, true);
            SelectionArrowX.RecalculateNormals();

            CombineInstance zArrow = new CombineInstance();

            zArrow.mesh      = selectionArrowMesh;
            zArrow.transform = Matrix4x4.TRS(Vector3.forward, Quaternion.AngleAxis(90, Vector3.right), Vector3.one);
            SelectionArrowZ  = new Mesh();
            SelectionArrowZ.CombineMeshes(new[] { zArrow }, true);
            SelectionArrowZ.RecalculateNormals();

            yArrow.mesh = CreateConeMesh(YColor);
            xArrow.mesh = CreateConeMesh(XColor);
            zArrow.mesh = CreateConeMesh(ZColor);
            Arrows      = new Mesh();
            Arrows.CombineMeshes(new[] { yArrow, xArrow, zArrow }, true);
            Arrows.RecalculateNormals();

            SelectionCube = CreateCubeMesh(SelectionColor, 0.1f, 0.1f, 0.1f);
            CubeX         = CreateCubeMesh(XColor, 0.1f, 0.1f, 0.1f);
            CubeY         = CreateCubeMesh(YColor, 0.1f, 0.1f, 0.1f);
            CubeZ         = CreateCubeMesh(ZColor, 0.1f, 0.1f, 0.1f);
            CubeUniform   = CreateCubeMesh(AltColor, 0.1f, 0.1f, 0.1f);

            SceneGizmoSelectedAxis = CreateSceneGizmoHalfAxis(SelectionColor, Quaternion.AngleAxis(90, Vector3.right));
            SceneGizmoXAxis        = CreateSceneGizmoAxis(XColor, AltColor, Quaternion.AngleAxis(-90, Vector3.forward));
            SceneGizmoYAxis        = CreateSceneGizmoAxis(YColor, AltColor, Quaternion.identity);
            SceneGizmoZAxis        = CreateSceneGizmoAxis(ZColor, AltColor, Quaternion.AngleAxis(90, Vector3.right));
            SceneGizmoCube         = CreateCubeMesh(AltColor);
            SceneGizmoSelectedCube = CreateCubeMesh(SelectionColor);
            SceneGizmoQuad         = CreateQuadMesh();
        }
Ejemplo n.º 28
0
    // Start is called before the first frame update
    void Start()
    {
        //also from youtube
        for (int x = 0; x < chunkSizeVerts; x++)
        {
            for (int y = 0; y < chunkSizeVerts; y++)
            {
                for (int z = 0; z < chunkSizeVerts; z++)
                {
                    float noise = Perlin3D(x * noiseScale, y * noiseScale, z * noiseScale);
                    if (noise >= threshold) //here we pass floats instead so that Perlin behaves
                    {
                        //sampling unity's perlin noise with an integer returns the same value, which was less than the threshold
                        //Instantiate(blockPrefab, new Vector3(x, y, z), Quaternion.identity);//not rotated is what quaternion.identity says
                        //^^ this is if you treat each point as a cube. I will treat each point as a vertex instead.

                        /*bool xSafe = false;
                         * bool ySafe = false;
                         * bool zSafe = false;
                         * if (x == chunkSize - 1)
                         * {
                         *  //check edges (x - 1)
                         * }
                         * else
                         * {
                         *  //check edges (x + 1)
                         * }
                         * if (y == chunkSize - 1)
                         * {
                         *  //check y edges accordingly
                         * }
                         * else
                         * {
                         *  //check edges (y + 1)
                         * }
                         * if (z == chunkSize - 1)
                         * {
                         *  //check z edges accordingly
                         * }
                         * else
                         * {
                         *  //check edges (z + 1)
                         * }
                         * if (xSafe && ySafe && zSafe) { //make sure that we have checked edges, if all edges are filled, then it is safe to set to 0; we are checking if a cube is like covered or not
                         *  chunkData[chunkSize - x - 1, chunkSize - y - 1, z] = 0;
                         * }
                         * else
                         * {
                         *  chunkData[chunkSize - x - 1, chunkSize - y - 1, z] = 1;
                         * }*/
                        chunkData[chunkSizeVerts - x - 1, chunkSizeVerts - y - 1, z] = 1;
                    }
                    else
                    {
                        chunkData[chunkSizeVerts - x - 1, chunkSizeVerts - y - 1, z] = 0;//idk if it instantiates to all 0's
                    }
                }
            }
        }

        chunkData = hollowOut(chunkData);

        //now that we have our verticies, lets march some cubes?

        //some for loop logic to get to one cube
        //now that we are at a cube:
        //check each of the 8 verticies to see if it is on or off
        //index = 0;
        //for all of the 8
        //index += (vertex value [1 or 0]) * 2^(vertex index)
        //lookup, then make triangle

        CombineInstance[] wholeMesh = new CombineInstance[(int)Mathf.Pow(chunkSizeBlocks, 3)];

        Mesh mesh = GetComponent <MeshFilter>().mesh;

        mesh.Clear();

        int[] initialVoxels = { (int)chunkData[0, 0, 0], (int)chunkData[1, 0, 0], (int)chunkData[1, 0, 1], (int)chunkData[0, 0, 1], (int)chunkData[0, 1, 0], (int)chunkData[1, 1, 0], (int)chunkData[1, 1, 1], (int)chunkData[0, 1, 1] };

        Mesh temp = MarchingCubes3.perCube(new Vector3(0, 0, 0), initialVoxels, 0);

        //foreach (int i in initialVoxels)
        //    Debug.Log(i);

        //mesh.triangles = temp.triangles;
        //mesh.vertices = temp.vertices;

        //mesh.RecalculateBounds();
        //mesh.RecalculateNormals();

        wholeMesh[0]      = new CombineInstance();
        wholeMesh[0].mesh = temp;

        //per chunk
        for (int x = 0; x < chunkSizeVerts - 1; x++) //or x < chunkSizeBlocks
        {
            for (int y = 0; y < chunkSizeVerts - 1; y++)
            {
                for (int z = 0; z < chunkSizeVerts - 1; z++)
                {
                    if (x == 0 && y == 0 && z == 0)
                    {
                        continue;
                    }
                    //set blockNum somehow
                    int blockNum = (int)(z + y * (Mathf.Pow(chunkSizeBlocks, 1)) + x * (Mathf.Pow(chunkSizeBlocks, 2)));
                    //percube
                    int[] voxels = { (int)chunkData[x, y, z], (int)chunkData[x + 1, y, z], (int)chunkData[x + 1, y, z + 1], (int)chunkData[x, y, z + 1], (int)chunkData[x, y + 1, z], (int)chunkData[x + 1, y + 1, z], (int)chunkData[x + 1, y + 1, z + 1], (int)chunkData[x, y + 1, z + 1] }; //this is a line worth checking, I made it match up with MarchingCubes3.localVerticies
                    Mesh  m      = MarchingCubes3Clean.perCube(new Vector3(0, 0, 0), voxels, blockNum);
                    //^^ this causes unity to freeze up

                    //if combineInstance has too many verts: //IMPLEMENT THIS LOGIC LATER, MAYBE IF COMBINING CHUNKS???
                    //save the current combineInstance to a mesh
                    //make a new one
                    //Debug.Log(wholeMesh[blockNum]);
                    wholeMesh[blockNum]      = new CombineInstance();
                    wholeMesh[blockNum].mesh = m;
                    //Debug.Log(wholeMesh[blockNum]);
                    //wholeMesh[blockNum].transform. = MarchingCubes3Clean.beginningCoordinates(new Vector3(0, 0, 0), blockNum);//comes with the mesh???
                    //merge meshes
                }
            }
        }

        /*mesh.Clear();
         *
         * mesh.CombineMeshes(wholeMesh);
         *
         * mesh.RecalculateBounds();
         * mesh.RecalculateNormals();*/

        //Mesh mesh = GetComponent<MeshFilter>().mesh;

        mesh = GetComponent <MeshFilter>().mesh; //mesh is invisible now.

        mesh.Clear();

        mesh.CombineMeshes(wholeMesh);

        //mesh.Optimize();

        //MeshCollider meshCollider = GetComponent<MeshCollider>();

        //meshCollider.sharedMesh = GetComponent<MeshFilter>().mesh; //this won't work but i want it to :(, also it shows up as black and unlit???
        //I think the mesh is centered but idk...

        mesh.RecalculateBounds();
        mesh.RecalculateNormals();
    }
Ejemplo n.º 29
0
    public void Start()
    {
        if (serializablePieceNumbers != null && serializablePieceNumbers.Length > 0)
        {
            piece = Piece.fromSerializable2DIntArray(serializablePieceNumbers);
        }

        if (piece == null)
        {
            Destroy(gameObject);
        }

        // Adding tiles in a wrapper object
        numberContainer = new GameObject("numbers");
        numberContainer.transform.parent        = transform;
        numberContainer.transform.localPosition = new Vector3(0, 0, 0);

        int[,] pieceNumbers = piece.to2DArray();

        Vector3 centerOffset = new Vector3((pieceNumbers.GetLength(1) - 1) / 2.0f, -(pieceNumbers.GetLength(0) - 1) / 2.0f, 0);

        for (int i = 0; i < piece.getHeight(); i++)
        {
            for (int j = 0; j < piece.getWidth(); j++)
            {
                // Create quads for valid numbers
                if (pieceNumbers[i, j] >= 1 && pieceNumbers[i, j] <= 9)
                {
                    GameObject numberTile = new GameObject(pieceNumbers[i, j] + "");
                    numberTile.transform.parent        = numberContainer.transform;
                    numberTile.transform.localPosition = new Vector3(j, -i, 0) - centerOffset;

                    GameObject quad        = GameObject.CreatePrimitive(PrimitiveType.Quad);
                    GameObject backQuad    = GameObject.CreatePrimitive(PrimitiveType.Quad);
                    GameObject outlineQuad = GameObject.CreatePrimitive(PrimitiveType.Quad);
                    quad.transform.parent        = numberTile.transform;
                    backQuad.transform.parent    = numberTile.transform;
                    outlineQuad.transform.parent = numberTile.transform;

                    quad.transform.localPosition        = Vector3.zero;
                    backQuad.transform.localPosition    = Vector3.zero;
                    outlineQuad.transform.localPosition = new Vector3(0, 0, 0.1f);
                    outlineQuad.transform.localScale    = new Vector3(1.05f, 1.05f, 1);

                    // Set the texture to the corresponding number
                    quad.renderer.material       = numberSprites[pieceNumbers[i, j] - 1];
                    quad.renderer.material.color = numberColor;

                    backQuad.renderer.material       = backSprite;
                    backQuad.renderer.material.color = backColor;

                    outlineQuad.renderer.material       = silhouette;
                    outlineQuad.renderer.material.color = numberColor;

                    Destroy(quad.GetComponent <MeshCollider>());
                    Destroy(backQuad.GetComponent <MeshCollider>());
                    Destroy(outlineQuad.GetComponent <MeshCollider>());

                    numberTile.AddComponent <ForceTileUpright>();
                }
            }
        }

        if (!hint)
        {
            Vector3    savePosition = transform.position;
            Quaternion saveRotation = transform.rotation;

            transform.position = new Vector3(0, 0, 0);
            transform.rotation = Quaternion.Euler(0, 0, 0);

            MeshFilter[]      meshFilters = GetComponentsInChildren <MeshFilter>();
            CombineInstance[] combine     = new CombineInstance[meshFilters.Length];
            for (int i = 0; i < meshFilters.Length; i++)
            {
                combine[i].mesh      = meshFilters[i].sharedMesh;
                combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
            }

            MeshFilter meshFilter = gameObject.AddComponent <MeshFilter>();
            meshFilter.mesh.CombineMeshes(combine);

            collider            = gameObject.AddComponent <MeshCollider>();
            collider.sharedMesh = meshFilter.mesh;

            transform.position = savePosition;
            transform.rotation = saveRotation;
        }

        targetRotation = Quaternion.Euler(0, 0, 0);
        StartCoroutine(rotatePiece());

        float x = transform.position.x;
        float y = transform.position.y;

        float newX = Mathf.Clamp(x, -13, 13);
        float newY = Mathf.Clamp(y, -10, 5);

        transform.position = new Vector3(newX, newY, 0);

        if (hint)
        {
            float xOffset = (piece.getWidth() - 1) / 2.0f;
            float yOffset = (piece.getHeight() - 1) / 2.0f;

            int correctRow = (int)(piece.getCorrectPosition().y);
            int correctCol = (int)(piece.getCorrectPosition().x);

            float correctY = 4 - correctRow - yOffset;
            float correctX = correctCol - 4 + xOffset;

            transform.position = new Vector3(correctX, correctY, 0);

            snapPiece();
        }
    }
Ejemplo n.º 30
0
    public void CreateFromLines(List <Line> _segments)
    {
        if (_segments.Count == 0)
        {
            return;
        }

        Vector3 infiniteRandomPoint = new Vector3(Random.value * 10000.0f + 1000.0f, 0.0f, Random.value * 1000.0f + 10000.0f);

        List <Line> segments = new List <Line> ();

        List <Vector3> vbuffer = new List <Vector3> ();

        // split segment to multiple segments for windows
        for (int i = 0; i < _segments.Count; i++)
        {
//			if (_segments [i].Windows.Count != 0) {
//
//				if (_segments [i].Windows [0].Position.x != 0) {
//
//					int id1 = vbuffer.IndexOf (_segments [i].a);
//					if (id1 == -1) {
//						id1 = vbuffer.Count;
//						vbuffer.Add (_segments [i].a);
//					}
//					Vector3 v2 = _segments [i].a + (_segments [i].b - _segments [i].a).normalized * _segments [i].Windows [0].Position.x;
//					int id2 = vbuffer.IndexOf (v2);
//					if (id2 == -1) {
//						id2 = vbuffer.Count;
//						vbuffer.Add (v2);
//					}
//
//					Line firstSeg = new Line (vbuffer, id1, id2, _segments[i].Thickness, _segments [i].LineMaterial, _segments [i].InnerMaterial, _segments [i].OuterMaterial, _segments [i].SideMaterial);
//					firstSeg.Height = _segments [i].Height;
//					firstSeg.LineType = LineType.Wall;
//					firstSeg.ParentLine = _segments [i];
//					segments.Add (firstSeg);
//				}
//
//				for (int j = 0; j < _segments[i].Windows.Count - 1; j++) {
//					Vector3 start = _segments [i].a + (_segments [i].b - _segments [i].a).normalized * _segments [i].Windows [j].Position.x;
//					Vector3 end = _segments [i].a + (_segments [i].b - _segments [i].a).normalized * (_segments [i].Windows [j].Position.x + _segments [i].Windows [j].WindowWidth);
//
//					int istart = vbuffer.IndexOf (start);
//					if (istart == -1) {
//						istart = vbuffer.Count;
//						vbuffer.Add (start);
//					}
//					int iend = vbuffer.IndexOf (end);
//					if (iend == -1) {
//						iend = vbuffer.Count;
//						vbuffer.Add (end);
//					}
//
//
//					Line windowSeg = new Line (vbuffer, istart, iend, _segments[i].Thickness, _segments [i].LineMaterial, _segments [i].InnerMaterial, _segments [i].OuterMaterial, _segments [i].SideMaterial);
//					windowSeg.LedgeHeight = _segments [i].Windows [j].Position.y;
//					windowSeg.WindowHeight = _segments [i].Windows [j].WindowHeight;
//					windowSeg.LineType = LineType.Window;
//					windowSeg.Height = _segments [i].Height;
//					windowSeg.ParentLine = _segments [i];
//					segments.Add (windowSeg);
//
//					Vector3 nextStart = _segments [i].a + (_segments [i].b - _segments [i].a).normalized * _segments [i].Windows [j + 1].Position.x;
//					int inextStart = vbuffer.IndexOf (nextStart);
//					if (inextStart == -1) {
//						inextStart = vbuffer.Count;
//						vbuffer.Add (nextStart);
//					}
//					Line nextSeg = new Line(vbuffer, iend, inextStart, _segments[i].Thickness, _segments[i].LineMaterial, _segments[i].InnerMaterial, _segments [i].OuterMaterial, _segments [i].SideMaterial);
//					nextSeg.Height = _segments [i].Height;
//					nextSeg.LineType = LineType.Wall;
//					nextSeg.ParentLine = _segments [i];
//					segments.Add (nextSeg);
//				}
//
//				{
//					Vector3 start = _segments [i].a + (_segments [i].b - _segments [i].a).normalized * _segments [i].Windows [_segments [i].Windows.Count - 1].Position.x;
//					Vector3 end = _segments [i].a + (_segments [i].b - _segments [i].a).normalized * (_segments [i].Windows [_segments [i].Windows.Count - 1].Position.x + _segments [i].Windows [_segments [i].Windows.Count - 1].WindowWidth);
//					int istart = vbuffer.IndexOf (start);
//					if (istart == -1) {
//						istart = vbuffer.Count;
//						vbuffer.Add (start);
//					}
//					int iend = vbuffer.IndexOf (end);
//					if (iend == -1) {
//						iend = vbuffer.Count;
//						vbuffer.Add (end);
//					}
//
//
//					Line windowSeg = new Line (vbuffer, istart, iend, _segments[i].Thickness, _segments [i].LineMaterial, _segments [i].InnerMaterial, _segments [i].OuterMaterial, _segments [i].SideMaterial);
//					windowSeg.LedgeHeight = _segments [i].Windows [_segments [i].Windows.Count - 1].Position.y;
//					windowSeg.WindowHeight = _segments [i].Windows [_segments [i].Windows.Count - 1].WindowHeight;
//					windowSeg.LineType = LineType.Window;
//					windowSeg.Height = _segments [i].Height;
//					windowSeg.ParentLine = _segments [i];
//					segments.Add (windowSeg);
//
//					int id2 = vbuffer.IndexOf (_segments [i].b);
//					if (id2 == -1) {
//						id2 = vbuffer.Count;
//						vbuffer.Add (_segments [i].b);
//					}
//
//					Line lastSeg = new Line(vbuffer, iend, id2, _segments[i].Thickness, _segments[i].LineMaterial, _segments[i].InnerMaterial, _segments [i].OuterMaterial, _segments [i].SideMaterial);
//					lastSeg.Height = _segments [i].Height;
//					lastSeg.LineType = LineType.Wall;
//					lastSeg.ParentLine = _segments [i];
//					segments.Add (lastSeg);
//				}
//
//
//
//			} else
            {
                segments.Add(_segments [i]);
            }
        }



        List <Vector3> segmentsWithContour = Line.Offsets(segments);
        // lines, lines offseted, lines offseted backward

        //segments.Clear ();
        HashSet <Vector3> vertices       = new HashSet <Vector3> ();
        HashSet <int>     linesContoured = new HashSet <int> ();

        // loop all lines, find intersection between offsets on the same side, then replace intersection point

        Line.WeldIntersections(segmentsWithContour, out vertices);

        // find end point edges
        List <Vector3> endpointsSegments = new List <Vector3> ();

        for (int i = 0; i < segmentsWithContour.Count; i += 6)
        {
            if (!vertices.Contains(segmentsWithContour [i]))
            {
                endpointsSegments.Add(segmentsWithContour [i + 2]);
                endpointsSegments.Add(segmentsWithContour [i + 4]);
            }
            if (!vertices.Contains(segmentsWithContour [i + 1]))
            {
                endpointsSegments.Add(segmentsWithContour [i + 3]);
                endpointsSegments.Add(segmentsWithContour [i + 5]);
            }
        }

        // remove original lines
        for (int i = segmentsWithContour.Count - 6; i >= 0; i -= 6)
        {
            segmentsWithContour.RemoveAt(i);
            segmentsWithContour.RemoveAt(i);
        }

        // add endpoint edges to contour list
        segmentsWithContour.AddRange(endpointsSegments);

        // find directed paths (to determine inner, outer walls)
        List <List <Vector3> > directedPaths = new List <List <Vector3> >();

        directedPaths.Add(new List <Vector3> ());
        directedPaths[directedPaths.Count - 1].Add(segmentsWithContour [0]);
        directedPaths[directedPaths.Count - 1].Add(segmentsWithContour [1]);
        segmentsWithContour.RemoveRange(0, 2);
        while (segmentsWithContour.Count > 0)
        {
            bool flag = true;
            for (int i = 0; i < segmentsWithContour.Count; i += 2)
            {
                if (directedPaths[directedPaths.Count - 1] [directedPaths[directedPaths.Count - 1].Count - 1] == segmentsWithContour [i])
                {
                    directedPaths[directedPaths.Count - 1].Add(segmentsWithContour [i]);
                    directedPaths[directedPaths.Count - 1].Add(segmentsWithContour [i + 1]);
                    segmentsWithContour.RemoveRange(i, 2);
                    flag = false;
                    break;
                }
                else if (directedPaths[directedPaths.Count - 1] [directedPaths[directedPaths.Count - 1].Count - 1] == segmentsWithContour [i + 1])
                {
                    directedPaths[directedPaths.Count - 1].Add(segmentsWithContour [i + 1]);
                    directedPaths[directedPaths.Count - 1].Add(segmentsWithContour [i]);
                    segmentsWithContour.RemoveRange(i, 2);
                    flag = false;
                    break;
                }
            }

            if (flag)
            {
                // to avoid infinite loop
                // make new directed path
                directedPaths.Add(new List <Vector3> ());
                directedPaths[directedPaths.Count - 1].Add(segmentsWithContour [0]);
                directedPaths[directedPaths.Count - 1].Add(segmentsWithContour [1]);
                segmentsWithContour.RemoveRange(0, 2);
            }
        }

        // find outer loop (nearest to infinite) and reverse it if needed
        for (int i = 0; i < directedPaths.Count; i++)
        {
            int   minSeg = -1;
            float dst    = float.MaxValue;
            for (int j = 0; j < directedPaths[i].Count; j += 2)
            {
                float det = (directedPaths[i] [j] - Vector3.right * 1000.0f).sqrMagnitude;
                det += (directedPaths[i] [j + 1] - Vector3.right * 1000.0f).sqrMagnitude;
                if (det < dst)
                {
                    dst    = det;
                    minSeg = j;
                }
            }

            if (minSeg != -1)
            {
                if (Vector3.Dot(Vector3.Normalize(directedPaths [i] [minSeg] - directedPaths [i] [minSeg + 1]), Vector3.forward) < 0)
                {
                    directedPaths [i].Reverse();
                }
            }
        }



        float thicknessSqrd = _segments [0].Thickness * _segments [0].Thickness;        //thickness * thickness;

        List <List <Line> > pathId = new List <List <Line> > ();

        for (int i = 0; i < directedPaths.Count; i++)
        {
            pathId.Add(new List <Line>());
        }


        // for each path find intersection count from (any vertex) to (infinite) which will determine if this is inner or outer wall
        // then generate walls or windows
        // destroy line if its for the window (not original line)
        for (int i = 0; i < directedPaths.Count; i++)
        {
            float pathidDst = 0;
            // bug .. [\] will not work correctly
            int     rand         = Random.Range(0, directedPaths[i].Count / 2) * 2;
            Vector3 randomVertex = Vector3.Lerp(directedPaths [i] [rand], directedPaths [i] [rand + 1], Random.Range(1, 99) / 100.0f);

            Vector3 randomOutterPoint = new Vector3(Random.Range(10000.0f, 50000.0f), 0, Random.Range(10000.0f, 50000.0f));

            int intersectionCount = 0;
            for (int j = 0; j < directedPaths.Count; j++)
            {
                if (i != j)
                {
                    for (int k = 0; k < directedPaths[j].Count; k += 2)
                    {
                        Vector3 tmp;
                        if (Line.RayRayIntersection(out tmp, directedPaths [j] [k], directedPaths [j] [k + 1], randomVertex, randomOutterPoint))
                        {
                            if ((tmp - randomOutterPoint).magnitude <= (randomVertex - randomOutterPoint).magnitude)
                            {
                                if ((tmp - directedPaths [j] [k]).magnitude <= (directedPaths [j] [k + 1] - directedPaths [j] [k]).magnitude)
                                {
                                    if (Vector3.Dot(tmp - directedPaths [j] [k], directedPaths [j] [k + 1] - directedPaths [j] [k]) >= 0)
                                    {
                                        intersectionCount++;
                                    }
                                }
                            }
                        }
                    }
                }
            }



            if (intersectionCount % 2 == 1)
            {
                directedPaths [i].Reverse();

                for (int j = 0; j < directedPaths [i].Count; j += 2)
                {
                    if (Mathf.Abs((directedPaths [i] [j] - directedPaths [i] [j + 1]).sqrMagnitude - thicknessSqrd) <= 0.0001f)
                    {
                        Line  l   = null;
                        float dst = float.MaxValue;
                        for (int k = 0; k < segments.Count; k++)
                        {
                            float det1 = (segments [k].a - directedPaths [i] [j]).sqrMagnitude;
                            if (det1 < dst)
                            {
                                dst = det1;
                                l   = segments [k];
                            }
                            else
                            {
                                float det2 = (segments [k].b - directedPaths [i] [j]).sqrMagnitude;
                                if (det2 < dst)
                                {
                                    dst = det2;
                                    l   = segments [k];
                                }
                            }
                        }


                        if (pathId [i].Count == 0)
                        {
                            pathId [i].Add(l.ParentLine == null ? l : l.ParentLine);
                            pathidDst = (infiniteRandomPoint - pathId [i] [0].a).sqrMagnitude + (infiniteRandomPoint - pathId [i] [0].b).sqrMagnitude;
                        }
                        else
                        {
                            Line  tmp = l.ParentLine == null ? l : l.ParentLine;
                            float det = (infiniteRandomPoint - tmp.a).sqrMagnitude + (infiniteRandomPoint - tmp.b).sqrMagnitude;
                            if (det > pathidDst)
                            {
                                pathId [i].Clear();
                                pathidDst = det;
                                pathId [i].Add(tmp);
                            }
                            else if (det == pathidDst)
                            {
                                pathId [i].Add(tmp);
                            }
                        }

                        if (l.ParentLine != null)
                        {
                            l.Destroy();
                        }
                    }
                    else
                    {
                        Line  l   = null;
                        float dst = float.MaxValue;
                        for (int k = 0; k < segments.Count; k++)
                        {
                            float det1 = (segments [k].a - directedPaths [i] [j]).sqrMagnitude;
                            det1 += (segments [k].b - directedPaths [i] [j + 1]).sqrMagnitude;
                            if (det1 < dst)
                            {
                                dst = det1;
                                l   = segments [k];
                            }
                            float det2 = (segments [k].b - directedPaths [i] [j]).sqrMagnitude;
                            det2 += (segments [k].a - directedPaths [i] [j + 1]).sqrMagnitude;
                            if (det2 < dst)
                            {
                                dst = det2;
                                l   = segments [k];
                            }
                        }

                        if (pathId [i].Count == 0)
                        {
                            pathId [i].Add(l.ParentLine == null ? l : l.ParentLine);
                            pathidDst = (infiniteRandomPoint - pathId [i] [0].a).sqrMagnitude + (infiniteRandomPoint - pathId [i] [0].b).sqrMagnitude;
                        }
                        else
                        {
                            Line  tmp = l.ParentLine == null ? l : l.ParentLine;
                            float det = (infiniteRandomPoint - tmp.a).sqrMagnitude + (infiniteRandomPoint - tmp.b).sqrMagnitude;
                            if (det > pathidDst)
                            {
                                pathId [i].Clear();
                                pathidDst = det;
                                pathId [i].Add(tmp);
                            }
                            else if (det == pathidDst)
                            {
                                pathId [i].Add(tmp);
                            }
                        }

                        if (l.ParentLine != null)
                        {
                            l.Destroy();
                        }
                    }
                }
            }
            else
            {
                for (int j = 0; j < directedPaths [i].Count; j += 2)
                {
                    if (Mathf.Abs((directedPaths [i] [j] - directedPaths [i] [j + 1]).sqrMagnitude - thicknessSqrd) <= 0.0001f)
                    {
                        Line  l   = null;
                        float dst = float.MaxValue;
                        for (int k = 0; k < segments.Count; k++)
                        {
                            float det1 = (segments [k].a - directedPaths [i] [j]).sqrMagnitude;
                            if (det1 < dst)
                            {
                                dst = det1;
                                l   = segments [k];
                            }
                            else
                            {
                                float det2 = (segments [k].b - directedPaths [i] [j]).sqrMagnitude;
                                if (det2 < dst)
                                {
                                    dst = det2;
                                    l   = segments [k];
                                }
                            }
                        }

                        if (pathId [i].Count == 0)
                        {
                            pathId [i].Add(l.ParentLine == null ? l : l.ParentLine);
                            pathidDst = (infiniteRandomPoint - pathId [i][0].a).sqrMagnitude + (infiniteRandomPoint - pathId [i][0].b).sqrMagnitude;
                        }
                        else
                        {
                            Line  tmp = l.ParentLine == null ? l : l.ParentLine;
                            float det = (infiniteRandomPoint - tmp.a).sqrMagnitude + (infiniteRandomPoint - tmp.b).sqrMagnitude;
                            if (det > pathidDst)
                            {
                                pathId [i].Clear();
                                pathidDst = det;
                                pathId [i].Add(tmp);
                            }
                            else if (det == pathidDst)
                            {
                                pathId [i].Add(tmp);
                            }
                        }

                        if (l.ParentLine != null)
                        {
                            l.Destroy();
                        }
                    }
                    else
                    {
                        Line  l   = null;
                        float dst = float.MaxValue;
                        for (int k = 0; k < segments.Count; k++)
                        {
                            float det1 = (segments [k].a - directedPaths [i] [j]).sqrMagnitude;
                            det1 += (segments [k].b - directedPaths [i] [j + 1]).sqrMagnitude;
                            if (det1 < dst)
                            {
                                dst = det1;
                                l   = segments [k];
                            }
                            float det2 = (segments [k].b - directedPaths [i] [j]).sqrMagnitude;
                            det2 += (segments [k].a - directedPaths [i] [j + 1]).sqrMagnitude;
                            if (det2 < dst)
                            {
                                dst = det2;
                                l   = segments [k];
                            }
                        }

                        if (pathId [i].Count == 0)
                        {
                            pathId [i].Add(l.ParentLine == null ? l : l.ParentLine);
                            pathidDst = (infiniteRandomPoint - pathId [i] [0].a).sqrMagnitude + (infiniteRandomPoint - pathId [i] [0].b).sqrMagnitude;
                        }
                        else
                        {
                            Line  tmp = l.ParentLine == null ? l : l.ParentLine;
                            float det = (infiniteRandomPoint - tmp.a).sqrMagnitude + (infiniteRandomPoint - tmp.b).sqrMagnitude;
                            if (det > pathidDst)
                            {
                                pathId [i].Clear();
                                pathidDst = det;
                                pathId [i].Add(tmp);
                            }
                            else if (det == pathidDst)
                            {
                                pathId [i].Add(tmp);
                            }
                        }

                        if (l.ParentLine != null)
                        {
                            l.Destroy();
                        }
                    }
                }
            }
        }

        List <Vector3>         __Vertices       = new List <Vector3> ();
        List <CombineInstance> combineInstances = new List <CombineInstance> ();
        List <Material>        sideMaterials    = new List <Material> ();

        for (int i = directedPaths.Count - 1; i >= 0; i--)
        {
            int dpcount  = 0;
            int secondID = -1;
            for (int j = 0; j < directedPaths.Count; j++)
            {
                if (i >= pathId.Count || j >= pathId.Count)
                {
                    i--;
                }

                if (pathId [i] != null && i != j && helper.anyEqualAny(pathId [i], pathId [j]))
                {
                    if (dpcount > 2)
                    {
                        throw new UnityException("More than 2 directed pathes for same line !");
                    }
                    dpcount++;
                    secondID = j;
                }
            }

            if (dpcount == 1)
            {
                // find nearest 2 lines from each directed path
                Vector3 l1v1 = directedPaths [i] [directedPaths [i].Count - 1];
                Vector3 l1v2 = directedPaths [i] [directedPaths [i].Count - 2];
                directedPaths [i].RemoveAt(directedPaths [i].Count - 1);
                directedPaths [i].RemoveAt(directedPaths [i].Count - 1);
                Vector3 tmp       = (l1v1 + l1v2) * 0.5f;
                float   dst       = float.MaxValue;
                int     selectedj = -1;
                for (int j = 0; j < directedPaths [secondID].Count; j += 2)
                {
                    float det = ((directedPaths [secondID] [j] + directedPaths [secondID] [j + 1]) * 0.5f - tmp).sqrMagnitude;
                    if (dst > det)
                    {
                        dst       = det;
                        selectedj = j;
                    }
                }

                Vector3 l2v1 = directedPaths [secondID] [selectedj];
                Vector3 l2v2 = directedPaths [secondID] [selectedj + 1];
                directedPaths [secondID].RemoveAt(selectedj);
                directedPaths [secondID].RemoveAt(selectedj);

                if ((l2v2 - l1v1).sqrMagnitude < (l2v1 - l1v1).sqrMagnitude)
                {
                    tmp  = l2v1;
                    l2v1 = l2v2;
                    l2v2 = tmp;
                }


                List <Line> directedPath = new List <Line> ();
                for (int j = 0; j < directedPaths [i].Count; j += 2)
                {
                    int id1 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((directedPaths [i] [j] - obj).sqrMagnitude <= 0.0000001f);
                    });
                    int id2 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((directedPaths [i] [j + 1] - obj).sqrMagnitude <= 0.0000001f);
                    });

                    if (id1 == -1)
                    {
                        id1 = __Vertices.Count;
                        __Vertices.Add(directedPaths [i] [j]);
                    }
                    if (id2 == -1)
                    {
                        id2 = __Vertices.Count;
                        __Vertices.Add(directedPaths [i] [j + 1]);
                    }

                    directedPath.Add(new Line(__Vertices, id1, id2, 1, null, null, null, pathId [i] [0].SideMaterial));
                }

                {
                    int id1 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((l1v1 - obj).sqrMagnitude <= 0.0000001f);
                    });
                    int id2 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((l2v1 - obj).sqrMagnitude <= 0.0000001f);
                    });

                    if (id1 == -1)
                    {
                        id1 = __Vertices.Count;
                        __Vertices.Add(l1v1);
                    }
                    if (id2 == -1)
                    {
                        id2 = __Vertices.Count;
                        __Vertices.Add(l2v1);
                    }

                    directedPath.Add(new Line(__Vertices, id1, id2, 1, null, null, null, pathId [i] [0].SideMaterial));
                }

                {
                    int id1 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((l1v2 - obj).sqrMagnitude <= 0.0000001f);
                    });
                    int id2 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((l2v2 - obj).sqrMagnitude <= 0.0000001f);
                    });

                    if (id1 == -1)
                    {
                        id1 = __Vertices.Count;
                        __Vertices.Add(l1v2);
                    }
                    if (id2 == -1)
                    {
                        id2 = __Vertices.Count;
                        __Vertices.Add(l2v2);
                    }

                    directedPath.Add(new Line(__Vertices, id1, id2, 1, null, null, null, pathId [i] [0].SideMaterial));
                }

                for (int j = 0; j < directedPaths [secondID].Count; j += 2)
                {
                    int id1 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((directedPaths [secondID] [j] - obj).sqrMagnitude <= 0.0000001f);
                    });
                    int id2 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((directedPaths [secondID] [j + 1] - obj).sqrMagnitude <= 0.0000001f);
                    });

                    if (id1 == -1)
                    {
                        id1 = __Vertices.Count;
                        __Vertices.Add(directedPaths [secondID] [j]);
                    }
                    if (id2 == -1)
                    {
                        id2 = __Vertices.Count;
                        __Vertices.Add(directedPaths [secondID] [j + 1]);
                    }

                    directedPath.Add(new Line(__Vertices, id1, id2, 1, null, null, null, pathId [secondID] [0].SideMaterial));
                }

                // final quad
                Line.WeldVertices(directedPath);
                List <int>     indices;
                List <Vector2> uvs;
                List <Vector3> verts;
                List <Vector3> normals;
                try {
                    Line.FillCap(directedPath, out indices, out verts, out uvs, out normals);

                    CombineInstance ci = new CombineInstance();
                    ci.mesh = new Mesh();
                    for (int j = 0; j < verts.Count; j++)
                    {
                        verts [j] = new Vector3(verts [j].x, pathId [i] [0].Height, verts [j].z);
                    }
                    ci.mesh.vertices = verts.ToArray();
                    ci.mesh.uv       = uvs.ToArray();
                    ci.mesh.normals  = normals.ToArray();
                    ci.mesh.SetIndices(indices.ToArray(), MeshTopology.Triangles, 0);
                    ci.transform = Matrix4x4.identity;

                    ci.subMeshIndex = combineInstances.Count;
                    combineInstances.Add(ci);
                    sideMaterials.Add(pathId [i] [0].SideMaterial);
                    pathId.Add(pathId [i]);
                    pathId.RemoveAt(i);
                    pathId.RemoveAt(secondID);
                    directedPaths.RemoveAt(i);
                    directedPaths.RemoveAt(secondID);
                    List <Vector3> finalQuad = new List <Vector3> ();
                    finalQuad.Add(l1v1);
                    finalQuad.Add(l1v2);
                    finalQuad.Add(l2v1);
                    finalQuad.Add(l2v2);
                    finalQuad.Add(l1v1);
                    finalQuad.Add(l2v1);
                    finalQuad.Add(l1v2);
                    finalQuad.Add(l2v2);
                    directedPaths.Add(finalQuad);
//				pathId.Add (null);
//				i--;
                } catch {
                    Debug.Log("Cap Upper wall face !!");
                }
            }
            else
            {
                List <Line> directedPath = new List <Line> ();
                for (int j = 0; j < directedPaths [i].Count; j += 2)
                {
                    int id1 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((directedPaths [i] [j] - obj).sqrMagnitude <= 0.0000001f);
                    });
                    int id2 = __Vertices.FindIndex(delegate(Vector3 obj) {
                        return((directedPaths [i] [j + 1] - obj).sqrMagnitude <= 0.0000001f);
                    });

                    if (id1 == -1)
                    {
                        id1 = __Vertices.Count;
                        __Vertices.Add(directedPaths [i] [j]);
                    }
                    if (id2 == -1)
                    {
                        id2 = __Vertices.Count;
                        __Vertices.Add(directedPaths [i] [j + 1]);
                    }

                    directedPath.Add(new Line(__Vertices, id1, id2, 1, null, null, null, pathId [i] [0].SideMaterial));
                }

                Line.WeldVertices(directedPath);
                List <int>     indices;
                List <Vector2> uvs;
                List <Vector3> verts;
                List <Vector3> normals;
                try {
                    Line.FillCap(directedPath, out indices, out verts, out uvs, out normals);
                    CombineInstance ci = new CombineInstance();
                    ci.mesh = new Mesh();
                    for (int j = 0; j < verts.Count; j++)
                    {
                        verts [j] = new Vector3(verts [j].x, pathId [i] [0].Height, verts [j].z);
                    }


                    ci.mesh.vertices = verts.ToArray();
                    ci.mesh.uv       = uvs.ToArray();
                    ci.mesh.normals  = normals.ToArray();
                    ci.mesh.SetIndices(indices.ToArray(), MeshTopology.Triangles, 0);
                    ci.transform = Matrix4x4.identity;

                    ci.subMeshIndex = 0;                    //combineInstances.Count;
                    combineInstances.Add(ci);
                } catch {
                    Debug.Log("Cap upper wall face !");
                }
                sideMaterials.Add(pathId [i] [0].SideMaterial);
            }
        }


        _filter = this.gameObject.AddComponent <MeshFilter> ();


        _mesh.Clear();
        _mesh.CombineMeshes(combineInstances.ToArray());
        update();
        _renderer           = this.gameObject.AddComponent <MeshRenderer> ();
        _renderer.materials = sideMaterials.ToArray();
    }
Ejemplo n.º 31
0
		public void CombineMeshes(CombineInstance[] combine){}
Ejemplo n.º 32
0
        static void ImportSingle(double OriginX, double OriginY)
        {
            double originX      = OriginX;
            double originY      = OriginY;
            string basefilepath = "E:/TiledData/Terrain1000x1000/";

            string jsonfilename = originX.ToString() + "-" + originY.ToString() + ".json";

            float  tileSize = 1000;
            string filepath = basefilepath;

            Debug.Log(filepath);

            if (File.Exists(filepath + jsonfilename))
            {
                CityModel cm = new CityModel(filepath, jsonfilename);

                //type voetpad
                Mesh RoadsvoetpadMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> {
                    "voetpad", "voetgangersgebied", "ruiterpad", "voetpad op trap"
                }, true);
                Mesh LandUseVoetpadMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> {
                    "open verharding"
                }, true);
                LandUseVoetpadMesh = SimplifyMesh(LandUseVoetpadMesh, 0.05f);
                //combine meshes of type "voetpad"
                CombineInstance[] voetpadcombi = new CombineInstance[2];
                voetpadcombi[0].mesh = RoadsvoetpadMesh;
                voetpadcombi[1].mesh = LandUseVoetpadMesh;
                Mesh voetpadmesh = new Mesh();
                voetpadmesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                voetpadmesh.CombineMeshes(voetpadcombi, true, false);
                //type fietspad
                Mesh fietspadMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> {
                    "fietspad"
                }, true);

                //type parkeervak
                Mesh parkeervlakMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> {
                    "parkeervlak"
                }, true);
                //type spoorbaan
                Mesh spoorbaanMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> {
                    "spoorbaan"
                }, true);
                //type woonerf
                Mesh WoonerfMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> {
                    "transitie", "woonerf"
                }, true);

                // type weg
                Mesh roadsMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> {
                    "fietspad", "parkeervlak", "ruiterpad", "spoorbaan", "voetgangersgebied", "voetpad", "voetpad op trap", "woonerf"
                }, false);
                Mesh LandUseVerhardMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> {
                    "gesloten verharding"
                }, true);
                LandUseVerhardMesh = SimplifyMesh(LandUseVerhardMesh, 0.05f);
                // combine meshes of type "weg"
                CombineInstance[] wegcombi = new CombineInstance[2];
                wegcombi[0].mesh = roadsMesh;
                wegcombi[1].mesh = LandUseVerhardMesh;
                Mesh wegmesh = new Mesh();
                wegmesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                wegmesh.CombineMeshes(wegcombi, true, false);

                // type groen
                Mesh plantcoverMesh = CreateCityObjectMesh(cm, "PlantCover", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> {
                    "alles"
                }, false);
                Mesh LanduseGroenMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> {
                    "groenvoorziening"
                }, true);
                LanduseGroenMesh = SimplifyMesh(LanduseGroenMesh, 0.05f);
                //combine meshes of type "groen"
                CombineInstance[] groencombi = new CombineInstance[2];
                groencombi[0].mesh = plantcoverMesh;
                groencombi[1].mesh = LanduseGroenMesh;
                Mesh groenMesh = new Mesh();
                groenMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                groenMesh.CombineMeshes(groencombi, true, false);

                //type erf
                Mesh erfMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> {
                    "erf"
                }, true);
                erfMesh = SimplifyMesh(erfMesh, 0.05f);

                //type onverhard
                Mesh LandUseMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> {
                    "erf", "groenvoorziening", "gesloten verharding", "open verharding"
                }, false);
                LandUseMesh = SimplifyMesh(LandUseMesh, 0.05f);

                Mesh genericCityObjectMesh = CreateCityObjectMesh(cm, "GenericCityObject", originX, originY, tileSize, "bgt_type", null, true);
                Mesh waterBodyMesh         = CreateCityObjectMesh(cm, "WaterBody", originX, originY, tileSize, "bgt_type", null, true);
                Mesh bridgeMesh            = CreateCityObjectMesh(cm, "Bridge", originX, originY, tileSize, "bgt_type", null, true);



                //create LOD1 Mesh
                CombineInstance[] combi = new CombineInstance[12];
                combi[0].mesh  = voetpadmesh;     //
                combi[1].mesh  = fietspadMesh;    //
                combi[2].mesh  = parkeervlakMesh; //
                combi[3].mesh  = wegmesh;         //
                combi[4].mesh  = groenMesh;       //
                combi[5].mesh  = erfMesh;         //
                combi[6].mesh  = LandUseMesh;     //
                combi[7].mesh  = spoorbaanMesh;   //
                combi[8].mesh  = WoonerfMesh;     //
                combi[9].mesh  = genericCityObjectMesh;
                combi[10].mesh = bridgeMesh;
                combi[11].mesh = waterBodyMesh;
                ;

                Mesh lod1Mesh = new Mesh();
                lod1Mesh.CombineMeshes(combi, false, false);
                lod1Mesh.uv2 = RDuv2(lod1Mesh.vertices, CoordConvert.RDtoUnity(new Vector3RD(originX, originY, 0)), tileSize);
                Physics.BakeMesh(lod1Mesh.GetInstanceID(), false);
                AssetDatabase.CreateAsset(lod1Mesh, "Assets/terrainMeshes/LOD0/terrain_" + originX + "-" + originY + "-lod1.mesh");
                //for debug

                //GetComponent<MeshFilter>().sharedMesh = lod1Mesh;



                //create LOD0MEsh
                combi         = new CombineInstance[5];
                combi[0].mesh = voetpadmesh;
                combi[1].mesh = fietspadMesh;
                combi[2].mesh = parkeervlakMesh;
                combi[3].mesh = wegmesh;
                combi[4].mesh = spoorbaanMesh;


                Mesh Roads = new Mesh();
                Roads.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                Roads.CombineMeshes(combi, true, false);
                Roads = SimplifyMesh(Roads, 0.05f);

                combi         = new CombineInstance[3];
                combi[0].mesh = erfMesh;
                combi[1].mesh = LandUseMesh;
                combi[2].mesh = WoonerfMesh;

                Mesh landuse = new Mesh();
                landuse.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                landuse.CombineMeshes(combi, true, false);
                landuse = SimplifyMesh(landuse, 0.05f);

                combi = new CombineInstance[12];


                combi[0].mesh  = CreateEmptyMesh();              //
                combi[1].mesh  = CreateEmptyMesh();              //
                combi[2].mesh  = CreateEmptyMesh();              //
                combi[3].mesh  = Roads;                          //
                combi[4].mesh  = SimplifyMesh(groenMesh, 0.05f); //
                combi[5].mesh  = CreateEmptyMesh();              //
                combi[6].mesh  = landuse;                        //
                combi[7].mesh  = CreateEmptyMesh();              //
                combi[8].mesh  = CreateEmptyMesh();              //
                combi[9].mesh  = genericCityObjectMesh;
                combi[10].mesh = bridgeMesh;
                combi[11].mesh = waterBodyMesh;


                Mesh lod0Mesh = new Mesh();
                lod0Mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
                lod0Mesh.CombineMeshes(combi, false, false);
                lod0Mesh.uv2 = RDuv2(lod0Mesh.vertices, CoordConvert.RDtoUnity(new Vector3RD(originX, originY, 0)), tileSize);
                Physics.BakeMesh(lod0Mesh.GetInstanceID(), false);
                AssetDatabase.CreateAsset(lod0Mesh, "Assets/terrainMeshes/LOD0/terrain_" + originX + "-" + originY + "-lod0.mesh");
            }
        }