Use entities and components to define objects in the game world and represent the game scene as a graph
99 lines
4.3 KiB
Common Lisp
99 lines
4.3 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/import
|
|
(:use :cl :maths
|
|
:stoe/core/utils
|
|
:stoe/core/jobs
|
|
:stoe/core/resources
|
|
:stoe/engine/gl-utils
|
|
:stoe/engine/mesh
|
|
:stoe/engine/scene
|
|
:stoe/engine/model)
|
|
(:export #:import-graphic-assets))
|
|
(in-package :stoe/engine/import)
|
|
|
|
(defun import-stream (stream attrib)
|
|
(let* ((len (array-total-size stream)))
|
|
(when (> len 0)
|
|
(let* ((count len)
|
|
(stride (array-total-size (aref stream 0)))
|
|
(elt-type (array-element-type (aref stream 0)))
|
|
(ctype (ltype-to-ctype elt-type (* count stride)))
|
|
(array (make-array (list (* count stride)) :element-type elt-type)))
|
|
(loop for i below count
|
|
do (let ((row (aref stream i)))
|
|
(loop for j below stride
|
|
do (setf (aref array (+ j (* i stride))) (aref row j)))))
|
|
(make-vertex-stream array ctype count attrib stride)))))
|
|
|
|
(defun import-faces (faces mode)
|
|
(let* ((count (array-total-size faces))
|
|
(stride (array-total-size (aref faces 0)))
|
|
(elt-type (array-element-type (aref faces 0)))
|
|
(ctype (ltype-to-ctype elt-type (* count stride)))
|
|
(array (make-array (list (* count stride)) :element-type 'fixnum)))
|
|
(loop for i below count
|
|
do (let ((row (aref faces i)))
|
|
(loop for j below stride
|
|
do (setf (aref array (+ j (* i stride))) (aref row j)))))
|
|
(make-index-stream array ctype count mode)))
|
|
|
|
(defun import-transform (trans)
|
|
(let ((mat (mat-null 4 'single-float)))
|
|
(loop for i below (first (dimensions mat))
|
|
do (loop for j below (second (dimensions mat))
|
|
do (setf (mref mat i j) (aref trans (+ j (* i (second (dimensions mat))))))))
|
|
mat))
|
|
|
|
(defun import-nodes (node)
|
|
(let ((len (length (classimp:children node)))
|
|
model-node)
|
|
(loop for i below len
|
|
for child = (aref (classimp:children node) i)
|
|
do (let ((child-node (import-nodes child)))
|
|
(when child-node
|
|
(unless model-node
|
|
(setf model-node
|
|
(make-model-node
|
|
(classimp:name node) (coerce (classimp:meshes node) 'list)
|
|
nil (import-transform (classimp:transform node)))))
|
|
(attach-node child-node model-node))))
|
|
(when (and (null model-node) (> (length (classimp:meshes node)) 0))
|
|
(setf model-node (make-model-node
|
|
(classimp:name node) (coerce (classimp:meshes node) 'list)
|
|
nil (import-transform (classimp:transform node)))))
|
|
model-node))
|
|
|
|
(defun import-modes (mesh)
|
|
(when (classimp:mesh-has-multiple-primitive-types mesh)
|
|
(error "Multiple primitive types are not yet supported"))
|
|
(cond
|
|
((classimp:mesh-has-points mesh) :points)
|
|
((classimp:mesh-has-lines mesh) :lines)
|
|
((classimp:mesh-has-triangles mesh) :triangles)
|
|
((classimp:mesh-has-polygons mesh) (error "Polygons mode is not supported."))))
|
|
|
|
(eval-when (:compile-toplevel :load-toplevel :execute)
|
|
(defun import-graphic-assets (path)
|
|
(async-job (path)
|
|
(classimp:import-into-lisp path))))
|
|
|
|
(defrestype "dae" model-resource
|
|
((:load (path (ai-scene (import-graphic-assets path)) res)
|
|
(with-slots (root-node meshes) res
|
|
(setf meshes
|
|
(coerce (loop for i below (array-total-size (classimp:meshes ai-scene))
|
|
for mesh = (aref (classimp:meshes ai-scene) i)
|
|
collect (make-mesh
|
|
(remove nil
|
|
(list (import-stream (classimp:vertices mesh)
|
|
:position)
|
|
(when (> (length (classimp:colors mesh)) 0)
|
|
(import-stream (aref (classimp:colors mesh) 0)
|
|
:color))))
|
|
(import-faces (classimp:faces mesh) (import-modes mesh))))
|
|
'vector)
|
|
root-node (import-nodes (classimp:root-node ai-scene)))))))
|