import JolkEngine import Foundation import simd struct Scene1: Scene { private var env = Environment() private var worldMesh = RenderMesh.empty private var cube = RenderMesh.empty private var suzanne = RenderMesh.empty private var toybox = RenderMesh.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) } } }