From f5a304e4f24ac52ead2cda74bcca445bebeaa492 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 13 Feb 2019 21:27:47 -0400 Subject: [PATCH] Importing code from previous merged project --- .gitignore | 12 +++ README.org | 39 ++++++++ Torus.elm | 253 +++++++++++++++++++++++++++++++++++++++++++++++ elm-package.json | 19 ++++ 4 files changed, 323 insertions(+) create mode 100644 .gitignore create mode 100644 README.org create mode 100644 Torus.elm create mode 100644 elm-package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..88a5828 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +/assg3-distrib/ +elm-stuff/build-artifacts/ +*.pdf +*.log +*.swp +*.suo +*.html +presentation/ +final/ +.idea/ +*.zip +elm-stuff/ diff --git a/README.org b/README.org new file mode 100644 index 0000000..fbd99c2 --- /dev/null +++ b/README.org @@ -0,0 +1,39 @@ +### FPS Scene + +You can walk around the scene with simple FPS controls. +Open `scene.html` with an http server, you can use the following; + +```python3 -m http.server 8000``` + +Unfortunately, elm-reactor has issues with loading obj files so that's why the +python server is needed. + +![alt text](screenshots/elm-fps.png "FPS Scene") + + +##### Controls + +Mouse - Look Rotation + +WASD - Player movement + +◀ ▼ ▲ ▶ - Move the Robot + +N and M - Rotate robot left and right + +Y and H - Rotate robot arm up and down + +U and J - Rotate robot hand up and down + + +### PQTorusknot + +Either open up `torus.html`, or use the command `elm-reactor`, if you want to be able to modify the source file and compile; + +https://guide.elm-lang.org/install.html + +Alternatively, here's the Ellie link + +https://ellie-app.com/vVTgpBj77ra1 + +![alt text](screenshots/elm-knot.png "PQ Torus Knot") diff --git a/Torus.elm b/Torus.elm new file mode 100644 index 0000000..959c03e --- /dev/null +++ b/Torus.elm @@ -0,0 +1,253 @@ +module Torus exposing (..) + +import Html exposing (Html) +import Html.Attributes exposing (width, height, style) +import AnimationFrame +import Time exposing (Time) +import Math.Matrix4 as Mat4 exposing (Mat4) +import Math.Vector2 as Vec2 exposing (vec2, Vec2) +import Math.Vector3 as Vec3 exposing (vec3, Vec3) +import Math.Vector4 as Vec4 exposing (vec4, Vec4) +import WebGL exposing (Mesh, Shader) +import Color exposing (..) +import Window +import WebGL.Texture as Texture exposing (..) +import Task exposing (..) + +main : Program Never Model Msg +main = Html.program + { init = init + , view = view + , update = update + , subscriptions = subscriptions } + +type alias Attributes = { position : Vec3 , normal : Vec3 } + +type Msg + = Animate Time + | WindowResized Window.Size + +type alias Model = + { p : Float + , q : Float +-- , mesh : Mesh Attributes + , time : Float + , winSize : Window.Size } + +init: ( Model , Cmd Msg ) +init = + -- ( { p = 1 , q = 0 , time = 0.0 , winSize = (Window.Size 1 1) + ( { p = 12 , q = 29 , time = 0.0 , winSize = (Window.Size 1 1) +-- , mesh = (torusPoints 2 15 |> torusShell) + } + , Cmd.batch [ Task.perform WindowResized Window.size ] ) + + +subscriptions: Model -> Sub Msg +subscriptions _ = + Sub.batch + [ AnimationFrame.diffs Animate + , Window.resizes WindowResized ] + +update: Msg -> Model -> (Model , Cmd Msg) +update msg model = + let m = case msg of + Animate dt -> +-- { model | time = model.time + dt * 0.001 } + { model | time = model.time + dt * 0.001 , p = model.p + 0.008 , q = model.q + 0.004} +-- Animate dt -> model + + WindowResized size -> { model | winSize = size } + in ( m , Cmd.none ) + +view: Model -> Html Msg +view model = + WebGL.toHtml + [ width model.winSize.width + , height model.winSize.height + , style [ ( "display" , "block") , ( "background" , "black" ) ] ] + ([ WebGL.entity + diffuseVS + diffuseFS +-- model.mesh +-- (constructTorus model) + (constructTorus2 model) + (DiffuseColor + (Mat4.makePerspective + 50 + (toFloat model.winSize.width / toFloat model.winSize.height) + 0.01 + 1000) + (Mat4.makeLookAt (vec3 0 0 5) (vec3 0 0 0) (vec3 0 1 0)) + (Mat4.makeRotate (model.time * 0.5) (vec3 1 1 1 ) ) +-- (Mat4.makeRotate (pi) (vec3 0.3 0.5 1 ) ) +-- Mat4.identity + (colorToVec3 Color.red) +-- (colorToVec3 Color.darkGrey) +-- (colorToVec3 Color.white) + (vec3 1 1 1) + (vec3 1 1 1) + (vec3 1 1 1) + 1.0) ] ) + +totalLinePoints = 100 +ringRadius = 0.15 +ringVerts = 18 + +constructTorus: Model -> Mesh Attributes +constructTorus model = + let points = torusPoints model.p model.q |> makePairs + rings = torusRings points |> List.concatMap makePairs + in points ++ rings |> toLines +-- in points |> toLines + + +constructTorus2: Model -> Mesh Attributes +constructTorus2 model = + torusPoints model.p model.q + |> makePairs + |> torusRings + |> torusTris + |> withTris +-- |> wireframe |> List.map (\ x -> toAttributes x Vec3.i) |> WebGL.lineStrip + +withTris: List (Vec3 , Vec3 , Vec3) -> Mesh Attributes +withTris tris = + tris + |> List.map (\ (v1, v2, v3) -> + let n = Vec3.cross (Vec3.sub v1 v2) (Vec3.sub v3 v1) |> Vec3.normalize + in (toAttributes v1 n, toAttributes v2 n, toAttributes v3 n)) + |> WebGL.triangles + +torusPoints: Float -> Float -> List Vec3 +torusPoints p q = + interpolatedCircle totalLinePoints + |> List.map + (\ t -> + let r = 0.5 * (2 + sin (q * t)) + in vec3 + (cos (t * p) * r) + (cos (t * q) * r * 0.5) + (sin (t * p) * r) ) + + +torusRings: List (Vec3, Vec3) -> List (List Vec3) +torusRings verts = + verts + |> List.map + (\ (p1, p2)-> + (List.map circlePoint <| interpolatedCircle ringVerts) + |> List.map (\ p -> + let (mid , dir) = (Vec3.add p1 p2 |> Vec3.scale 0.5 , Vec3.sub p2 p1 |> Vec3.normalize) + p_ = Vec3.toRecord p + dir_ = Vec3.toRecord dir + u = Vec3.cross dir Vec3.j |> Vec3.normalize + v = Vec3.cross dir u |> Vec3.normalize + point = Vec3.add (Vec3.scale p_.x u) (Vec3.scale p_.y v) |> Vec3.scale ringRadius + in Vec3.add point mid)) + +torusTris: List (List Vec3) -> List (Vec3 , Vec3 , Vec3) +torusTris rings = + makePairs rings + |> List.concatMap + (\ (rs1 , rs2) -> + List.map2 (,) (makePairs rs1) (makePairs rs2) + |> List.concatMap + (\ (pair1 , pair2) -> + let a = Tuple.first pair1 + b = Tuple.second pair1 + c = Tuple.first pair2 + d = Tuple.second pair2 + in [ (a , b , c) , (d , c , b) ] ) ) + +wireframe: List (Vec3 , Vec3 , Vec3) -> List Vec3 +wireframe tris = + List.foldl (\ (v1, v2, v3) acc -> acc ++ [ v1 , v2 , v3 ] ) [] tris + +circlePoint: Float -> Vec3 +circlePoint x = vec3 (cos x) (sin x) 0 + +makePairs: List a -> List (a ,a) +makePairs ps = List.map2 (,) ps (List.drop 1 ps) + +closedPairs: List a -> List (a ,a) +closedPairs xs = + List.map2 (,) + xs + (case List.head xs of + Just x -> List.append (List.drop 1 xs) [ x ] + Nothing -> [] + ) + +toLines: List (Vec3 , Vec3) -> Mesh Attributes +toLines vs = List.map (\ (v1 , v2) -> (toAttributes v1 Vec3.i , toAttributes v2 Vec3.i) ) vs |> WebGL.lines + +interpolatedCircle: Int -> List Float +interpolatedCircle steps = + List.range 0 steps + |> List.map (\ step -> (pi * 2 / (toFloat steps) * (toFloat step) ) ) + +toAttributes: Vec3 -> Vec3 -> Attributes +toAttributes v n = Attributes v n + + +colorToVec3: Color -> Vec3 +colorToVec3 color = + let to01 x = toFloat x / 255 + c = Color.toRgb color + in vec3 (to01 c.red) (to01 c.green) (to01 c.blue) + +type alias DiffuseColor = + { projection : Mat4 + , view : Mat4 + , model : Mat4 + , color : Vec3 + , ambient : Vec3 + , diffuse : Vec3 + , specular : Vec3 + , shininess : Float } + + +diffuseVS: Shader { position : Vec3 , normal : Vec3 } DiffuseColor { vlightWeight : Vec3 } +diffuseVS = + [glsl| + attribute vec3 position; + attribute vec3 normal; + uniform mat4 projection; + uniform mat4 view; + uniform mat4 model; + uniform vec3 ambient; + uniform vec3 diffuse; + uniform vec3 specular; + uniform float shininess; + varying vec3 vlightWeight; + + void main() + { + gl_Position = projection * view * model * vec4(position, 1.0); + + vec3 lightDir = normalize(vec3(0.0, -0.5, -0.5)); + vec4 norm = model * vec4(normal, 0.0); + vec3 n = norm.xyz; + float dir = max(dot(n, lightDir), 0.0); + float v = 0.5; + vlightWeight = diffuse * dir + vec3(v, v, v); + } + |] + +diffuseFS: Shader {} DiffuseColor { vlightWeight : Vec3 } +diffuseFS = + [glsl| + + precision mediump float; + uniform vec3 color; + varying vec3 vlightWeight; + + void main() + { + gl_FragColor = vec4(color * vlightWeight, 1.0); + } + |] + + + diff --git a/elm-package.json b/elm-package.json new file mode 100644 index 0000000..85715a5 --- /dev/null +++ b/elm-package.json @@ -0,0 +1,19 @@ +{ + "version": "1.0.0", + "summary": "PQ Torus Knot", + "repository": "https://github.com/user/project.git", + "license": "MIT", + "source-directories": [ + "." + ], + "exposed-modules": [], + "dependencies": { + "elm-community/linear-algebra": "3.1.2 <= v < 4.0.0", + "elm-community/webgl": "2.0.5 <= v < 3.0.0", + "elm-lang/animation-frame": "1.0.1 <= v < 2.0.0", + "elm-lang/core": "5.1.1 <= v < 6.0.0", + "elm-lang/window": "1.0.1 <= v < 2.0.0", + "elm-lang/html": "2.0.0 <= v < 3.0.0" + }, + "elm-version": "0.18.0 <= v < 0.19.0" +}