/// <summary> /// Adds RDB flat to scene node. /// </summary> /// <param name="obj">RdbObject.</param> /// <param name="blockNode">BlockNode.</param> private void AddRDBFlat(DFBlock.RdbObject obj, BlockNode blockNode) { // Get flat type BillboardNode.BillboardType billboardType = GetFlatType(obj.Resources.FlatResource.TextureArchive); // Add light if needed // Load flat int textureKey; Vector2 startSize; Vector2 finalSize; if (true == LoadDaggerfallFlat( obj.Resources.FlatResource.TextureArchive, obj.Resources.FlatResource.TextureRecord, TextureManager.TextureCreateFlags.Dilate | TextureManager.TextureCreateFlags.PreMultiplyAlpha, out textureKey, out startSize, out finalSize)) { // Foliage (TEXTURE.500 and up) do not seem to use scaling // in dungeons. Revert scaling. if (obj.Resources.FlatResource.TextureArchive > 499) { finalSize = startSize; } // Calcuate position Vector3 position = new Vector3( obj.XPos, -obj.YPos, -obj.ZPos); // Create billboard node BillboardNode billboardNode = new BillboardNode( billboardType, textureKey, finalSize); billboardNode.Position = position; blockNode.Add(billboardNode); // Add point light node if (billboardType == BillboardNode.BillboardType.Light) { AddPointLight(position, PointLightNode.DungeonRadius, blockNode); } } }
/// <summary> /// Constructs a scene node from the specified RMB block. /// </summary> /// <param name="block">DFBlock.</param> /// <param name="climate">Climate settings.</param> /// <returns>BlockNode.</returns> private BlockNode BuildRMBNode(ref DFBlock block, DFLocation.ClimateSettings climate) { // Create parent block node BlockNode blockNode = new BlockNode(block); // Add child nodes AddRMBModels(ref block, blockNode); AddRMBMiscModels(ref block, blockNode); AddRMBGroundPlane(ref block, blockNode, climate); AddRMBMiscFlats(ref block, blockNode); AddRMBSceneryFlats(ref block, blockNode, climate.SceneryArchive); return(blockNode); }
/// <summary> /// Constructs a scene node from the specified RDB block. /// </summary> /// <param name="block">DFBlock.</param> /// <returns>BlockNode.</returns> private BlockNode BuildRDBNode(ref DFBlock block) { // Create parent block node BlockNode blockNode = new BlockNode(block); // Clear action link dictionary actionLinkDict.Clear(); // Iterate through object groups int groupIndex = 0; foreach (DFBlock.RdbObjectRoot group in block.RdbBlock.ObjectRootList) { // Skip empty object groups if (null == group.RdbObjects) { groupIndex++; continue; } // Iterate through objects in this group foreach (DFBlock.RdbObject obj in group.RdbObjects) { // Filter by type switch (obj.Type) { case DFBlock.RdbResourceTypes.Model: AddRDBModel(ref block, obj, blockNode, groupIndex); break; case DFBlock.RdbResourceTypes.Flat: AddRDBFlat(obj, blockNode); break; default: // Only drawing models and flats for now break; } } // Increment group index groupIndex++; } // Link action nodes LinkActionNodes(); return(blockNode); }
/// <summary> /// Adds miscellaneous RMB models to block node. /// </summary> /// <param name="block">DFBlock</param> /// <param name="blockNode">BlockNode.</param> private void AddRMBMiscModels(ref DFBlock block, BlockNode blockNode) { // Iterate through all misc records float degrees; foreach (DFBlock.RmbBlock3dObjectRecord obj in block.RmbBlock.Misc3dObjectRecords) { // Create misc record node SceneNode miscNode = CreateModelNode(obj.ModelIdNum); degrees = obj.YRotation / rotationDivisor; miscNode.Position = new Vector3(obj.XPos, -obj.YPos, -rmbSide + -obj.ZPos); miscNode.Rotation = new Vector3(0f, MathHelper.ToRadians(degrees), 0f); blockNode.Add(miscNode); } }
/// <summary> /// Creates a new block node. /// </summary> /// <param name="name">Block name.</param> /// <param name="climate">Climate settings.</param> /// <param name="clearGroundTextures">Clear ground plane texture dictionary.</param> /// <returns>BlockNode.</returns> public BlockNode CreateBlockNode(string name, DFLocation.ClimateSettings?climate, bool clearGroundTextures) { // Load block DFBlock block; if (!LoadDaggerfallBlock(name, out block)) { return(null); } // Set default world climate if (climate == null) { climate = MapsFile.GetWorldClimateSettings(defaultWorldClimate); } // Reset ground plane texture cache if (clearGroundTextures) { textureManager.ClearGroundTextures(); } // Build node BlockNode node = null; switch (block.Type) { case DFBlock.BlockTypes.Rmb: textureManager.ClimateType = climate.Value.ClimateType; node = BuildRMBNode(ref block, climate.Value); break; case DFBlock.BlockTypes.Rdb: textureManager.ClimateType = DFLocation.ClimateBaseType.None; node = BuildRDBNode(ref block); break; } return(node); }
/// <summary> /// Adds RDB model to block node. /// </summary> /// <param name="block">DFBlock.</param> /// <param name="obj">RdbObject.</param> /// <param name="blockNode">BlockNode.</param> /// <param name="groupIndex">Group index.</param> private void AddRDBModel(ref DFBlock block, DFBlock.RdbObject obj, BlockNode blockNode, int groupIndex) { // Get model reference index, desc, and id int modelReference = obj.Resources.ModelResource.ModelIndex; string modelDescription = block.RdbBlock.ModelReferenceList[modelReference].Description; uint modelId = block.RdbBlock.ModelReferenceList[modelReference].ModelIdNum; // Get rotation angle for each axis float degreesX = obj.Resources.ModelResource.XRotation / rotationDivisor; float degreesY = obj.Resources.ModelResource.YRotation / rotationDivisor; float degreesZ = -obj.Resources.ModelResource.ZRotation / rotationDivisor; // Calcuate position Vector3 position = new Vector3( obj.XPos, -obj.YPos, -obj.ZPos); // Calculate rotation Vector3 rotation = new Vector3( MathHelper.ToRadians(degreesX), MathHelper.ToRadians(degreesY), MathHelper.ToRadians(degreesZ)); // Create model node ModelNode modelNode = CreateModelNode(modelId); modelNode.Position = position; modelNode.Rotation = rotation; blockNode.Add(modelNode); // Setup actions for this node CreateModelAction( obj.Resources.ModelResource.ActionResource, modelNode, modelDescription, groupIndex, obj.Index); }