Exemplo n.º 1
0
        private static void AddProps(
            DaggerfallUnity dfUnity,
            ref DFBlock blockData,
            out List <StaticDoor> doorsOut,
            ModelCombiner combiner = null,
            Transform parent       = null)
        {
            doorsOut = new List <StaticDoor>();

            // Iterate through all misc records
            foreach (DFBlock.RmbBlock3dObjectRecord obj in blockData.RmbBlock.Misc3dObjectRecords)
            {
                // Get model transform
                Vector3   modelPosition = new Vector3(obj.XPos, -obj.YPos + propsOffsetY, obj.ZPos + BlocksFile.RMBDimension) * MeshReader.GlobalScale;
                Vector3   modelRotation = new Vector3(-obj.XRotation / BlocksFile.RotationDivisor, -obj.YRotation / BlocksFile.RotationDivisor, -obj.ZRotation / BlocksFile.RotationDivisor);
                Vector3   modelScale    = GetModelScaleVector(obj);
                Matrix4x4 modelMatrix   = Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), modelScale);

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

                // Does this model have doors?
                if (modelData.Doors != null)
                {
                    doorsOut.AddRange(GameObjectHelper.GetStaticDoors(ref modelData, blockData.Index, 0, modelMatrix));
                }

                // Import custom GameObject
                if (MeshReplacement.ImportCustomGameobject(obj.ModelIdNum, parent, modelMatrix) != null)
                {
                    continue;
                }

                // Use Daggerfall Model
                // Add or combine
                if (combiner == null || IsBulletinBoard(obj.ModelIdNum) || PlayerActivate.HasCustomActivation(obj.ModelIdNum))
                {
                    AddStandaloneModel(dfUnity, ref modelData, modelMatrix, parent);
                }
                else
                {
                    combiner.Add(ref modelData, modelMatrix);
                }
            }
        }
Exemplo n.º 2
0
        private static void PlaceWagon(bool fromSave = false)
        {
            if (fromSave == false)
            {
                WagonMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel;
                if (!transportManager.HasHorse())
                {
                    SetWagonPositionAndRotation(true);
                    DaggerfallUI.MessageBox("You have no horse to pull your wagon.");
                    ItemCollection playerItems = GameManager.Instance.PlayerEntity.Items;
                    for (int i = 0; i < playerItems.Count; i++)
                    {
                        DaggerfallUnityItem item = playerItems.GetItem(i);
                        if (item != null && item.IsOfTemplate(ItemGroups.Transportation, (int)Transportation.Small_cart))
                        {
                            playerItems.RemoveItem(item);
                        }
                    }
                }
                else
                {
                    SetWagonPositionAndRotation();
                }
            }
            else
            {
                PlaceWagonOnGround();
            }
            Wagon = MeshReplacement.ImportCustomGameobject(wagonModelID, null, WagonMatrix);
            if (Wagon == null)
            {
                Wagon = GameObjectHelper.CreateDaggerfallMeshGameObject(wagonModelID, null);
            }

            Wagon.transform.SetPositionAndRotation(WagonPosition, WagonRotation);
            if (GameManager.Instance.PlayerEnterExit.IsPlayerInsideDungeon)
            {
                Wagon.SetActive(false);
            }
            else
            {
                Wagon.SetActive(true);
            }
            WagonDeployed = true;
        }
Exemplo n.º 3
0
 private static void DeployTent(bool fromSave = false)
 {
     if (fromSave == false)
     {
         TentMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel;
         SetTentPositionAndRotation();
     }
     //Attempt to load a model replacement
     Tent = MeshReplacement.ImportCustomGameobject(tentModelID, null, TentMatrix);
     if (Tent == null)
     {
         Tent = GameObjectHelper.CreateDaggerfallMeshGameObject(tentModelID, null);
     }
     //Set the model's position in the world
     Tent.transform.SetPositionAndRotation(TentPosition, TentRotation);
     Tent.SetActive(true);
     TentDeployed = true;
 }
Exemplo n.º 4
0
        public static void DeployTent(bool fromSave = false)
        {
            if (fromSave == false)
            {
                CampMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel;
                SetTentPositionAndRotation();
                DaggerfallUI.MessageBox("You set up camp");
            }
            else
            {
                PlaceTentOnGround();
            }
            //Attempt to load a model replacement
            Tent = MeshReplacement.ImportCustomGameobject(tentModelID, null, TentMatrix);
            Fire = GameObjectHelper.CreateDaggerfallBillboardGameObject(210, 1, null);
            if (Tent == null)
            {
                Tent = GameObjectHelper.CreateDaggerfallMeshGameObject(tentModelID, null);
            }
            //Set the model's position in the world

            Tent.transform.SetPositionAndRotation(TentPosition, TentRotation);
            if (GameManager.Instance.PlayerEnterExit.IsPlayerInsideDungeon)
            {
                FirePosition = Tent.transform.position + (Tent.transform.up * 0.8f);
                Tent.SetActive(false);
            }
            else
            {
                FirePosition = Tent.transform.position + (Tent.transform.forward * 3) + (Tent.transform.up * 0.8f);
                Tent.SetActive(true);
            }

            Fire.transform.SetPositionAndRotation(FirePosition, TentRotation);
            Fire.SetActive(true);
            AddTorchAudioSource(Fire);
            GameObject lightsNode = new GameObject("Lights");

            lightsNode.transform.parent = Fire.transform;
            AddLight(DaggerfallUnity.Instance, Fire, lightsNode.transform);
            CampDeployed = true;
            FireLit      = true;
        }
        private void Display3dModelSelection(int selectedIdx)
        {
            if (goModel)
            {
                Object.Destroy(goModel);
                goModel = null;
            }

            // Position camera and set model id
            uint modelId = 0;

            if (housesForSale == null)
            {
                camera.transform.position = new Vector3(0, 12, DaggerfallBankManager.GetShipCameraDist((ShipType)selectedIdx));
                modelId = DaggerfallBankManager.GetShipModelId((ShipType)selectedIdx);
            }
            else
            {
                camera.transform.position = new Vector3(0, 3, -20);
                BuildingSummary house = housesForSale[selectedIdx];
                modelId = house.ModelID;
            }

            // Inject custom GameObject if available else create standard mesh game object for the model
            goModel = MeshReplacement.ImportCustomGameobject(modelId, goBankPurchase.transform, new Matrix4x4());
            if (goModel == null)
            {
                goModel = GameObjectHelper.CreateDaggerfallMeshGameObject(modelId, goBankPurchase.transform);
            }

            goModel.layer = layer;

            // Apply current climate
            ClimateBases   climateBase = ClimateSwaps.FromAPIClimateBase(GameManager.Instance.PlayerGPS.ClimateSettings.ClimateType);
            ClimateSeason  season      = (DaggerfallUnity.WorldTime.Now.SeasonValue == DaggerfallDateTime.Seasons.Winter) ? ClimateSeason.Winter : ClimateSeason.Summer;
            DaggerfallMesh dfMesh      = goModel.GetComponent <DaggerfallMesh>();

            dfMesh.SetClimate(climateBase, season, WindowStyle.Day);
        }
        public static GameObject Add3dObject(DFBlock.RdbObject obj, ref DFBlock.RdbModelReference[] modelReferenceList)
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            // Get model reference index and id
            int  modelReference = obj.Resources.ModelResource.ModelIndex;
            uint modelId        = modelReferenceList[modelReference].ModelIdNum;

            // Get matrix
            Vector3   modelRotation = new Vector3(-obj.Resources.ModelResource.XRotation / BlocksFile.RotationDivisor, -obj.Resources.ModelResource.YRotation / BlocksFile.RotationDivisor, -obj.Resources.ModelResource.ZRotation / BlocksFile.RotationDivisor);
            Vector3   modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;
            Matrix4x4 modelMatrix   = Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), Vector3.one);

            // Get model data
            ModelData modelData;

            dfUnity.MeshReader.GetModelData(modelId, out modelData);

            // Get GameObject
            GameObject modelGO = MeshReplacement.ImportCustomGameobject(modelId, null, modelMatrix, false);

            if (modelGO == null)
            {
                if (modelData.DFMesh.TotalVertices != 0)
                {
                    modelGO = GameObjectHelper.CreateDaggerfallMeshGameObject(modelId, null);
                    modelGO.transform.position   = modelMatrix.GetColumn(3);
                    modelGO.transform.rotation   = modelMatrix.rotation;
                    modelGO.transform.localScale = modelMatrix.lossyScale;
                }
                else
                {
                    Debug.LogError("Custom model not found for modelId " + modelId);
                }
            }
            return(modelGO);
        }
Exemplo n.º 7
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();
        }
Exemplo n.º 8
0
        /// <summary>
        /// Add action doors to parent transform.
        /// </summary>
        private void AddActionDoors()
        {
            // Using 9000-9005 here but identical door models are also found at 900x, 910x, through to 980x
            // They seem to be duplicate models but can have different model origins so not all ranges are suitable
            const int doorModelBaseId = 9000;

            GameObject actionDoorsNode = new GameObject("Action Doors");

            actionDoorsNode.transform.parent = this.transform;

            foreach (DFBlock.RmbBlockDoorRecord obj in recordData.Interior.BlockDoorRecords)
            {
                // Create unique LoadID for save sytem
                ulong loadID = (ulong)(blockData.Position + obj.Position);

                // Get model transform
                Vector3 modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0);
                Vector3 modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;

                // Instantiate door prefab and add model - DoorModelIndex is modulo to known-good range just in case
                // A custom prefab can be provided by mods and must include DaggerfallActionDoor component with all requirements.
                uint       modelId = (uint)(doorModelBaseId + obj.DoorModelIndex % 5);
                GameObject go      = MeshReplacement.ImportCustomGameobject(modelId, actionDoorsNode.transform, Matrix4x4.identity);
                if (!go)
                {
                    go = GameObjectHelper.InstantiatePrefab(dfUnity.Option_InteriorDoorPrefab.gameObject, string.Empty, actionDoorsNode.transform, Vector3.zero);
                    GameObjectHelper.CreateDaggerfallMeshGameObject(modelId, actionDoorsNode.transform, false, go, true);

                    // Resize box collider to new mesh bounds
                    BoxCollider  boxCollider  = go.GetComponent <BoxCollider>();
                    MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>();
                    if (boxCollider != null && meshRenderer != null)
                    {
                        boxCollider.center = meshRenderer.bounds.center;
                        boxCollider.size   = meshRenderer.bounds.size;
                    }

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

                // Apply transforms
                go.transform.rotation = Quaternion.Euler(modelRotation);
                go.transform.position = modelPosition;

                // Get action door script
                DaggerfallActionDoor actionDoor = go.GetComponent <DaggerfallActionDoor>();

                // Assign loadID
                if (actionDoor)
                {
                    actionDoor.LoadID = loadID;
                }

                if (SaveLoadManager.Instance != null)
                {
                    go.AddComponent <SerializableActionDoor>();
                }
            }
        }
Exemplo n.º 9
0
        private static void AddModels(
            DaggerfallUnity dfUnity,
            int layoutX,
            int layoutY,
            ref DFBlock blockData,
            out List <StaticDoor> doorsOut,
            out List <StaticBuilding> buildingsOut,
            ModelCombiner combiner = null,
            Transform parent       = null)
        {
            doorsOut     = new List <StaticDoor>();
            buildingsOut = new List <StaticBuilding>();

            // Iterate through all subrecords
            int recordCount = 0;

            foreach (DFBlock.RmbSubRecord subRecord in blockData.RmbBlock.SubRecords)
            {
                // Get subrecord transform
                Vector3   subRecordPosition = new Vector3(subRecord.XPos, 0, BlocksFile.RMBDimension - subRecord.ZPos) * MeshReader.GlobalScale;
                Vector3   subRecordRotation = new Vector3(0, -subRecord.YRotation / BlocksFile.RotationDivisor, 0);
                Matrix4x4 subRecordMatrix   = Matrix4x4.TRS(subRecordPosition, Quaternion.Euler(subRecordRotation), Vector3.one);

                // Iterate through models in this subrecord
                bool firstModel = true;
                foreach (DFBlock.RmbBlock3dObjectRecord obj in subRecord.Exterior.Block3dObjectRecords)
                {
                    // Get model transform
                    Vector3   modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;
                    Vector3   modelRotation = new Vector3(-obj.XRotation / BlocksFile.RotationDivisor, -obj.YRotation / BlocksFile.RotationDivisor, -obj.ZRotation / BlocksFile.RotationDivisor);
                    Vector3   modelScale    = GetModelScaleVector(obj);
                    Matrix4x4 modelMatrix   = subRecordMatrix * Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), modelScale);

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

                    // Does this model have doors?
                    StaticDoor[] staticDoors = null;
                    if (modelData.Doors != null)
                    {
                        staticDoors = GameObjectHelper.GetStaticDoors(ref modelData, blockData.Index, recordCount, modelMatrix);
                    }

                    // Store building information for first model of record
                    // First model is main record structure, others are attachments like posts
                    // Only main structure is needed to resolve building after hit-test
                    int buildingKey = 0;
                    if (firstModel)
                    {
                        // Create building key for this record - considered experimental for now
                        buildingKey = BuildingDirectory.MakeBuildingKey((byte)layoutX, (byte)layoutY, (byte)recordCount);

                        StaticBuilding staticBuilding = new StaticBuilding();
                        staticBuilding.modelMatrix = modelMatrix;
                        staticBuilding.recordIndex = recordCount;
                        staticBuilding.centre      = new Vector3(modelData.DFMesh.Centre.X, modelData.DFMesh.Centre.Y, modelData.DFMesh.Centre.Z) * MeshReader.GlobalScale;
                        staticBuilding.size        = new Vector3(modelData.DFMesh.Size.X, modelData.DFMesh.Size.Y, modelData.DFMesh.Size.Z) * MeshReader.GlobalScale;
                        buildingsOut.Add(staticBuilding);
                        firstModel = false;
                    }

                    bool dontCreateStaticDoors = false;

                    // Import custom GameObject or use Daggerfall Model
                    GameObject go;
                    if (go = MeshReplacement.ImportCustomGameobject(obj.ModelIdNum, parent, modelMatrix))
                    {
                        // Find doors
                        if (staticDoors != null && staticDoors.Length > 0)
                        {
                            CustomDoor.InitDoors(go, staticDoors, buildingKey, out dontCreateStaticDoors);
                        }
                    }
                    else if (combiner == null || IsCityGate(obj.ModelIdNum) || IsBulletinBoard(obj.ModelIdNum) || PlayerActivate.HasCustomActivation(obj.ModelIdNum))
                    {
                        AddStandaloneModel(dfUnity, ref modelData, modelMatrix, parent);
                    }
                    else
                    {
                        combiner.Add(ref modelData, modelMatrix);
                    }

                    if (modelData.Doors != null && !dontCreateStaticDoors)
                    {
                        doorsOut.AddRange(staticDoors);
                    }
                }

                // Increment record count
                recordCount++;
            }
        }
Exemplo n.º 10
0
        private static void AddModels(
            DaggerfallUnity dfUnity,
            ref DFBlock blockData,
            out List <StaticDoor> doorsOut,
            out List <StaticBuilding> buildingsOut,
            ModelCombiner combiner = null,
            Transform parent       = null)
        {
            doorsOut     = new List <StaticDoor>();
            buildingsOut = new List <StaticBuilding>();

            // Iterate through all subrecords
            int recordCount = 0;

            foreach (DFBlock.RmbSubRecord subRecord in blockData.RmbBlock.SubRecords)
            {
                // Get subrecord transform
                Vector3   subRecordPosition = new Vector3(subRecord.XPos, 0, BlocksFile.RMBDimension - subRecord.ZPos) * MeshReader.GlobalScale;
                Vector3   subRecordRotation = new Vector3(0, -subRecord.YRotation / BlocksFile.RotationDivisor, 0);
                Matrix4x4 subRecordMatrix   = Matrix4x4.TRS(subRecordPosition, Quaternion.Euler(subRecordRotation), Vector3.one);

                // Iterate through models in this subrecord
                bool firstModel = true;
                foreach (DFBlock.RmbBlock3dObjectRecord obj in subRecord.Exterior.Block3dObjectRecords)
                {
                    // Get model transform
                    Vector3   modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;
                    Vector3   modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0);
                    Matrix4x4 modelMatrix   = subRecordMatrix * Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), Vector3.one);

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

                    // Does this model have doors?
                    if (modelData.Doors != null)
                    {
                        doorsOut.AddRange(GameObjectHelper.GetStaticDoors(ref modelData, blockData.Index, recordCount, modelMatrix));
                    }

                    // Store building information for first model of record
                    // First model is main record structure, others are attachments like posts
                    // Only main structure is needed to resolve building after hit-test
                    if (firstModel)
                    {
                        StaticBuilding staticBuilding = new StaticBuilding();
                        staticBuilding.modelMatrix = modelMatrix;
                        staticBuilding.recordIndex = recordCount;
                        staticBuilding.centre      = new Vector3(modelData.DFMesh.Centre.X, modelData.DFMesh.Centre.Y, modelData.DFMesh.Centre.Z) * MeshReader.GlobalScale;
                        staticBuilding.size        = new Vector3(modelData.DFMesh.Size.X, modelData.DFMesh.Size.Y, modelData.DFMesh.Size.Z) * MeshReader.GlobalScale;
                        buildingsOut.Add(staticBuilding);
                        firstModel = false;
                    }

                    // Import custom GameObject
                    if (MeshReplacement.ImportCustomGameobject(obj.ModelIdNum, parent, modelMatrix) != null)
                    {
                        continue;
                    }

                    // Use Daggerfall Model
                    // Add or combine
                    if (combiner == null || IsCityGate(obj.ModelIdNum))
                    {
                        AddStandaloneModel(dfUnity, ref modelData, modelMatrix, parent);
                    }
                    else
                    {
                        combiner.Add(ref modelData, modelMatrix);
                    }
                }

                // Increment record count
                recordCount++;
            }
        }
Exemplo n.º 11
0
        /// <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();
        }
Exemplo n.º 12
0
        public static GameObject CreatePlacedObject(PlacedObjectData_v2 data, Transform parent, bool previewGo = false)
        {
            // Custom models like Handpainted Models have insanley different scales (< 0.0 to 200+) Set all models as a child to a parent, so
            // EditMode can uniformly scale properly.

            GameObject parentGo = new GameObject();
            GameObject childGo;

            parentGo.transform.parent = parent;

            if (data.modelID == 0)
            {
                childGo = MeshReplacement.ImportCustomFlatGameobject(data.archive, data.record, Vector3.zero, parentGo.transform);

                if (childGo == null)
                {
                    childGo = GameObjectHelper.CreateDaggerfallBillboardGameObject(data.archive, data.record, parentGo.transform);
                }
            }
            else
            {
                Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one);

                childGo = MeshReplacement.ImportCustomGameobject(data.modelID, parentGo.transform, matrix);

                if (childGo == null)
                {
                    childGo = GameObjectHelper.CreateDaggerfallMeshGameObject(data.modelID, parentGo.transform);
                }
            }

            parentGo.transform.eulerAngles = Vector3.zero;
            childGo.transform.eulerAngles  = Vector3.zero;

            if (previewGo)
            {
                data.isLight = true;
            }

            BoxCollider parentCollider = parentGo.AddComponent <BoxCollider>();
            BoxCollider childCollider;


            //Expanding collider a little gives better hit detection.
            float buffer = 0.02f;

            // Some custom models have a box collider and are made of multiple smaller models. Get the parent collider size.
            if (childCollider = childGo.GetComponent <BoxCollider>())
            {
                parentCollider.size = new Vector3((childCollider.size.x * childGo.transform.localScale.x) + buffer,
                                                  (childCollider.size.y * childGo.transform.localScale.y) + buffer,
                                                  (childCollider.size.z * childGo.transform.localScale.z) + buffer);

                parentCollider.center = new Vector3(childCollider.center.x * childGo.transform.localScale.x,
                                                    childCollider.center.y * childGo.transform.localScale.y,
                                                    childCollider.center.z * childGo.transform.localScale.z);

                // Child colliders screw with EditMode.
                GameObject.Destroy(childCollider);
            }
            else
            {
                Bounds childBounds = childGo.GetComponent <MeshFilter>().sharedMesh.bounds;

                parentCollider.size = new Vector3((childBounds.size.x * childGo.transform.localScale.x) + buffer,
                                                  (childBounds.size.y * childGo.transform.localScale.y) + buffer,
                                                  (childBounds.size.z * childGo.transform.localScale.z) + buffer);

                parentCollider.center = new Vector3(childBounds.center.x * childGo.transform.localScale.x,
                                                    childBounds.center.y * childGo.transform.localScale.y,
                                                    childBounds.center.z * childGo.transform.localScale.z);
            }

            parentCollider.isTrigger = true;

            parentGo.AddComponent <PlacedObject>();
            SetPlacedObject(data, parentGo);

            return(parentGo);
        }
        public static GameObject Add3dObject(DFBlock.RmbBlock3dObjectRecord rmbBlock)
        {
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            // Get model data
            ModelData modelData;

            dfUnity.MeshReader.GetModelData(rmbBlock.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 (rmbBlock.ObjectType == (int)InteractiveObject)
            {
                // 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(rmbBlock.XPos, rmbBlock.YPos, rmbBlock.ZPos) * MeshReader.GlobalScale;
                modelPosition += new Vector3(0, -bottom.y, 0);
            }
            else
            {
                modelPosition = new Vector3(rmbBlock.XPos, -rmbBlock.YPos, rmbBlock.ZPos) * MeshReader.GlobalScale;
            }

            // Fix 3D models with 0,0,0 scale
            if (rmbBlock.XScale == 0)
            {
                rmbBlock.XScale = 1;
            }
            if (rmbBlock.YScale == 0)
            {
                rmbBlock.YScale = 1;
            }
            if (rmbBlock.ZScale == 0)
            {
                rmbBlock.ZScale = 1;
            }

            // Get model transform
            Vector3   modelRotation = new Vector3(-rmbBlock.XRotation / BlocksFile.RotationDivisor, -rmbBlock.YRotation / BlocksFile.RotationDivisor, -rmbBlock.ZRotation / BlocksFile.RotationDivisor);
            Vector3   modelScale    = new Vector3(rmbBlock.XScale, rmbBlock.YScale, rmbBlock.ZScale);
            Matrix4x4 modelMatrix   = Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), modelScale);

            // Inject custom GameObject if available
            GameObject modelGO = MeshReplacement.ImportCustomGameobject(rmbBlock.ModelIdNum, null, modelMatrix);

            if (modelGO == null)
            {
                if (modelData.DFMesh.TotalVertices != 0)
                {
                    modelGO = DaggerfallWorkshop.Utility.GameObjectHelper.CreateDaggerfallMeshGameObject(rmbBlock.ModelIdNum, null);
                    modelGO.transform.position   = modelMatrix.GetColumn(3);
                    modelGO.transform.rotation   = modelMatrix.rotation;
                    modelGO.transform.localScale = modelMatrix.lossyScale;
                }
                else
                {
                    Debug.LogError("Custom model not found for modelId " + rmbBlock.ModelIdNum);
                }
            }
            return(modelGO);
        }