예제 #1
0
        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);
        }
예제 #2
0
        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
        }
예제 #3
0
 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);
         }
     }
 }
예제 #4
0
        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);
        }
예제 #5
0
        //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);
        }
예제 #6
0
        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
                            );
                    }
                }
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        public static float GetZ(Vector3 cameraPosition, Vector3 vec)
        {
            var res = VectorMath.DistanceSquared(vec, cameraPosition);

            return(res);
        }
예제 #9
0
        public static float GetZ(Matrix4 world, Vector3 cameraPosition, Vector3 vec)
        {
            var res = VectorMath.DistanceSquared(world.Transform(vec), cameraPosition);

            return(res);
        }
예제 #10
0
        //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);
        }
예제 #11
0
        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);
                        }
                    }
                }
            }
        }