import Foundation import Maths import simd import JolkEngine struct CaveScene: Scene { private var colin = Colin() private var world = Collision() private var worldModel = RenderMesh.empty private var rockModel = RenderMesh.empty, axisModel = RenderMesh.empty private var rockAlbedo = Texture2D.empty, rockNormal = Texture2D.empty, axisAlbedo = Texture2D.empty private var skung = Quatf.init(), skungFrom = Quatf.init(), skungTo = Quatf.init() private var skungx: Float = 0.0 private var axisPos = Vec3f(2.0, 0.5, 0.0) private var drawEdges = false mutating func setup(render: inout any JolkEngine.Renderer) { colin.setPosition(Vec3f(3.55475903, 0.0667395443, 0.221960306)) colin.setAngle(Vec2f(-1.47447872, 0.0)) skungTo = .lookAt(from: axisPos, to: colin.position + .up) } mutating func loadContent(content: inout JolkEngine.ContentManager) throws { let obj = try ObjReader.read(url: try content.getResource("CaveScene.obj")) let mesh: Mesh = try ObjLoader.read(model: obj, content: &content) worldModel = try content.create(mesh: mesh) rockModel = try content.load("rock.mesh") rockAlbedo = try content.load("rock.dds") rockNormal = try content.load("rocknorm.dds") axisModel = try content.load("Axis.obj.cache") axisAlbedo = try content.load("AxisTex.png") if let collision = obj.objects["Collision3D"] { world.build(obj: obj, collision: collision) } } mutating func update(deltaTime: Float) { colin.update(deltaTime: deltaTime, world: world) skungx = skungx + deltaTime if skungx >= 1 { skungx = fmod(skungx, 1.0) skungFrom = skungTo skungTo = .lookAt(from: axisPos, to: colin.position + .up) } skung = skungFrom.slerp(skungTo, skungx.smoothStep()) if let pad = GamePad.current?.state { if pad.down(.north) { axisPos += .forward * skung * deltaTime } } if Input.instance.keyboard.keyPressed(.c) { drawEdges = !drawEdges } } func draw(render: inout Renderer, deltaTime: Float, aspectRatio aspect: Float) { render.setProjection(matrix: .perspective( fovY: Float.rad(fromDeg: colin.fov), aspect: aspect, zNear: 0.1, zFar: 4000.0)) render.setView(matrix: colin.transform) var env = Environment() let drawRanges = { [render](range: any Sequence) in for i in range { let subMesh = worldModel.subMeshes[i] render.setMaterial(worldModel.materials[subMesh.material]) render.draw(mesh: worldModel, subMesh: subMesh, environment: env) } } if colin.position.x < 14 { drawRanges([ 0, 1, 2, 6 ]) } else { drawRanges(3...5) } //print(Mat4f.rotate(yawPitch: colin.angle) * -Vec3f.Z) env.addDirectionalLight(direction: -.init(-0.6199881, 0.7049423, 0.34448668), colour: .white) render.setMaterial(.init( //specular: .init(grey: 0.5), specular: .white, gloss: 1, texture: axisAlbedo.id)) render.draw(mesh: axisModel, model: .translate(axisPos) * Mat4f(quat: skung), environment: env) render.setMaterial(.init( diffuse: XnaColour.DarkGray.lighten(by: -0.1), //specular: .init(grey: 0.9), specular: .white, emmision: XnaColour.Green.mix(with: .black, 0.876), gloss: 20, texture: rockAlbedo.id)) render.draw(mesh: rockModel, model: .translate(.init(27.622196, 0.8187093, -19.366903)), environment: env) if drawEdges { world.draw(render, position: colin.position) } } }