Introduce sprite variables
This commit is contained in:
parent
55e4dabea9
commit
6d311f04d6
28
bot/bot.rkt
28
bot/bot.rkt
|
@ -19,25 +19,27 @@
|
||||||
|
|
||||||
(define (bouncy-box)
|
(define (bouncy-box)
|
||||||
(define me (symbol->string (strong-gensym 'user)))
|
(define me (symbol->string (strong-gensym 'user)))
|
||||||
(define start-time (current-inexact-milliseconds))
|
|
||||||
(define-field deadline start-time)
|
(define x (* (- (random) 0.5) 100))
|
||||||
(define-field x (* (- (random) 0.5) 100))
|
|
||||||
(define y0 (+ 1.0 (* (random) 10)))
|
(define y0 (+ 1.0 (* (random) 10)))
|
||||||
(define-field y y0)
|
(define z (* (- (random) 0.5) 100))
|
||||||
(define-field z (* (- (random) 0.5) 100))
|
|
||||||
(at ds
|
|
||||||
(on (asserted (LaterThan (deadline)))
|
|
||||||
(deadline (+ (deadline) (/ 1000 10)))
|
|
||||||
(y (+ y0 (cos (/ (- (deadline) start-time) 1000.0 (/ 1 2 pi)))))))
|
|
||||||
(define r (random))
|
(define r (random))
|
||||||
(define g (random))
|
(define g (random))
|
||||||
(define b (random))
|
(define b (random))
|
||||||
|
|
||||||
|
(define-field y y0)
|
||||||
|
(define start-time (current-inexact-milliseconds))
|
||||||
|
(define-field deadline start-time)
|
||||||
|
(at ds
|
||||||
|
(on (asserted (LaterThan (deadline)))
|
||||||
|
(deadline (+ (deadline) (/ 1000 30)))
|
||||||
|
(y (+ y0 (cos (/ (- (deadline) start-time) 1000.0 (/ 1 2 pi)))))))
|
||||||
|
|
||||||
(at scene
|
(at scene
|
||||||
(assert (Sprite me (Move (Vector3 (x) (y) (z))
|
(assert (Variable me 'y (y)))
|
||||||
(Color-opaque r g b (Box)))))
|
(assert (Sprite me '(y) (Move (ImmediateVector3 x 'y z) (Color-opaque r g b (Box)))))))
|
||||||
))
|
|
||||||
|
|
||||||
(for [(i 100)] (bouncy-box)))))
|
(for [(i 100)] (bouncy-box)))))
|
||||||
|
|
||||||
(run-tcp-client-relay ds #:hostname "vr.demo.leastfixedpoint.com" #:port 9001
|
(run-tcp-client-relay ds #:hostname "localhost" #;"vr.demo.leastfixedpoint.com" #:port 9001
|
||||||
#:import (lambda (v) (on-connected (embedded-value v))))))
|
#:import (lambda (v) (on-connected (embedded-value v))))))
|
||||||
|
|
|
@ -59,7 +59,10 @@
|
||||||
((and dest
|
((and dest
|
||||||
(record
|
(record
|
||||||
'gravity
|
'gravity
|
||||||
(list (app shapes:parse-Vector3 (and ?direction (not (== eof)))))))
|
(list
|
||||||
|
(app
|
||||||
|
shapes:parse-LiteralVector3
|
||||||
|
(and ?direction (not (== eof)))))))
|
||||||
(Gravity ?direction))
|
(Gravity ?direction))
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-Gravity! (parse-success-or-error 'parse-Gravity parse-Gravity))
|
(define parse-Gravity! (parse-success-or-error 'parse-Gravity parse-Gravity))
|
||||||
|
@ -89,7 +92,9 @@
|
||||||
(list
|
(list
|
||||||
(and ?name (? string?))
|
(and ?name (? string?))
|
||||||
(app parse-PortalDestination (and ?destination (not (== eof))))
|
(app parse-PortalDestination (and ?destination (not (== eof))))
|
||||||
(app shapes:parse-Vector3 (and ?position (not (== eof)))))))
|
(app
|
||||||
|
shapes:parse-LiteralVector3
|
||||||
|
(and ?position (not (== eof)))))))
|
||||||
(Portal ?name ?destination ?position))
|
(Portal ?name ?destination ?position))
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-Portal! (parse-success-or-error 'parse-Portal parse-Portal))
|
(define parse-Portal! (parse-success-or-error 'parse-Portal parse-Portal))
|
||||||
|
|
|
@ -172,21 +172,21 @@
|
||||||
(record
|
(record
|
||||||
'scale
|
'scale
|
||||||
(list
|
(list
|
||||||
(app parse-Vector3 (and ?v (not (== eof))))
|
(app parse-LiteralVector3 (and ?v (not (== eof))))
|
||||||
(app parse-CSGExpr (and ?shape (not (== eof)))))))
|
(app parse-CSGExpr (and ?shape (not (== eof)))))))
|
||||||
(CSGExpr-scale ?v ?shape))
|
(CSGExpr-scale ?v ?shape))
|
||||||
((and dest
|
((and dest
|
||||||
(record
|
(record
|
||||||
'move
|
'move
|
||||||
(list
|
(list
|
||||||
(app parse-Vector3 (and ?v (not (== eof))))
|
(app parse-LiteralVector3 (and ?v (not (== eof))))
|
||||||
(app parse-CSGExpr (and ?shape (not (== eof)))))))
|
(app parse-CSGExpr (and ?shape (not (== eof)))))))
|
||||||
(CSGExpr-move ?v ?shape))
|
(CSGExpr-move ?v ?shape))
|
||||||
((and dest
|
((and dest
|
||||||
(record
|
(record
|
||||||
'rotate
|
'rotate
|
||||||
(list
|
(list
|
||||||
(app parse-Vector3 (and ?v (not (== eof))))
|
(app parse-LiteralVector3 (and ?v (not (== eof))))
|
||||||
(app parse-CSGExpr (and ?shape (not (== eof)))))))
|
(app parse-CSGExpr (and ?shape (not (== eof)))))))
|
||||||
(CSGExpr-rotate ?v ?shape))
|
(CSGExpr-rotate ?v ?shape))
|
||||||
((and dest
|
((and dest
|
||||||
|
@ -235,9 +235,9 @@
|
||||||
(record
|
(record
|
||||||
'color
|
'color
|
||||||
(list
|
(list
|
||||||
(exact->inexact (*->preserve ?r))
|
(*->preserve ?r)
|
||||||
(exact->inexact (*->preserve ?g))
|
(*->preserve ?g)
|
||||||
(exact->inexact (*->preserve ?b))
|
(*->preserve ?b)
|
||||||
(*->preserve ?shape))))))))
|
(*->preserve ?shape))))))))
|
||||||
(struct
|
(struct
|
||||||
Color-transparent
|
Color-transparent
|
||||||
|
@ -253,10 +253,10 @@
|
||||||
(record
|
(record
|
||||||
'color
|
'color
|
||||||
(list
|
(list
|
||||||
(exact->inexact (*->preserve ?r))
|
(*->preserve ?r)
|
||||||
(exact->inexact (*->preserve ?g))
|
(*->preserve ?g)
|
||||||
(exact->inexact (*->preserve ?b))
|
(*->preserve ?b)
|
||||||
(exact->inexact (*->preserve ?alpha))
|
(*->preserve ?alpha)
|
||||||
(*->preserve ?shape))))))))
|
(*->preserve ?shape))))))))
|
||||||
(define (parse-Color input)
|
(define (parse-Color input)
|
||||||
(match
|
(match
|
||||||
|
@ -265,23 +265,53 @@
|
||||||
(record
|
(record
|
||||||
'color
|
'color
|
||||||
(list
|
(list
|
||||||
(and ?r (? flonum?))
|
(app parse-DoubleValue (and ?r (not (== eof))))
|
||||||
(and ?g (? flonum?))
|
(app parse-DoubleValue (and ?g (not (== eof))))
|
||||||
(and ?b (? flonum?))
|
(app parse-DoubleValue (and ?b (not (== eof))))
|
||||||
(app parse-Shape (and ?shape (not (== eof)))))))
|
(app parse-Shape (and ?shape (not (== eof)))))))
|
||||||
(Color-opaque ?r ?g ?b ?shape))
|
(Color-opaque ?r ?g ?b ?shape))
|
||||||
((and dest
|
((and dest
|
||||||
(record
|
(record
|
||||||
'color
|
'color
|
||||||
(list
|
(list
|
||||||
(and ?r (? flonum?))
|
(app parse-DoubleValue (and ?r (not (== eof))))
|
||||||
(and ?g (? flonum?))
|
(app parse-DoubleValue (and ?g (not (== eof))))
|
||||||
(and ?b (? flonum?))
|
(app parse-DoubleValue (and ?b (not (== eof))))
|
||||||
(and ?alpha (? flonum?))
|
(app parse-DoubleValue (and ?alpha (not (== eof))))
|
||||||
(app parse-Shape (and ?shape (not (== eof)))))))
|
(app parse-Shape (and ?shape (not (== eof)))))))
|
||||||
(Color-transparent ?r ?g ?b ?alpha ?shape))
|
(Color-transparent ?r ?g ?b ?alpha ?shape))
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-Color! (parse-success-or-error 'parse-Color parse-Color))
|
(define parse-Color! (parse-success-or-error 'parse-Color parse-Color))
|
||||||
|
(define (DoubleValue? p)
|
||||||
|
(or (DoubleValue-immediate? p) (DoubleValue-reference? p)))
|
||||||
|
(struct
|
||||||
|
DoubleValue-immediate
|
||||||
|
(value)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match
|
||||||
|
preservable
|
||||||
|
((DoubleValue-immediate src) (exact->inexact (*->preserve src)))))))
|
||||||
|
(struct
|
||||||
|
DoubleValue-reference
|
||||||
|
(value)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match preservable ((DoubleValue-reference src) (*->preserve src))))))
|
||||||
|
(define (parse-DoubleValue input)
|
||||||
|
(match
|
||||||
|
input
|
||||||
|
((and dest (? flonum?)) (DoubleValue-immediate dest))
|
||||||
|
((and dest (? symbol?)) (DoubleValue-reference dest))
|
||||||
|
(_ eof)))
|
||||||
|
(define parse-DoubleValue!
|
||||||
|
(parse-success-or-error 'parse-DoubleValue parse-DoubleValue))
|
||||||
(struct
|
(struct
|
||||||
External
|
External
|
||||||
(path)
|
(path)
|
||||||
|
@ -324,7 +354,19 @@
|
||||||
(define parse-Floor! (parse-success-or-error 'parse-Floor parse-Floor))
|
(define parse-Floor! (parse-success-or-error 'parse-Floor parse-Floor))
|
||||||
(struct
|
(struct
|
||||||
Ground
|
Ground
|
||||||
(size)
|
()
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match preservable ((Ground) (record 'ground (list)))))))
|
||||||
|
(define (parse-Ground input)
|
||||||
|
(match input ((and dest (record 'ground (list))) (Ground)) (_ eof)))
|
||||||
|
(define parse-Ground! (parse-success-or-error 'parse-Ground parse-Ground))
|
||||||
|
(struct
|
||||||
|
ImmediateQuaternion
|
||||||
|
(a b c d)
|
||||||
#:transparent
|
#:transparent
|
||||||
#:methods
|
#:methods
|
||||||
gen:preservable
|
gen:preservable
|
||||||
|
@ -332,17 +374,84 @@
|
||||||
(define (->preserve preservable)
|
(define (->preserve preservable)
|
||||||
(match
|
(match
|
||||||
preservable
|
preservable
|
||||||
((Ground ?size) (record 'ground (list (*->preserve ?size))))))))
|
((ImmediateQuaternion ?a ?b ?c ?d)
|
||||||
(define (parse-Ground input)
|
(record
|
||||||
|
'q
|
||||||
|
(list
|
||||||
|
(*->preserve ?a)
|
||||||
|
(*->preserve ?b)
|
||||||
|
(*->preserve ?c)
|
||||||
|
(*->preserve ?d))))))))
|
||||||
|
(define (parse-ImmediateQuaternion input)
|
||||||
(match
|
(match
|
||||||
input
|
input
|
||||||
((and dest
|
((and dest
|
||||||
(record
|
(record
|
||||||
'ground
|
'q
|
||||||
(list (app parse-Vector2 (and ?size (not (== eof)))))))
|
(list
|
||||||
(Ground ?size))
|
(app parse-DoubleValue (and ?a (not (== eof))))
|
||||||
|
(app parse-DoubleValue (and ?b (not (== eof))))
|
||||||
|
(app parse-DoubleValue (and ?c (not (== eof))))
|
||||||
|
(app parse-DoubleValue (and ?d (not (== eof)))))))
|
||||||
|
(ImmediateQuaternion ?a ?b ?c ?d))
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-Ground! (parse-success-or-error 'parse-Ground parse-Ground))
|
(define parse-ImmediateQuaternion!
|
||||||
|
(parse-success-or-error
|
||||||
|
'parse-ImmediateQuaternion
|
||||||
|
parse-ImmediateQuaternion))
|
||||||
|
(struct
|
||||||
|
ImmediateVector2
|
||||||
|
(x y)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match
|
||||||
|
preservable
|
||||||
|
((ImmediateVector2 ?x ?y)
|
||||||
|
(record 'v (list (*->preserve ?x) (*->preserve ?y))))))))
|
||||||
|
(define (parse-ImmediateVector2 input)
|
||||||
|
(match
|
||||||
|
input
|
||||||
|
((and dest
|
||||||
|
(record
|
||||||
|
'v
|
||||||
|
(list
|
||||||
|
(app parse-DoubleValue (and ?x (not (== eof))))
|
||||||
|
(app parse-DoubleValue (and ?y (not (== eof)))))))
|
||||||
|
(ImmediateVector2 ?x ?y))
|
||||||
|
(_ eof)))
|
||||||
|
(define parse-ImmediateVector2!
|
||||||
|
(parse-success-or-error 'parse-ImmediateVector2 parse-ImmediateVector2))
|
||||||
|
(struct
|
||||||
|
ImmediateVector3
|
||||||
|
(x y z)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match
|
||||||
|
preservable
|
||||||
|
((ImmediateVector3 ?x ?y ?z)
|
||||||
|
(record
|
||||||
|
'v
|
||||||
|
(list (*->preserve ?x) (*->preserve ?y) (*->preserve ?z))))))))
|
||||||
|
(define (parse-ImmediateVector3 input)
|
||||||
|
(match
|
||||||
|
input
|
||||||
|
((and dest
|
||||||
|
(record
|
||||||
|
'v
|
||||||
|
(list
|
||||||
|
(app parse-DoubleValue (and ?x (not (== eof))))
|
||||||
|
(app parse-DoubleValue (and ?y (not (== eof))))
|
||||||
|
(app parse-DoubleValue (and ?z (not (== eof)))))))
|
||||||
|
(ImmediateVector3 ?x ?y ?z))
|
||||||
|
(_ eof)))
|
||||||
|
(define parse-ImmediateVector3!
|
||||||
|
(parse-success-or-error 'parse-ImmediateVector3 parse-ImmediateVector3))
|
||||||
(struct
|
(struct
|
||||||
Light
|
Light
|
||||||
(v)
|
(v)
|
||||||
|
@ -364,6 +473,37 @@
|
||||||
(Light ?v))
|
(Light ?v))
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-Light! (parse-success-or-error 'parse-Light parse-Light))
|
(define parse-Light! (parse-success-or-error 'parse-Light parse-Light))
|
||||||
|
(struct
|
||||||
|
LiteralVector3
|
||||||
|
(x y z)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match
|
||||||
|
preservable
|
||||||
|
((LiteralVector3 ?x ?y ?z)
|
||||||
|
(record
|
||||||
|
'v
|
||||||
|
(list
|
||||||
|
(exact->inexact (*->preserve ?x))
|
||||||
|
(exact->inexact (*->preserve ?y))
|
||||||
|
(exact->inexact (*->preserve ?z)))))))))
|
||||||
|
(define (parse-LiteralVector3 input)
|
||||||
|
(match
|
||||||
|
input
|
||||||
|
((and dest
|
||||||
|
(record
|
||||||
|
'v
|
||||||
|
(list
|
||||||
|
(and ?x (? flonum?))
|
||||||
|
(and ?y (? flonum?))
|
||||||
|
(and ?z (? flonum?)))))
|
||||||
|
(LiteralVector3 ?x ?y ?z))
|
||||||
|
(_ eof)))
|
||||||
|
(define parse-LiteralVector3!
|
||||||
|
(parse-success-or-error 'parse-LiteralVector3 parse-LiteralVector3))
|
||||||
(define (Mesh? p)
|
(define (Mesh? p)
|
||||||
(or (Mesh-Sphere? p)
|
(or (Mesh-Sphere? p)
|
||||||
(Mesh-Box? p)
|
(Mesh-Box? p)
|
||||||
|
@ -508,36 +648,32 @@
|
||||||
(define (parse-Plane input)
|
(define (parse-Plane input)
|
||||||
(match input ((and dest (record 'plane (list))) (Plane)) (_ eof)))
|
(match input ((and dest (record 'plane (list))) (Plane)) (_ eof)))
|
||||||
(define parse-Plane! (parse-success-or-error 'parse-Plane parse-Plane))
|
(define parse-Plane! (parse-success-or-error 'parse-Plane parse-Plane))
|
||||||
|
(define (Quaternion? p)
|
||||||
|
(or (Quaternion-immediate? p) (Quaternion-reference? p)))
|
||||||
(struct
|
(struct
|
||||||
Quaternion
|
Quaternion-immediate
|
||||||
(a b c d)
|
(value)
|
||||||
#:transparent
|
#:transparent
|
||||||
#:methods
|
#:methods
|
||||||
gen:preservable
|
gen:preservable
|
||||||
((define/generic *->preserve ->preserve)
|
((define/generic *->preserve ->preserve)
|
||||||
(define (->preserve preservable)
|
(define (->preserve preservable)
|
||||||
(match
|
(match preservable ((Quaternion-immediate src) (*->preserve src))))))
|
||||||
preservable
|
(struct
|
||||||
((Quaternion ?a ?b ?c ?d)
|
Quaternion-reference
|
||||||
(record
|
(value)
|
||||||
'q
|
#:transparent
|
||||||
(list
|
#:methods
|
||||||
(exact->inexact (*->preserve ?a))
|
gen:preservable
|
||||||
(exact->inexact (*->preserve ?b))
|
((define/generic *->preserve ->preserve)
|
||||||
(exact->inexact (*->preserve ?c))
|
(define (->preserve preservable)
|
||||||
(exact->inexact (*->preserve ?d)))))))))
|
(match preservable ((Quaternion-reference src) (*->preserve src))))))
|
||||||
(define (parse-Quaternion input)
|
(define (parse-Quaternion input)
|
||||||
(match
|
(match
|
||||||
input
|
input
|
||||||
((and dest
|
((app parse-ImmediateQuaternion (and dest (not (== eof))))
|
||||||
(record
|
(Quaternion-immediate dest))
|
||||||
'q
|
((and dest (? symbol?)) (Quaternion-reference dest))
|
||||||
(list
|
|
||||||
(and ?a (? flonum?))
|
|
||||||
(and ?b (? flonum?))
|
|
||||||
(and ?c (? flonum?))
|
|
||||||
(and ?d (? flonum?)))))
|
|
||||||
(Quaternion ?a ?b ?c ?d))
|
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-Quaternion!
|
(define parse-Quaternion!
|
||||||
(parse-success-or-error 'parse-Quaternion parse-Quaternion))
|
(parse-success-or-error 'parse-Quaternion parse-Quaternion))
|
||||||
|
@ -873,7 +1009,7 @@
|
||||||
(define parse-Sphere! (parse-success-or-error 'parse-Sphere parse-Sphere))
|
(define parse-Sphere! (parse-success-or-error 'parse-Sphere parse-Sphere))
|
||||||
(struct
|
(struct
|
||||||
Sprite
|
Sprite
|
||||||
(name shape)
|
(name formals shape)
|
||||||
#:transparent
|
#:transparent
|
||||||
#:methods
|
#:methods
|
||||||
gen:preservable
|
gen:preservable
|
||||||
|
@ -881,8 +1017,13 @@
|
||||||
(define (->preserve preservable)
|
(define (->preserve preservable)
|
||||||
(match
|
(match
|
||||||
preservable
|
preservable
|
||||||
((Sprite ?name ?shape)
|
((Sprite ?name ?formals ?shape)
|
||||||
(record 'sprite (list (*->preserve ?name) (*->preserve ?shape))))))))
|
(record
|
||||||
|
'sprite
|
||||||
|
(list
|
||||||
|
(*->preserve ?name)
|
||||||
|
(for/list ((item (in-list ?formals))) (*->preserve item))
|
||||||
|
(*->preserve ?shape))))))))
|
||||||
(define (parse-Sprite input)
|
(define (parse-Sprite input)
|
||||||
(match
|
(match
|
||||||
input
|
input
|
||||||
|
@ -891,8 +1032,9 @@
|
||||||
'sprite
|
'sprite
|
||||||
(list
|
(list
|
||||||
(and ?name (? string?))
|
(and ?name (? string?))
|
||||||
|
(list (and ?formals (? symbol?)) ...)
|
||||||
(app parse-Shape (and ?shape (not (== eof)))))))
|
(app parse-Shape (and ?shape (not (== eof)))))))
|
||||||
(Sprite ?name ?shape))
|
(Sprite ?name ?formals ?shape))
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-Sprite! (parse-success-or-error 'parse-Sprite parse-Sprite))
|
(define parse-Sprite! (parse-success-or-error 'parse-Sprite parse-Sprite))
|
||||||
(struct
|
(struct
|
||||||
|
@ -962,7 +1104,7 @@
|
||||||
(*->preserve ?path)
|
(*->preserve ?path)
|
||||||
(*->preserve ?scale)
|
(*->preserve ?scale)
|
||||||
(*->preserve ?offset)
|
(*->preserve ?offset)
|
||||||
(exact->inexact (*->preserve ?alpha))))))))
|
(*->preserve ?alpha)))))))
|
||||||
(define (parse-TextureSpec input)
|
(define (parse-TextureSpec input)
|
||||||
(match
|
(match
|
||||||
input
|
input
|
||||||
|
@ -978,7 +1120,7 @@
|
||||||
(and ?path (? string?))
|
(and ?path (? string?))
|
||||||
(app parse-Vector2 (and ?scale (not (== eof))))
|
(app parse-Vector2 (and ?scale (not (== eof))))
|
||||||
(app parse-Vector2 (and ?offset (not (== eof))))
|
(app parse-Vector2 (and ?offset (not (== eof))))
|
||||||
(and ?alpha (? flonum?))))
|
(app parse-DoubleValue (and ?alpha (not (== eof))))))
|
||||||
(TextureSpec-uvAlpha ?path ?scale ?offset ?alpha))
|
(TextureSpec-uvAlpha ?path ?scale ?offset ?alpha))
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-TextureSpec!
|
(define parse-TextureSpec!
|
||||||
|
@ -1006,8 +1148,8 @@
|
||||||
(define parse-Touchable!
|
(define parse-Touchable!
|
||||||
(parse-success-or-error 'parse-Touchable parse-Touchable))
|
(parse-success-or-error 'parse-Touchable parse-Touchable))
|
||||||
(struct
|
(struct
|
||||||
Vector2
|
Variable
|
||||||
(x y)
|
(spriteName variable value)
|
||||||
#:transparent
|
#:transparent
|
||||||
#:methods
|
#:methods
|
||||||
gen:preservable
|
gen:preservable
|
||||||
|
@ -1015,47 +1157,79 @@
|
||||||
(define (->preserve preservable)
|
(define (->preserve preservable)
|
||||||
(match
|
(match
|
||||||
preservable
|
preservable
|
||||||
((Vector2 ?x ?y)
|
((Variable ?spriteName ?variable ?value)
|
||||||
(record
|
(record
|
||||||
'v
|
'variable
|
||||||
(list
|
(list
|
||||||
(exact->inexact (*->preserve ?x))
|
(*->preserve ?spriteName)
|
||||||
(exact->inexact (*->preserve ?y)))))))))
|
(*->preserve ?variable)
|
||||||
(define (parse-Vector2 input)
|
(*->preserve ?value))))))))
|
||||||
(match
|
(define (parse-Variable input)
|
||||||
input
|
|
||||||
((and dest (record 'v (list (and ?x (? flonum?)) (and ?y (? flonum?)))))
|
|
||||||
(Vector2 ?x ?y))
|
|
||||||
(_ eof)))
|
|
||||||
(define parse-Vector2! (parse-success-or-error 'parse-Vector2 parse-Vector2))
|
|
||||||
(struct
|
|
||||||
Vector3
|
|
||||||
(x y z)
|
|
||||||
#:transparent
|
|
||||||
#:methods
|
|
||||||
gen:preservable
|
|
||||||
((define/generic *->preserve ->preserve)
|
|
||||||
(define (->preserve preservable)
|
|
||||||
(match
|
|
||||||
preservable
|
|
||||||
((Vector3 ?x ?y ?z)
|
|
||||||
(record
|
|
||||||
'v
|
|
||||||
(list
|
|
||||||
(exact->inexact (*->preserve ?x))
|
|
||||||
(exact->inexact (*->preserve ?y))
|
|
||||||
(exact->inexact (*->preserve ?z)))))))))
|
|
||||||
(define (parse-Vector3 input)
|
|
||||||
(match
|
(match
|
||||||
input
|
input
|
||||||
((and dest
|
((and dest
|
||||||
(record
|
(record
|
||||||
'v
|
'variable
|
||||||
(list
|
(list
|
||||||
(and ?x (? flonum?))
|
(and ?spriteName (? string?))
|
||||||
(and ?y (? flonum?))
|
(and ?variable (? symbol?))
|
||||||
(and ?z (? flonum?)))))
|
?value)))
|
||||||
(Vector3 ?x ?y ?z))
|
(Variable ?spriteName ?variable ?value))
|
||||||
|
(_ eof)))
|
||||||
|
(define parse-Variable!
|
||||||
|
(parse-success-or-error 'parse-Variable parse-Variable))
|
||||||
|
(define (Vector2? p) (or (Vector2-immediate? p) (Vector2-reference? p)))
|
||||||
|
(struct
|
||||||
|
Vector2-immediate
|
||||||
|
(value)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match preservable ((Vector2-immediate src) (*->preserve src))))))
|
||||||
|
(struct
|
||||||
|
Vector2-reference
|
||||||
|
(value)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match preservable ((Vector2-reference src) (*->preserve src))))))
|
||||||
|
(define (parse-Vector2 input)
|
||||||
|
(match
|
||||||
|
input
|
||||||
|
((app parse-ImmediateVector2 (and dest (not (== eof))))
|
||||||
|
(Vector2-immediate dest))
|
||||||
|
((and dest (? symbol?)) (Vector2-reference dest))
|
||||||
|
(_ eof)))
|
||||||
|
(define parse-Vector2! (parse-success-or-error 'parse-Vector2 parse-Vector2))
|
||||||
|
(define (Vector3? p) (or (Vector3-immediate? p) (Vector3-reference? p)))
|
||||||
|
(struct
|
||||||
|
Vector3-immediate
|
||||||
|
(value)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match preservable ((Vector3-immediate src) (*->preserve src))))))
|
||||||
|
(struct
|
||||||
|
Vector3-reference
|
||||||
|
(value)
|
||||||
|
#:transparent
|
||||||
|
#:methods
|
||||||
|
gen:preservable
|
||||||
|
((define/generic *->preserve ->preserve)
|
||||||
|
(define (->preserve preservable)
|
||||||
|
(match preservable ((Vector3-reference src) (*->preserve src))))))
|
||||||
|
(define (parse-Vector3 input)
|
||||||
|
(match
|
||||||
|
input
|
||||||
|
((app parse-ImmediateVector3 (and dest (not (== eof))))
|
||||||
|
(Vector3-immediate dest))
|
||||||
|
((and dest (? symbol?)) (Vector3-reference dest))
|
||||||
(_ eof)))
|
(_ eof)))
|
||||||
(define parse-Vector3!
|
(define parse-Vector3!
|
||||||
(parse-success-or-error 'parse-Vector3 parse-Vector3)))
|
(parse-success-or-error 'parse-Vector3 parse-Vector3)))
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
version 1 .
|
version 1 .
|
||||||
|
|
||||||
Portal = <portal @name string @destination PortalDestination @position shapes.Vector3> .
|
Portal = <portal @name string @destination PortalDestination @position shapes.LiteralVector3> .
|
||||||
PortalDestination =
|
PortalDestination =
|
||||||
/ @local #!any
|
/ @local #!any
|
||||||
/ @remote noise.Route
|
/ @remote noise.Route
|
||||||
.
|
.
|
||||||
|
|
||||||
Gravity = <gravity @direction shapes.Vector3> .
|
Gravity = <gravity @direction shapes.LiteralVector3> .
|
||||||
|
|
||||||
AmbientSound = <ambient-sound @name string @spec shapes.SoundSpec> .
|
AmbientSound = <ambient-sound @name string @spec shapes.SoundSpec> .
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
version 1 .
|
version 1 .
|
||||||
|
|
||||||
Sprite = <sprite @name string @shape Shape> .
|
Sprite = <sprite @name string @formals [symbol ...] @shape Shape> .
|
||||||
|
Variable = <variable @spriteName string @variable symbol @value any> .
|
||||||
|
|
||||||
Shape = Mesh / Light / Scale / Move / Rotate / @many [Shape ...] / Texture / Color / Sound / Name / Floor / Nonphysical / Touchable / CSG / Skybox .
|
Shape = Mesh / Light / Scale / Move / Rotate / @many [Shape ...] / Texture / Color / Sound / Name / Floor / Nonphysical / Touchable / CSG / Skybox .
|
||||||
|
|
||||||
|
@ -8,15 +9,23 @@ Mesh = Sphere / Box / Ground / Plane / External .
|
||||||
|
|
||||||
Sphere = <sphere> .
|
Sphere = <sphere> .
|
||||||
Box = <box> .
|
Box = <box> .
|
||||||
Ground = <ground @size Vector2> .
|
Ground = <ground> .
|
||||||
Plane = <plane> .
|
Plane = <plane> .
|
||||||
External = <external @path string> .
|
External = <external @path string> .
|
||||||
|
|
||||||
Light = <hemispheric-light @v Vector3> .
|
Light = <hemispheric-light @v Vector3> .
|
||||||
|
|
||||||
Vector2 = <v @x double @y double> .
|
DoubleValue = @immediate double / @reference symbol .
|
||||||
Vector3 = <v @x double @y double @z double> .
|
|
||||||
Quaternion = <q @a double @b double @c double @d double> .
|
ImmediateVector2 = <v @x DoubleValue @y DoubleValue> .
|
||||||
|
ImmediateVector3 = <v @x DoubleValue @y DoubleValue @z DoubleValue> .
|
||||||
|
ImmediateQuaternion = <q @a DoubleValue @b DoubleValue @c DoubleValue @d DoubleValue> .
|
||||||
|
|
||||||
|
LiteralVector3 = <v @x double @y double @z double> .
|
||||||
|
|
||||||
|
Vector2 = @immediate ImmediateVector2 / @reference symbol .
|
||||||
|
Vector3 = @immediate ImmediateVector3 / @reference symbol .
|
||||||
|
Quaternion = @immediate ImmediateQuaternion / @reference symbol .
|
||||||
|
|
||||||
Scale = <scale @v Vector3 @shape Shape> .
|
Scale = <scale @v Vector3 @shape Shape> .
|
||||||
Move = <move @v Vector3 @shape Shape> .
|
Move = <move @v Vector3 @shape Shape> .
|
||||||
|
@ -26,12 +35,12 @@ Texture = <texture @spec TextureSpec @shape Shape> .
|
||||||
TextureSpec =
|
TextureSpec =
|
||||||
/ @simple [@path string]
|
/ @simple [@path string]
|
||||||
/ @uv [@path string @scale Vector2 @offset Vector2]
|
/ @uv [@path string @scale Vector2 @offset Vector2]
|
||||||
/ @uvAlpha [@path string @scale Vector2 @offset Vector2 @alpha double]
|
/ @uvAlpha [@path string @scale Vector2 @offset Vector2 @alpha DoubleValue]
|
||||||
.
|
.
|
||||||
|
|
||||||
Color =
|
Color =
|
||||||
/ @opaque <color @r double @g double @b double @shape Shape>
|
/ @opaque <color @r DoubleValue @g DoubleValue @b DoubleValue @shape Shape>
|
||||||
/ @transparent <color @r double @g double @b double @alpha double @shape Shape>
|
/ @transparent <color @r DoubleValue @g DoubleValue @b DoubleValue @alpha DoubleValue @shape Shape>
|
||||||
.
|
.
|
||||||
|
|
||||||
Sound = <sound @spec SoundSpec @shape Shape> .
|
Sound = <sound @spec SoundSpec @shape Shape> .
|
||||||
|
@ -50,9 +59,9 @@ CSG = <csg @expr CSGExpr> .
|
||||||
|
|
||||||
CSGExpr =
|
CSGExpr =
|
||||||
/ <mesh @shape Mesh>
|
/ <mesh @shape Mesh>
|
||||||
/ <scale @v Vector3 @shape CSGExpr>
|
/ <scale @v LiteralVector3 @shape CSGExpr>
|
||||||
/ <move @v Vector3 @shape CSGExpr>
|
/ <move @v LiteralVector3 @shape CSGExpr>
|
||||||
/ <rotate @v Vector3 @shape CSGExpr>
|
/ <rotate @v LiteralVector3 @shape CSGExpr>
|
||||||
/ <subtract [@base CSGExpr @more CSGExpr ...]>
|
/ <subtract [@base CSGExpr @more CSGExpr ...]>
|
||||||
/ <union [@base CSGExpr @more CSGExpr ...]>
|
/ <union [@base CSGExpr @more CSGExpr ...]>
|
||||||
/ <intersect [@base CSGExpr @more CSGExpr ...]>
|
/ <intersect [@base CSGExpr @more CSGExpr ...]>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<sprite "light" <hemispheric-light <v 0.1 1.0 0.0>>>
|
<sprite "light" [] <hemispheric-light <v 0.1 1.0 0.0>>>
|
||||||
<gravity <v 0.0 -9.81 0.0>>
|
<gravity <v 0.0 -9.81 0.0>>
|
||||||
<sprite "sky" <skybox "textures/Daylight Box UV_0">>
|
<sprite "sky" [] <skybox "textures/Daylight Box UV_0">>
|
||||||
|
|
||||||
<sprite "ground"
|
<sprite "ground" []
|
||||||
<texture ["textures/grass-256x256.jpg"
|
<texture ["textures/grass-256x256.jpg"
|
||||||
<v 100.0 100.0>
|
<v 100.0 100.0>
|
||||||
<v 0.0 0.0>]
|
<v 0.0 0.0>]
|
||||||
<floor <ground <v 300.0 300.0>>>>>
|
<floor <scale <v 300.0 1.0 300.0> <ground>>>>>
|
||||||
|
|
||||||
<sprite "box"
|
<sprite "box" []
|
||||||
<move <v -6.0 1.0 8.0>
|
<move <v -6.0 1.0 8.0>
|
||||||
<scale <v 10.0 0.1 10.0>
|
<scale <v 10.0 0.1 10.0>
|
||||||
<texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
<texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
||||||
|
@ -17,20 +17,20 @@
|
||||||
0.75]
|
0.75]
|
||||||
<floor <box>>>>>>
|
<floor <box>>>>>>
|
||||||
|
|
||||||
<sprite "box2"
|
<sprite "box2" []
|
||||||
<move <v -500.0 0.5 3.0>
|
<move <v -500.0 0.5 3.0>
|
||||||
<floor
|
<floor
|
||||||
<color 0.0 0.0 1.0 1.0
|
<color 0.0 0.0 1.0 1.0
|
||||||
<scale <v 1000.0 1.0 1.0> <box>>>>>>
|
<scale <v 1000.0 1.0 1.0> <box>>>>>>
|
||||||
|
|
||||||
<Exit "p" "lobby">
|
<Exit "p" "lobby">
|
||||||
<sprite "p"
|
<sprite "p" []
|
||||||
<move <v -999.5 2.0 3.0>
|
<move <v -999.5 2.0 3.0>
|
||||||
<rotate <v 0.0 -0.25 0.0>
|
<rotate <v 0.0 -0.25 0.0>
|
||||||
<color 1.0 0.0 1.0
|
<color 1.0 0.0 1.0
|
||||||
<touchable <scale <v 1.0 2.0 1.0> <plane>>>>>>>
|
<touchable <scale <v 1.0 2.0 1.0> <plane>>>>>>>
|
||||||
|
|
||||||
<sprite "steps"
|
<sprite "steps" []
|
||||||
<color 0.0 0.5 0.0
|
<color 0.0 0.5 0.0
|
||||||
<move <v 0.0 0.0 3.5>
|
<move <v 0.0 0.0 3.5>
|
||||||
<scale <v 1.0 1.0 3.0>
|
<scale <v 1.0 1.0 3.0>
|
||||||
|
@ -42,8 +42,9 @@
|
||||||
]>>>>>
|
]>>>>>
|
||||||
|
|
||||||
<Exit "door" "other">
|
<Exit "door" "other">
|
||||||
<sprite "door"
|
<variable "door" y 0.0>
|
||||||
<move <v -3.0 0.0 1.5>
|
<sprite "door" [y]
|
||||||
|
<move <v -3.0 y 1.5>
|
||||||
<rotate <v 0.0 -0.1 0.0> [
|
<rotate <v 0.0 -0.1 0.0> [
|
||||||
<scale <v 1.0 2.11 1.0>
|
<scale <v 1.0 2.11 1.0>
|
||||||
<texture ["textures/door1.jpg"]
|
<texture ["textures/door1.jpg"]
|
||||||
|
@ -52,7 +53,7 @@
|
||||||
]>>>
|
]>>>
|
||||||
|
|
||||||
<portal "door2" <route [<ws "wss://vr.demo.eighty-twenty.org/ws">]>>
|
<portal "door2" <route [<ws "wss://vr.demo.eighty-twenty.org/ws">]>>
|
||||||
<sprite "door2"
|
<sprite "door2" []
|
||||||
<move <v -5.0 0.0 1.5>
|
<move <v -5.0 0.0 1.5>
|
||||||
<rotate <v 0.0 -0.1 0.0> [
|
<rotate <v 0.0 -0.1 0.0> [
|
||||||
<scale <v 1.0 2.11 1.0>
|
<scale <v 1.0 2.11 1.0>
|
||||||
|
@ -61,14 +62,14 @@
|
||||||
<scale <v 1.0 2.11 0.1> <move <v 0.0 0.5 0.6> <box>>>
|
<scale <v 1.0 2.11 0.1> <move <v 0.0 0.5 0.6> <box>>>
|
||||||
]>>>
|
]>>>
|
||||||
|
|
||||||
<sprite "plans"
|
<sprite "plans" []
|
||||||
<texture ["plans/signal-2022-12-27-125451_002.jpeg"]
|
<texture ["plans/signal-2022-12-27-125451_002.jpeg"]
|
||||||
<move <v 0.0 1.0 -10.0>
|
<move <v 0.0 1.0 -10.0>
|
||||||
<rotate <v 0.1 0.0 0.0>
|
<rotate <v 0.1 0.0 0.0>
|
||||||
<scale <v 2.0 2.0 0.1>
|
<scale <v 2.0 2.0 0.1>
|
||||||
<box>>>>>>
|
<box>>>>>>
|
||||||
|
|
||||||
<sprite "tower"
|
<sprite "tower" []
|
||||||
<rotate <v 0.1 0.0 0.0>
|
<rotate <v 0.1 0.0 0.0>
|
||||||
<move <v -10.0 50.0 13.0>
|
<move <v -10.0 50.0 13.0>
|
||||||
<scale <v 3.0 100.0 3.0>
|
<scale <v 3.0 100.0 3.0>
|
||||||
|
@ -76,7 +77,7 @@
|
||||||
<color 0.5 0.5 0.0
|
<color 0.5 0.5 0.0
|
||||||
<box>>>>>>>
|
<box>>>>>>>
|
||||||
|
|
||||||
; <sprite "sponge"
|
; <sprite "sponge" []
|
||||||
; <move <v 4.0 1.6 0.0> [
|
; <move <v 4.0 1.6 0.0> [
|
||||||
; <scale <v 0.001 0.001 0.001>
|
; <scale <v 0.001 0.001 0.001>
|
||||||
; <external "objects/usnm_346-100k-obj/usnm_346-01-100k.obj">>
|
; <external "objects/usnm_346-100k-obj/usnm_346-01-100k.obj">>
|
||||||
|
@ -86,12 +87,12 @@
|
||||||
; <box>>>>
|
; <box>>>>
|
||||||
; ]>>
|
; ]>>
|
||||||
|
|
||||||
; <sprite "sofa"
|
; <sprite "sofa" []
|
||||||
; <rotate <v -0.125 0.5 0.0>
|
; <rotate <v -0.125 0.5 0.0>
|
||||||
; <scale <v 0.01 0.01 0.01>
|
; <scale <v 0.01 0.01 0.01>
|
||||||
; <external "objects/IKE020001_obj/IKEA-Arild_2_Seat_Sofa-3D.obj">>>>
|
; <external "objects/IKE020001_obj/IKEA-Arild_2_Seat_Sofa-3D.obj">>>>
|
||||||
|
|
||||||
<sprite "x"
|
<sprite "x" []
|
||||||
<move <v 10.0 1.6 -5.0>
|
<move <v 10.0 1.6 -5.0>
|
||||||
<texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
<texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
||||||
<v 1.0 3.0 1.0>
|
<v 1.0 3.0 1.0>
|
||||||
|
@ -105,7 +106,7 @@
|
||||||
>>>>>
|
>>>>>
|
||||||
|
|
||||||
; <Exit "y" "lobby">
|
; <Exit "y" "lobby">
|
||||||
; <sprite "y"
|
; <sprite "y" []
|
||||||
; <move <v 12.0 0.75 -5.0>
|
; <move <v 12.0 0.75 -5.0>
|
||||||
; <texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
; <texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
||||||
; <v 1.0 1.0 1.0>
|
; <v 1.0 1.0 1.0>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<sprite "light" <hemispheric-light <v 0.1 1.0 0.0>>>
|
<sprite "light" [] <hemispheric-light <v 0.1 1.0 0.0>>>
|
||||||
;<gravity <v 0.0 -9.81 0.0>>
|
;<gravity <v 0.0 -9.81 0.0>>
|
||||||
<sprite "sky" <skybox "textures/eso0932a">>
|
<sprite "sky" [] <skybox "textures/eso0932a">>
|
||||||
|
|
||||||
<ambient-sound "space" <loop "sounds/Space-atmosphere-sound/Space-atmosphere-sound.mp3">>
|
<ambient-sound "space" <loop "sounds/Space-atmosphere-sound/Space-atmosphere-sound.mp3">>
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
; <floor <ground <v 300.0 300.0>>>>>
|
; <floor <ground <v 300.0 300.0>>>>>
|
||||||
|
|
||||||
<Exit "home" "lobby" <v -2.5 0.0 0.5>>
|
<Exit "home" "lobby" <v -2.5 0.0 0.5>>
|
||||||
<sprite "home"
|
<sprite "home" []
|
||||||
<move <v 0.0 0.0 -2.0>
|
<move <v 0.0 0.0 -2.0>
|
||||||
<rotate <v 0.0 -0.5 0.0> [
|
<rotate <v 0.0 -0.5 0.0> [
|
||||||
<scale <v 1.0 2.11 1.0>
|
<scale <v 1.0 2.11 1.0>
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<scale <v 1.0 2.11 0.1> <move <v 0.0 0.5 0.6> <box>>>
|
<scale <v 1.0 2.11 0.1> <move <v 0.0 0.5 0.6> <box>>>
|
||||||
]>>>
|
]>>>
|
||||||
|
|
||||||
<sprite "x"
|
<sprite "x" []
|
||||||
<move <v 0.0 0.0 10.0>
|
<move <v 0.0 0.0 10.0>
|
||||||
<texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
<texture ["textures/oak-herringbone-5e80fb40b00c9-1200.jpg"
|
||||||
<v 1.0 3.0 1.0>
|
<v 1.0 3.0 1.0>
|
||||||
|
|
84
src/index.ts
84
src/index.ts
|
@ -1,4 +1,4 @@
|
||||||
import { is, fromJS, Dataflow, Dataspace, Embedded, Reader, Ref, Schemas, Sturdy, Turn } from "@syndicate-lang/core";
|
import { is, fromJS, Dataflow, Dataspace, Embedded, Ref, Schemas, Turn } from "@syndicate-lang/core";
|
||||||
import * as html from "@syndicate-lang/html";
|
import * as html from "@syndicate-lang/html";
|
||||||
import * as timer from "@syndicate-lang/timer";
|
import * as timer from "@syndicate-lang/timer";
|
||||||
import * as wsRelay from "@syndicate-lang/ws-relay";
|
import * as wsRelay from "@syndicate-lang/ws-relay";
|
||||||
|
@ -14,7 +14,7 @@ import {
|
||||||
Vector3,
|
Vector3,
|
||||||
} from '@babylonjs/core/Legacy/legacy';
|
} from '@babylonjs/core/Legacy/legacy';
|
||||||
|
|
||||||
import { activeFloorMeshes, activeTouchableMeshes, ShapeTree, v3, scale3, buildSound, builder as B } from './shapes.js';
|
import { activeFloorMeshes, activeTouchableMeshes, Environment, ShapeTree, buildSound, builder as B, u2, u3, u3v } from './shapes.js';
|
||||||
import { RunningEngine } from './engine.js';
|
import { RunningEngine } from './engine.js';
|
||||||
import { uuid } from './uuid.js';
|
import { uuid } from './uuid.js';
|
||||||
|
|
||||||
|
@ -22,13 +22,14 @@ assertion type SceneHandle(ds: Embedded<Ref>);
|
||||||
|
|
||||||
function interpretScene(myId: string, runningEngine: RunningEngine, rootMesh: Mesh, sceneDs: Ref) {
|
function interpretScene(myId: string, runningEngine: RunningEngine, rootMesh: Mesh, sceneDs: Ref) {
|
||||||
at sceneDs {
|
at sceneDs {
|
||||||
during Shapes.Sprite({ "name": $name: string }) => spawn named `sprite:${name}` {
|
during Shapes.Sprite({ "name": $name: string, "formals": $formals }) => spawn named `sprite:${name}` {
|
||||||
if (name === myId) {
|
if (name === myId) {
|
||||||
console.log('ignoring sprite', name);
|
console.log('ignoring sprite', name);
|
||||||
} else {
|
} else {
|
||||||
console.log('+shape', name);
|
console.log('+shape', name);
|
||||||
on stop console.log('-shape', name);
|
on stop console.log('-shape', name);
|
||||||
spriteMain(name, runningEngine, rootMesh, sceneDs);
|
const env = new Environment(name, formals as symbol[], sceneDs);
|
||||||
|
spriteMain(env, runningEngine, rootMesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,20 +43,20 @@ function interpretScene(myId: string, runningEngine: RunningEngine, rootMesh: Me
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function spriteMain(spriteName: string, runningEngine: RunningEngine, rootMesh: Mesh, sceneDs: Ref) {
|
function spriteMain(env: Environment, runningEngine: RunningEngine, rootMesh: Mesh) {
|
||||||
at sceneDs {
|
at env.sceneDs {
|
||||||
let currentShape = ShapeTree.empty(spriteName, runningEngine.scene);
|
let currentShape = ShapeTree.empty(env.spriteName, runningEngine.scene);
|
||||||
currentShape.rootnode.parent = rootMesh;
|
currentShape.rootnode.parent = rootMesh;
|
||||||
on stop currentShape.remove();
|
on stop currentShape.remove();
|
||||||
during Shapes.Sprite({ "name": spriteName, "shape": $shape: Shapes.Shape }) => {
|
during Shapes.Sprite({ "name": env.spriteName, "shape": $shape: Shapes.Shape }) => {
|
||||||
currentShape = currentShape.reconcile(spriteName, spriteName, shape);
|
currentShape = currentShape.reconcile(env, env.spriteName, shape);
|
||||||
currentShape.rootnode.parent = rootMesh;
|
currentShape.rootnode.parent = rootMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
during SceneProtocol.Gravity($direction: Shapes.Vector3) => {
|
during SceneProtocol.Gravity($direction: Shapes.LiteralVector3) => {
|
||||||
runningEngine.applyGravity = true;
|
runningEngine.applyGravity = true;
|
||||||
on stop runningEngine.applyGravity = false;
|
on stop runningEngine.applyGravity = false;
|
||||||
runningEngine.gravity = v3(direction);
|
runningEngine.gravity = new Vector3(direction.x, direction.y, direction.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,21 +102,23 @@ async function enterScene(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const currentPosition = () => Shapes.Vector3(runningEngine.position);
|
const TAU = 2 * Math.PI;
|
||||||
const currentRotation = () => Shapes.Vector3(runningEngine.rotation);
|
|
||||||
|
|
||||||
field position: Shapes.Vector3 = currentPosition();
|
const currentPosition = () => u3(runningEngine.position);
|
||||||
field rotation: Shapes.Vector3 = currentRotation();
|
const currentRotation = () => u3(runningEngine.rotation, 1/TAU);
|
||||||
|
|
||||||
|
field position: Shapes.ImmediateVector3 = currentPosition();
|
||||||
|
field rotation: Shapes.ImmediateVector3 = currentRotation();
|
||||||
|
|
||||||
const refreshPeriod = Math.floor(1000 / 10);
|
const refreshPeriod = Math.floor(1000 / 10);
|
||||||
at ds {
|
at ds {
|
||||||
on message timer.PeriodicTick(refreshPeriod) => {
|
on message timer.PeriodicTick(refreshPeriod) => {
|
||||||
const newPosition = currentPosition();
|
const newPosition = currentPosition();
|
||||||
const newRotation = currentRotation();
|
const newRotation = currentRotation();
|
||||||
if (!is(Shapes.fromVector3(position.value), Shapes.fromVector3(newPosition))) {
|
if (!is(Shapes.fromImmediateVector3(position.value), Shapes.fromImmediateVector3(newPosition))) {
|
||||||
position.value = newPosition;
|
position.value = newPosition;
|
||||||
}
|
}
|
||||||
if (!is(Shapes.fromVector3(rotation.value), Shapes.fromVector3(newRotation))) {
|
if (!is(Shapes.fromImmediateVector3(rotation.value), Shapes.fromImmediateVector3(newRotation))) {
|
||||||
rotation.value = newRotation;
|
rotation.value = newRotation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +131,7 @@ async function enterScene(
|
||||||
on asserted SceneProtocol.Portal({
|
on asserted SceneProtocol.Portal({
|
||||||
"name": o,
|
"name": o,
|
||||||
"destination": $dest: SceneProtocol.PortalDestination,
|
"destination": $dest: SceneProtocol.PortalDestination,
|
||||||
"position": $targetPosition: Shapes.Vector3,
|
"position": $targetPosition: Shapes.LiteralVector3,
|
||||||
}) => {
|
}) => {
|
||||||
const newPos = new Vector3(targetPosition.x,
|
const newPos = new Vector3(targetPosition.x,
|
||||||
targetPosition.y,
|
targetPosition.y,
|
||||||
|
@ -169,29 +172,46 @@ async function enterScene(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert Shapes.Sprite({
|
const _POS = Symbol.for('pos');
|
||||||
|
const _HEAD = Symbol.for('head');
|
||||||
|
const _BODY = Symbol.for('body');
|
||||||
|
|
||||||
|
assert Shapes.Variable({ spriteName: id, variable: _POS, value: Shapes.fromImmediateVector3(position.value) });
|
||||||
|
assert Shapes.Variable({ spriteName: id, variable: _HEAD, value: Shapes.fromImmediateVector3(rotation.value) });
|
||||||
|
assert Shapes.Variable({ spriteName: id, variable: _BODY, value: Shapes.fromImmediateVector3({
|
||||||
|
x: Shapes.DoubleValue.immediate(0),
|
||||||
|
y: rotation.value.y,
|
||||||
|
z: Shapes.DoubleValue.immediate(0),
|
||||||
|
}) });
|
||||||
|
|
||||||
|
assert (() => {
|
||||||
|
const s = Shapes.Sprite({
|
||||||
name: id,
|
name: id,
|
||||||
|
formals: [_POS, _HEAD, _BODY],
|
||||||
shape: B.nonphysical(
|
shape: B.nonphysical(
|
||||||
B.move(position.value, B.many([
|
B.move(Shapes.Vector3.reference(_POS), B.many([
|
||||||
B.move({ x: 0, y: -0.9, z: 0 },
|
B.move(u3v({x: 0, y: -0.9, z: 0}),
|
||||||
B.rotate(scale3({ x: 0, y: rotation.value.y, z: 0 }, 1 / (2 * Math.PI)),
|
B.rotate(Shapes.Vector3.reference(_BODY),
|
||||||
B.scale({ x: 0.4, y: 1.4, z: 0.1 }, B.box()))),
|
B.scale(u3v({x: 0.4, y: 1.4, z: 0.1}), B.box()))),
|
||||||
B.rotate(scale3(rotation.value, 1 / (2 * Math.PI)),
|
B.rotate(Shapes.Vector3.reference(_HEAD),
|
||||||
B.scale({ x: 0.15, y: 0.23, z: 0.18 }, B.many([
|
B.scale(u3v({x: 0.15, y: 0.23, z: 0.18}), B.many([
|
||||||
B.box(),
|
B.box(),
|
||||||
B.move({ x: 0, y: 0, z: 0.501 },
|
B.move(u3v({x: 0, y: 0, z: 0.501}),
|
||||||
B.texture(
|
B.texture(
|
||||||
Shapes.TextureSpec.uvAlpha({
|
Shapes.TextureSpec.uvAlpha({
|
||||||
path: `https://www.gravatar.com/avatar/${md5(new TextEncoder().encode(email.value.trim()))}?s=256&d=wavatar`,
|
path: `https://www.gravatar.com/avatar/${md5(new TextEncoder().encode(email.value.trim()))}?s=256&d=wavatar`,
|
||||||
scale: Shapes.Vector2({ x:1, y:1 }),
|
scale: Shapes.Vector2.immediate(u2({ x:1, y:1 })),
|
||||||
offset: Shapes.Vector2({ x:0, y:0 }),
|
offset: Shapes.Vector2.immediate(u2({ x:0, y:0 })),
|
||||||
alpha: 1
|
alpha: Shapes.DoubleValue.immediate(1),
|
||||||
}),
|
}),
|
||||||
B.rotate({ x: 0, y: 0.5, z: 0 },
|
B.rotate(u3v({ x: 0, y: 0.5, z: 0 }),
|
||||||
B.plane()))),
|
B.plane()))),
|
||||||
]))),
|
]))),
|
||||||
]))),
|
]))),
|
||||||
});
|
});
|
||||||
|
console.log(s);
|
||||||
|
return s;
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +285,7 @@ window.addEventListener('load', async () => {
|
||||||
Dataspace.boot(ds => {
|
Dataspace.boot(ds => {
|
||||||
html.boot(ds);
|
html.boot(ds);
|
||||||
timer.boot(ds);
|
timer.boot(ds);
|
||||||
wsRelay.boot(ds, false);
|
wsRelay.boot(ds, true);
|
||||||
wakeDetector.boot(ds);
|
wakeDetector.boot(ds);
|
||||||
bootApp(ds, runningEngine);
|
bootApp(ds, runningEngine);
|
||||||
});
|
});
|
||||||
|
|
213
src/shapes.ts
213
src/shapes.ts
|
@ -20,10 +20,46 @@ import {
|
||||||
Vector2,
|
Vector2,
|
||||||
Vector3,
|
Vector3,
|
||||||
} from '@babylonjs/core/Legacy/legacy';
|
} from '@babylonjs/core/Legacy/legacy';
|
||||||
import { KeyedDictionary, Value, is } from "@syndicate-lang/core";
|
import { Dataflow, IdentityMap, KeyedDictionary, Ref, Value, is } from "@syndicate-lang/core";
|
||||||
|
|
||||||
import * as Shapes from './gen/shapes.js';
|
import * as Shapes from './gen/shapes.js';
|
||||||
|
|
||||||
|
export class Environment {
|
||||||
|
fields = new IdentityMap<symbol, Dataflow.Field<Value<Ref>>>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public spriteName: string,
|
||||||
|
public formals: symbol[],
|
||||||
|
public sceneDs: Ref,
|
||||||
|
) {
|
||||||
|
formals.forEach(f => {
|
||||||
|
field v: Value<Ref> = false;
|
||||||
|
at this.sceneDs {
|
||||||
|
on asserted Shapes.Variable({
|
||||||
|
"spriteName": this.spriteName,
|
||||||
|
"variable": f,
|
||||||
|
"value": $newValue,
|
||||||
|
}) => {
|
||||||
|
console.log('Got value for', spriteName, f, newValue);
|
||||||
|
v.value = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.fields.set(f, v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
lookup(f: symbol, k: (v: Value<Ref>) => void) {
|
||||||
|
dataflow {
|
||||||
|
const v = this.fields.get(f);
|
||||||
|
if (v === void 0) throw new Error(`Lookup of ${f.description} in ${this.spriteName} failed`);
|
||||||
|
const w = v.value;
|
||||||
|
if (w !== false) k(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ValueK = (v: Value<Ref>) => void;
|
||||||
|
|
||||||
export const activeFloorMeshes: Array<AbstractMesh> = [];
|
export const activeFloorMeshes: Array<AbstractMesh> = [];
|
||||||
export const activeTouchableMeshes: Array<AbstractMesh> = [];
|
export const activeTouchableMeshes: Array<AbstractMesh> = [];
|
||||||
|
|
||||||
|
@ -50,13 +86,13 @@ export class ShapeTree<N extends Node = Node> {
|
||||||
return this.subnodes.then(ns => [this.rootnode, ... ns]);
|
return this.subnodes.then(ns => [this.rootnode, ... ns]);
|
||||||
}
|
}
|
||||||
|
|
||||||
reconcile(spriteName: string, name: string, shape: Shapes.Shape): ShapeTree {
|
reconcile(env: Environment, name: string, shape: Shapes.Shape): ShapeTree {
|
||||||
if (is(Shapes.fromShape(shape), this.shapePreserve)) {
|
if (is(Shapes.fromShape(shape), this.shapePreserve)) {
|
||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
this.remove();
|
this.remove();
|
||||||
return build(name, this.scene, shape, {
|
return build(env, name, this.scene, shape, {
|
||||||
spriteName: async m => m.rootnode.metadata.spriteName = spriteName,
|
spriteName: async m => m.rootnode.metadata.spriteName = env.spriteName,
|
||||||
collisions: async m => (await m.allnodes).forEach(n => n.checkCollisions = true),
|
collisions: async m => (await m.allnodes).forEach(n => n.checkCollisions = true),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -82,20 +118,64 @@ export class ShapeTree<N extends Node = Node> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function v2(v: Shapes.Vector2): Vector2 {
|
export function dv(env: Environment, v: Shapes.DoubleValue, k: (v: number) => void) {
|
||||||
return new Vector2(v.x, v.y);
|
switch (v._variant) {
|
||||||
|
case "immediate": k(v.value); break;
|
||||||
|
case "reference": env.lookup(v.value, k as ValueK); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function v3(v: Shapes.Vector3): Vector3 {
|
export function u2(v: {x: number, y: number}): Shapes.ImmediateVector2 {
|
||||||
return new Vector3(v.x, v.y, v.z);
|
return Shapes.ImmediateVector2({
|
||||||
|
x: Shapes.DoubleValue.immediate(v.x),
|
||||||
|
y: Shapes.DoubleValue.immediate(v.y),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scale3(v: Shapes.Vector3, scale: number): Shapes.Vector3 {
|
export function lv2(env: Environment, v: Shapes.ImmediateVector2, k: (v: Vector2) => void) {
|
||||||
return Shapes.Vector3({ x: v.x * scale, y: v.y * scale, z: v.z * scale });
|
dv(env, v.x, x => dv(env, v.y, y => k(new Vector2(x, y))));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function q(q: Shapes.Quaternion): Quaternion {
|
export function v2(env: Environment, v: Shapes.Vector2, k: (v: Vector2) => void) {
|
||||||
return new Quaternion(q.a, q.b, q.c, q.d);
|
switch (v._variant) {
|
||||||
|
case "immediate": lv2(env, v.value, k); break;
|
||||||
|
case "reference": env.lookup(v.value, v => lv2(env, Shapes.asImmediateVector2(v), k)); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function u3(v: {x: number, y: number, z: number}, scale = 1): Shapes.ImmediateVector3 {
|
||||||
|
return Shapes.ImmediateVector3({
|
||||||
|
x: Shapes.DoubleValue.immediate(v.x * scale),
|
||||||
|
y: Shapes.DoubleValue.immediate(v.y * scale),
|
||||||
|
z: Shapes.DoubleValue.immediate(v.z * scale),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function u3v(v: {x: number, y: number, z: number}, scale = 1): Shapes.Vector3 {
|
||||||
|
return Shapes.Vector3.immediate(u3(v, scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function lv3(env: Environment, v: Shapes.ImmediateVector3, k: (v: Vector3) => void) {
|
||||||
|
dv(env, v.x, x => dv(env, v.y, y => dv(env, v.z, z => k(new Vector3(x, y, z)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function v3(env: Environment, v: Shapes.Vector3, k: (v: Vector3) => void) {
|
||||||
|
switch (v._variant) {
|
||||||
|
case "immediate": lv3(env, v.value, k); break;
|
||||||
|
case "reference": env.lookup(v.value, v => lv3(env, Shapes.asImmediateVector3(v), k)); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function lq(env: Environment, q: Shapes.ImmediateQuaternion, k: (v: Quaternion) => void) {
|
||||||
|
dv(env, q.a, a => dv(env, q.b, b => dv(env, q.c, c => dv(env, q.d, d =>
|
||||||
|
k(new Quaternion(a, b, c, d))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function q(env: Environment, q: Shapes.Quaternion, k: (v: Quaternion) => void) {
|
||||||
|
switch (q._variant) {
|
||||||
|
case "immediate": lq(env, q.value, k); break;
|
||||||
|
case "reference": env.lookup(q.value, q => lq(env, Shapes.asImmediateQuaternion(q), k)); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MeshCustomizer = { [key: string]: ((m: ShapeTree<AbstractMesh>) => void) };
|
export type MeshCustomizer = { [key: string]: ((m: ShapeTree<AbstractMesh>) => void) };
|
||||||
|
@ -111,7 +191,7 @@ type CachedTexture = {
|
||||||
};
|
};
|
||||||
const textureCache = new KeyedDictionary<Value, CachedTexture>();
|
const textureCache = new KeyedDictionary<Value, CachedTexture>();
|
||||||
|
|
||||||
function buildTexture(name: string, scene: Scene, spec: Shapes.TextureSpec): CachedTexture {
|
function buildTexture(env: Environment, name: string, scene: Scene, spec: Shapes.TextureSpec): CachedTexture {
|
||||||
const cacheKey = Shapes.fromTextureSpec(spec);
|
const cacheKey = Shapes.fromTextureSpec(spec);
|
||||||
const entry = textureCache.get(cacheKey);
|
const entry = textureCache.get(cacheKey);
|
||||||
if (entry !== void 0) {
|
if (entry !== void 0) {
|
||||||
|
@ -125,18 +205,18 @@ function buildTexture(name: string, scene: Scene, spec: Shapes.TextureSpec): Cac
|
||||||
case "simple":
|
case "simple":
|
||||||
break;
|
break;
|
||||||
case "uvAlpha":
|
case "uvAlpha":
|
||||||
mat.alpha = spec.alpha;
|
mat.alpha = 0;
|
||||||
|
dv(env, spec.alpha, a => mat.alpha = a);
|
||||||
tex.hasAlpha = true;
|
tex.hasAlpha = true;
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
case "uv": {
|
case "uv":
|
||||||
const scale = v2(spec.scale);
|
v2(env, spec.scale, scale => v2(env, spec.offset, offset => {
|
||||||
const offset = v2(spec.offset);
|
tex.uScale = scale.x;
|
||||||
tex.uScale = scale.x;
|
tex.vScale = scale.y;
|
||||||
tex.vScale = scale.y;
|
tex.uOffset = offset.x;
|
||||||
tex.uOffset = offset.x;
|
tex.vOffset = offset.y;
|
||||||
tex.vOffset = offset.y;
|
}));
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const newEntry = {
|
const newEntry = {
|
||||||
key: cacheKey,
|
key: cacheKey,
|
||||||
|
@ -167,13 +247,7 @@ export function buildMesh(
|
||||||
switch (meshSpec._variant) {
|
switch (meshSpec._variant) {
|
||||||
case "Sphere": return { rootnode: MeshBuilder.CreateSphere(name, {}, scene) };
|
case "Sphere": return { rootnode: MeshBuilder.CreateSphere(name, {}, scene) };
|
||||||
case "Box": return { rootnode: MeshBuilder.CreateBox(name, {}, scene) };
|
case "Box": return { rootnode: MeshBuilder.CreateBox(name, {}, scene) };
|
||||||
case "Ground": {
|
case "Ground": return { rootnode: MeshBuilder.CreateGround(name, {}, scene ?? void 0) };
|
||||||
const v = v2(meshSpec.value.size);
|
|
||||||
return {
|
|
||||||
rootnode: MeshBuilder.CreateGround(
|
|
||||||
name, { width: v.x, height: v.y }, scene ?? void 0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "Plane": return { rootnode: MeshBuilder.CreatePlane(name, {}, scene) };
|
case "Plane": return { rootnode: MeshBuilder.CreatePlane(name, {}, scene) };
|
||||||
case "External": {
|
case "External": {
|
||||||
const rootnode = new Mesh(name, scene);
|
const rootnode = new Mesh(name, scene);
|
||||||
|
@ -210,7 +284,7 @@ export function buildSound(name: string, scene: Scene, spec: Shapes.SoundSpec, s
|
||||||
return new Sound(name, spec.url, scene, null, options);
|
return new Sound(name, spec.url, scene, null, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function build(name: string, scene: Scene, shape: Shapes.Shape, customize: MeshCustomizer): ShapeTree {
|
export function build(env: Environment, name: string, scene: Scene, shape: Shapes.Shape, customize: MeshCustomizer): ShapeTree {
|
||||||
switch (shape._variant) {
|
switch (shape._variant) {
|
||||||
case "Mesh": {
|
case "Mesh": {
|
||||||
const m = buildMesh(name, scene, shape.value);
|
const m = buildMesh(name, scene, shape.value);
|
||||||
|
@ -219,23 +293,23 @@ export function build(name: string, scene: Scene, shape: Shapes.Shape, customize
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Light":
|
case "Light": {
|
||||||
return new ShapeTree(
|
const light = new HemisphericLight(name, new Vector3(0, 1, 0), scene);
|
||||||
scene,
|
v3(env, shape.value.v, v => light.direction = v);
|
||||||
shape,
|
return new ShapeTree(scene, shape, light);
|
||||||
new HemisphericLight(name, v3(shape.value.v), scene));
|
}
|
||||||
|
|
||||||
case "Scale": {
|
case "Scale": {
|
||||||
const t = ShapeTree.transform(name, scene, shape);
|
const t = ShapeTree.transform(name, scene, shape);
|
||||||
t.rootnode.scaling = v3(shape.value.v);
|
v3(env, shape.value.v, v => t.rootnode.scaling = v);
|
||||||
build(name + '.inner', scene, shape.value.shape, customize).parent = t;
|
build(env, name + '.inner', scene, shape.value.shape, customize).parent = t;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Move": {
|
case "Move": {
|
||||||
const t = ShapeTree.transform(name, scene, shape);
|
const t = ShapeTree.transform(name, scene, shape);
|
||||||
t.rootnode.position = v3(shape.value.v);
|
v3(env, shape.value.v, v => t.rootnode.position = v);
|
||||||
build(name + '.inner', scene, shape.value.shape, customize).parent = t;
|
build(env, name + '.inner', scene, shape.value.shape, customize).parent = t;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,28 +317,30 @@ export function build(name: string, scene: Scene, shape: Shapes.Shape, customize
|
||||||
const t = ShapeTree.transform(name, scene, shape);
|
const t = ShapeTree.transform(name, scene, shape);
|
||||||
switch (shape.value._variant) {
|
switch (shape.value._variant) {
|
||||||
case "euler":
|
case "euler":
|
||||||
t.rootnode.rotation = v3(shape.value.v);
|
v3(env, shape.value.v, v => {
|
||||||
t.rootnode.rotation.scaleInPlace(2 * Math.PI);
|
t.rootnode.rotation = v;
|
||||||
|
t.rootnode.rotation.scaleInPlace(2 * Math.PI);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case "quaternion":
|
case "quaternion":
|
||||||
t.rootnode.rotationQuaternion = q(shape.value.q);
|
q(env, shape.value.q, q => t.rootnode.rotationQuaternion = q);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
build(name + '.inner', scene, shape.value.shape, customize).parent = t;
|
build(env, name + '.inner', scene, shape.value.shape, customize).parent = t;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "many": {
|
case "many": {
|
||||||
const t = ShapeTree.transform(name, scene, shape);
|
const t = ShapeTree.transform(name, scene, shape);
|
||||||
shape.value.forEach((s, i) => {
|
shape.value.forEach((s, i) => {
|
||||||
build(name + '[' + i + ']', scene, s, customize).parent = t;
|
build(env, name + '[' + i + ']', scene, s, customize).parent = t;
|
||||||
});
|
});
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Texture": {
|
case "Texture": {
|
||||||
const entry = buildTexture(name + '.texture', scene, shape.value.spec);
|
const entry = buildTexture(env, name + '.texture', scene, shape.value.spec);
|
||||||
const t = build(name + '.inner', scene, shape.value.shape, {
|
const t = build(env, name + '.inner', scene, shape.value.shape, {
|
||||||
... customize,
|
... customize,
|
||||||
material: async m => (await m.allnodes).forEach(n => n.material = entry.material),
|
material: async m => (await m.allnodes).forEach(n => n.material = entry.material),
|
||||||
});
|
});
|
||||||
|
@ -274,9 +350,13 @@ export function build(name: string, scene: Scene, shape: Shapes.Shape, customize
|
||||||
|
|
||||||
case "Color": {
|
case "Color": {
|
||||||
const mat = new StandardMaterial(name + '.texture', scene);
|
const mat = new StandardMaterial(name + '.texture', scene);
|
||||||
mat.diffuseColor = new Color3(shape.value.r, shape.value.g, shape.value.b);
|
dv(env, shape.value.r, r =>
|
||||||
if (shape.value._variant === "transparent") mat.alpha = shape.value.alpha;
|
dv(env, shape.value.g, g =>
|
||||||
const t = build(name + '.inner', scene, shape.value.shape, {
|
dv(env, shape.value.b, b => mat.diffuseColor = new Color3(r, g, b))));
|
||||||
|
if (shape.value._variant === "transparent") {
|
||||||
|
dv(env, shape.value.alpha, a => mat.alpha = a);
|
||||||
|
}
|
||||||
|
const t = build(env, name + '.inner', scene, shape.value.shape, {
|
||||||
... customize,
|
... customize,
|
||||||
material: async m => (await m.allnodes).forEach(n => n.material = mat),
|
material: async m => (await m.allnodes).forEach(n => n.material = mat),
|
||||||
});
|
});
|
||||||
|
@ -286,7 +366,7 @@ export function build(name: string, scene: Scene, shape: Shapes.Shape, customize
|
||||||
|
|
||||||
case "Sound": {
|
case "Sound": {
|
||||||
const sound = buildSound(name + ".sound", scene, shape.value.spec, true);
|
const sound = buildSound(name + ".sound", scene, shape.value.spec, true);
|
||||||
const t = build(name + ".inner", scene, shape.value.shape, {
|
const t = build(env, name + ".inner", scene, shape.value.shape, {
|
||||||
... customize,
|
... customize,
|
||||||
sound: async m => sound.attachToMesh(m.rootnode),
|
sound: async m => sound.attachToMesh(m.rootnode),
|
||||||
});
|
});
|
||||||
|
@ -295,10 +375,10 @@ export function build(name: string, scene: Scene, shape: Shapes.Shape, customize
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Name":
|
case "Name":
|
||||||
return build(name + '.' + shape.value.base, scene, shape.value.shape, customize);
|
return build(env, name + '.' + shape.value.base, scene, shape.value.shape, customize);
|
||||||
|
|
||||||
case "Floor":
|
case "Floor":
|
||||||
return build(name, scene, shape.value.shape, {
|
return build(env, name, scene, shape.value.shape, {
|
||||||
... customize,
|
... customize,
|
||||||
floor: async m => {
|
floor: async m => {
|
||||||
const nodes = await m.allnodes;
|
const nodes = await m.allnodes;
|
||||||
|
@ -311,13 +391,13 @@ export function build(name: string, scene: Scene, shape: Shapes.Shape, customize
|
||||||
});
|
});
|
||||||
|
|
||||||
case "Nonphysical":
|
case "Nonphysical":
|
||||||
return build(name, scene, shape.value.shape, {
|
return build(env, name, scene, shape.value.shape, {
|
||||||
... customize,
|
... customize,
|
||||||
collisions: async m => (await m.allnodes).forEach(n => n.checkCollisions = false),
|
collisions: async m => (await m.allnodes).forEach(n => n.checkCollisions = false),
|
||||||
});
|
});
|
||||||
|
|
||||||
case "Touchable":
|
case "Touchable":
|
||||||
return build(name, scene, shape.value.shape, {
|
return build(env, name, scene, shape.value.shape, {
|
||||||
... customize,
|
... customize,
|
||||||
touchable: async m => {
|
touchable: async m => {
|
||||||
const nodes = await m.allnodes;
|
const nodes = await m.allnodes;
|
||||||
|
@ -426,23 +506,30 @@ export function buildCSG(name: string, scene: Scene, expr: Shapes.CSGExpr): Buil
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const builder: { [key: string]: (... args: any[]) => Shapes.Shape } = {
|
export const builder = {
|
||||||
sphere: () => Shapes.Shape.Mesh(Shapes.Mesh.Sphere(Shapes.Sphere())),
|
sphere: () => Shapes.Shape.Mesh(Shapes.Mesh.Sphere(Shapes.Sphere())),
|
||||||
box: () => Shapes.Shape.Mesh(Shapes.Mesh.Box(Shapes.Box())),
|
box: () => Shapes.Shape.Mesh(Shapes.Mesh.Box(Shapes.Box())),
|
||||||
plane: () => Shapes.Shape.Mesh(Shapes.Mesh.Plane(Shapes.Plane())),
|
plane: () => Shapes.Shape.Mesh(Shapes.Mesh.Plane(Shapes.Plane())),
|
||||||
ground: (v: Shapes.Vector2) => Shapes.Shape.Mesh(Shapes.Mesh.Ground(Shapes.Ground(Shapes.Vector2(v)))),
|
ground: () => Shapes.Shape.Mesh(Shapes.Mesh.Ground(Shapes.Ground())),
|
||||||
light: (v: Shapes.Vector3) => Shapes.Shape.Light(Shapes.Light(Shapes.Vector3(v))),
|
light: (v: Shapes.Vector3) => Shapes.Shape.Light(Shapes.Light(v)),
|
||||||
scale: (v: Shapes.Vector3, shape: Shapes.Shape) => Shapes.Shape.Scale(Shapes.Scale({ v: Shapes.Vector3(v), shape })),
|
scale: (v: Shapes.Vector3, shape: Shapes.Shape) => Shapes.Shape.Scale(Shapes.Scale({ v, shape })),
|
||||||
move: (v: Shapes.Vector3, shape: Shapes.Shape) => Shapes.Shape.Move(Shapes.Move({ v: Shapes.Vector3(v), shape })),
|
move: (v: Shapes.Vector3, shape: Shapes.Shape) => Shapes.Shape.Move(Shapes.Move({ v, shape })),
|
||||||
rotate: (v: Shapes.Vector3, shape: Shapes.Shape) => Shapes.Shape.Rotate(Shapes.Rotate.euler({ v: Shapes.Vector3(v), shape })),
|
rotate: (v: Shapes.Vector3, shape: Shapes.Shape) => Shapes.Shape.Rotate(Shapes.Rotate.euler({ v, shape })),
|
||||||
many: (shapes: Shapes.Shape[]) => Shapes.Shape.many(shapes),
|
many: (shapes: Shapes.Shape[]) => Shapes.Shape.many(shapes),
|
||||||
texture: (spec: Shapes.TextureSpec, shape: Shapes.Shape) => Shapes.Shape.Texture(Shapes.Texture({ spec, shape })),
|
texture: (spec: Shapes.TextureSpec, shape: Shapes.Shape) => Shapes.Shape.Texture(Shapes.Texture({ spec, shape })),
|
||||||
color: (r: number, g: number, b: number, shape: Shapes.Shape, alpha = 1.0) => {
|
color: (r0: number | symbol, g0: number | symbol, b0: number | symbol, shape: Shapes.Shape, alpha0: number | symbol = 1.0) => {
|
||||||
return Shapes.Shape.Color((alpha === 1.0)
|
function vd(x: number | symbol): Shapes.DoubleValue {
|
||||||
|
return typeof x === 'number' ? Shapes.DoubleValue.immediate(x) : Shapes.DoubleValue.reference(x);
|
||||||
|
}
|
||||||
|
const r = vd(r0);
|
||||||
|
const g = vd(g0);
|
||||||
|
const b = vd(b0);
|
||||||
|
const alpha = vd(alpha0);
|
||||||
|
return Shapes.Shape.Color((alpha0 === 1.0)
|
||||||
? Shapes.Color.opaque({ r, g, b, shape })
|
? Shapes.Color.opaque({ r, g, b, shape })
|
||||||
: Shapes.Color.transparent({ r, g, b, alpha, shape }));
|
: Shapes.Color.transparent({ r, g, b, alpha, shape }));
|
||||||
},
|
},
|
||||||
name: (base: string, shape: Shapes.Shape) => Shapes.Shape.Name(Shapes.Name({ base, shape })),
|
name: (base: string, shape: Shapes.Shape) => Shapes.Shape.Name(Shapes.Name({ base, shape })),
|
||||||
floor: (shape: Shapes.Shape) => Shapes.Shape.Floor(Shapes.Floor(shape)),
|
floor: (shape: Shapes.Shape) => Shapes.Shape.Floor(Shapes.Floor(shape)),
|
||||||
nonphysical: (shape: Shapes.Shape) => Shapes.Shape.Nonphysical(Shapes.Nonphysical(shape)),
|
nonphysical: (shape: Shapes.Shape) => Shapes.Shape.Nonphysical(Shapes.Nonphysical(shape)),
|
||||||
};
|
} satisfies { [key: string]: (... args: any[]) => Shapes.Shape };
|
||||||
|
|
Loading…
Reference in New Issue