Skip to content

Commit

Permalink
LookAt cams snap to pixels & respect magnification
Browse files Browse the repository at this point in the history
  • Loading branch information
davesmith00000 committed Nov 20, 2023
1 parent e53cc07 commit 1c62788
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,41 @@ object CameraHelper:
def calculateCameraMatrix(
screenWidth: Double,
screenHeight: Double,
magnification: Double,
renderMagnification: Double,
actualMagnification: Double,
cameraX: Double,
cameraY: Double,
cameraZoom: Double,
flipY: Boolean,
cameraRotation: Radians,
isLookAt: Boolean
): CheapMatrix4 =
val newWidth = screenWidth / magnification
val newHeight = screenHeight / magnification
val newWidth = screenWidth / renderMagnification
val newHeight = screenHeight / renderMagnification

val bounds: (Float, Float, Float, Float) =
if isLookAt then zoom(0, 0, newWidth.toFloat, newHeight.toFloat, cameraZoom.toFloat)
else zoom(cameraX.toFloat, cameraY.toFloat, newWidth.toFloat, newHeight.toFloat, cameraZoom.toFloat)

val mat =
if isLookAt then
CheapMatrix4.identity
.translate(-cameraX.toFloat, -cameraY.toFloat, 1.0f)
.rotate(cameraRotation.toFloat)
.translate(newWidth.toFloat / 2.0f, newHeight.toFloat / 2.0f, 1.0f) *
CheapMatrix4
.orthographic(
bounds._1,
bounds._2,
bounds._3,
bounds._4
val m1 =
CheapMatrix4.identity
.translate(-cameraX.toFloat, -cameraY.toFloat, 1.0f)
.rotate(cameraRotation.toFloat)
.translate(
Math.floor(newWidth.toFloat / (2.0f * actualMagnification.toFloat)).toFloat,
Math.floor(newHeight.toFloat / (2.0f * actualMagnification.toFloat)).toFloat,
1.0f
)

m1 * CheapMatrix4
.orthographic(
bounds._1,
bounds._2,
bounds._3,
bounds._4
)
else
CheapMatrix4.identity
.rotate(cameraRotation.toFloat) *
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ final class RendererWebGL1(
cNc.canvas.width.toDouble,
cNc.canvas.height.toDouble,
m.toDouble,
m.toDouble,
0,
0,
1,
Expand All @@ -130,6 +131,7 @@ final class RendererWebGL1(
cNc.canvas.width.toDouble,
cNc.canvas.height.toDouble,
cNc.magnification.toDouble,
1.0,
c.position.x.toDouble,
c.position.y.toDouble,
c.zoom.toDouble,
Expand All @@ -146,6 +148,7 @@ final class RendererWebGL1(
cNc.canvas.width.toDouble,
cNc.canvas.height.toDouble,
m.toDouble,
1.0,
c.position.x.toDouble,
c.position.y.toDouble,
c.zoom.toDouble,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import indigo.shared.platform.ProcessedSceneData
import indigo.shared.platform.RendererConfig
import indigo.shared.scenegraph.Blend
import indigo.shared.scenegraph.BlendFactor
import indigo.shared.scenegraph.Camera
import indigo.shared.shader.RawShaderCode
import indigo.shared.shader.ShaderId
import indigo.shared.shader.StandardShaders
Expand Down Expand Up @@ -248,7 +247,8 @@ final class RendererWebGL2(
.calculateCameraMatrix(
lastWidth.toDouble,
lastHeight.toDouble,
1.0d, // Layers aren't magnified
1.0d, // Layers aren't magnified during rendering.
layer.magnification.map(_.toDouble).getOrElse(1.0),
c.position.x.toDouble,
c.position.y.toDouble,
c.zoom.toDouble,
Expand Down Expand Up @@ -287,6 +287,7 @@ final class RendererWebGL2(
lastWidth.toDouble,
lastHeight.toDouble,
m.toDouble,
1.0d, // During merge, we always used a fixed camera, so irrelevant.
0,
0,
1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.example.sandbox.scenes.BoundingCircleScene
import com.example.sandbox.scenes.BoundsScene
import com.example.sandbox.scenes.BoxesScene
import com.example.sandbox.scenes.CameraScene
import com.example.sandbox.scenes.CameraWithCloneTilesScene
import com.example.sandbox.scenes.ClipScene
import com.example.sandbox.scenes.ConfettiScene
import com.example.sandbox.scenes.CratesScene
Expand Down Expand Up @@ -46,7 +47,7 @@ object SandboxGame extends IndigoGame[SandboxBootData, SandboxStartupData, Sandb
val viewportHeight: Int = gameHeight * magnificationLevel // 256

def initialScene(bootData: SandboxBootData): Option[SceneName] =
Some(OriginalScene.name)
Some(CameraWithCloneTilesScene.name)

def scenes(bootData: SandboxBootData): NonEmptyList[Scene[SandboxStartupData, SandboxGameModel, SandboxViewModel]] =
NonEmptyList(
Expand All @@ -71,7 +72,8 @@ object SandboxGame extends IndigoGame[SandboxBootData, SandboxStartupData, Sandb
UltravioletScene,
PointersScene,
BoundingCircleScene,
LineReflectionScene
LineReflectionScene,
CameraWithCloneTilesScene
)

val eventFilters: EventFilters = EventFilters.Permissive
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.example.sandbox.scenes

import com.example.sandbox.SandboxAssets
import com.example.sandbox.SandboxGameModel
import com.example.sandbox.SandboxStartupData
import com.example.sandbox.SandboxViewModel
import indigo.*
import indigo.scenes.*
import indigo.syntax.*

object CameraWithCloneTilesScene extends Scene[SandboxStartupData, SandboxGameModel, SandboxViewModel]:

type SceneModel = Unit
type SceneViewModel = Unit

def eventFilters: EventFilters =
EventFilters.Permissive

def modelLens: Lens[SandboxGameModel, Unit] =
Lens.unit

def viewModelLens: Lens[SandboxViewModel, Unit] =
Lens.unit

def name: SceneName =
SceneName("crates with camera")

def subSystems: Set[SubSystem] =
Set()

def updateModel(
context: SceneContext[SandboxStartupData],
model: Unit
): GlobalEvent => Outcome[Unit] =
_ => Outcome(model)

def updateViewModel(
context: SceneContext[SandboxStartupData],
model: Unit,
viewModel: Unit
): GlobalEvent => Outcome[Unit] =
_ => Outcome(viewModel)

val graphic = Graphic(64, 64, SandboxAssets.cratesMaterial.withLighting(LightingModel.Unlit))

val cloneId: CloneId = CloneId("crates")

val cloneBlanks: Batch[CloneBlank] =
Batch(CloneBlank(cloneId, graphic).static)

val crates =
(0 to 5).flatMap { row =>
(0 to 5).map { col =>
CloneTileData(col * 32, row * 32, Radians.zero, 1.0, 1.0, 0, 0, 32, 32)
}
}.toBatch

def present(
context: SceneContext[SandboxStartupData],
model: Unit,
viewModel: Unit
): Outcome[SceneUpdateFragment] =
Outcome(
SceneUpdateFragment(
Layer(
CloneTiles(cloneId, crates)
).withMagnification(2)
.withCamera(Camera.LookAt(Point(96)))
).addCloneBlanks(cloneBlanks)
)

0 comments on commit 1c62788

Please sign in to comment.