Updating README.org to explain new project, tweak speed constants, new gifs
This commit is contained in:
parent
dad5943ff5
commit
b1e2ef2261
106
README.org
106
README.org
@ -1,39 +1,105 @@
|
||||
### FPS Scene
|
||||
#+OPTIONS: toc:nil
|
||||
|
||||
You can walk around the scene with simple FPS controls.
|
||||
Open `scene.html` with an http server, you can use the following;
|
||||
* FP Rendering Engine
|
||||
** TL;DR
|
||||
Graphics + Web + Functional Programming
|
||||
|
||||
```python3 -m http.server 8000```
|
||||
[[https://ferano.io/3d-fp/][Play it here]]
|
||||
|
||||
Unfortunately, elm-reactor has issues with loading obj files so that's why the
|
||||
python server is needed.
|
||||
** About
|
||||
The goal of this project is to learn about the intersection of 3 different
|
||||
topics; graphics, web, and functional programming. The FP acronym refers to both
|
||||
the fact that it's a *F*irst *P*erson camera, as well as being implemented using
|
||||
*F*unctional *P*rogramming. It uses Elm with WebGL to create a 3D first-person
|
||||
scene implementing several lower level graphics techniques including matrix
|
||||
transformations to model parent/child local transforms, texture mapping, and
|
||||
basic lighting with shaders.
|
||||
|
||||

|
||||
I worked on this project for a few weeks in 2019, however, it was just thrown
|
||||
into a git repo without much consideration, along with [[https://git.ferano.io/JosephFerano/pqtorusknot][this]] project. I felt this
|
||||
deserved a little bit more TLC, so I decided to spruce it up a little bit and
|
||||
move it to its own repository. Here's the original [[https://github.com/JosephFerano/elm-graphics][project]].
|
||||
|
||||
** Showcase
|
||||
|
||||
*** First Person Camera
|
||||
[[file:screenshots/play1.gif]]
|
||||
|
||||
[[https://ferano.io/3d-fp/play1.mp4][Higher Resolution Version]]
|
||||
*** Sextus
|
||||
[[file:screenshots/sextus.gif]]
|
||||
|
||||
[[https://ferano.io/3d-fp/sextus.mp4][Higher Resolution Version]]
|
||||
|
||||
|
||||
##### Controls
|
||||
** Building with Elm 0.18.0
|
||||
To install the binaries manually, follow this short guide; - [[https://sirfitz.medium.com/install-elm-0-18-0-in-2021-3f64ce298801][Install Binaries]]
|
||||
|
||||
Mouse - Look Rotation
|
||||
If you want to use =npm= instead; - =npm install -g elm@elm0.18.0=
|
||||
|
||||
WASD - Player movement
|
||||
If you use =npm=, note that you will likely need an older version of Node.js, so
|
||||
it is recommended to use [[https://github.com/nvm-sh/nvm][nvm]] for that. I have not attempted this method
|
||||
personally, fyi.
|
||||
|
||||
◀ ▼ ▲ ▶ - Move the Robot
|
||||
Once you have the Elm compiler, go ahead and run
|
||||
|
||||
N and M - Rotate robot left and right
|
||||
=elm make Scene.elm=
|
||||
|
||||
Y and H - Rotate robot arm up and down
|
||||
And that should first pull in all the dependencies then generate an =index.html=
|
||||
file.
|
||||
|
||||
U and J - Rotate robot hand up and down
|
||||
*** Issues with dependencies
|
||||
One of the dependencies of this project, =Zinggi/elm-obj-loader=, is getting a 404
|
||||
when Elm tries to pull in all the deps during compilation. Therefore this
|
||||
dependency will be included in version control, on the off chance someone
|
||||
actually wants to build this.
|
||||
|
||||
** Running
|
||||
In order to be able to load the textures and models, the files must be served by
|
||||
an HTTP server because of browser security, see [[https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy][SOP]] and [[https://developer.mozilla.org/en-US/docs/Glossary/CORS][CORS]] if curious.
|
||||
|
||||
### PQTorusknot
|
||||
You can use ~elm-reactor~, run the command and open up your browser to
|
||||
~https://localhost:8000~ and then click on ~Scene.elm~ in the nice project webview
|
||||
provided. If you don't want to do that and have Python 3 installed, run =python3
|
||||
-m http.server=, but make sure to compile with the ~elm make Scene.elm~ command
|
||||
first.
|
||||
|
||||
Either open up `torus.html`, or use the command `elm-reactor`, if you want to be able to modify the source file and compile;
|
||||
** How to Play
|
||||
You can walk around the scene and also control the robot which I have named
|
||||
Emperor Sextus, Conqueror of the Luddites.
|
||||
|
||||
https://guide.elm-lang.org/install.html
|
||||
*** Keybindings
|
||||
- Look Around: =Mouse=
|
||||
|
||||
Alternatively, here's the Ellie link
|
||||
- FPS Movement: =WASD=
|
||||
|
||||
https://ellie-app.com/vVTgpBj77ra1
|
||||
- Robot Movement: =◀ ▼ ▲ ▶=
|
||||
|
||||

|
||||
- Rotate Robot: =N | M=
|
||||
|
||||
- Rotate Robot Arm: =H | J=
|
||||
|
||||
- Rotate Robot Hand: =Y | U=
|
||||
|
||||
** Takeaways
|
||||
The Elm WebGL library provides a few abstractions (namely =WebGL.Entity=) that
|
||||
help reduce some of the boilerplate usually associated with creating a WebGL
|
||||
application from scratch. While it was useful for the purposes of this
|
||||
prototype, it remains to be seen if it would scale if this would become a proper
|
||||
3D rendering engine.
|
||||
|
||||
Despite what might be potentially undiscovered performance issues, Elm was
|
||||
pleasant to work with, and it sold me two ideas; functional programming and
|
||||
minimalism. The touted safety and correctness were noticeable, the learning
|
||||
curve wasn't as steep, and using the Elm debugger to be able to step back in
|
||||
time through the game was eye-opening in showing what's possible when you
|
||||
architect your state management with immutability in mind. It would be
|
||||
interesting to see if a modern game engine could switch between the functional,
|
||||
immutable data structures in a debug context and the cache-friendly mutable data
|
||||
structures for improved performance in a release build. Thus boosting
|
||||
productivity during development, while still remaining performant in the hands
|
||||
of players.
|
||||
|
||||
** License
|
||||
This project is licensed under the terms of the MIT license. For more
|
||||
information, see the included LICENSE file.
|
||||
|
13
Scene.elm
13
Scene.elm
@ -107,7 +107,7 @@ update msg model =
|
||||
(model.keys.a , model.keys.s , model.keys.w , model.keys.d)
|
||||
model.lookDir
|
||||
model.pos
|
||||
0.08
|
||||
0.11
|
||||
, robot = updateRobot model dt
|
||||
, rot = model.rot + 0.001 * dt}
|
||||
WindowResized size -> { model | winSize = size }
|
||||
@ -126,15 +126,16 @@ update msg model =
|
||||
|
||||
updateRobot: Model -> Time -> Robot
|
||||
updateRobot { robot , keys } dt =
|
||||
let rr part = part + dt * 0.005
|
||||
rl part = part - dt * 0.005
|
||||
let rotSpeed = 0.003
|
||||
rr part = part + dt * rotSpeed
|
||||
rl part = part - dt * rotSpeed
|
||||
rot = radians robot.rot
|
||||
in { pos =
|
||||
movePos
|
||||
(keys.left, keys.down, keys.up, keys.right)
|
||||
(vec3 (sin rot) (sin rot) (cos rot))
|
||||
robot.pos
|
||||
0.03
|
||||
0.05
|
||||
, rot = if keys.n then rr robot.rot else if keys.m then rl robot.rot else robot.rot
|
||||
, armRot =
|
||||
let angle = if keys.j then rr robot.armRot else if keys.h then rl robot.armRot else robot.armRot
|
||||
@ -168,8 +169,8 @@ getRobot model =
|
||||
|> Mat4.inverse |> Maybe.withDefault Mat4.identity
|
||||
|> Mat4.mul (Mat4.makeTranslate3 0 0 0.6)
|
||||
|> Mat4.mul arm
|
||||
in [ getEntity3 model (body |> Mat4.scale3 0.5 0.5 0.5) cube Color.blue
|
||||
, getEntity3 model (arm |> Mat4.scale3 0.2 0.2 0.5) cube Color.green
|
||||
in [ getEntity3 model (body |> Mat4.scale3 0.5 0.5 0.5) cube Color.blue
|
||||
, getEntity3 model (arm |> Mat4.scale3 0.2 0.2 0.5) cube Color.green
|
||||
, getEntity3 model (hand |> Mat4.scale3 0.15 0.15 0.45) cube Color.red
|
||||
] |> List.concat
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 488 KiB |
BIN
screenshots/play1.gif
Normal file
BIN
screenshots/play1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 MiB |
BIN
screenshots/sextus.gif
Normal file
BIN
screenshots/sextus.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 554 KiB |
Loading…
x
Reference in New Issue
Block a user