4 ;; -- keep track of every mesh instance ----------------------------------
6 (defparameter *meshes
* (make-hash-table :test
'equalp
)
9 (unless (find-package :mesh-names
)
10 (make-package :mesh-names
))
12 ;; -- define a few common types of mesh for luck --------------------------
16 ;; simple mesh w vertices
17 (def-mesh-type simple-mesh
(base-mesh) ((vertex vertices-of vertex3d
)))
19 ;; simple mesh with normals for lighting
20 (def-mesh-type mesh
(simple-mesh) ((normal normals-of vector3d
) (face-normals face-normals-of vector3d
)))
23 (def-mesh-type textured-mesh
(simple-mesh) ((texcoord uvs-of vector2d
)))
25 ;; mesh with vertex colours or other attributes
26 (def-mesh-type coloured-mesh
(simple-mesh) ((colour colours-of colour
)))
29 ;; -- operations on normals et al --------------------
31 (def-tuple-op calc-face-normal
32 ((vertex-a vertex3d
(ax ay az aw
))
33 (vertex-b vertex3d
(bx by bz bw
))
34 (vertex-c vertex3d
(cx cy cz cw
)))
35 "return the normal of a face"
39 (delta-vector3d vertex-a vertex-b
)
40 (delta-vector3d vertex-a vertex-c
)))))
42 (def-tuple-op vector3d-sum
43 ((vector-a vector3d
(ax ay az
))
44 (vector-b vector3d
(bx by bz
)))
45 "return the sum of two vectors"
47 (vector3d* (+ ax bx
) (+ ay by
) (+ az bz
))))
49 ;; declarations to allow the iterate macro to iterate over the
50 ;; triangles in a mesh or the vertices
51 (defclause-sequence in-triangles index-of-triangle
52 :access-fn
'triangle-aref
53 :size-fn
'triangle-array-dimensions
54 :sequence-type
'vector
55 :element-type
'(values (unsigned-byte 16) (unsigned-byte 16) (unsigned-byte 16)))
58 (defclause-sequence in-vertices index-of-vertex
59 :access-fn
'vertex3d-aref
60 :size-fn
'vertex3d-array-dimensions
61 :sequence-type
'vector
62 :element-type
'(values (unsigned-byte 16) (unsigned-byte 16) (unsigned-byte 16) (unsigned-byte 16)))
64 (defgeneric calc-face-normals
(mesh))
66 (defmethod calc-face-normals ((self mesh
))
67 "Calculate the face normals of a mesh."
68 (let* ((face-normals (make-vector3d-array (triangle-array-dimensions (faces-of self
)))))
70 (for (values a b c
) in-triangles
(faces-of self
))
71 (for triangle-index upfrom
0)
72 (setf (vector3d-aref face-normals triangle-index
)
74 (vertex3d-aref (vertices-of self
) a
)
75 (vertex3d-aref (vertices-of self
) b
)
76 (vertex3d-aref (vertices-of self
) c
))))
77 (setf (face-normals-of self
) face-normals
)))
79 (defgeneric calc-vertex-normals
(mesh))
81 (defmethod calc-vertex-normals ((self mesh
))
82 "Calculate the vertex normals of a mesh."
83 (let ((vertex-normals (make-vector3d-array (length (vertices-of self
)))))
85 (for index index-of-vertex
(vertices-of self
))
86 (let ((normal (new-vector3d)))
88 (for (values a b c
) in-triangles
(faces-of self
))
89 (for face-index upfrom
0)
90 (when (or (= a index
) (= b index
) (= c index
))
91 (setf (vector3d normal
)
92 (vector3d-sum (vector3d normal
)
93 (vector3d-aref (face-normals-of self
) face-index
))))
94 (setf (vector3d-aref vertex-normals index
) (vector3d normal
)))))
95 (setf (normals-of self
) vertex-normals
)))
98 ;; mesh geometry calculation ---------------------------------------------
100 (defgeneric box-of
(mesh))
102 (defmethod box-of ((self mesh
))
103 "Return a bounding box for the mesh."
104 (let ((maxx most-negative-single-float
)
105 (minx most-positive-single-float
)
106 (maxy most-negative-single-float
)
107 (miny most-positive-single-float
)
108 (maxz most-negative-single-float
)
109 (minz most-positive-single-float
))
111 (for index index-of-vertex
(vertices-of self
))
113 (vertex3d-aref (vertices-of self
) index
)
116 ((< x minx
) (setf minx x
))
117 ((> x maxx
) (setf maxx x
))
118 ((< y miny
) (setf miny y
))
119 ((> y maxy
) (setf maxy y
))
120 ((< z minz
) (setf minz z
))
121 ((< z minz
) (setf minz z
)))))
122 (values minx maxx miny maxy minz maxz
)))
124 (defgeneric normalize-scale
(mesh))
126 (defmethod normalize-scale ((self mesh
))
127 "Rescale geometry to fit into a 1:1:1 bounding box"
129 (minx maxx miny maxy minz maxz
)
131 (let ((dx (- maxx minx
))
136 ((and (> dx dz
) (> dx dy
))
137 ;; dx is largest dimension
138 (setf scale
(/ 1 (- maxx minx
))))
139 ;; dy is largest dimension
140 ((and (> dy dz
) (> dy dx
))
141 (setf scale
(/ 1 (- maxy miny
))))
142 ;; dz is largest dimension
143 ((and (> dz dy
) (> dz dx
))
144 (setf scale
(/ 1 (- maxy miny
)))))
146 (for index index-of-vertex
(vertices-of self
))
148 (vertex3d-aref (vertices-of self
) index
)
150 (setf (vertex3d-aref (vertices-of self
) index
)
151 (vertex3d* (* x scale
) (* y scale
) (* z scale
) w
)))))))
154 (defgeneric stripify
(mesh))
156 (defmethod stripify ((self mesh
))
161 ;; empty base class to specialise on
162 (defclass compiled-mesh
()
166 ;; (defmethod decompilation ((self compiled-mesh))
167 ;; "Create a modifiable mesh from a compiled mesh")
169 (defmethod mesh-compile ((self mesh
) &rest args
)
170 "Given a mesh return a compiled mesh, which is a non-modifiable mesh optimised for rendering in foreign memory."
171 (declare (ignorable args
))