static bool SphereRayIntersect(Vector3 rayOrigin, Vector3 d, float maxdistance, Vector3 centre, float radius) { var dist = VectorMath.DistanceSquared(rayOrigin, centre); if (dist > (maxdistance - radius) * (maxdistance - radius)) { return(false); } //Ray start offset from sphere centre var p = rayOrigin - centre; float rSquared = radius * radius; float p_d = Vector3.Dot(p, d); if (p_d > 0 || Vector3.Dot(p, p) < rSquared) { return(false); } var a = p - p_d * d; var aSquared = Vector3.Dot(a, a); return(aSquared < rSquared); }
public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { var visible = ( VectorMath.DistanceSquared(camera.Position, pos) < CULL && camera.Frustum.Intersects(new BoundingSphere(pos, equip.BulbSize * 3)) ); this.sys = sys; if (visible) { sys.AddObject(this); return(true); } else { return(false); } /*if (lt_on && camera.Frustum.Intersects(new BoundingSphere(pos, 100))) * { * sys.PointLightDX(pos, 50, new Color4(equip.GlowColor, 1), new Vector3(1, 0.01f, 0.000055f)); * }*///TODO: Configurable }
public override void Draw(ICamera camera, CommandBuffer commands, SystemLighting lights, NebulaRenderer nr) { Init(); if (Dfm != null) { Dfm.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); var center = VectorMath.Transform(Vector3.Zero, World); //var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, 20, nr, LitAmbient, LitDynamic, NoFog); Dfm.DrawBuffer(commands, World, ref Lighting.Empty); } if (Model != null) { if (Model.Levels.Length > 0) { Model.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); var center = VectorMath.Transform(Model.Levels[0].Center, World); var lvl = GetLevel(Model, center, camera.Position); if (lvl == null) { return; } var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, Model.Levels[0].Radius, nr, LitAmbient, LitDynamic, NoFog); var r = Model.Levels [0].Radius + lighting.FogRange.Y; if (lighting.FogMode != FogModes.Linear || VectorMath.DistanceSquared(camera.Position, center) <= (r * r)) { Model.DrawBufferLevel(lvl, commands, World, ref lighting); } } } else if (Cmp != null) { Cmp.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); foreach (Part p in Cmp.Parts) { var model = p.Model; Matrix4 w = World; if (p.Construct != null) { w = p.Construct.Transform * World; } if (model.Levels.Length > 0) { var center = VectorMath.Transform(model.Levels[0].Center, w); var lvl = GetLevel(model, center, camera.Position); if (lvl == null) { continue; } var bsphere = new BoundingSphere( center, model.Levels[0].Radius ); if (camera.Frustum.Intersects(bsphere)) { var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, model.Levels[0].Radius, nr, LitAmbient, LitDynamic, NoFog); var r = model.Levels [0].Radius + lighting.FogRange.Y; if (lighting.FogMode != FogModes.Linear || VectorMath.DistanceSquared(camera.Position, center) <= (r * r)) { model.DrawBufferLevel(lvl, commands, w, ref lighting); } } } } } else if (CmpParts != null) { _parentCmp.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); foreach (Part p in CmpParts) { p.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); var model = p.Model; Matrix4 w = World; if (p.Construct != null) { w = p.Construct.Transform * World; } if (model.Levels.Length > 0) { var center = VectorMath.Transform(model.Levels[0].Center, w); var lvl = GetLevel(model, center, camera.Position); if (lvl == null) { continue; } var bsphere = new BoundingSphere( center, model.Levels[0].Radius ); if (camera.Frustum.Intersects(bsphere)) { var lighting = RenderHelpers.ApplyLights(lights, LightGroup, center, model.Levels[0].Radius, nr, LitAmbient, LitDynamic, NoFog); var r = model.Levels[0].Radius + lighting.FogRange.Y; if (lighting.FogMode != FogModes.Linear || VectorMath.DistanceSquared(camera.Position, center) <= (r * r)) { model.DrawBufferLevel(lvl, commands, w, ref lighting); } } } } } else if (Sph != null) { Sph.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); var l = RenderHelpers.ApplyLights(lights, LightGroup, pos, Sph.Radius, nr, LitAmbient, LitDynamic, NoFog); var r = Sph.Radius + l.FogRange.Y; if (l.FogMode != FogModes.Linear || VectorMath.DistanceSquared(camera.Position, pos) <= (r * r)) { Sph.DrawBuffer(commands, World, ref l); } } }
public override bool PrepareRender(ICamera camera, NebulaRenderer nr, SystemRenderer sys) { this.sysr = sys; if (Nebula != null && nr != Nebula) { return(false); } var dsq = VectorMath.DistanceSquared(pos, camera.Position); if (LODRanges != null) //Fastest cull { var maxd = LODRanges[LODRanges.Length - 1] * sysr.LODMultiplier; maxd *= maxd; if (dsq > maxd) { return(false); } } if (Model != null) { if (Model.Levels.Length != 0) { var center = VectorMath.Transform(Model.Levels[0].Center, World); var lvl = GetLevel(Model, center, camera.Position); if (lvl == null) { return(false); } var bsphere = new BoundingSphere( center, Model.Levels[0].Radius ); if (!camera.Frustum.Intersects(bsphere)) { return(false); //Culled } sys.AddObject(this); return(true); } } else if (Cmp != null || CmpParts != null) { //Check if -something- renders var partCol = (IEnumerable <Part>)CmpParts ?? Cmp.Parts; bool cmpParts = CmpParts != null; foreach (Part p in partCol) { if (cmpParts) { p.Update(camera, TimeSpan.Zero, TimeSpan.FromSeconds(sysr.Game.TotalTime)); } var model = p.Model; Matrix4 w = World; if (p.Construct != null) { w = p.Construct.Transform * World; } if (model.Levels.Length > 0) { var center = VectorMath.Transform(model.Levels[0].Center, w); var lvl = GetLevel(model, center, camera.Position); if (lvl == null) { continue; } var bsphere = new BoundingSphere( center, model.Levels[0].Radius ); if (camera.Frustum.Intersects(bsphere)) { sys.AddObject(this); return(true); } } } return(false); } else if (Sph != null) { var bsphere = new BoundingSphere( pos, Math.Max(Sph.Radius, radiusAtmosphere)); if (!camera.Frustum.Intersects(bsphere)) { return(false); } sys.AddObject(this); return(true); } return(false); }
//Select by bounding box, not by mesh bool SelectionCast(Vector3 rayOrigin, Vector3 direction, float maxDist, out RigidBody body) { float dist = float.MaxValue; body = null; var jitterDir = direction * maxDist; foreach (var b in world.Physics.RigidBodies) { var rb = (RigidBody)b; if (rb.Tag == player) { continue; } if (rb.Shape is SphereShape) { //Test spheres var sph = (SphereShape)rb.Shape; if (SphereRayIntersect(rayOrigin, direction, maxDist, rb.Position, sph.Radius)) { var nd = VectorMath.DistanceSquared(rb.Position, camera.Position); if (nd < dist) { dist = nd; body = rb; } } } else { var tag = rb.Tag as GameObject; if (!rb.BoundingBox.RayIntersect(ref rayOrigin, ref jitterDir)) { continue; } if (tag == null || tag.CmpParts.Count == 0) { //Single part var nd = VectorMath.DistanceSquared(rb.Position, camera.Position); if (nd < dist) { dist = nd; body = rb; } } else { //Test by cmp parts var sh = (CompoundSurShape)rb.Shape; for (int i = 0; i < sh.Shapes.Length; i++) { sh.Shapes[i].UpdateBoundingBox(); var bb = sh.Shapes[i].BoundingBox; bb.Min += rb.Position; bb.Max += rb.Position; if (bb.RayIntersect(ref rayOrigin, ref jitterDir)) { var nd = VectorMath.DistanceSquared(rb.Position, camera.Position); if (nd < dist) { dist = nd; body = rb; } break; } } } } } return(body != null); }
public void Draw(ResourceManager res, SystemLighting lighting, CommandBuffer buffer, NebulaRenderer nr) { //Null check if (_camera == null) { return; } //Asteroids! if (VectorMath.DistanceSquared(cameraPos, field.Zone.Position) <= renderDistSq) { float fadeNear = field.FillDist * 0.9f; float fadeFar = field.FillDist; if (field.Cube.Count > 0) { if (cubeCount == -1) { return; } for (int i = 0; i < cubeDrawCalls.Count; i++) { cubeDrawCalls[i].Material.Update(_camera); } var lt = RenderHelpers.ApplyLights(lighting, 0, cameraPos, field.FillDist, nr); while (!_asteroidsCalculated) { } for (int j = 0; j < cubeCount; j++) { var center = cubes[j].pos; var z = RenderHelpers.GetZ(cameraPos, center); for (int i = 0; i < cubeDrawCalls.Count; i++) { var dc = cubeDrawCalls[i]; if (VectorMath.DistanceSquared(center, cameraPos) < (fadeNear * fadeNear)) { //TODO: Accurately determine whether or not a cube has fading } buffer.AddCommandFade( dc.Material.Render, cubes[j].tr, lt, cube_vbo, PrimitiveTypes.TriangleList, dc.StartIndex, dc.Count / 3, SortLayers.OBJECT, new Vector2(fadeNear, fadeFar), z ); } } } if (field.BillboardCount != -1 || false) { var cameraLights = RenderHelpers.ApplyLights(lighting, 0, cameraPos, 1, nr); if (billboardTex == null || billboardTex.IsDisposed) { billboardTex = (Texture2D)res.FindTexture(field.BillboardShape.Texture); } for (int i = 0; i < astbillboards.Length; i++) { if (!astbillboards [i].Inited) { astbillboards [i].Spawn(this); } var d = VectorMath.DistanceSquared(cameraPos, astbillboards [i].Position); if (d < (field.BillboardDistance * field.BillboardDistance) || d > (field.FillDist * field.FillDist)) { astbillboards [i].Spawn(this); } if (astbillboards [i].Visible) { var alpha = 1f; var coords = billboardCoords [astbillboards [i].Texture]; sys.Game.Billboards.DrawTri( billboardTex, astbillboards [i].Position, astbillboards[i].Size, new Color4(field.BillboardTint * cameraLights.Ambient.Rgb, alpha), coords[0], coords[2], coords[1], 0, SortLayers.OBJECT ); } } } } //Band is last if (renderBand) { if (!_camera.Frustum.Intersects(new BoundingSphere(field.Zone.Position, lightingRadius))) { return; } var tex = (Texture2D)res.FindTexture(field.Band.Shape); for (int i = 0; i < SIDES; i++) { var p = bandCylinder.GetSidePosition(i); var zcoord = RenderHelpers.GetZ(bandTransform, cameraPos, p); p = bandTransform.Transform(p); var lt = RenderHelpers.ApplyLights(lighting, 0, p, lightingRadius, nr); if (lt.FogMode != FogModes.Linear || VectorMath.DistanceSquared(cameraPos, p) <= (lightingRadius + lt.FogRange.Y) * (lightingRadius + lt.FogRange.Y)) { buffer.AddCommand( bandShader.Shader, bandShaderDelegate, bandShaderCleanup, bandTransform, lt, new RenderUserData() { Float = field.Band.TextureAspect, Color = field.Band.ColorShift, Camera = _camera, Texture = tex, Matrix2 = bandNormal }, bandCylinder.VertexBuffer, PrimitiveTypes.TriangleList, 0, i * 6, 2, true, SortLayers.OBJECT, zcoord ); } } } }
public static Lighting ApplyLights(SystemLighting src, int lightGroup, Vector3 c, float r, NebulaRenderer nebula, bool lambient = true, bool ldynamic = true, bool nofog = false) { var lights = Lighting.Create(); lights.Ambient = lambient ? src.Ambient : Color4.Black; lights.NumberOfTilesX = src.NumberOfTilesX; if (nofog) { lights.FogMode = FogModes.None; } else { lights.FogMode = src.FogMode; lights.FogDensity = src.FogDensity; lights.FogColor = src.FogColor; lights.FogRange = src.FogRange; } int lc = 0; if (ldynamic) { lights.Lights.SourceLighting = src; for (int i = 0; i < src.Lights.Count; i++) { if (src.Lights[i].LightGroup != lightGroup) { continue; } if (!src.Lights[i].Active) { continue; } var l = src.Lights[i].Light; var r2 = r + l.Range; //l.Kind > 0 - test if not directional if (l.Kind > 0 && VectorMath.DistanceSquared(l.Position, c) > (r2 * r2)) { continue; } //Advanced spotlight cull if ((l.Kind == LightKind.Spotlight) && SpotlightTest(ref l, c, r)) { continue; } if ((lc + 1) > MAX_LIGHTS) { throw new Exception("Too many lights!"); } lc++; lights.Lights.SourceEnabled[i] = true; } } if (nebula != null) { Color4? ambient; bool fogenabled; Vector2 fogrange; Color4 fogcolor; RenderLight?lightning; nebula.GetLighting(out fogenabled, out ambient, out fogrange, out fogcolor, out lightning); if (ambient != null) { lights.Ambient = ambient.Value; } if (fogenabled) { lights.FogMode = FogModes.Linear; lights.FogColor = fogcolor; lights.FogRange = fogrange; } if (lightning != null && src.NumberOfTilesX == -1) { if ((lc + 1) > MAX_LIGHTS) { throw new Exception("Too many lights!"); } lights.Lights.Nebula0 = lightning.Value; lights.Lights.NebulaCount = 1; } } return(lights); }
public static float GetZ(Vector3 cameraPosition, Vector3 vec) { var res = VectorMath.DistanceSquared(vec, cameraPosition); return(res); }
public static float GetZ(Matrix4 world, Vector3 cameraPosition, Vector3 vec) { var res = VectorMath.DistanceSquared(world.Transform(vec), cameraPosition); return(res); }
//Select by bounding box, not by mesh bool SelectionCast(Vector3 rayOrigin, Vector3 direction, float maxDist, out PhysicsObject body) { float dist = float.MaxValue; body = null; var jitterDir = direction * maxDist; foreach (var rb in world.Physics.Objects) { if (rb.Tag == player) { continue; } if (rb.Collider is SphereCollider) { //Test spheres var sph = (SphereCollider)rb.Collider; if (SphereRayIntersect(rayOrigin, direction, maxDist, rb.Position, sph.Radius)) { var nd = VectorMath.DistanceSquared(rb.Position, camera.Position); if (nd < dist) { dist = nd; body = rb; } } } else { //var tag = rb.Tag as GameObject; if (!rb.GetBoundingBox().RayIntersect(ref rayOrigin, ref jitterDir)) { continue; } body = rb; /*if (tag == null || tag.CmpParts.Count == 0) * { * //Single part * var nd = VectorMath.DistanceSquared(rb.Position, camera.Position); * if (nd < dist) * { * dist = nd; * body = rb; * } * } * else * { * //Test by cmp parts * var sh = (CompoundSurShape)rb.Shape; * for (int i = 0; i < sh.Shapes.Length; i++) * { * sh.Shapes[i].UpdateBoundingBox(); * var bb = sh.Shapes[i].BoundingBox; * bb.Min += rb.Position; * bb.Max += rb.Position; * if (bb.RayIntersect(ref rayOrigin, ref jitterDir)) * { * * var nd = VectorMath.DistanceSquared(rb.Position, camera.Position); * if (nd < dist) * { * dist = nd; * body = rb; * } * break; * } * } * }*/ } } return(body != null); }
public override void FixedUpdate(TimeSpan time) { var world = Parent.GetWorld(); var player = world.GetObject("player"); if (player == null) { return; } if (VectorMath.DistanceSquared(player.PhysicsComponent.Body.Position, Field.Zone.Position) > activateDist) { return; } var cds = (Field.CubeSize + COLLIDE_DISTANCE); cds *= cds; for (int i = bodies.Count - 1; i >= 0; i--) { var distance = VectorMath.DistanceSquared(player.PhysicsComponent.Body.Position, bodies[i].Position); if (distance > cds) { world.Physics.RemoveObject(bodies[i]); bodies.RemoveAt(i); } } var close = AsteroidFieldShared.GetCloseCube(player.PhysicsComponent.Body.Position, Field.CubeSize); var cubeRad = new Vector3(Field.CubeSize) * 0.5f; int amountCubes = (int)Math.Floor((COLLIDE_DISTANCE / Field.CubeSize)) + 1; for (int x = -amountCubes; x <= amountCubes; x++) { for (int y = -amountCubes; y <= amountCubes; y++) { for (int z = -amountCubes; z <= amountCubes; z++) { var center = close + new Vector3(x * Field.CubeSize, y * Field.CubeSize, z * Field.CubeSize); if (!Field.Zone.Shape.ContainsPoint(center)) { continue; } if (VectorMath.DistanceSquared(player.PhysicsComponent.Body.Position, center) > cds) { continue; } float tval; if (!AsteroidFieldShared.CubeExists(center, Field.EmptyCubeFrequency, out tval)) { continue; } if (GetExclusionZone(center) != null) { continue; } bool create = true; for (int i = 0; i < bodies.Count; i++) { if ((bodies[i].Position - center).LengthFast < 3) { create = false; break; } } if (create) { var transform = Field.CubeRotation.GetRotation(tval) * Matrix4.CreateTranslation(center); var body = phys.AddStaticObject(transform, shape); bodies.Add(body); } } } } }