private void LoadEntitiesFromLump(EntityLump entityLump) { var childEntities = entityLump.GetChildEntityNames(); foreach (var childEntityName in childEntities) { // TODO: Should be controlled in UI with world layers if (childEntityName.Contains("_destruction")) { continue; } var newResource = guiContext.LoadFileByAnyMeansNecessary(childEntityName + "_c"); if (newResource == null) { continue; } LoadEntitiesFromLump(new EntityLump(newResource)); } var worldEntities = entityLump.GetEntities(); foreach (var entity in worldEntities) { var scale = string.Empty; var position = string.Empty; var angles = string.Empty; string model = null; var skin = string.Empty; var colour = new byte[0]; var classname = string.Empty; string particle = null; string animation = null; foreach (var property in entity.Properties) { if (property.Key == EntityLumpKeyLookup.Get("model")) { model = property.Data as string; } else if (property.Key == EntityLumpKeyLookup.Get("origin")) { position = property.Data as string; } else if (property.Key == EntityLumpKeyLookup.Get("angles")) { angles = property.Data as string; } else if (property.Key == EntityLumpKeyLookup.Get("scales")) { scale = property.Data as string; } else if (property.Key == EntityLumpKeyLookup.Get("skin")) { skin = property.Data as string; } else if (property.Key == EntityLumpKeyLookup.Get("rendercolor")) { colour = property.Data as byte[]; } else if (property.Key == EntityLumpKeyLookup.Get("classname")) { classname = property.Data as string; } else if (property.Key == EntityLumpKeyLookup.Get("effect_name")) { particle = property.Data as string; } else if (property.Key == EntityLumpKeyLookup.Get("defaultanim")) { animation = property.Data as string; } } 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"; 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 (particle != null) { var particleResource = guiContext.LoadFileByAnyMeansNecessary(particle + "_c"); if (particleResource != null) { var particleSystem = new ParticleSystem(particleResource); var origin = new System.Numerics.Vector3(positionVector.X, positionVector.Y, positionVector.Z); //particleRenderers.Add(new ParticleRenderer.ParticleRenderer(particleSystem, guiContext, origin)); } continue; } if (isCamera) { if (classname == "worldspawn") { // TODO //glRenderControl.SetDefaultWorldCamera(positionVector); } else { // TODO //glRenderControl.AddCamera(name == string.Empty ? $"{classname} #{anonymousCameraCount++}" : name, transformationMatrix); } continue; } else if (isGlobalLight) { // TODO //glRenderControl.SetWorldGlobalLight(positionVector); // TODO: set light angle continue; } else if (model == null) { 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 = guiContext.LoadFileByAnyMeansNecessary(model + "_c"); if (newEntity == null) { continue; } var newModel = new Model(newEntity); var modelRenderer = new ModelRenderer(newModel, guiContext, skin, false); modelRenderer.SetMeshTransform(transformationMatrix); modelRenderer.SetTint(objColor); if (animation != default) { modelRenderer.LoadAnimation(animation); // Load only this animation modelRenderer.SetAnimation(animation); } worldOctree.Insert(modelRenderer); modelRenderers.Add(modelRenderer); BoundingBox = BoundingBox.IsZero ? modelRenderer.BoundingBox : BoundingBox.Union(modelRenderer.BoundingBox); } }
private void SetupMeshRenderers() { var data = WorldNode.GetData(); var sceneObjectLayerIndices = data.ContainsKey("m_sceneObjectLayerIndices") ? data.GetIntegerArray("m_sceneObjectLayerIndices") : null; var sceneObjects = data.GetArray("m_sceneObjects"); var i = 0; // Output is WorldNode_t we need to iterate m_sceneObjects inside it foreach (var sceneObject in sceneObjects) { if (sceneObjectLayerIndices != null) { var layerIndex = sceneObjectLayerIndices[i]; i++; // TODO: We want UI for this if (layerIndex == 2 || layerIndex == 4) { continue; } } // sceneObject is SceneObject_t var renderableModel = sceneObject.GetProperty <string>("m_renderableModel"); var transform = sceneObject.GetArray("m_vTransform"); var matrix = Matrix4.Identity; // Copy transform matrix to right type for (var x = 0; x < transform.Length; x++) { var a = transform[x].ToVector4(); switch (x) { case 0: matrix.Column0 = new Vector4(a.X, a.Y, a.Z, a.W); break; case 1: matrix.Column1 = new Vector4(a.X, a.Y, a.Z, a.W); break; case 2: matrix.Column2 = new Vector4(a.X, a.Y, a.Z, a.W); break; case 3: matrix.Column3 = new Vector4(a.X, a.Y, a.Z, a.W); break; } } var tintColorWrongVector = sceneObject.GetSubCollection("m_vTintColor").ToVector4(); Vector4 tintColor; if (tintColorWrongVector.W == 0) { // Ignoring tintColor, it will f**k things up. tintColor = Vector4.One; } else { tintColor = new Vector4(tintColorWrongVector.X, tintColorWrongVector.Y, tintColorWrongVector.Z, tintColorWrongVector.W); } if (renderableModel != null) { var newResource = guiContext.LoadFileByAnyMeansNecessary(renderableModel + "_c"); if (newResource == null) { continue; } var renderer = new ModelRenderer(new Model(newResource), guiContext, null, false); renderer.SetMeshTransform(matrix); renderer.SetTint(tintColor); meshRenderers.Add(renderer); BoundingBox = BoundingBox.IsZero ? renderer.BoundingBox : BoundingBox.Union(renderer.BoundingBox); meshOctree.Insert(renderer); } var renderable = sceneObject.GetProperty <string>("m_renderable"); if (renderable != null) { var newResource = guiContext.LoadFileByAnyMeansNecessary(renderable + "_c"); if (newResource == null) { continue; } var renderer = new MeshRenderer(new Mesh(newResource), guiContext); renderer.Transform = matrix; renderer.Tint = tintColor; meshRenderers.Add(renderer); BoundingBox = BoundingBox.IsZero ? renderer.BoundingBox : BoundingBox.Union(renderer.BoundingBox); meshOctree.Insert(renderer); } } }