コード例 #1
0
        private static void AddModels(
            DaggerfallUnity dfUnity,
            ref DFBlock blockData,
            out List <StaticDoor> doorsOut,
            ModelCombiner combiner = null,
            Transform parent       = null)
        {
            doorsOut = new List <StaticDoor>();

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

                    // 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++;
            }
        }
コード例 #2
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);
                }
            }
        }
コード例 #3
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(0, -obj.YRotation / BlocksFile.RotationDivisor, 0);
                Matrix4x4 modelMatrix   = 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, 0, modelMatrix));
                }

                // Add or combine
                if (combiner == null)
                {
                    AddStandaloneModel(dfUnity, ref modelData, modelMatrix, parent);
                }
                else
                {
                    combiner.Add(ref modelData, modelMatrix);
                }
            }
        }
コード例 #4
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++;
            }
        }
コード例 #5
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++;
            }
        }
コード例 #6
0
        /// <summary>
        /// Adds models and their actions to scene.
        /// </summary>
        private static void AddModels(
            DaggerfallUnity dfUnity,
            ref DFBlock blockData,
            int[] textureTable,
            bool allowExitDoors,
            out List <StaticDoor> exitDoorsOut,
            ModelCombiner combiner       = null,
            Transform modelsParent       = null,
            Transform actionModelsParent = null)
        {
            exitDoorsOut = new List <StaticDoor>();

            // Action record linkages
            Dictionary <int, ActionLink> actionLinkDict = new Dictionary <int, ActionLink>();

            // Iterate object groups
            int groupIndex = 0;

            foreach (DFBlock.RdbObjectRoot group in blockData.RdbBlock.ObjectRootList)
            {
                // Skip empty object groups
                if (null == group.RdbObjects)
                {
                    groupIndex++;
                    continue;
                }

                // Iterate objects in this group
                foreach (DFBlock.RdbObject obj in group.RdbObjects)
                {
                    // Add models
                    if (obj.Type == DFBlock.RdbResourceTypes.Model)
                    {
                        // Get model reference index and id
                        int  modelReference = obj.Resources.ModelResource.ModelIndex;
                        uint modelId        = blockData.RdbBlock.ModelReferenceList[modelReference].ModelIdNum;

                        // Filter exit door models where flag not set
                        if (modelId == exitDoorModelID && !allowExitDoors)
                        {
                            continue;
                        }

                        // Filter action door models
                        // These must be added by AddActionDoors()
                        if (IsActionDoor(ref blockData, obj, modelReference))
                        {
                            continue;
                        }

                        // Get matrix
                        Matrix4x4 modelMatrix = GetModelMatrix(obj);

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

                        // Add to static doors
                        exitDoorsOut.AddRange(GameObjectHelper.GetStaticDoors(ref modelData, blockData.Index, 0, modelMatrix));

                        // Check if model has an action record
                        bool hasAction = HasAction(obj);

                        // Special handling for tapestries and banners
                        // Some of these are so far out from wall player can become stuck behind them
                        // Adding model invidually without collider to avoid problem
                        // Not sure if these object ever actions, but bypass this hack if they do
                        if (modelId >= minTapestryID && modelId <= maxTapestryID && !hasAction)
                        {
                            AddStandaloneModel(dfUnity, ref modelData, modelMatrix, modelsParent, hasAction, true);
                            continue;
                        }

                        // Add or combine
                        GameObject standaloneObject = null;
                        Transform  parent           = (hasAction) ? actionModelsParent : modelsParent;
                        if (combiner == null || hasAction)
                        {
                            standaloneObject = AddStandaloneModel(dfUnity, ref modelData, modelMatrix, parent, hasAction);
                            standaloneObject.GetComponent <DaggerfallMesh>().SetDungeonTextures(textureTable);
                        }
                        else
                        {
                            combiner.Add(ref modelData, modelMatrix);
                        }

                        // Add action
                        if (hasAction && standaloneObject != null)
                        {
                            AddAction(standaloneObject, blockData, obj, modelReference, groupIndex, actionLinkDict);
                        }
                    }
                }

                // Increment group index
                groupIndex++;
            }

            // Link action nodes
            LinkActionNodes(actionLinkDict);
        }
コード例 #7
0
        private void AddRDBModel(DFBlock.RdbObject obj, out List <StaticDoor> doorsOut, Transform parent)
        {
            bool overrideCombine = false;

            doorsOut = new List <StaticDoor>();

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

            // Get rotation angle for each axis
            float degreesX = -obj.Resources.ModelResource.XRotation / BlocksFile.RotationDivisor;
            float degreesY = -obj.Resources.ModelResource.YRotation / BlocksFile.RotationDivisor;
            float degreesZ = -obj.Resources.ModelResource.ZRotation / BlocksFile.RotationDivisor;

            // Calcuate transform
            Vector3 position = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale;

            // Calculate matrix
            Vector3   rx          = new Vector3(degreesX, 0, 0);
            Vector3   ry          = new Vector3(0, degreesY, 0);
            Vector3   rz          = new Vector3(0, 0, degreesZ);
            Matrix4x4 modelMatrix = Matrix4x4.identity;

            modelMatrix *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);
            modelMatrix *= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rz), Vector3.one);
            modelMatrix *= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(rx), Vector3.one);
            modelMatrix *= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(ry), Vector3.one);

            // Get model data
            ModelData modelData;

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

            // Discard static exit doors not in starting block
            // Exit doors are just a model slapped over wall or doorway
            // This allows Daggerfall to toggle exits on and off
            if (modelData.DFMesh.ObjectId == 70300)
            {
                if (!isStartingBlock)
                {
                    return;
                }
            }

            // Doors - there are no working static building doors inside dungeons, just the exits and action doors
            bool isActionDoor = IsActionDoor(blockData, obj, modelReference);

            if (isActionDoor)
            {
                parent = doorsNode.transform;
            }
            else if (modelData.Doors != null)
            {
                doorsOut.AddRange(GameObjectHelper.GetStaticDoors(ref modelData, blockData.Index, 0, modelMatrix));
            }

            // Action records
            bool hasAction = HasAction(blockData, obj, modelReference);

            if (hasAction)
            {
                parent = actionModelsNode.transform;
            }

            // Flags
            bool isStatic = dfUnity.Option_SetStaticFlags;

            if (isActionDoor || hasAction)
            {
                // Moving objects are never static or combined
                isStatic        = false;
                overrideCombine = true;
            }

            // Add to scene
            if (dfUnity.Option_CombineRDB && !overrideCombine)
            {
                combiner.Add(ref modelData, modelMatrix);
            }
            else
            {
                // Spawn mesh gameobject
                GameObject go = GameObjectHelper.CreateDaggerfallMeshGameObject(modelId, parent, isStatic);
                go.GetComponent <DaggerfallMesh>().SetDungeonTextures(textureTable);

                // Apply transforms
                go.transform.Rotate(0, degreesY, 0, Space.World);
                go.transform.Rotate(degreesX, 0, 0, Space.World);
                go.transform.Rotate(0, 0, degreesZ, Space.World);
                go.transform.localPosition = position;

                // Add action door
                if (isActionDoor)
                {
                    DaggerfallActionDoor dfActionDoor = go.AddComponent <DaggerfallActionDoor>();

                    // Add action door audio
                    if (dfUnity.Option_DefaultSounds)
                    {
                        AddActionDoorAudioSource(go);
                        dfActionDoor.SetDungeonDoorSounds();
                    }
                }

                // Add action component
                if (hasAction && !isActionDoor)
                {
                    AddAction(go, blockData, obj, modelReference);
                }
            }
        }