Files
CavesOfSwift/Sources/Test/Scenes/Scene1.swift
2024-05-09 20:52:01 +10:00

195 lines
6.9 KiB
Swift

import JolkEngine
import Foundation
import simd
struct Scene1: Scene
{
private var env = Environment()
private var worldMesh = RenderMesh<VertexPositionNormalColourTexcoord>.empty
private var cube = RenderMesh<VertexPositionNormalTexcoord>.empty
private var suzanne = RenderMesh<VertexPositionNormalTexcoord>.empty
private var toybox = RenderMesh<VertexPositionNormalTexcoord>.empty
private var jolkTex = Texture2D.empty, suzanneDiffuse = Texture2D.empty
private var drawEdges = false
private var world = Collision()
private var colin = Colin()
private var jolkCube = JolkCube(position: .init(0, 1, -4))
private var lightTheta: Float = 0
mutating func setup(render: inout any JolkEngine.Renderer)
{
render.clearColour = XnaColour.CornflowerBlue
env.setFog(
colour: XnaColour.CornflowerBlue,
//mode: .depth, falloff: .range(type: .linear, start: 4, end: 38))
//mode: .depth, falloff: .range(type: .linear, start: 1.25, end: 24.5))
//mode: .distance, falloff: .factor(type: .exp2, density: 0.1))
mode: .depth, falloff: .factor(type: .exp2, density: 0.0222))
env.addAmbientLight(colour: XnaColour.DarkSlateGray.lighten(by: -0.666))
env.addDirectionalLight(
direction: -Vec3f(1, -1, -1).normalised,
colour: XnaColour.BlanchedAlmond
.lighten(by: -0.02)
.mix(with: XnaColour.LightSlateGray, 0.5)
.mix(with: XnaColour.White, 0.125))
env.addPointLight(
position: Vec3f(3, 0.33, -5),
colour: XnaColour.Green.mix(with: XnaColour.Gray, 0.5),
intensity: 2)
env.addPointLight(
position: Vec3f(5.5, 0.33, -6),
colour: XnaColour.Red.mix(with: XnaColour.Gray, 0.5),
intensity: 2)
env.addPointLight(
position: Vec3f(4, 0.33, -7),
colour: XnaColour.Blue.mix(with: XnaColour.Gray, 0.5),
intensity: 2)
}
mutating func loadContent(content: inout JolkEngine.ContentManager) throws
{
try loadWorld(&content)
cube = try content.create(mesh: .init(
vertices: [
.init(position: Vec3f(-1, -1, 1), normal: .forward, texCoord: Vec2f(0, 0)),
.init(position: Vec3f( 1, -1, 1), normal: .forward, texCoord: Vec2f(1, 0)),
.init(position: Vec3f(-1, 1, 1), normal: .forward, texCoord: Vec2f(0, 1)),
.init(position: Vec3f( 1, 1, 1), normal: .forward, texCoord: Vec2f(1, 1)),
.init(position: Vec3f( 1, -1, 1), normal: .right, texCoord: Vec2f(0, 0)),
.init(position: Vec3f( 1, -1, -1), normal: .right, texCoord: Vec2f(1, 0)),
.init(position: Vec3f( 1, 1, 1), normal: .right, texCoord: Vec2f(0, 1)),
.init(position: Vec3f( 1, 1, -1), normal: .right, texCoord: Vec2f(1, 1)),
.init(position: Vec3f( 1, -1, -1), normal: .back, texCoord: Vec2f(0, 0)),
.init(position: Vec3f(-1, -1, -1), normal: .back, texCoord: Vec2f(1, 0)),
.init(position: Vec3f( 1, 1, -1), normal: .back, texCoord: Vec2f(0, 1)),
.init(position: Vec3f(-1, 1, -1), normal: .back, texCoord: Vec2f(1, 1)),
.init(position: Vec3f(-1, -1, -1), normal: .left, texCoord: Vec2f(0, 0)),
.init(position: Vec3f(-1, -1, 1), normal: .left, texCoord: Vec2f(1, 0)),
.init(position: Vec3f(-1, 1, -1), normal: .left, texCoord: Vec2f(0, 1)),
.init(position: Vec3f(-1, 1, 1), normal: .left, texCoord: Vec2f(1, 1)),
.init(position: Vec3f(-1, -1, -1), normal: .down, texCoord: Vec2f(0, 0)),
.init(position: Vec3f( 1, -1, -1), normal: .down, texCoord: Vec2f(1, 0)),
.init(position: Vec3f(-1, -1, 1), normal: .down, texCoord: Vec2f(0, 1)),
.init(position: Vec3f( 1, -1, 1), normal: .down, texCoord: Vec2f(1, 1)),
.init(position: Vec3f(-1, 1, 1), normal: .up, texCoord: Vec2f(0, 0)),
.init(position: Vec3f( 1, 1, 1), normal: .up, texCoord: Vec2f(1, 0)),
.init(position: Vec3f(-1, 1, -1), normal: .up, texCoord: Vec2f(0, 1)),
.init(position: Vec3f( 1, 1, -1), normal: .up, texCoord: Vec2f(1, 1))
],
indices: [
0, 1, 2, 2, 1, 3,
4, 5, 6, 6, 5, 7,
8, 9, 10, 10, 9, 11,
12, 13, 14, 14, 13, 15,
16, 17, 18, 18, 17, 19,
20, 21, 22, 22, 21, 23 ]))
suzanne = try content.load("suzanne.g3db")
toybox = try content.load("toybox.g3db")
let linearMipped = Texture2DParameters(
minFilter: .linear, magFilter: .linear,
wrapMode: .repeating,
mipMode: .linear)
let linearClamp = Texture2DParameters(
minFilter: .linear, magFilter: .linear,
wrapMode: .clampEdge)
jolkTex = try content.load("jolkmeup.jpg", params: linearClamp)
suzanneDiffuse = try content.load("suzanne_diffuse.png", params: linearMipped)
}
private mutating func loadWorld(_ content: inout ContentManager) throws
{
let name = "World.obj"
let obj = try ObjReader.read(url: try content.getResource(name))
let mesh: Mesh = try ObjLoader.read(model: obj, content: &content)
worldMesh = try content.create(mesh: mesh)
if let collision = obj.objects["Collision3D"]
{
world.build(obj: obj, collision: collision)
}
}
mutating func update(deltaTime: Float)
{
colin.update(deltaTime: deltaTime, world: world)
jolkCube.update(deltaTime: deltaTime, world: world)
// Update point lights
lightTheta += deltaTime
var theta = Vec3f(repeating: lightTheta) * Vec3f(0.12, 0.011, 0.056) * 6
var i = env.lights.startIndex
while i != env.lights.endIndex
{
if case .point(let colour, _, _) = env.lights[i]
{
env.lights[i] = .point(
colour: colour,
position: Vec3f(
4 + 6 * cos(theta[0]),
0.33 + 0.33 * sin(theta[1]),
-6 + 3 * sin(theta[0] * 2)),
intensity: 3.1 + 1.53 * cos(theta[2]))
let spacing = 0.5 * Float.pi * (2 / 3.0)
theta += spacing * Vec3f(1, 0.98, 0.5566)
}
i = env.lights.index(after: i)
}
if Input.instance.keyboard.keyPressed(.c) { drawEdges = !drawEdges }
}
func draw(render: inout Renderer, deltaTime: Float, aspectRatio aspect: Float)
{
// Setup camera
render.setProjection(matrix:
.perspective(fovY: Float.rad(fromDeg: colin.fov), aspect: aspect, zNear: 0.1, zFar: 100))
render.setView(matrix: colin.transform)
// Draw world
for s in worldMesh.subMeshes
{
//render.setMaterial(Material(
// specular: XnaColour.BlanchedAlmond.mix(with: .black, 0.12),
// texture: texture.id))
if s.material != -1
{
render.setMaterial(worldMesh.materials[s.material])
}
else
{
render.setMaterial(.init())
}
render.draw(mesh: worldMesh, subMesh: s, environment: env)
}
// Draw jolked up shit
render.setMaterial(Material(
specular: XnaColour.Gray,
gloss: 20.0,
texture: jolkTex.id))
render.draw(mesh: cube, model: jolkCube.transform, environment: env)
render.setMaterial(Material(texture: suzanneDiffuse.id))
render.draw(mesh: suzanne, model: .translate(.up + Vec3f(3.0, 0.0, -3.5) * 2.5), environment: env)
render.draw(mesh: toybox,
model: .translate(Vec3f(6.0, 0.667, -3.5) * Vec3f(2.5, 1, 2.5))
* .rotate(y: lightTheta * 0.5) * .scale(scalar: 0.25), environment: env)
if drawEdges
{
world.draw(render, position: colin.position)
}
}
}