private void LoadEntities(string entityName, Renderer.Renderer renderer, string path, Package package) { if (entityName == null) { return; } var newResource = FileExtensions.LoadFileByAnyMeansNecessary(entityName + "_c", path, package); if (newResource == null) { Console.WriteLine("unable to load entity lump " + entityName + "_c"); return; } var entityLump = new EntityLump(newResource); var childEntities = entityLump.GetChildEntityNames(); foreach (var childEntityName in childEntities) { // TODO: Should be controlled in UI with world layers if (childEntityName.Contains("_destruction")) { continue; } LoadEntities(childEntityName, renderer, path, package); } var worldEntities = entityLump.GetEntities(); foreach (var entity in worldEntities) { var scale = string.Empty; var position = string.Empty; var angles = string.Empty; var model = string.Empty; var skin = string.Empty; var colour = new byte[0]; var classname = string.Empty; var name = string.Empty; foreach (var property in entity.Properties) { //metadata switch (property.MiscType) { case 3368008710: //World Model model = property.Data as string; break; case 3827302934: //Position position = property.Data as string; break; case 3130579663: //Angles angles = property.Data as string; break; case 432137260: //Scale scale = property.Data as string; break; case 2020856412: //Skin skin = property.Data as string; break; case 588463423: //Colour colour = property.Data as byte[]; break; case 3323665506: //Classname classname = property.Data as string; break; case 1094168427: name = property.Data as string; break; } } if (scale == string.Empty || position == string.Empty || angles == string.Empty) { continue; } var isGlobalLight = classname == "env_global_light"; var isCamera = classname == "info_player_start" || classname == "worldspawn" || classname == "sky_camera" || classname == "point_devshot_camera" || classname == "point_camera"; if (!isGlobalLight && !isCamera && model == string.Empty) { continue; } var scaleMatrix = Matrix4.CreateScale(ParseCoordinates(scale)); var positionVector = ParseCoordinates(position); var positionMatrix = Matrix4.CreateTranslation(positionVector); var pitchYawRoll = ParseCoordinates(angles); var rollMatrix = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(pitchYawRoll.Z)); // Roll var pitchMatrix = Matrix4.CreateRotationY(MathHelper.DegreesToRadians(pitchYawRoll.X)); // Pitch var yawMatrix = Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(pitchYawRoll.Y)); // Yaw var rotationMatrix = rollMatrix * pitchMatrix * yawMatrix; var transformationMatrix = scaleMatrix * rotationMatrix * positionMatrix; if (isCamera) { if (classname == "worldspawn") { renderer.SetDefaultWorldCamera(positionVector); } else { renderer.AddCamera(name == string.Empty ? $"{classname} #{anonymousCameraCount++}" : name, transformationMatrix); } continue; } else if (isGlobalLight) { renderer.SetWorldGlobalLight(positionVector); // TODO: set light angle continue; } var objColor = Vector4.One; // Parse colour if present if (colour.Length == 4) { for (var i = 0; i < 4; i++) { objColor[i] = colour[i] / 255.0f; } } var newEntity = FileExtensions.LoadFileByAnyMeansNecessary(model + "_c", path, package); if (newEntity == null) { Console.WriteLine($"unable to load entity {model}_c"); continue; } var newModel = new Model(newEntity); var entityModel = new RenderModel(newModel); entityModel.LoadMeshes(renderer, path, transformationMatrix, objColor, package, skin); } }
private static void LoadEntities(NTROValue lump, Renderer.Renderer renderer, string path, Package package) { var reference = ((NTROValue <ResourceExtRefList.ResourceReferenceInfo>)lump).Value; if (reference == null) { return; } var newResource = FileExtensions.LoadFileByAnyMeansNecessary(reference.Name + "_c", path, package); if (newResource == null) { Console.WriteLine("unable to load entity lump " + reference.Name + "_c"); return; } var entityLump = newResource.Blocks[BlockType.DATA] as EntityLump; var childLumps = (NTROArray)entityLump.Output["m_childLumps"]; foreach (var lump2 in childLumps) { var lol = ((NTROValue <ResourceExtRefList.ResourceReferenceInfo>)lump).Value; // TODO: Should be controlled in UI with world layers if (lol.Name.Contains("_destruction")) { continue; } LoadEntities(lump2, renderer, path, package); } foreach (var entity in entityLump.Datas) { var scale = string.Empty; var position = string.Empty; var angles = string.Empty; var model = string.Empty; var skin = string.Empty; var colour = new byte[0]; var classname = string.Empty; var name = string.Empty; foreach (var property in entity) { //metadata switch (property.Item2) { case 3368008710: //World Model model = property.Item3 as string; break; case 3827302934: //Position position = property.Item3 as string; break; case 3130579663: //Angles angles = property.Item3 as string; break; case 432137260: //Scale scale = property.Item3 as string; break; case 2020856412: //Skin skin = property.Item3 as string; break; case 588463423: //Colour colour = property.Item3 as byte[]; break; case 3323665506: //Classname classname = property.Item3 as string; break; case 1094168427: name = property.Item3 as string; break; } } if (scale == string.Empty || position == string.Empty || angles == string.Empty) { continue; } var isCamera = classname == "info_player_start" || classname == "worldspawn" || classname == "sky_camera" || classname == "point_devshot_camera" || classname == "point_camera"; if (!isCamera && model == string.Empty) { continue; } var scaleMatrix = Matrix4.CreateScale(ParseCoordinates(scale)); var positionVector = ParseCoordinates(position); var positionMatrix = Matrix4.CreateTranslation(positionVector); var pitchYawRoll = ParseCoordinates(angles); var rollMatrix = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(pitchYawRoll.Z)); // Roll var pitchMatrix = Matrix4.CreateRotationY(MathHelper.DegreesToRadians(pitchYawRoll.X)); // Pitch var yawMatrix = Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(pitchYawRoll.Y)); // Yaw var rotationMatrix = rollMatrix * pitchMatrix * yawMatrix; var transformationMatrix = scaleMatrix * rotationMatrix * positionMatrix; if (isCamera) { if (classname == "worldspawn") { renderer.SetDefaultWorldCamera(positionVector); } else { renderer.AddCamera(name == string.Empty ? $"{classname} #{anonymousCameraCount++}" : name, transformationMatrix); } continue; } var objColor = Vector4.One; // Parse colour if present if (colour.Length == 4) { for (var i = 0; i < 4; i++) { objColor[i] = colour[i] / 255.0f; } } var newEntity = FileExtensions.LoadFileByAnyMeansNecessary(model + "_c", path, package); if (newEntity == null) { Console.WriteLine($"unable to load entity {model}_c"); continue; } var entityModel = new Model(newEntity); entityModel.LoadMeshes(renderer, path, transformationMatrix, objColor, package, skin); } }
private static void LoadEntities(NTROValue lump, Renderer.Renderer renderer, string path, Package package) { var reference = ((NTROValue <ResourceExtRefList.ResourceReferenceInfo>)lump).Value; if (reference == null) { return; } var newResource = FileExtensions.LoadFileByAnyMeansNecessary(reference.Name + "_c", path, package); if (newResource == null) { Console.WriteLine("unable to load entity lump " + reference.Name + "_c"); return; } var entityLump = newResource.Blocks[BlockType.DATA] as EntityLump; var childLumps = (NTROArray)entityLump.Output["m_childLumps"]; foreach (var lump2 in childLumps) { var lol = ((NTROValue <ResourceExtRefList.ResourceReferenceInfo>)lump).Value; // TODO: Should be controlled in UI with world layers if (lol.Name.Contains("_destruction")) { continue; } LoadEntities(lump2, renderer, path, package); } foreach (var entity in entityLump.Datas) { var scale = string.Empty; var position = string.Empty; var angles = string.Empty; var model = string.Empty; var skin = string.Empty; var colour = new byte[0]; var classname = string.Empty; var name = string.Empty; foreach (var property in entity) { //metadata switch (property.Item2) { case 3368008710: //World Model model = property.Item3 as string; break; case 3827302934: //Position position = property.Item3 as string; break; case 3130579663: //Angles angles = property.Item3 as string; break; case 432137260: //Scale scale = property.Item3 as string; break; case 2020856412: //Skin skin = property.Item3 as string; break; case 588463423: //Colour colour = property.Item3 as byte[]; break; case 3323665506: //Classname classname = property.Item3 as string; break; case 1094168427: name = property.Item3 as string; break; } } if (scale == string.Empty || position == string.Empty || angles == string.Empty) { continue; } if (classname == "point_camera" || classname == "vr_teleport_marker" || model != string.Empty) { var scaleMatrix = Matrix4.CreateScale(ParseCoordinates(scale)); var positionMatrix = Matrix4.CreateTranslation(ParseCoordinates(position)); var rotationVector = ParseCoordinates(angles); var rotationMatrix = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(rotationVector.Z)); rotationMatrix *= Matrix4.CreateRotationY(MathHelper.DegreesToRadians(rotationVector.X)); rotationMatrix *= Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(rotationVector.Y)); var megaMatrix = scaleMatrix * rotationMatrix * positionMatrix; var objColor = Vector4.One; // Parse colour if present if (colour.Length == 4) { for (var i = 0; i < 4; i++) { objColor[i] = colour[i] / 255.0f; } } //This model is hardcoded into the FGD if (classname == "vr_teleport_marker") { model = "models/effects/teleport/teleport_marker.vmdl"; } if (classname == "point_camera") { renderer.AddCamera(name == string.Empty ? $"Camera {anonymousCameraCount++}" : name, megaMatrix); } else { var newEntity = FileExtensions.LoadFileByAnyMeansNecessary(model + "_c", path, package); if (newEntity == null) { Console.WriteLine("unable to load entity " + model + "_c"); continue; } var entityModel = new Model(newEntity); entityModel.LoadMeshes(renderer, path, megaMatrix, objColor, package, skin); } } } }