Create some classes to store the mesh data streams and adapt the import file accordingly. Add object and camera classes to be manipulated by the game. Render the meshes in the graph scene using only position vertex stream and an unicolor shader. Also add some models and a startup package to ease testing.
84 lines
3.8 KiB
Common Lisp
84 lines
3.8 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/engine/gl-utils
|
|
:stoe/engine/mesh
|
|
:stoe/engine/scene)
|
|
(: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)
|
|
(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
|
|
(import-transform (classimp:transform node)))))
|
|
(rec node root-node)
|
|
root-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."))))
|
|
|
|
(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-mesh
|
|
(remove nil (list (import-stream (classimp:vertices mesh)
|
|
:position)
|
|
(import-stream (classimp:colors mesh)
|
|
:color)))
|
|
(import-faces (classimp:faces mesh) (import-modes mesh))))
|
|
'vector)
|
|
:root-node (import-nodes (classimp:root-node ai-scene)))))
|