/// <summary>
        /// Finds the interior door that is closest to ground level and farthest from the center of the building.
        /// </summary>
        /// <param name="lowestDoorPositionOut">Position of lowest door in scene.</param>
        /// <param name="lowestDoorNormalOut">Normal vector of lowest door in scene.</param>
        /// <returns>True if successful. False if no doors are found.</returns>
        public bool FindLowestOuterInteriorDoor(out Vector3 lowestDoorPositionOut, out Vector3 lowestDoorNormalOut)
        {
            lowestDoorPositionOut = lowestDoorNormalOut = Vector3.zero;
            DaggerfallStaticDoors interiorDoors = GetComponent <DaggerfallStaticDoors>();

            if (!interiorDoors)
            {
                return(false);
            }

            if (interiorDoors.FindLowestOutermostDoor(-1, out lowestDoorPositionOut, out int doorIndex))
            {
                lowestDoorNormalOut = interiorDoors.GetDoorNormal(doorIndex);
                return(true);
            }

            return(false);
        }
예제 #2
0
        public bool FindClosestInteriorDoor(Vector3 playerPos, out Vector3 closestDoorPositionOut, out Vector3 closestDoorNormalOut)
        {
            closestDoorPositionOut = closestDoorNormalOut = Vector3.zero;
            DaggerfallStaticDoors interiorDoors = GetComponent <DaggerfallStaticDoors>();

            if (!interiorDoors)
            {
                return(false);
            }

            int doorIndex;

            if (interiorDoors.FindClosestDoorToPlayer(playerPos, -1, out closestDoorPositionOut, out doorIndex))
            {
                closestDoorNormalOut = interiorDoors.GetDoorNormal(doorIndex);
                return(true);
            }

            return(false);
        }
예제 #3
0
        /// <summary>
        /// Add interior models.
        /// </summary>
        private void AddModels(PlayerGPS.DiscoveredBuilding buildingData)
        {
            List <StaticDoor> doors     = new List <StaticDoor>();
            GameObject        node      = new GameObject("Models");
            GameObject        doorsNode = new GameObject("Doors");

            node.transform.parent      = this.transform;
            doorsNode.transform.parent = this.transform;

            // Iterate through models in this subrecord
            combiner.NewCombiner();
            foreach (DFBlock.RmbBlock3dObjectRecord obj in recordData.Interior.Block3dObjectRecords)
            {
                bool stopCombine = false;

                // Get model data
                ModelData modelData;
                dfUnity.MeshReader.GetModelData(obj.ModelIdNum, out modelData);

                // Get model position by type (3 seems to indicate props/clutter)
                // Also stop these from being combined as some may carry a loot container
                Vector3 modelPosition;
                if (obj.ObjectType == propModelType)
                {
                    // Props axis needs to be transformed to lowest Y point
                    Vector3 bottom = modelData.Vertices[0];
                    for (int i = 0; i < modelData.Vertices.Length; i++)
                    {
                        if (modelData.Vertices[i].y < bottom.y)
                        {
                            bottom = modelData.Vertices[i];
                        }
                    }
                    modelPosition  = new Vector3(obj.XPos, obj.YPos, obj.ZPos) * MeshReader.GlobalScale;
                    modelPosition += new Vector3(0, -bottom.y, 0);
                    stopCombine    = true;
                }
                else
                {
                    modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;
                }

                // Stop special object from being combined
                if (obj.ModelIdNum == ladderModelId)
                {
                    stopCombine = true;
                }

                // Get model transform
                Vector3   modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0);
                Matrix4x4 modelMatrix   = Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), Vector3.one);

                // Does this model have doors?
                if (modelData.Doors != null)
                {
                    doors.AddRange(GameObjectHelper.GetStaticDoors(ref modelData, entryDoor.blockIndex, entryDoor.recordIndex, modelMatrix));
                }

                // Inject custom GameObject if available
                GameObject go = MeshReplacement.ImportCustomGameobject(obj.ModelIdNum, node.transform, modelMatrix);

                // Otherwise use Daggerfall mesh - combine or add
                if (!go)
                {
                    if (dfUnity.Option_CombineRMB && !stopCombine)
                    {
                        combiner.Add(ref modelData, modelMatrix);
                    }
                    else
                    {
                        // Add individual GameObject
                        go = GameObjectHelper.CreateDaggerfallMeshGameObject(obj.ModelIdNum, node.transform, dfUnity.Option_SetStaticFlags);
                        go.transform.position = modelMatrix.GetColumn(3);
                        go.transform.rotation = GameObjectHelper.QuaternionFromMatrix(modelMatrix);

                        // Update climate
                        DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>();
                        dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled);
                    }
                }

                // Make ladder collider convex
                if (obj.ModelIdNum == ladderModelId)
                {
                    var meshCollider = go.GetComponent <MeshCollider>();
                    if (meshCollider)
                    {
                        meshCollider.convex = true;
                    }
                    go.AddComponent <DaggerfallLadder>();
                }

                // Optionally add action objects to specific furniture items (e.g. loot containers), except when laying out map (buildingType=AllValid)
                if (obj.ObjectType == propModelType && buildingData.buildingType != DFLocation.BuildingTypes.AllValid)
                {
                    AddFurnitureAction(obj, go, buildingData);
                }
            }

            // Add combined GameObject
            if (dfUnity.Option_CombineRMB)
            {
                if (combiner.VertexCount > 0)
                {
                    combiner.Apply();
                    GameObject go = GameObjectHelper.CreateCombinedMeshGameObject(combiner, "CombinedModels", node.transform, dfUnity.Option_SetStaticFlags);

                    // Update climate
                    DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>();
                    dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled);
                }
            }

            // Add static doors component
            DaggerfallStaticDoors c = this.gameObject.AddComponent <DaggerfallStaticDoors>();

            c.Doors = doors.ToArray();
        }
        /// <summary>
        /// Add interior models.
        /// </summary>
        private void AddModels()
        {
            List <StaticDoor> doors     = new List <StaticDoor>();
            GameObject        node      = new GameObject("Models");
            GameObject        doorsNode = new GameObject("Doors");

            node.transform.parent      = this.transform;
            doorsNode.transform.parent = this.transform;

            // Iterate through models in this subrecord
            combiner.NewCombiner();
            foreach (DFBlock.RmbBlock3dObjectRecord obj in recordData.Interior.Block3dObjectRecords)
            {
                // Get model data
                ModelData modelData;
                dfUnity.MeshReader.GetModelData(obj.ModelIdNum, out modelData);

                // Get model position by type (3 seems to indicate props/clutter)
                Vector3 modelPosition;
                if (obj.ObjectType == 3)
                {
                    // Props axis needs to be transformed to lowest Y point
                    Vector3 bottom = modelData.Vertices[0];
                    for (int i = 0; i < modelData.Vertices.Length; i++)
                    {
                        if (modelData.Vertices[i].y < bottom.y)
                        {
                            bottom = modelData.Vertices[i];
                        }
                    }
                    modelPosition  = new Vector3(obj.XPos, obj.YPos, obj.ZPos) * MeshReader.GlobalScale;
                    modelPosition += new Vector3(0, -bottom.y, 0);
                }
                else
                {
                    modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;
                }

                // Get model transform
                Vector3   modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0);
                Matrix4x4 modelMatrix   = Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), Vector3.one);

                // Does this model have doors?
                if (modelData.Doors != null)
                {
                    doors.AddRange(GameObjectHelper.GetStaticDoors(ref modelData, entryDoor.blockIndex, entryDoor.recordIndex, modelMatrix));
                }

                // Get GameObject
                if (MeshReplacement.ImportCustomGameobject(obj.ModelIdNum, node.transform, modelMatrix) == null)
                {
                    // Use Daggerfall Mesh: Combine or add
                    if (dfUnity.Option_CombineRMB)
                    {
                        combiner.Add(ref modelData, modelMatrix);
                    }
                    else
                    {
                        // Add GameObject
                        GameObject go = GameObjectHelper.CreateDaggerfallMeshGameObject(obj.ModelIdNum, node.transform, dfUnity.Option_SetStaticFlags);
                        go.transform.position = modelMatrix.GetColumn(3);
                        go.transform.rotation = GameObjectHelper.QuaternionFromMatrix(modelMatrix);

                        // Update climate
                        DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>();
                        dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled);
                    }
                }
            }

            // Add combined GameObject
            if (dfUnity.Option_CombineRMB)
            {
                if (combiner.VertexCount > 0)
                {
                    combiner.Apply();
                    GameObject go = GameObjectHelper.CreateCombinedMeshGameObject(combiner, "CombinedModels", node.transform, dfUnity.Option_SetStaticFlags);

                    // Update climate
                    DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>();
                    dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled);
                }
            }

            // Add static doors component
            DaggerfallStaticDoors c = this.gameObject.AddComponent <DaggerfallStaticDoors>();

            c.Doors = doors.ToArray();
        }
        /// <summary>
        /// Finds all doors of type across multiple door collections.
        /// </summary>
        /// <param name="doorCollections">Door collections.</param>
        /// <param name="type">Type of door to search for.</param>
        /// <returns>Array of matching doors.</returns>
        public static StaticDoor[] FindDoorsInCollections(DaggerfallStaticDoors[] doorCollections, DoorTypes type)
        {
            List<StaticDoor> doorsOut = new List<StaticDoor>();
            foreach (var collection in doorCollections)
            {
                for (int i = 0; i < collection.Doors.Length; i++)
                {
                    if (collection.Doors[i].doorType == type)
                    {
                        StaticDoor newDoor = collection.Doors[i];
                        newDoor.ownerPosition = collection.transform.position;
                        newDoor.ownerRotation = collection.transform.rotation;
                        doorsOut.Add(newDoor);
                    }
                }
            }

            return doorsOut.ToArray();
        }