stoe/engine/scene.lisp

71 lines
2.2 KiB
Common Lisp

#|
This file is a part of stoe project.
Copyright (c) 2015 Renaud Casenave-Péré (renaud@casenave-pere.fr)
|#
(uiop:define-package :stoe/engine/scene
(:use :cl :maths
:stoe/core/utils
:stoe/core/entity
:stoe/core/thread
:stoe/engine/mesh
:stoe/engine/scene-graph
:stoe/engine/camera)
(:export #:world #:world-component #:current-scene #:main-camera
#:create-world #:destroy-world #:locking-scene))
(in-package :stoe/engine/scene)
(defvar *world* nil)
(defun world () *world*)
(defcomponent world-component ()
((lock :initform (make-lock "scene-lock") :accessor scene-lock)
(scenes :initform nil :reader scenes)
(cameras :initform nil :reader cameras))
(:documentation "Component containing world's info."))
(defun current-scene (&optional (world (world)))
(with-components (world-component) world
(first (scenes world-component))))
(defun main-camera (&optional (world (world)))
(with-components (world-component) world
(first (cameras world-component))))
(defmethod initialize-instance :after ((world world-component) &key scene camera)
(with-slots (scenes cameras) world
(when scene
(push scene scenes))
(when camera
(push camera cameras))))
(defun make-scene (name)
(create-entity name graph-node-component))
(defun make-camera (name scene)
(create-entity name
(graph-node-component :parent scene)
(scene-object-component :position (vec 0.0 0.0 2.0))
(camera-component :fovy 90 :aspect (/ 16 9) :near 1.0 :far 1000.0)))
(defun create-world (name)
(when *world*
(error "World already exists."))
(let* ((scene (make-scene "Default Scene"))
(camera (make-camera "Default Camera" scene)))
(setf *world* (create-entity name
(world-component :scene scene :camera camera)))))
(defun destroy-world ()
(when *world*
(with-components (world-component) *world*
(with-slots (scenes cameras) world-component
(mapc #'destroy-entity scenes)
(mapc #'destroy-entity cameras)))
(destroy-entity *world*)
(setf *world* nil)))
(defmacro locking-scene (&body body)
`(with-lock-held ((scene-lock (component (world) 'world-component)))
,@body))