/// <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); }
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); }
/// <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(); }