Add a way to import graphic assets from various sources
This commit is contained in:
parent
4e974ad8a2
commit
ab0698bef1
4 changed files with 121 additions and 30 deletions
|
|
@ -8,9 +8,8 @@
|
|||
(:use-reexport
|
||||
:stoe/engine/gl-utils
|
||||
:stoe/engine/scene
|
||||
:stoe/engine/object
|
||||
:stoe/engine/mesh
|
||||
:stoe/engine/camera
|
||||
#+stoe-foreign-assets
|
||||
:stoe/engine/import
|
||||
:stoe/engine/render
|
||||
:stoe/engine/shaders
|
||||
:stoe/engine/shader/all))
|
||||
|
|
|
|||
66
engine/import.lisp
Normal file
66
engine/import.lisp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#|
|
||||
This file is a part of stoe project.
|
||||
Copyright (c) 2015 Renaud Casenave-Péré (renaud@casenave-pere.fr)
|
||||
|#
|
||||
|
||||
(uiop:define-package :stoe/engine/import
|
||||
(:use :cl :maths
|
||||
:stoe/engine/scene)
|
||||
(:export #:import-graphic-assets))
|
||||
(in-package :stoe/engine/import)
|
||||
|
||||
(defun import-stream (stream)
|
||||
(let ((len (array-total-size stream)))
|
||||
(when (> len 0)
|
||||
(let* ((dim-x len)
|
||||
(dim-y (array-total-size (aref stream 0)))
|
||||
(array (make-array (list (* dim-x dim-y)) :element-type 'single-float)))
|
||||
(loop for i below dim-x
|
||||
do (let ((row (aref stream i)))
|
||||
(loop for j below dim-y
|
||||
do (setf (aref array (+ j (* i dim-y))) (aref row j)))))
|
||||
(make-stream-array array dim-x dim-y)))))
|
||||
|
||||
(defun import-faces (faces)
|
||||
(let* ((dim-x (array-total-size faces))
|
||||
(dim-y (array-total-size (aref faces 0)))
|
||||
(array (make-array (list (* dim-x dim-y)) :element-type 'fixnum)))
|
||||
(loop for i below dim-x
|
||||
do (let ((row (aref faces i)))
|
||||
(loop for j below dim-y
|
||||
do (setf (aref array (+ j (* i dim-y))) (aref row j)))))
|
||||
array))
|
||||
|
||||
(defun import-transform (trans)
|
||||
(let ((mat (mat-null 4 'single-float)))
|
||||
(loop for i below (first (dimension mat))
|
||||
do (loop for j below (second (dimension mat))
|
||||
do (setf (mref mat i j) (aref trans (+ j (* i (second (dimension mat))))))))
|
||||
mat))
|
||||
|
||||
(defun import-nodes (node)
|
||||
(labels ((rec (node parent)
|
||||
(let ((len (array-total-size (classimp:children node))))
|
||||
(loop for i below len
|
||||
for child = (aref (classimp:children node) i)
|
||||
do (let ((scene-node (make-scene-node (classimp:name child) parent
|
||||
(import-transform (classimp:transform child))
|
||||
(coerce (classimp:meshes child) 'list))))
|
||||
(rec child scene-node))))))
|
||||
(when node
|
||||
(let ((root-node (make-scene-node (classimp:name node) nil (classimp:transform node))))
|
||||
(rec node root-node)
|
||||
root-node))))
|
||||
|
||||
(defun import-graphic-assets (filename)
|
||||
(let ((ai-scene (classimp:import-into-lisp filename)))
|
||||
(make-instance 'scene
|
||||
:meshes
|
||||
(coerce (loop for i below (array-total-size (classimp:meshes ai-scene))
|
||||
for mesh = (aref (classimp:meshes ai-scene) i)
|
||||
collect (make-instance 'mesh
|
||||
:vertices (import-stream (classimp:vertices mesh))
|
||||
:colors (import-stream (classimp:colors mesh))
|
||||
:faces (import-faces (classimp:faces mesh))))
|
||||
'vector)
|
||||
:root-node (import-nodes (classimp:root-node ai-scene)))))
|
||||
|
|
@ -4,39 +4,63 @@
|
|||
|#
|
||||
|
||||
(uiop:define-package :stoe/engine/scene
|
||||
(:export #:scene-node #:parent #:children
|
||||
#:attach #:detach
|
||||
#:walk-graph))
|
||||
(:use :cl)
|
||||
(:export #:scene-node #:make-scene-node #:attach-child
|
||||
#:scene #:make-scene
|
||||
#:mesh #:make-mesh
|
||||
#:stream-array
|
||||
#:make-stream-array))
|
||||
(in-package :stoe/engine/scene)
|
||||
|
||||
(defclass scene-node ()
|
||||
((parent :initform nil :reader parent)
|
||||
(children :initform nil :reader children))
|
||||
((name :initarg :name)
|
||||
(parent :initform nil)
|
||||
(transform :initarg :transform)
|
||||
(children :initarg :children)
|
||||
(meshes :initarg :meshes))
|
||||
(:documentation "Base class for a node in the scene graph."))
|
||||
|
||||
(defgeneric attach (scene-node parent)
|
||||
(:documentation "Attach a new node to the scene graph to be rendered."))
|
||||
(defun make-scene-node (name &optional parent transform meshes)
|
||||
(let ((node (make-instance 'scene-node :name name :transform transform :meshes meshes)))
|
||||
(when parent
|
||||
(attach-child node parent))
|
||||
node))
|
||||
|
||||
(defmethod attach ((scene-node scene-node) (parent scene-node))
|
||||
(with-slots (children) parent
|
||||
(with-slots ((new-parent parent)) scene-node
|
||||
(push scene-node children)
|
||||
(setf new-parent parent))))
|
||||
(defun attach-child (node parent)
|
||||
(with-slots (node-parent) node
|
||||
(when parent
|
||||
(with-slots (children) parent
|
||||
(setf children (append children (list node)))
|
||||
(setf node-parent parent))))
|
||||
node)
|
||||
|
||||
(defgeneric detach (scene-node)
|
||||
(:documentation "Detach a node from the scene graph to prevent it and its
|
||||
children from being rendered."))
|
||||
(defun detach-child (node)
|
||||
(with-slots (node-parent) node
|
||||
(when node-parent
|
||||
(with-slots (children) node-parent
|
||||
(delete node children)))))
|
||||
|
||||
(defmethod detach ((scene-node scene-node))
|
||||
(with-slots (parent) scene-node
|
||||
(with-slots (children) parent
|
||||
(setf children (remove scene-node children))
|
||||
(setf parent nil))))
|
||||
(defclass scene ()
|
||||
((root-node :initarg :root-node)
|
||||
(meshes :initarg :meshes))
|
||||
(:documentation "Class for the current scene."))
|
||||
|
||||
(defun walk-scene (fun node)
|
||||
"Walk through the scene graph and apply `fun' at each node."
|
||||
(with-slots (children) node
|
||||
(loop for child in children
|
||||
do (progn
|
||||
(apply fun child)
|
||||
(walk-scene fun child)))))
|
||||
(defun make-scene ()
|
||||
(make-instance 'scene))
|
||||
|
||||
(defclass mesh ()
|
||||
((vertices :initarg :vertices)
|
||||
(colors :initarg :colors)
|
||||
(faces :initarg :faces))
|
||||
(:documentation "Class for a single mesh."))
|
||||
|
||||
(defun make-mesh (name)
|
||||
(make-instance 'mesh :name name))
|
||||
|
||||
(defclass stream-array ()
|
||||
((array :initarg :array)
|
||||
(count :initarg :count)
|
||||
(stride :initarg :stride)))
|
||||
|
||||
(defun make-stream-array (array count stride)
|
||||
(make-instance 'stream-array :array array :count count :stride stride))
|
||||
|
|
|
|||
2
stoe.asd
2
stoe.asd
|
|
@ -42,6 +42,8 @@
|
|||
"blackbird"
|
||||
"cl-opengl"
|
||||
"glop"
|
||||
#+stoe-foreign-assets
|
||||
"classimp"
|
||||
"stoe/maths/all"
|
||||
"stoe/core/all"
|
||||
"stoe/engine/all"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue