From 198902f9e1dbdacacef622c62b2a0c807a7cfc44 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Tue, 6 Jun 2017 19:32:00 -0400 Subject: [PATCH] gamnit: cache UICamera anchor points MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- contrib/action_nitro/src/action_nitro.nit | 2 +- lib/gamnit/bmfont.nit | 3 +- lib/gamnit/cameras.nit | 74 ++++++++++++++++++++++++----- lib/gamnit/flat.nit | 21 ++++++++ 4 files changed, 86 insertions(+), 14 deletions(-) diff --git a/contrib/action_nitro/src/action_nitro.nit b/contrib/action_nitro/src/action_nitro.nit index e5a68f9..56a055b 100644 --- a/contrib/action_nitro/src/action_nitro.nit +++ b/contrib/action_nitro/src/action_nitro.nit @@ -561,7 +561,7 @@ redef class Player end # Display respawn instructions - app.ui_sprites.add new Sprite(app.texts_sheet.respawn, app.ui_camera.center) + app.ui_sprites.add new Sprite(app.texts_sheet.respawn, app.ui_camera.center.offset(0.0, 0.0, 0.0)) end end diff --git a/lib/gamnit/bmfont.nit b/lib/gamnit/bmfont.nit index 4abdaa5..2cd69d7 100644 --- a/lib/gamnit/bmfont.nit +++ b/lib/gamnit/bmfont.nit @@ -270,7 +270,8 @@ end # ~~~ # redef class App # var font = new BMFontAsset("arial.fnt") -# var ui_text = new TextSprites(font, ui_camera.top_left) +# var pos: Point3d[Float] = ui_camera.top_left.offset(128.0, -128.0, 0.0) +# var ui_text = new TextSprites(font, pos) # # redef fun on_create # do diff --git a/lib/gamnit/cameras.nit b/lib/gamnit/cameras.nit index 042896a..7183e6b 100644 --- a/lib/gamnit/cameras.nit +++ b/lib/gamnit/cameras.nit @@ -29,7 +29,7 @@ abstract class Camera var display: GamnitDisplay # Position of this camera in world space - var position = new Point3d[Float](0.0, 0.0, 0.0) is writable + var position = new Point3d[Float](0.0, 0.0, 0.0) # The Model-View-Projection matrix created by this camera # @@ -238,33 +238,31 @@ class UICamera end # Center of the screen, from the point of view of the camera, at z = 0 - fun center: Point3d[Float] do return new Point3d[Float](position.x + width / 2.0, position.y - height / 2.0, 0.0) + var center: IPoint3d[Float] = new CameraAnchor(self, 0.5, -0.5) # Center of the top of the screen, at z = 0 - fun top: Point3d[Float] do return new Point3d[Float](position.x + width / 2.0, position.y, 0.0) + var top: IPoint3d[Float] = new CameraAnchor(self, 0.5, 0.0) # Center of the bottom of the screen, at z = 0 - fun bottom: Point3d[Float] do return new Point3d[Float](position.x + width / 2.0, position.y - height, 0.0) + var bottom: IPoint3d[Float] = new CameraAnchor(self, 0.5, -1.0) # Center of the left border of the screen, at z = 0 - fun left: Point3d[Float] do return new Point3d[Float](position.x, position.y - height / 2.0, 0.0) + var left: IPoint3d[Float] = new CameraAnchor(self, 0.0, -1.0) # Center of the right border of the screen, at z = 0 - fun right: Point3d[Float] do return new Point3d[Float](position.x + width, position.y - height / 2.0, 0.0) + var right: IPoint3d[Float] = new CameraAnchor(self, 1.0, -1.0) # Top left corner of the screen, at z = 0 - fun top_left: Point3d[Float] do return new Point3d[Float](position.x, position.y, 0.0) + var top_left: IPoint3d[Float] = new CameraAnchor(self, 0.0, 0.0) # Top right corner of the screen, at z = 0 - fun top_right: Point3d[Float] do return new Point3d[Float](position.x + width, position.y, 0.0) + var top_right: IPoint3d[Float] = new CameraAnchor(self, 1.0, 0.0) # Bottom left corner of the screen, at z = 0 - fun bottom_left: Point3d[Float] do return new Point3d[Float](position.x, position.y - height, 0.0) + var bottom_left: IPoint3d[Float] = new CameraAnchor(self, 0.0, -1.0) # Bottom right corner of the screen, at z = 0 - fun bottom_right: Point3d[Float] do return new Point3d[Float](position.x + width, position.y - height, 0.0) - - # TODO cache the anchors + var bottom_right: IPoint3d[Float] = new CameraAnchor(self, 1.0, -1.0) redef fun mvp_matrix do @@ -279,3 +277,55 @@ class UICamera return view * projection end end + +# Immutable relative anchors for reference points on `camera` +private class CameraAnchor + super IPoint3d[Float] + + # Reference camera + var camera: UICamera + + # Reference position, the top left of the screen + var ref: Point3d[Float] = camera.position is lazy + + # X position as proportion of the screen width + var relative_x: Float + + # Y position as proportion of the screen height + var relative_y: Float + + redef fun x do return ref.x + relative_x*camera.width + redef fun y do return ref.y + relative_y*camera.height + redef fun z do return ref.z + + redef fun offset(x, y, z) do return new OffsetPoint3d(self, x.to_f, y.to_f, z.to_f) +end + +# Position relative to another point or usually a `CameraAnchor` +private class OffsetPoint3d + super Point3d[Float] + + autoinit ref, offset_x, offset_y, offset_z + + # Reference point to which the offsets are applied + var ref: IPoint3d[Float] + + # Difference on the X axis + var offset_x: Float + + # Difference on the X axis + var offset_y: Float + + # Difference on the X axis + var offset_z: Float + + redef fun x do return ref.x + offset_x + redef fun y do return ref.y + offset_y + redef fun z do return ref.z + offset_z + + redef fun x=(value) do if value != null then offset_x += value - x + redef fun y=(value) do if value != null then offset_y += value - y + redef fun z=(value) do if value != null then offset_z += value - z + + redef fun offset(x, y, z) do return new OffsetPoint3d(self, x.to_f, y.to_f, z.to_f) +end diff --git a/lib/gamnit/flat.nit b/lib/gamnit/flat.nit index f7f7c4a..cafac8a 100644 --- a/lib/gamnit/flat.nit +++ b/lib/gamnit/flat.nit @@ -42,6 +42,7 @@ import performance_analysis import gamnit import gamnit::cameras_cache +intrude import gamnit::cameras import gamnit::dynamic_resolution import gamnit::limit_fps import gamnit::camera_control @@ -633,6 +634,26 @@ redef class Point3d[N] end end +redef class OffsetPoint3d + redef fun x=(v) + do + if isset _x and v != x then needs_update + super + end + + redef fun y=(v) + do + if isset _y and v != y then needs_update + super + end + + redef fun z=(v) + do + if isset _z and v != z then needs_update + super + end +end + # Set of sprites sorting them into different `SpriteContext` private class SpriteSet super HashSet[Sprite] -- 1.7.9.5