コード例 #1
0
ファイル: WallSection.cs プロジェクト: ishui/unity3DScripts
        public static WallSection CreateWallSection(string name = null, string directory = null)
        {
            WallSection wallSection = CreateInstance <WallSection>();

            if (Application.isPlaying)
            {
                return(wallSection);
            }
            if (name != null)
            {
                wallSection.name = name;
            }
#if UNITY_EDITOR
            if (directory == null)
            {
                UnityEditor.AssetDatabase.CreateAsset(wallSection, AssetCreator.GeneratePath("newWallSection.asset", "WallSections"));
            }
            else
            {
                UnityEditor.AssetDatabase.CreateAsset(wallSection, Path.Combine(directory, "newWallSection.asset"));
            }
#endif

            BuildRSettings settings = BuildRSettings.GetSettings();
            wallSection._openingWidthAbs  = settings.defaultWindowWidth;
            wallSection._openingHeightAbs = settings.defaultWindowHeight;
            wallSection._openingDepth     = settings.defaultWindowDepth;

            return(wallSection);
        }
コード例 #2
0
ファイル: WallSection.cs プロジェクト: ishui/unity3DScripts
        private static WallSection MenuCreateNewWallSection()
        {
            WallSection output = CreateWallSection();

            UnityEditor.Selection.activeObject = output;
            return(output);
        }
コード例 #3
0
        private void UpdateUsedWallsectionList()
        {
            _usedWallSections.Clear();
            int basePatternCount = _basePattern.Count;

            for (int b = 0; b < basePatternCount; b++)
            {
                FacadeRow row      = _basePattern[b];
                int       rowCount = row.Count;
                for (int r = 0; r < rowCount; r++)
                {
                    WallSection section = row[r];
                    if (!_usedWallSections.Contains(section))
                    {
                        _usedWallSections.Add(section);
                    }
                }
            }

            int groundPatternCount = _groundFloorPattern.Count;

            for (int b = 0; b < groundPatternCount; b++)
            {
                if (_groundFloorPattern != null && _groundFloorPattern.Count > 0 && !_usedWallSections.Contains(_groundFloorPattern[b]))
                {
                    _usedWallSections.Add(_groundFloorPattern[b]);
                }
            }
            //todo add other pattern lists when implemented
        }
コード例 #4
0
ファイル: WallSection.cs プロジェクト: ishui/unity3DScripts
        private static WallSection MenuCreateNewWallSectionB()
        {
            string      activeFolder = AssetCreator.ActiveSelectionPath();
            WallSection output       = CreateWallSection(null, activeFolder);

            UnityEditor.Selection.activeObject = output;
            return(output);
        }
コード例 #5
0
        public void SetGroundWallSection(int x, WallSection newWallSection)
        {
            HUtils.log();

            x = x % _baseWidth;
            _groundFloorPattern[x] = newWallSection;
            MarkModified();
        }
コード例 #6
0
        public void SetBaseWallSection(int x, int y, WallSection newWallSection)
        {
            HUtils.log();

            x = x % _baseWidth;
            y = y % _baseHeight;
            _basePattern[x][y] = newWallSection;
            MarkModified();
        }
コード例 #7
0
        private void OnEnable()
        {
            _wallSection = (WallSection)target;
            _plane       = Primitives.Plane(10);
            _settings    = BuildingEditor.GetSettings();

            UpdatePreview();
//            InteractivePreview.Reset();
        }
コード例 #8
0
        public static void GenerateFacade(FacadeGenerator.FacadeData data, Texture2D texture, Rect space)
        {
            Vector3    facadeVector = data.baseB - data.baseA;
            int        wallSections = 0;
            Vector2    wallSectionPhyicalSize;
            Vector2Int wallSectionPixelSize;

            if (data.isStraight)
            {
                var facadeLength = facadeVector.magnitude;
                wallSections = Mathf.FloorToInt(facadeLength / data.minimumWallUnitLength);
            }
            else
            {
                wallSections = data.anchors.Count - 1;
            }
            wallSectionPhyicalSize = new Vector2(Vector2.Distance(data.anchors[0].vector2, data.anchors[1].vector2), data.floorHeight);
            wallSectionPixelSize   = new Vector2Int(Mathf.RoundToInt(space.width / wallSections), Mathf.RoundToInt(space.height / data.floors));
            Dictionary <WallSection, Color32[]> generatedSections = new Dictionary <WallSection, Color32[]>();

            int startFloor = data.startFloor;

            for (int fl = startFloor; fl < data.floorCount; fl++)
            {
                for (int s = 0; s < wallSections; s++)
                {
                    //                    Debug.Log(s);
                    WallSection section = data.facadeDesign.GetWallSection(s, fl, wallSections, data.floorCount);
                    //                    Debug.Log(section);
                    if (section == null)
                    {
                        continue;
                    }
                    //                    Texture2D generatedTexture;
                    Color32[] wallsectionColourArray;
                    if (generatedSections.ContainsKey(section))
                    {
                        wallsectionColourArray = generatedSections[section];
                    }
                    else
                    {
                        WallSectionGenerator.Texture(out wallsectionColourArray, section, wallSectionPixelSize, wallSectionPhyicalSize);
                        generatedSections.Add(section, wallsectionColourArray);
                    }

                    int xPosition = Mathf.RoundToInt(space.x) + wallSectionPixelSize.x * s;
                    int yPosition = Mathf.RoundToInt(space.y) + wallSectionPixelSize.y * fl;
                    texture.SetPixels32(xPosition, yPosition, wallSectionPixelSize.x, wallSectionPixelSize.y, wallsectionColourArray);
                }
                //note string courses ignored for now
            }
        }
コード例 #9
0
        public static WallSection[,] GenerateFacadeArray(Facade facade, int width, int height)
        {
            WallSection[,] output = new WallSection[width, height];

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    output[x, y] = facade.GetWallSection(x, y);
                }
            }

            return(output);
        }
コード例 #10
0
ファイル: BuildRAtlas.cs プロジェクト: ishui/unity3DScripts
        public Rect GetRect(WallSection section)
        {
            int wallsectionCount = wallSections.Length;

            for (int w = 0; w < wallsectionCount; w++)
            {
                if (wallSections[w] == section)
                {
                    return(packedRects[w]);
                }
            }
            Debug.LogWarning(string.Format("Wall Section ({0}) not present in atlas", section));
            return(new Rect());
        }
コード例 #11
0
        public static Color32[] GenerateFacadePreview(Facade design, Vector2Int pixelSize, Vector2Int patternSize)
        {
            var wallSectionPixelSize = new Vector2Int(Mathf.RoundToInt(pixelSize.x / (float)patternSize.x), Mathf.RoundToInt(pixelSize.y / (float)patternSize.y));
            int outputWidth          = Mathf.RoundToInt(pixelSize.x);
            int outputHeight         = Mathf.RoundToInt(pixelSize.y);
            int dataSize             = outputWidth * outputHeight;

            Color32[] output = new Color32[dataSize];
            Dictionary <WallSection, Color32[]> generatedSections = new Dictionary <WallSection, Color32[]>();

            for (int fl = 0; fl < patternSize.y; fl++)
            {
                for (int s = 0; s < patternSize.x; s++)
                {
                    WallSection section = design.GetWallSection(s, fl, patternSize.x, patternSize.y);
                    if (section == null)
                    {
                        continue;
                    }
                    Color32[] wallsectionColourArray;
                    if (generatedSections.ContainsKey(section))
                    {
                        wallsectionColourArray = generatedSections[section];
                    }
                    else
                    {
                        WallSectionGenerator.Texture(out wallsectionColourArray, section, wallSectionPixelSize, Vector2.one * 3);
                        generatedSections.Add(section, wallsectionColourArray);
                    }
                    int xPosition = wallSectionPixelSize.x * s;
                    int yPosition = wallSectionPixelSize.y * fl;

                    for (int x = 0; x < wallSectionPixelSize.x; x++)
                    {
                        for (int y = 0; y < wallSectionPixelSize.y; y++)
                        {
                            output[xPosition + x + (yPosition + y) * outputWidth] = wallsectionColourArray[x + y * wallSectionPixelSize.x];
                        }
                    }
                }
            }

            return(output);
        }
コード例 #12
0
ファイル: FacadeEditor.cs プロジェクト: ishui/unity3DScripts
        private static Rect WallSectionItem(Facade facade, int x, int inverseY, bool isGround = false)
        {
            WallSection wallSection = !isGround?facade.GetBaseWallSection(x, inverseY) : facade.GetGroundWallSection(x);

            string wallSectionName = wallSection != null ? wallSection.name : "";

            Undo.RecordObject(facade, "Add wall section to facade");
            GUIContent texture;

            if (wallSection != null)
            {
                texture = new GUIContent(wallSection.previewTexture);
            }
            else
            {
                texture = new GUIContent(wallSectionName);
            }
            EditorGUILayout.BeginHorizontal("box", GUILayout.Width(SECTION_PREVIEW_SIZE), GUILayout.Height(SECTION_PREVIEW_SIZE));
            EditorGUILayout.LabelField(texture, GUILayout.Width(SECTION_PREVIEW_SIZE), GUILayout.Height(SECTION_PREVIEW_SIZE));
            EditorGUILayout.EndHorizontal();
            Rect sectionRect = GUILayoutUtility.GetLastRect();
//            facadeRects[x].Add(sectionRect);
            WallSection newSection = EditorGUI.ObjectField(sectionRect, wallSection, typeof(WallSection), false) as WallSection;

            if (newSection != wallSection)
            {
                if (!isGround)
                {
                    facade.SetBaseWallSection(x, inverseY, newSection);
                }
                else
                {
                    facade.SetGroundWallSection(x, newSection);
                }
            }
            EditorGUI.DrawPreviewTexture(sectionRect, EditorGUIUtility.whiteTexture);
            EditorGUI.LabelField(sectionRect, texture);
            EditorGUI.DropShadowLabel(sectionRect, wallSectionName, BuildingEditor.FacadeLabel);

            return(sectionRect);
        }
コード例 #13
0
ファイル: FacadeEditor.cs プロジェクト: ishui/unity3DScripts
        private static void BasePatternEditor(Facade facade)
        {
            EventType eventType = Event.current.type;
//            if (eventType == EventType.DragUpdated)
//                Debug.Log("DragUpdated");
//            if (eventType == EventType.DragPerform)
//                Debug.Log("DragPerform");


            List <List <Rect> > facadeRects = new List <List <Rect> >();

            float calWidth  = Mathf.Min((SECTION_PREVIEW_SIZE + 20) * facade.baseWidth, BuildingEditor.MAIN_GUI_WIDTH - SECTION_PREVIEW_SIZE);
            float calHeight = (SECTION_PREVIEW_SIZE + 30) * facade.baseHeight;

            SCROLL_POS = EditorGUILayout.BeginScrollView(SCROLL_POS, GUILayout.Width(calWidth), GUILayout.Height(calHeight));
            EditorGUILayout.BeginHorizontal(GUILayout.Width(calWidth));
            for (int x = 0; x < facade.baseWidth; x++)
            {
                facadeRects.Add(new List <Rect>());
                EditorGUILayout.BeginVertical(GUILayout.Width(SECTION_PREVIEW_SIZE));
                for (int y = 0; y < facade.baseHeight; y++)
                {
                    int  inverseY = facade.baseHeight - y - 1;
                    Rect itemrect = WallSectionItem(facade, x, inverseY);
                    facadeRects[x].Add(itemrect);
                }
                EditorGUILayout.EndVertical();
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndScrollView();

            WallSection output = null;

//            EventType eventType = Event.current.type;

            if (eventType == EventType.DragUpdated || eventType == EventType.DragPerform)
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
                Object[] objArray = DragAndDrop.objectReferences;
                if (objArray != null)
                {
                    if (objArray[0].GetType() == typeof(WallSection))
                    {
                        DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                        if (eventType == EventType.DragPerform)
                        {
                            output = (WallSection)objArray[0];
                            DragAndDrop.AcceptDrag();

                            Vector2 mousePos = Event.current.mousePosition;

                            for (int x = 0; x < facade.baseWidth; x++)
                            {
                                for (int y = 0; y < facade.baseHeight; y++)
                                {
                                    if (facadeRects[x][y].Contains(mousePos))
                                    {
                                        int         inverseY    = facade.baseHeight - y - 1;
                                        WallSection wallSection = facade.GetBaseWallSection(x, inverseY);
                                        if (output != wallSection)
                                        {
                                            Undo.RecordObject(facade, "Add wall section to facade");
                                            facade.SetBaseWallSection(x, inverseY, output);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #14
0
        public static void GeneratePrefabs(FacadeData data)
        {
            if (data.meshType != BuildingMeshTypes.Full)
            {
                return;
            }
            Vector3 facadeVector    = data.baseB - data.baseA;
            Vector3 facadeDirection = facadeVector.normalized;
            Vector3 facadeNormal    = Vector3.Cross(facadeDirection, Vector3.up);
            float   wallThickness   = data.wallThickness;
            int     wallSections    = 0;
            Vector2 wallSectionSize;
            float   facadeLength = 0;

            if (data.isStraight)
            {
                facadeLength = facadeVector.magnitude;
                wallSections = Mathf.FloorToInt(facadeLength / data.minimumWallUnitLength);
                if (wallSections < 1)
                {
                    wallSections = 1;
                }
                wallSectionSize = new Vector2(facadeLength / wallSections, data.floorHeight);
            }
            else
            {
                wallSections = data.anchors.Count - 1;                //baseCurvepoints.Count - 1;
                if (wallSections < 1)
                {
                    wallSections = 1;
                }
                float sectionWidth = Vector2.Distance(data.anchors[0].vector2, data.anchors[1].vector2);                //Vector3.Distance(baseCurvepoints[0], baseCurvepoints[1]));
                wallSectionSize = new Vector2(sectionWidth, data.floorHeight);
            }

            int startFloor = data.startFloor;

            for (int fl = startFloor; fl < data.floorCount; fl++)
            {
                for (int s = 0; s < wallSections; s++)
                {
                    WallSection section = data.facadeDesign.GetWallSection(s, fl, wallSections, data.floorCount);

                    if (section == null)
                    {
                        continue;                        //nothing to instanciate
                    }

                    bool cullOpening = data.cullDoors && section.isDoor;
                    if (data.isStraight)
                    {
                        Quaternion meshRot           = Quaternion.LookRotation(facadeNormal, Vector3.up);
                        Vector3    baseMeshPos       = data.baseA + facadeDirection * wallSectionSize.x + Vector3.up * wallSectionSize.y;
                        Vector3    wallSectionVector = new Vector3(wallSectionSize.x * s, wallSectionSize.y * fl, 0);
                        baseMeshPos += meshRot * wallSectionVector;
                        Vector3 meshPos = baseMeshPos + meshRot * -wallSectionSize * 0.5f;

                        Matrix4x4 matrix = Matrix4x4.TRS(meshPos, meshRot, Vector3.one);
                        WallSectionGenerator.InstantiatePrefabs(data.prefabs, section, wallSectionSize, matrix, wallThickness, cullOpening);
                    }
                    else
                    {
                        //todo switch - support wall section based curves for now

                        Vector3 cp0 = data.anchors[s].vector3XZ;                        //baseCurvepoints[s];
                        cp0.y = data.baseA.y;
                        Vector3 cp1 = data.anchors[s + 1].vector3XZ;                    //baseCurvepoints[s + 1];
                        cp1.y = data.baseA.y;
                        Vector3 curveVector    = cp1 - cp0;
                        Vector3 curveDirection = curveVector.normalized;
                        Vector3 curveNormal    = Vector3.Cross(curveDirection, Vector3.up);
                        float   actualWidth    = curveVector.magnitude;

                        Quaternion meshRot           = Quaternion.LookRotation(curveNormal, Vector3.up);
                        Vector3    meshPos           = cp1 + Vector3.up * wallSectionSize.y;
                        Vector3    wallSectionVector = new Vector3(0, wallSectionSize.y * fl, 0);
                        meshPos += meshRot * wallSectionVector;
                        meshPos += meshRot * -new Vector3(actualWidth, wallSectionSize.y, 0) * 0.5f;
                        Vector3 meshScale = new Vector3(actualWidth / wallSectionSize.x, 1, 1);

                        Matrix4x4 matrix = Matrix4x4.TRS(meshPos, meshRot, meshScale);
                        WallSectionGenerator.InstantiatePrefabs(data.prefabs, section, wallSectionSize, matrix, wallThickness, cullOpening);
                    }
                }
            }
        }
コード例 #15
0
        public static void GenerateFacade(FacadeData data, BuildRMesh dmesh, BuildRCollider collider = null)
        {
//		    Debug.Log("******************* "+data.facadeDesign.ToString());
            Vector3 facadeVector = data.baseB - data.baseA;

            if (facadeVector.magnitude < Mathf.Epsilon)
            {
                return;
            }
            Vector3   facadeDirection = facadeVector.normalized;
            Vector3   facadeNormal    = Vector3.Cross(facadeDirection, Vector3.up);
            Vector4   facadeTangent   = BuildRMesh.CalculateTangent(facadeDirection);
            RandomGen rGen            = new RandomGen();

            rGen.GenerateNewSeed();
            float                 wallThickness = data.wallThickness;
            float                 foundation    = data.foundationDepth;
            BuildingMeshTypes     meshType      = data.meshType;
            BuildingColliderTypes colliderType  = data.colliderType;
            int     wallSections = 0;
            Vector2 wallSectionSize;
            float   facadeLength = 0;

            if (data.isStraight)
            {
                facadeLength = facadeVector.magnitude;
                wallSections = Mathf.FloorToInt(facadeLength / data.minimumWallUnitLength);
                if (wallSections < 1)
                {
                    wallSections = 1;
                }
                wallSectionSize = new Vector2(facadeLength / wallSections, data.floorHeight);
            }
            else
            {
                wallSections = data.anchors.Count - 1;
                if (wallSections < 1)
                {
                    wallSections = 1;
                }
                float sectionWidth = Vector2.Distance(data.anchors[0].vector2, data.anchors[1].vector2);
                wallSectionSize = new Vector2(sectionWidth, data.floorHeight);
            }

            Dictionary <WallSection, RawMeshData>           generatedSections                  = new Dictionary <WallSection, RawMeshData>();
            Dictionary <WallSection, RawMeshData>           generatedSectionMeshColliders      = new Dictionary <WallSection, RawMeshData>();
            Dictionary <WallSection, BuildRCollider.BBox[]> generatedSectionPrimitiveColliders = new Dictionary <WallSection, BuildRCollider.BBox[]>();

            int startFloor = data.startFloor;

//		    Debug.Log("st fl "+startFloor);
//		    Debug.Log("fl ct "+ data.floorCount);
            for (int fl = startFloor; fl < data.floorCount; fl++)
            {
//			    Debug.Log(fl);
                if (data.facadeDesign.randomisationMode == Facade.RandomisationModes.RandomRows)
                {
                    generatedSections.Clear();                                                                             //recalculate each row
                }
//			    Debug.Log(wallSections);
                for (int s = 0; s < wallSections; s++)
                {
//				    Debug.Log(s);
                    WallSection section = data.facadeDesign.GetWallSection(s, fl + data.actualStartFloor, wallSections, data.floorCount);
//				    Debug.Log(section);
                    dmesh.submeshLibrary.Add(section);                    //add the wallsection to the main submesh library
                    RawMeshData generatedSection         = null;
                    RawMeshData generatedSectionCollider = null;

                    BuildRCollider.BBox[] bboxes = new BuildRCollider.BBox[0];

                    if (section == null)
                    {
                        GenerationOutput output         = GenerationOutput.CreateRawOutput();
                        GenerationOutput outputCollider = null;
                        if (colliderType == BuildingColliderTypes.Complex)
                        {
                            outputCollider = GenerationOutput.CreateRawOutput();
                        }
                        if (colliderType == BuildingColliderTypes.Primitive)
                        {
                            BuildRCollider.BBox[] bbox = WallSectionGenerator.Generate(section, wallSectionSize, wallThickness);
                            generatedSectionPrimitiveColliders.Add(section, bbox);
                        }
                        WallSectionGenerator.Generate(section, output, wallSectionSize, false, wallThickness, true, outputCollider, dmesh.submeshLibrary);

                        generatedSection = output.raw;
                        if (outputCollider != null)
                        {
                            generatedSectionCollider = outputCollider.raw;
                        }
                    }
                    else
                    {
                        if (generatedSections.ContainsKey(section))
                        {
                            generatedSection = generatedSections[section];
                            if (generatedSectionMeshColliders.ContainsKey(section))
                            {
                                generatedSectionCollider = generatedSectionMeshColliders[section];
                            }
                        }
                        else
                        {
                            GenerationOutput output         = GenerationOutput.CreateRawOutput();
                            GenerationOutput outputCollider = null;
                            bool             cullOpening    = data.cullDoors && section.isDoor;
                            if (colliderType == BuildingColliderTypes.Complex)
                            {
                                outputCollider = GenerationOutput.CreateRawOutput();
                            }
                            if (colliderType == BuildingColliderTypes.Primitive)
                            {
                                BuildRCollider.BBox[] bbox = WallSectionGenerator.Generate(section, wallSectionSize, wallThickness, cullOpening);
                                generatedSectionPrimitiveColliders.Add(section, bbox);
                            }
                            WallSectionGenerator.Generate(section, output, wallSectionSize, false, wallThickness, cullOpening, outputCollider, dmesh.submeshLibrary);

                            generatedSections.Add(section, output.raw);
                            if (generatedSectionCollider != null)
                            {
                                generatedSectionMeshColliders.Add(section, outputCollider.raw);
                            }

                            generatedSection = output.raw;
                            if (generatedSectionCollider != null)
                            {
                                generatedSectionCollider = outputCollider.raw;
                            }
                        }

                        if (generatedSectionPrimitiveColliders.ContainsKey(section))
                        {
                            bboxes = generatedSectionPrimitiveColliders[section];
                        }
                    }

//				    Debug.Log("data strt" + data.isStraight);
                    if (data.isStraight)
                    {
                        Quaternion meshRot           = Quaternion.LookRotation(facadeNormal, Vector3.up);
                        Vector3    baseMeshPos       = data.baseA + facadeDirection * wallSectionSize.x + Vector3.up * wallSectionSize.y;
                        Vector3    wallSectionVector = new Vector3(wallSectionSize.x * s, wallSectionSize.y * fl, 0);
                        baseMeshPos += meshRot * wallSectionVector;
                        Vector3 meshPos = baseMeshPos + meshRot * -wallSectionSize * 0.5f;

                        Vector2 uvOffset       = new Vector2(wallSectionSize.x * s, wallSectionSize.y * fl);
                        Vector2 uvOffsetScaled = uvOffset;
                        if (section != null && section.wallSurface != null)
                        {
                            uvOffsetScaled = CalculateUv(uvOffsetScaled, section.wallSurface);
                        }

                        //TODO account for the mesh mode of the wall section - custom meshes
                        if (meshType == BuildingMeshTypes.Full)
                        {
                            dmesh.AddData(generatedSection, meshPos, meshRot, Vector3.one, uvOffsetScaled);
                        }
                        if (collider != null && generatedSectionCollider != null)
                        {
                            collider.mesh.AddData(generatedSectionCollider, meshPos, meshRot, Vector3.one);
                        }
                        if (collider != null && bboxes.Length > 0)
                        {
                            collider.AddBBox(bboxes, meshPos, meshRot);
                        }

//					    Debug.Log("foundation");
                        if (fl == 0 && foundation > Mathf.Epsilon)
                        {
                            Vector3 fp3 = baseMeshPos + Vector3.down * wallSectionSize.y;
                            Vector3 fp2 = fp3 - facadeDirection * wallSectionSize.x;
                            Vector3 fp0 = fp2 + Vector3.down * foundation;
                            Vector3 fp1 = fp3 + Vector3.down * foundation;

                            if (meshType == BuildingMeshTypes.Full)
                            {
                                Surface foundationSurface = data.foundationSurface != null ? data.foundationSurface : section.wallSurface;
                                int     foundationSubmesh = dmesh.submeshLibrary.SubmeshAdd(foundationSurface);                            //facadeSurfaces.IndexOf(section.wallSurface));
                                dmesh.AddPlane(fp0, fp1, fp2, fp3, new Vector2(uvOffset.x, -foundation), new Vector2(uvOffset.x + wallSectionSize.x, 0), -facadeNormal, facadeTangent, foundationSubmesh, foundationSurface);
                            }
                            if (collider != null && generatedSectionCollider != null)
                            {
                                collider.mesh.AddPlane(fp0, fp1, fp2, fp3, 0);
                            }
                        }
                    }
                    else
                    {
                        //todo switch - support wall section based curves for now

                        Vector3 cp0 = data.anchors[s].vector3XZ;
                        cp0.y = data.baseA.y;
                        Vector3 cp1 = data.anchors[s + 1].vector3XZ;
                        cp1.y = data.baseA.y;
                        Vector3 curveVector    = cp1 - cp0;
                        Vector3 curveDirection = curveVector.normalized;
                        Vector3 curveNormal    = Vector3.Cross(curveDirection, Vector3.up);
                        float   actualWidth    = curveVector.magnitude;

                        Quaternion meshRot           = Quaternion.LookRotation(curveNormal, Vector3.up);
                        Vector3    meshPos           = cp1 + Vector3.up * wallSectionSize.y;
                        Vector3    wallSectionVector = new Vector3(0, wallSectionSize.y * fl, 0);
                        meshPos += meshRot * wallSectionVector;
                        meshPos += meshRot * -new Vector3(actualWidth, wallSectionSize.y, 0) * 0.5f;
                        Vector3 meshScale = new Vector3(actualWidth / wallSectionSize.x, 1, 1);

                        //Thanks Anthony Cuellar - issue #12
                        Vector2 uvOffset       = new Vector2(wallSectionVector.x, wallSectionVector.y + (section.hasOpening ? 0 : wallSectionSize.y / 2f));
                        Vector2 uvOffsetScaled = CalculateUv(uvOffset, section.wallSurface);
                        //TODO account for the mesh mode of the wall section - custom meshes
                        if (meshType == BuildingMeshTypes.Full)
                        {
                            dmesh.AddData(generatedSection, meshPos, meshRot, meshScale, uvOffsetScaled);
                        }
                        if (collider != null && generatedSectionCollider != null)
                        {
                            collider.mesh.AddData(generatedSectionCollider, meshPos, meshRot, meshScale);
                        }
                        if (collider != null && bboxes.Length > 0)
                        {
                            collider.AddBBox(bboxes, meshPos, meshRot);
                        }

//					    Debug.Log("foundation");
                        if (fl == 0 && foundation > Mathf.Epsilon)
                        {
                            Vector3 fp3 = cp1;
                            Vector3 fp2 = fp3 - curveDirection * actualWidth;
                            Vector3 fp0 = fp2 + Vector3.down * foundation;
                            Vector3 fp1 = fp3 + Vector3.down * foundation;

                            if (meshType == BuildingMeshTypes.Full)
                            {
                                Surface foundationSurface = data.foundationSurface != null ? data.foundationSurface : section.wallSurface;
                                int     foundationSubmesh = dmesh.submeshLibrary.SubmeshAdd(foundationSurface);                            //facadeSurfaces.IndexOf(section.wallSurface);
                                dmesh.AddPlane(fp0, fp1, fp2, fp3, new Vector2(uvOffset.x, -foundation), new Vector2(uvOffset.x + actualWidth, 0), -curveNormal, facadeTangent, foundationSubmesh, foundationSurface);
                            }
                            if (collider != null && generatedSectionCollider != null)
                            {
                                collider.mesh.AddPlane(fp0, fp1, fp2, fp3, 0);
                            }
                        }
                    }
                }

                //string course is completely ignored for a collision
//			    Debug.Log("string");
                if (fl > 0 && data.facadeDesign.stringCourse && meshType == BuildingMeshTypes.Full)                //no string course on ground floor
                {
                    float   baseStringCoursePosition = wallSectionSize.y * fl + wallSectionSize.y * data.facadeDesign.stringCoursePosition;
                    Vector3 scBaseUp = baseStringCoursePosition * Vector3.up;
                    Vector3 scTopUp  = (data.facadeDesign.stringCourseHeight + baseStringCoursePosition) * Vector3.up;
                    if (data.isStraight)
                    {
                        Vector3 scNm    = data.facadeDesign.stringCourseDepth * facadeNormal;
                        Vector3 p0      = data.baseA;
                        Vector3 p1      = data.baseB;
                        Vector3 p0o     = data.baseA - scNm;
                        Vector3 p1o     = data.baseB - scNm;
                        int     submesh = dmesh.submeshLibrary.SubmeshAdd(data.facadeDesign.stringCourseSurface);                                                                                        //data.facadeDesign.stringCourseSurface != null ? facadeSurfaces.IndexOf(data.facadeDesign.stringCourseSurface) : 0;
                        Vector2 uvMax   = new Vector2(facadeLength, data.facadeDesign.stringCourseHeight);
                        dmesh.AddPlane(p0o + scBaseUp, p1o + scBaseUp, p0o + scTopUp, p1o + scTopUp, Vector3.zero, uvMax, -facadeNormal, facadeTangent, submesh, data.facadeDesign.stringCourseSurface); //front
                        dmesh.AddPlane(p0 + scBaseUp, p0o + scBaseUp, p0 + scTopUp, p0o + scTopUp, facadeNormal, facadeTangent, submesh);                                                                //left
                        dmesh.AddPlane(p1o + scBaseUp, p1 + scBaseUp, p1o + scTopUp, p1 + scTopUp, facadeNormal, facadeTangent, submesh);                                                                //right
                        float facadeAngle = BuildrUtils.CalculateFacadeAngle(facadeDirection);
                        dmesh.AddPlaneComplexUp(p0 + scBaseUp, p1 + scBaseUp, p0o + scBaseUp, p1o + scBaseUp, facadeAngle, Vector3.down, facadeTangent, submesh, data.facadeDesign.stringCourseSurface); //bottom
                        dmesh.AddPlaneComplexUp(p1 + scTopUp, p0 + scTopUp, p1o + scTopUp, p0o + scTopUp, facadeAngle, Vector3.up, facadeTangent, submesh, data.facadeDesign.stringCourseSurface);       //top
                    }
                    else
                    {
                        int       baseCurvePointCount = data.anchors.Count;                  //baseCurvepoints.Count;
                        Vector3[] interSectionNmls    = new Vector3[baseCurvePointCount];
                        for (int i = 0; i < baseCurvePointCount - 1; i++)
                        {
                            Vector3 p0 = data.anchors[i].vector3XZ;                            //baseCurvepoints[i];
                            Vector3 p1 = data.anchors[i + 1].vector3XZ;                        //baseCurvepoints[i + 1];
                            Vector3 p2 = data.anchors[Mathf.Max(i - 1, 0)].vector3XZ;          //baseCurvepoints[Mathf.Max(i - 1, 0)];
                            interSectionNmls[i] = Vector3.Cross((p1 - p0 + p0 - p2).normalized, Vector3.up);
                        }

                        for (int i = 0; i < baseCurvePointCount - 1; i++)
                        {
                            Vector3 p0            = data.anchors[i].vector3XZ;                 //baseCurvepoints[i];
                            Vector3 p1            = data.anchors[i + 1].vector3XZ;             //baseCurvepoints[i + 1];
                            Vector3 sectionVector = p1 - p0;
                            Vector3 sectionDir    = sectionVector.normalized;
                            Vector3 sectionNml    = Vector3.Cross(sectionDir, Vector3.up);
                            Vector4 sectionTgnt   = BuildRMesh.CalculateTangent(sectionDir);
                            Vector3 scNmA         = data.facadeDesign.stringCourseDepth * interSectionNmls[i + 0];
                            Vector3 scNmB         = data.facadeDesign.stringCourseDepth * interSectionNmls[i + 1];
                            Vector3 p0o           = p0 - scNmA;
                            Vector3 p1o           = p1 - scNmB;
                            int     submesh       = dmesh.submeshLibrary.SubmeshAdd(data.facadeDesign.stringCourseSurface);                  //data.facadeDesign.stringCourseSurface != null ? facadeSurfaces.IndexOf(data.facadeDesign.stringCourseSurface) : 0;
                            dmesh.AddPlane(p0o + scBaseUp, p1o + scBaseUp, p0o + scTopUp, p1o + scTopUp, sectionNml, sectionTgnt, submesh);
                            dmesh.AddPlane(p0 + scBaseUp, p0o + scBaseUp, p0 + scTopUp, p0o + scTopUp, sectionNml, sectionTgnt, submesh);
                            dmesh.AddPlane(p1o + scBaseUp, p1 + scBaseUp, p1o + scTopUp, p1 + scTopUp, sectionNml, sectionTgnt, submesh);
                            float facadeAngle = BuildrUtils.CalculateFacadeAngle(sectionDir);
                            dmesh.AddPlaneComplexUp(p0 + scBaseUp, p1 + scBaseUp, p0o + scBaseUp, p1o + scBaseUp, facadeAngle, Vector3.down, sectionTgnt, submesh, data.facadeDesign.stringCourseSurface);                      //bottom
                            dmesh.AddPlaneComplexUp(p1 + scTopUp, p0 + scTopUp, p1o + scTopUp, p0o + scTopUp, facadeAngle, Vector3.up, sectionTgnt, submesh, data.facadeDesign.stringCourseSurface);                            //top
                        }
                    }
                }
            }
        }
コード例 #16
0
 public void Remove(WallSection item)
 {
     content.Remove(item);
 }
コード例 #17
0
        public void InsertAt(int index, WallSection item)
        {
            HUtils.log();

            content.Insert(index, item);
        }
コード例 #18
0
 public void Add(WallSection item)
 {
     content.Add(item);
 }
コード例 #19
0
        static void ItemOnGui(string guid, Rect rect)
        {
            if (settings == null)
            {
                settings = BuildRSettings.GetSettings();
            }
            if (!settings.iconPreviews)
            {
                return;
            }

            bool  defaultFound  = settings.defaultIcon != null;
            Rect  squareRect    = new Rect(rect.x, rect.y, rect.height, rect.height);
            float defaultHeight = Mathf.Min(56, rect.height);
            float defaultWidth  = Mathf.Min(44, rect.width, defaultHeight * 0.7857f);
            float defaultX      = rect.x;
            float defaultY      = rect.y;

            if (rect.height > 56)
            {
                defaultX = rect.x + (rect.width - 44) * 0.5f;
                defaultY = rect.y + (rect.height - 70) * 0.5f;
            }
            Rect defaultRect = new Rect(defaultX, defaultY, defaultWidth, defaultHeight);

//            IconUtil.GUIDIconData iconData = settings.GetCustomIconData(guid);
//            if(iconData == null)
//            {
//                iconData = IconUtil.GenerateGUIDIconData(guid);
//                settings.AddCustomIconData(guid, iconData);
//            }

            string      assetPath   = AssetDatabase.GUIDToAssetPath(guid);
            WallSection wallSection = AssetDatabase.LoadAssetAtPath(assetPath, typeof(WallSection)) as WallSection;

            if (wallSection != null)
            {
                Texture2D wallSectionPreview = wallSection.previewTexture;
                if (wallSectionPreview != null)
                {
                    GUI.DrawTexture(squareRect, wallSectionPreview);
                }
                else if (defaultFound)
                {
                    GUI.DrawTexture(defaultRect, settings.defaultIcon);
                }
            }


            Facade facade = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Facade)) as Facade;

            if (facade != null)
            {
                Texture2D facadePreview = facade.previewTexture;
                if (facadePreview != null)
                {
                    GUI.DrawTexture(squareRect, facadePreview);
                }
                else if (defaultFound)
                {
                    GUI.DrawTexture(defaultRect, settings.defaultIcon);
                }
            }

            Surface surface = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Surface)) as Surface;

            if (surface != null && surface.previewTexture != null)
            {
                if (surface.previewTexture != null)
                {
                    GUI.DrawTexture(squareRect, surface.previewTexture);
                }
                else if (defaultFound)
                {
                    GUI.DrawTexture(defaultRect, settings.defaultIcon);
                }
            }

            Gable gable = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Gable)) as Gable;

            if (defaultFound && gable != null)
            {
                GUI.DrawTexture(defaultRect, settings.defaultIcon);
            }

            RoomStyle roomStyle = AssetDatabase.LoadAssetAtPath(assetPath, typeof(RoomStyle)) as RoomStyle;

            if (defaultFound && roomStyle != null)
            {
                GUI.DrawTexture(defaultRect, settings.defaultIcon);
            }

            Portal portal = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Portal)) as Portal;

            if (defaultFound && portal != null)
            {
                GUI.DrawTexture(defaultRect, settings.defaultIcon);
            }

            BuildRSettings settingsIcon = AssetDatabase.LoadAssetAtPath(assetPath, typeof(BuildRSettings)) as BuildRSettings;

            if (defaultFound && settingsIcon != null)
            {
                GUI.DrawTexture(defaultRect, settings.defaultIcon);
            }
        }
コード例 #20
0
        public static void Generate(IBuilding building, IVolume volume, IFloorplan floorplan, int volumeFloor, VerticalOpening[] openings, BuildRMesh mesh, BuildRCollider collider)
        {
            SubmeshLibrary submeshLibrary = mesh.submeshLibrary;

            bool           generateColliders     = building.colliderType != BuildingColliderTypes.None;
            bool           generateMeshColliders = building.colliderType != BuildingColliderTypes.Primitive && generateColliders;
            BuildRCollider sendCollider          = (generateColliders) ? collider : null;

            collider.thickness = volume.wallThickness;
            if (!generateMeshColliders)
            {
                collider = null;
            }

            float   wallThickness = volume.wallThickness;
            float   wallUp        = volume.floorHeight - wallThickness;
            Vector3 wallUpV       = Vector3.up * wallUp;
            Vector3 floorBaseV    = Vector3.up * volume.baseHeight;

            int roomCount = floorplan.RoomCount;

            int actualFloor  = building.VolumeBaseFloor(volume) + volumeFloor;
            int openingCount = openings.Length;

            bool[]       openingBelow           = new bool[openingCount];
            bool[]       openingAbove           = new bool[openingCount];
            FlatBounds[] openingBounds          = new FlatBounds[openingCount];
            Vector2[][]  openingShapes          = new Vector2[openingCount][];
            bool[]       openingUsedInThisFloor = new bool[openingCount];
            for (int o = 0; o < openingCount; o++)
            {
                VerticalOpening opening = openings[o];
                if (!openings[o].FloorIsIncluded(actualFloor))
                {
                    continue;
                }
                openingBelow[o]  = opening.FloorIsIncluded(actualFloor - 1);
                openingAbove[o]  = opening.FloorIsIncluded(actualFloor + 1);
                openingShapes[o] = opening.PointsRotated();
                openingBounds[o] = new FlatBounds(openingShapes[o]);

                submeshLibrary.Add(opening.surfaceA);
                submeshLibrary.Add(opening.surfaceB);
                submeshLibrary.Add(opening.surfaceC);
                submeshLibrary.Add(opening.surfaceD);
            }

            Dictionary <int, List <Vector2Int> > externalWallAnchors = volume.facadeWallAnchors;

            Room[] rooms = floorplan.AllRooms();
            for (int r = 0; r < roomCount; r++)
            {
                Room room       = rooms[r];
                int  pointCount = room.numberOfPoints;

                Surface floorSurface   = null;
                Surface wallSurface    = null;
                Surface ceilingSurface = null;

                if (room.style != null)
                {
                    RoomStyle style = room.style;
                    floorSurface   = style.floorSurface;
                    wallSurface    = style.wallSurface;
                    ceilingSurface = style.ceilingSurface;
                }

                int floorSubmesh   = submeshLibrary.SubmeshAdd(floorSurface);
                int wallSubmesh    = submeshLibrary.SubmeshAdd(wallSurface);
                int ceilingSubmesh = submeshLibrary.SubmeshAdd(ceilingSurface);

                FloorplanUtil.RoomWall[] walls = FloorplanUtil.CalculatePoints(room, volume);
                Vector2[] roomArchorPoints     = FloorplanUtil.RoomArchorPoints(walls);

                Vector4 tangent = BuildRMesh.CalculateTangent(Vector3.right);

                Vector2[] offsetRoomAnchorPoints = QuickPolyOffset.Execute(roomArchorPoints, wallThickness);

                FlatBounds             roomBounds   = new FlatBounds(offsetRoomAnchorPoints);
                List <Vector2[]>       floorCuts    = new List <Vector2[]>();
                List <Vector2[]>       ceilingCuts  = new List <Vector2[]>();
                List <VerticalOpening> roomOpenings = new List <VerticalOpening>();
                for (int o = 0; o < openingCount; o++)
                {
                    if (openings[o].FloorIsIncluded(actualFloor))
                    {
                        if (roomBounds.Overlaps(openingBounds[o]))
                        {
                            if (CheckShapeWithinRoom(offsetRoomAnchorPoints, openingShapes[o]))
                            {
                                if (openingBelow[o])
                                {
                                    floorCuts.Add(openingShapes[o]);
                                }
                                if (openingAbove[o])
                                {
                                    ceilingCuts.Add(openingShapes[o]);
                                }
                                if (openingAbove[o] || openingBelow[o])
                                {
                                    roomOpenings.Add(openings[o]);
                                    openingUsedInThisFloor[o] = true;
                                }
                            }
                        }
                    }
                }

                int offsetPointBase = 0;
                for (int p = 0; p < pointCount; p++)//generate room walls
                {
                    FloorplanUtil.RoomWall wall = walls[p];
                    int wallPointCount          = wall.offsetPoints.Length;

                    List <RoomPortal> wallPortals = floorplan.GetWallPortals(room, p);
                    int wallPortalCount           = wallPortals.Count;

                    if (!wall.isExternal)
                    {
                        int     indexA    = offsetPointBase;
                        int     indexB    = (offsetPointBase + 1) % roomArchorPoints.Length;
                        Vector2 origBaseA = roomArchorPoints[indexA];
                        Vector2 origBaseB = roomArchorPoints[indexB];
                        Vector2 baseA     = offsetRoomAnchorPoints[indexA];
                        Vector2 baseB     = offsetRoomAnchorPoints[indexB];
                        Vector3 v0        = new Vector3(origBaseA.x, 0, origBaseA.y) + floorBaseV;
                        Vector3 v1        = new Vector3(origBaseB.x, 0, origBaseB.y) + floorBaseV;
                        Vector3 vOffset0  = new Vector3(baseA.x, 0, baseA.y) + floorBaseV;
                        Vector3 vOffset1  = new Vector3(baseB.x, 0, baseB.y) + floorBaseV;
                        if (wallPortalCount == 0)  //just draw the wall - no portals to cut

                        {
                            Vector3 v2 = vOffset1 + wallUpV;
                            Vector3 v3 = vOffset0 + wallUpV;

                            Vector2 minUV = Vector2.zero;
                            Vector2 maxUV = new Vector2(Vector2.Distance(baseA, baseB), wallUp);
                            if (wallSurface != null)
                            {
                                maxUV = wallSurface.CalculateUV(maxUV);
                            }
                            Vector3 wallDir     = (vOffset0 - vOffset1).normalized;
                            Vector3 wallNormal  = Vector3.Cross(Vector3.up, wallDir);
                            Vector4 wallTangent = BuildRMesh.CalculateTangent(wallDir);
                            mesh.AddPlane(vOffset1, vOffset0, v2, v3, minUV, maxUV, wallNormal, wallTangent, wallSubmesh, wallSurface);

                            if (generateColliders)
                            {
                                collider.AddPlane(vOffset1, vOffset0, v2, v3);
                            }
                        }
                        else
                        {
                            List <float> useLaterals = new List <float>();
                            List <bool>  hasPortals  = new List <bool>();
                            for (int wp = 0; wp < wallPortalCount; wp++)
                            {
                                RoomPortal portal    = wallPortals[wp];
                                bool       hasPortal = room.HasPortal(portal);
                                hasPortals.Add(hasPortal);
                                if (hasPortal)
                                {
                                    useLaterals.Add(portal.lateralPosition);
                                }
                                else
                                {
                                    useLaterals.Add(1 - portal.lateralPosition);//portal from other wall - wall orientation is flipped
                                }
                            }

                            Vector3 wallVector               = vOffset1 - vOffset0;
                            Vector3 wallDirection            = wallVector.normalized;
                            Vector3 wallStart                = vOffset0;
                            Vector4 wallTangent              = BuildRMesh.CalculateTangent(wallDirection);
                            Vector3 wallNormal               = Vector3.Cross(Vector3.up, wallDirection);
                            Vector4 wallNormalTangent        = BuildRMesh.CalculateTangent(wallNormal);
                            Vector4 wallNormalTangentReverse = BuildRMesh.CalculateTangent(-wallNormal);

                            while (wallPortalCount > 0)
                            {
                                int        portalIndex = 0;
                                RoomPortal usePortal   = wallPortals[0];
                                float      lowestLat   = useLaterals[0];
                                for (int wp = 1; wp < wallPortalCount; wp++)
                                {
                                    if (useLaterals[wp] < lowestLat)
                                    {
                                        portalIndex = wp;
                                        usePortal   = wallPortals[wp];
                                        lowestLat   = useLaterals[wp];
                                    }
                                }

                                wallPortals.RemoveAt(portalIndex);
                                useLaterals.RemoveAt(portalIndex);
                                wallPortalCount--;

                                Vector3 vl0 = v0 + (-wallNormal + wallDirection) * wallThickness;
                                Vector3 vl1 = v1 + (-wallNormal - wallDirection) * wallThickness;

                                Vector3 portalCenter     = Vector3.Lerp(vl0, vl1, lowestLat);
                                Vector3 portalHalfvector = wallDirection * (usePortal.width * 0.5f);
                                Vector3 portalBase       = Vector3.up * (volume.floorHeight - usePortal.height) * usePortal.verticalPosition;
                                Vector3 portalUp         = portalBase + Vector3.up * usePortal.height;
                                Vector3 portalStart      = portalCenter - portalHalfvector;
                                Vector3 portalEnd        = portalCenter + portalHalfvector;

                                Vector2 initalWallUVMin = new Vector2(Vector3.Dot(portalStart, wallDirection), 0);
                                Vector2 initalWallUVMax = new Vector2(Vector3.Dot(wallStart, wallDirection), wallUp);
                                mesh.AddPlane(portalStart, wallStart, portalStart + wallUpV, wallStart + wallUpV, initalWallUVMin, initalWallUVMax, wallNormal, wallTangent, wallSubmesh, wallSurface);//initial wall
                                if (generateColliders)
                                {
                                    collider.AddPlane(portalStart, wallStart, portalStart + wallUpV, wallStart + wallUpV);
                                }
                                if (usePortal.verticalPosition > 0)
                                {
                                    Vector2 portalBaseUVMin = new Vector2(Vector3.Dot(portalEnd, wallDirection), 0);
                                    Vector2 portalBaseUVMax = new Vector2(Vector3.Dot(portalStart, wallDirection), portalBase.y);
                                    mesh.AddPlane(portalEnd, portalStart, portalEnd + portalBase, portalStart + portalBase, portalBaseUVMin, portalBaseUVMax, wallNormal, wallTangent, wallSubmesh, wallSurface);//bottom
                                    if (generateColliders)
                                    {
                                        collider.AddPlane(portalEnd, portalStart, portalEnd + portalBase, portalStart + portalBase);
                                    }
                                }
                                if (usePortal.verticalPosition < 1)
                                {
                                    Vector2 portalBaseUVMin = new Vector2(Vector3.Dot(portalEnd, wallDirection), portalUp.y);
                                    Vector2 portalBaseUVMax = new Vector2(Vector3.Dot(portalStart, wallDirection), wallUp);
                                    mesh.AddPlane(portalEnd + portalUp, portalStart + portalUp, portalEnd + wallUpV, portalStart + wallUpV, portalBaseUVMin, portalBaseUVMax, wallNormal, wallTangent, wallSubmesh, wallSurface);//top
                                    if (generateColliders)
                                    {
                                        collider.AddPlane(portalEnd + portalUp, portalStart + portalUp, portalEnd + wallUpV, portalStart + wallUpV);
                                    }
                                }

                                if (hasPortals[portalIndex])//only do this once - from the room it's attached to
                                {
                                    //portal interior frame
                                    Vector3 portalDepth = wallNormal * wallThickness * 2;

                                    //sides
                                    mesh.AddPlane(portalStart + portalDepth + portalBase, portalStart + portalBase, portalStart + portalDepth + portalUp, portalStart + portalUp, wallDirection, wallNormalTangentReverse, wallSubmesh);
                                    mesh.AddPlane(portalEnd + portalBase, portalEnd + portalDepth + portalBase, portalEnd + portalUp, portalEnd + portalDepth + portalUp, -wallDirection, wallNormalTangent, wallSubmesh);

                                    if (generateMeshColliders)
                                    {
                                        collider.AddPlane(portalStart + portalDepth + portalBase, portalStart + portalBase, portalStart + portalDepth + portalUp, portalStart + portalUp);
                                        collider.AddPlane(portalEnd + portalBase, portalEnd + portalDepth + portalBase, portalEnd + portalUp, portalEnd + portalDepth + portalUp);
                                    }

                                    //floor
                                    Vector2 minFloorUv = new Vector2((portalEnd + portalBase).z, (portalEnd + portalBase).x);
                                    Vector2 maxFloorUv = minFloorUv + new Vector2(wallThickness, usePortal.width);
                                    mesh.AddPlane(portalStart + portalBase, portalStart + portalDepth + portalBase, portalEnd + portalBase, portalEnd + portalDepth + portalBase, minFloorUv, maxFloorUv, Vector3.up, wallTangent, floorSubmesh, floorSurface);
                                    if (generateMeshColliders)
                                    {
                                        collider.AddPlane(portalStart + portalBase, portalStart + portalDepth + portalBase, portalEnd + portalBase, portalEnd + portalDepth + portalBase);
                                    }

                                    //ceiling
                                    mesh.AddPlane(portalEnd + portalUp, portalEnd + portalDepth + portalUp, portalStart + portalUp, portalStart + portalDepth + portalUp, Vector3.down, wallTangent, wallSubmesh);
                                    if (generateMeshColliders)
                                    {
                                        collider.AddPlane(portalEnd + portalUp, portalEnd + portalDepth + portalUp, portalStart + portalUp, portalStart + portalDepth + portalUp);
                                    }
                                }

                                wallStart = portalEnd;//move the start for the next calculation
                            }

                            Vector2 finalWallUVMin = new Vector2(Vector3.Dot(vOffset1, wallDirection), 0);
                            Vector2 finalWallUVMax = new Vector2(Vector3.Dot(wallStart, wallDirection), wallUp);
                            mesh.AddPlane(vOffset1, wallStart, vOffset1 + wallUpV, wallStart + wallUpV, finalWallUVMin, finalWallUVMax, wallNormal, wallTangent, wallSubmesh, wallSurface);//final wall section
                            if (generateColliders)
                            {
                                collider.AddPlane(vOffset1, wallStart, vOffset1 + wallUpV, wallStart + wallUpV);
                            }
                        }
                        offsetPointBase += 1;
                    }
                    else//external anchored wall
                    {
                        int    facadeIndex  = wall.facadeIndex;
                        Facade facadeDesign = volume.GetFacade(facadeIndex);
                        int    currentFacadeWallSectionLength = externalWallAnchors[facadeIndex].Count - 1;
                        int    currentWallSectionIndex        = wall.offsetPointWallSection[0];
                        int    wallOffsetPoints = wall.offsetPoints.Length;
                        for (int w = 0; w < wallOffsetPoints - 1; w++)
                        {
                            int     roomPointIndex   = offsetPointBase + w;
                            Vector2 baseA            = offsetRoomAnchorPoints[roomPointIndex];
                            int     offsetIndexB     = (roomPointIndex + 1) % offsetRoomAnchorPoints.Length;
                            Vector2 baseB            = offsetRoomAnchorPoints[offsetIndexB];
                            Vector3 v0               = new Vector3(baseA.x, 0, baseA.y) + floorBaseV;
                            Vector3 v1               = new Vector3(baseB.x, 0, baseB.y) + floorBaseV;
                            int     wallSectionIndex = wall.offsetPointWallSection[w];

                            bool canGenerateWallSection = facadeDesign != null;

                            Vector3 wallVector = v0 - v1;
                            Vector3 wallDir    = wallVector.normalized;
                            float   wallLength = wallVector.magnitude;

                            if (!canGenerateWallSection)
                            {
                                if (wallSurface != null)
                                {
                                    submeshLibrary.Add(wallSurface);
                                }

                                Vector3 v2 = v1 + wallUpV;
                                Vector3 v3 = v0 + wallUpV;

                                Vector2 minUV       = Vector2.zero;
                                Vector2 maxUV       = new Vector2(Vector2.Distance(baseA, baseB), wallUp);
                                Vector3 wallNormal  = Vector3.Cross(Vector3.up, wallDir);
                                Vector4 wallTangent = BuildRMesh.CalculateTangent(wallDir);
                                mesh.AddPlane(v1, v0, v2, v3, minUV, maxUV, wallNormal, wallTangent, wallSubmesh, wallSurface);

                                if (generateMeshColliders)
                                {
                                    collider.AddPlane(v1, v0, v2, v3);
                                }
                            }
                            else
                            {
                                WallSection section = facadeDesign.GetWallSection(wallSectionIndex, volumeFloor, currentFacadeWallSectionLength, volume.floors);
                                if (section.model != null)
                                {
                                    continue;//cannot account for custom meshes assume custom mesh does include interior mesh or if does - will be generated with the exterior
                                }
                                GenerationOutput generatedSection = GenerationOutput.CreateRawOutput();
                                Vector2          wallSectionSize  = new Vector2(wallLength, wallUp + wallThickness);
                                bool             cullOpening      = building.cullDoors && section.isDoor;
                                SubmeshLibrary   sectionLib       = new SubmeshLibrary();

                                if (wallSurface != null)
                                {
                                    sectionLib.Add(wallSurface);//add interior wall surface
                                    submeshLibrary.Add(wallSurface);
                                }

                                sectionLib.Add(section.openingSurface);//add windows - the only surface we'll use in the interior room
                                submeshLibrary.Add(section.openingSurface);

                                float offset = 0;
                                if (w == 0)
                                {
                                    offset = wallThickness;
                                }
                                if (w == wallOffsetPoints - 2)
                                {
                                    offset = -wallThickness;
                                }
                                WallSectionGenerator.Generate(section, generatedSection, wallSectionSize, true, wallThickness, cullOpening, null, sectionLib, offset);
                                int[]   mapping     = submeshLibrary.MapSubmeshes(generatedSection.raw.materials);
                                Vector3 curveNormal = Vector3.Cross(wallDir, Vector3.up);

                                Quaternion meshRot = Quaternion.LookRotation(curveNormal, Vector3.up);
                                Vector3    meshPos = new Vector3(v1.x, volume.baseHeight, v1.z) + wallDir * wallSectionSize.x + Vector3.up * wallSectionSize.y;
                                meshPos += meshRot * -new Vector3(wallSectionSize.x, wallSectionSize.y, 0) * 0.5f;
                                mesh.AddData(generatedSection.raw, mapping, meshPos, meshRot, Vector3.one);
                            }


                            currentWallSectionIndex++;
                            if (currentWallSectionIndex >= currentFacadeWallSectionLength)
                            {
                                //reached the end of the facade - move to the next one and continue
                                currentFacadeWallSectionLength = externalWallAnchors[facadeIndex].Count;
                                currentWallSectionIndex        = 0;
                            }
                        }

                        offsetPointBase += wallPointCount - 1;
                    }
                }

                //FLOOR
                Vector2[]   mainShape      = offsetRoomAnchorPoints;
                Vector2[][] floorCutPoints = floorCuts.ToArray();
                int         floorVertCount = mainShape.Length;
                for (int flc = 0; flc < floorCutPoints.Length; flc++)
                {
                    floorVertCount += floorCutPoints[flc].Length;
                }

                Vector2[] allFloorPoints  = new Vector2[floorVertCount];
                int       mainShapeLength = mainShape.Length;
                for (int ms = 0; ms < mainShapeLength; ms++)
                {
                    allFloorPoints[ms] = mainShape[ms];
                }
                int cutPointIterator = mainShapeLength;
                for (int flc = 0; flc < floorCutPoints.Length; flc++)
                {
                    for (int flcp = 0; flcp < floorCutPoints[flc].Length; flcp++)
                    {
                        allFloorPoints[cutPointIterator] = floorCutPoints[flc][flcp];
                        cutPointIterator++;
                    }
                }

                Vector3[] floorPoints   = new Vector3[floorVertCount];
                Vector2[] floorUvs      = new Vector2[floorVertCount];
                Vector3[] floorNorms    = new Vector3[floorVertCount];
                Vector4[] floorTangents = new Vector4[floorVertCount];
                for (int rp = 0; rp < floorVertCount; rp++)
                {
                    floorPoints[rp] = new Vector3(allFloorPoints[rp].x, 0, allFloorPoints[rp].y) + floorBaseV;
                    Vector2 uv = allFloorPoints[rp];
                    if (floorSurface != null)
                    {
                        uv = floorSurface.CalculateUV(uv);
                    }
                    floorUvs[rp]      = uv;
                    floorNorms[rp]    = Vector3.up;
                    floorTangents[rp] = tangent;
                }

                int[] tris = Poly2TriWrapper.Triangulate(mainShape, true, floorCutPoints);

                mesh.AddData(floorPoints, floorUvs, tris, floorNorms, floorTangents, floorSubmesh);
                if (generateColliders)
                {
                    collider.mesh.AddData(floorPoints, floorUvs, tris, floorNorms, floorTangents, 0);
                }

                //CEILING!
                Vector2[][] ceilingCutPoints = ceilingCuts.ToArray();
                int         ceilingVertCount = mainShape.Length;
                for (int flc = 0; flc < ceilingCutPoints.Length; flc++)
                {
                    ceilingVertCount += ceilingCutPoints[flc].Length;
                }

                Vector2[] allCeilingPoints = new Vector2[ceilingVertCount];
                for (int ms = 0; ms < mainShapeLength; ms++)
                {
                    allCeilingPoints[ms] = mainShape[ms];
                }
                cutPointIterator = mainShapeLength;
                for (int flc = 0; flc < ceilingCutPoints.Length; flc++)
                {
                    for (int flcp = 0; flcp < ceilingCutPoints[flc].Length; flcp++)
                    {
                        allCeilingPoints[cutPointIterator] = ceilingCutPoints[flc][flcp];
                        cutPointIterator++;
                    }
                }

                Vector3[] ceilingPoints   = new Vector3[ceilingVertCount];
                Vector2[] ceilingUvs      = new Vector2[ceilingVertCount];
                Vector3[] ceilingNorms    = new Vector3[ceilingVertCount];
                Vector4[] ceilingTangents = new Vector4[ceilingVertCount];
                for (int rp = 0; rp < ceilingVertCount; rp++)
                {
                    ceilingPoints[rp] = new Vector3(allCeilingPoints[rp].x, wallUp, allCeilingPoints[rp].y) + floorBaseV;
                    Vector2 uv = allCeilingPoints[rp];
                    if (floorSurface != null)
                    {
                        uv = ceilingSurface.CalculateUV(uv);
                    }
                    ceilingUvs[rp]      = uv;
                    ceilingNorms[rp]    = Vector3.down;
                    ceilingTangents[rp] = tangent;
                }

                tris = Poly2TriWrapper.Triangulate(mainShape, false, ceilingCutPoints);
                mesh.AddData(ceilingPoints, ceilingUvs, tris, ceilingNorms, ceilingTangents, ceilingSubmesh);
                if (generateColliders)
                {
                    collider.mesh.AddData(ceilingPoints, ceilingUvs, tris, ceilingNorms, ceilingTangents, 0);
                }

                for (int ob = 0; ob < openingCount; ob++)
                {
                    VerticalOpening opening      = openings[ob];
                    int             openingIndex = Array.IndexOf(openings, opening);
                    Vector3         basePosition = openingBounds[openingIndex].center;
                    basePosition.z = basePosition.y;
                    basePosition.y = volume.baseHeight;

                    if (roomOpenings.Contains(opening))//opening used in this floorplan
                    {
                        int externalWallSubmesh = wallSubmesh != -1 ? wallSubmesh : -1;
                        switch (opening.usage)
                        {
                        case VerticalOpening.Usages.Space:
                            if (ceilingCutPoints.Length <= ob)
                            {
                                continue;
                            }
                            Vector3   ceilingCutUpV = Vector3.up * wallThickness;
                            Vector2[] ceilingCut    = ceilingCutPoints[ob];
                            int       custSize      = ceilingCut.Length;
                            for (int cp = 0; cp < custSize; cp++)
                            {
                                int     indexA = (cp + 1) % custSize;
                                int     indexB = cp;
                                Vector3 cp0    = new Vector3(ceilingCut[indexA].x, wallUp, ceilingCut[indexA].y) + floorBaseV;
                                Vector3 cp1    = new Vector3(ceilingCut[indexB].x, wallUp, ceilingCut[indexB].y) + floorBaseV;
                                Vector3 cp2    = cp0 + ceilingCutUpV;
                                Vector3 cp3    = cp1 + ceilingCutUpV;
                                mesh.AddPlane(cp0, cp1, cp2, cp3, ceilingSubmesh);
                                if (generateColliders)
                                {
                                    collider.AddPlane(cp0, cp1, cp2, cp3);
                                }
                            }
                            break;

                        case VerticalOpening.Usages.Stairwell:
                            StaircaseGenerator.Generate(mesh, opening, basePosition, volume.floorHeight, actualFloor, externalWallSubmesh, sendCollider);
                            if (volumeFloor == volume.floors - 1 && opening.baseFloor + opening.floors > building.VolumeBaseFloor(volume) + volume.floors - 1 && volume.abovePlanCount == 0)
                            {
                                StaircaseGenerator.GenerateRoofAccess(mesh, opening, basePosition, volume.floorHeight, actualFloor, externalWallSubmesh, sendCollider);
                            }
                            break;

                        case VerticalOpening.Usages.Elevator:
                            ElevatorShaftGenerator.Generate(ref mesh, opening, actualFloor, basePosition, volume.floorHeight, externalWallSubmesh, sendCollider);
                            break;
                        }
                    }
                }
            }

            for (int ob = 0; ob < openingCount; ob++)
            {
                Vector2[] openingShape = openingShapes[ob];
                if (openingShape == null)
                {
                    continue;                      //opening not used by this floorplan
                }
                if (openingUsedInThisFloor[ob])
                {
                    continue;                            //opening already generated
                }
                //seal this opening from the void
                VerticalOpening opening      = openings[ob];
                int             openingIndex = Array.IndexOf(openings, opening);
                Vector3         basePosition = openingBounds[openingIndex].center;
                basePosition.z = basePosition.y;
                basePosition.y = 0;

                int       cutSize            = openingShape.Length;
                Vector3   sealingWallUpV     = Vector3.up * volume.floorHeight;
                int       sealWallSubmesh    = submeshLibrary.SubmeshAdd(opening.surfaceB);
                Vector2[] offsetOpeningShape = QuickPolyOffset.Execute(openingShape, wallThickness);
                for (int cp = 0; cp < cutSize; cp++)
                {
                    int     indexA = (cp + 1) % cutSize;
                    int     indexB = cp;
                    Vector2 p0     = opening.usage == VerticalOpening.Usages.Space ? openingShape[indexA] : offsetOpeningShape[indexA];
                    Vector2 p1     = opening.usage == VerticalOpening.Usages.Space ? openingShape[indexB] : offsetOpeningShape[indexB];
                    Vector3 cp0    = new Vector3(p0.x, 0, p0.y) + floorBaseV;
                    Vector3 cp1    = new Vector3(p1.x, 0, p1.y) + floorBaseV;
                    Vector3 cp2    = cp0 + sealingWallUpV;
                    Vector3 cp3    = cp1 + sealingWallUpV;
                    mesh.AddPlane(cp0, cp1, cp2, cp3, sealWallSubmesh);
                    if (generateColliders)
                    {
                        collider.AddPlane(cp0, cp1, cp2, cp3);
                    }
                }

                switch (opening.usage)
                {
                case VerticalOpening.Usages.Space:
                    //nothing to implement
                    break;

                case VerticalOpening.Usages.Stairwell:
                    //need stairs to connect used floors
                    StaircaseGenerator.GenerateStairs(mesh, opening, basePosition, volume.floorHeight, actualFloor, -1, sendCollider);
                    if (volumeFloor == volume.floors - 1)
                    {
                        StaircaseGenerator.GenerateRoofAccess(mesh, opening, basePosition, volume.floorHeight, actualFloor, -1, sendCollider);
                    }
                    break;

                case VerticalOpening.Usages.Elevator:
                    //nothing to implement
                    break;
                }
            }
        }
コード例 #21
0
ファイル: FacadeEditor.cs プロジェクト: ishui/unity3DScripts
        private static void GroundPatternEditor(Facade facade)
        {
            if (!facade.hasGroundFloorPattern)
            {
                return;
            }
            EventType eventType = Event.current.type;
//            if (eventType == EventType.DragUpdated)
//                Debug.Log("DragUpdated");
//            if (eventType == EventType.DragPerform)
//                Debug.Log("DragPerform");

            List <Rect> facadeRects = new List <Rect>();

            EditorGUILayout.BeginHorizontal();
            for (int x = 0; x < facade.baseWidth; x++)
            {
                Rect itemrect = WallSectionItem(facade, x, 0, true);
                facadeRects.Add(itemrect);

//                WallSection wallSection = facade.GetGroundWallSection(x);

                //                if(wallSection != null)
                //                {
                //                    EditorGUILayout.BeginHorizontal("box");
                //                    GUIContent texture = new GUIContent(wallSection.PreviewTexture());
                //                    EditorGUILayout.LabelField(texture, GUILayout.Width(SECTION_PREVIEW_SIZE), GUILayout.Height(SECTION_PREVIEW_SIZE));
                //                    EditorGUILayout.EndHorizontal();
                //                }
                //                else
                //                {
                //                    EditorGUILayout.BeginHorizontal("box");
                //                    EditorGUILayout.LabelField("", GUILayout.Width(SECTION_PREVIEW_SIZE), GUILayout.Height(SECTION_PREVIEW_SIZE));
                //                    EditorGUILayout.EndHorizontal();
                //                }
                //                facadeRects.Add(GUILayoutUtility.GetLastRect());
            }
            EditorGUILayout.EndHorizontal();

            WallSection output = null;

            //            EventType eventType = Event.current.type;

            if (eventType == EventType.DragUpdated || eventType == EventType.DragPerform)
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
                Object[] objArray = DragAndDrop.objectReferences;
                if (objArray != null)
                {
                    if (objArray[0].GetType() == typeof(WallSection))
                    {
                        DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                        if (eventType == EventType.DragPerform)
                        {
                            output = (WallSection)objArray[0];
                            DragAndDrop.AcceptDrag();

                            Vector2 mousePos = Event.current.mousePosition;

                            for (int x = 0; x < facade.baseWidth; x++)
                            {
                                if (facadeRects[x].Contains(mousePos))
                                {
                                    WallSection wallSection = facade.GetGroundWallSection(x);
                                    if (output != wallSection)
                                    {
                                        facade.SetGroundWallSection(x, output);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #22
0
        public void Add(WallSection section)
        {
            if (section == null)
            {
                return;
            }

            if (WALLSECTION_SUBMESH_MAPPING.ContainsKey(section))
            {
                return;
            }

            List <int> submeshMapping = new List <int>();

            submeshMapping.Add(Add(section.wallSurface));
            if (section.sillSurface != null)
            {
                submeshMapping.Add(Add(section.sillSurface));
            }
            if (section.ceilingSurface != null)
            {
                submeshMapping.Add(Add(section.ceilingSurface));
            }
            if (section.openingSurface != null)
            {
                submeshMapping.Add(Add(section.openingSurface));
            }

            List <bool> submeshTiling = new List <bool>();

            submeshTiling.Add(section.wallSurface != null && section.wallSurface.tiled);
            if (section.sillSurface != null)
            {
                submeshTiling.Add(section.sillSurface != null && section.sillSurface.tiled);
            }
            if (section.ceilingSurface != null)
            {
                submeshTiling.Add(section.ceilingSurface != null && section.ceilingSurface.tiled);
            }
            if (section.openingSurface != null)
            {
                submeshTiling.Add(section.openingSurface != null && section.openingSurface.tiled);
            }

            int[] balconySubmeshes = Add(section.balconyModel);
            submeshMapping.AddRange(balconySubmeshes);
            for (int b = 0; b < balconySubmeshes.Length; b++)
            {
                submeshTiling.Add(false);//no tiling
            }
            int[] shutterSubmeshes = Add(section.shutterModel);
            submeshMapping.AddRange(shutterSubmeshes);
            for (int b = 0; b < shutterSubmeshes.Length; b++)
            {
                submeshTiling.Add(false);//no tiling
            }
            int[] openingSubmeshes = Add(section.openingModel);
            submeshMapping.AddRange(openingSubmeshes);
            for (int b = 0; b < openingSubmeshes.Length; b++)
            {
                submeshTiling.Add(false);                //no tiling
            }
            int[] portalSubmeshes    = Add(section.portal);
            int   portalSubmeshCount = portalSubmeshes.Length;

            for (int s = 0; s < portalSubmeshCount; s++)
            {
                if (!submeshMapping.Contains(portalSubmeshes[s]))
                {
                    submeshMapping.Add(portalSubmeshes[s]);
                    Surface surf = SUBMESH[portalSubmeshes[s]] as Surface;
                    if (surf != null)
                    {
                        submeshTiling.Add(surf.tiled);
                    }
                    else
                    {
                        submeshTiling.Add(false);
                    }
                }
            }

            WALLSECTION_SUBMESH_MAPPING.Add(section, submeshMapping.ToArray());
            WALLSECTION_SUBMESH_TILING.Add(section, submeshTiling.ToArray());
        }