source: src/models/Mesh.pym @ 1345:ff8ef9c6bbb7

Revision 1345:ff8ef9c6bbb7, 7.5 KB checked in by Arc Riley <arcriley@…>, 5 years ago (diff)

Happy New Year! (copyright string update)

Line 
1# PySoy's models.Mesh class
2#
3# Copyright (C) 2006,2007,2008,2009 PySoy Group
4#
5#  This program is free software; you can redistribute it and/or modify
6#  it under the terms of the GNU Affero General Public License as published
7#  by the Free Software Foundation, either version 3 of the License, or
8#  (at your option) any later version.
9#
10#  This program is distributed in the hope that it will be useful,
11#  but WITHOUT ANY WARRANTY; without even the implied warranty of
12#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#  GNU Affero General Public License for more details.
14#
15#  You should have received a copy of the GNU Affero General Public License
16#  along with this program; if not, see http://www.gnu.org/licenses
17#
18# $Id: Mesh.pym 1393 2008-12-31 23:51:25Z ArcRiley $
19
20cdef class Mesh (Model) :
21  '''soy.models.Mesh
22
23    This is a collection of verticies and faces we call a "mesh".
24
25    Faces and verticies are added to a Mesh by passing the Mesh instance to
26    a new :class:`soy.atoms.Vertex` or :class:`soy.atoms.Face` object.
27
28    Materials are added to a Mesh by using it in one of its faces and is
29    automatically removed from a Mesh when no longer used by any Face.
30
31    Math and comparison is planned for the future, allowing two Mesh objects
32    to be combined, the area of one subtracted from another, etc.
33
34    An example of using a Mesh:
35{{{
36    >>> pyramid = soy.models.Mesh()
37    >>> pyrskin = soy.materials.darkWood
38    >>> [[ Add verticies/faces ]]
39    >>> pyrbody = soy.bodies.Body(scene)
40}}}
41
42    Mesh objects have three main properties, .faces .verts and .materials.
43    These are instances of :class:`soy._datatypes.FaceList`, :class:`soy._datatypes.VertexList`,
44    and :class:`soy._datatypes.MaterialList` respectively.  Each of these emulate a
45    Python list plus some additional functionality, see the help() on each
46    for more information.
47  '''
48  #
49  # A Mesh is mostly a placeholder class, it stores no actual data.
50  # The reason for this is alternatives to Mesh inherit it and sometimes
51  # use these datatypes in other ways, or don't use them at all.
52  #
53  # MaterialList (self._mates) stores a Children of Material objects and
54  # an array of Face ranges which use that Material.  This is to speed up
55  # rendering, to minimize the number of texture/etc changes during rendering.
56  #
57  # FaceList (self._faces) stores a Children of Face objects and the actual
58  # face data, each having three intices to a Vertex in that array/buffer.
59  #
60  # VertexList (self._verts) stores a Children of Vertex objects and the
61  # vertex array/buffer.
62  #
63  # It should be noted that the Children of _faces and _verts is only for
64  # Face and Vertex objects created by Python.  These need not exist to be
65  # rendered and hold only pointers to the data stored in the FaceList or
66  # VertexList.  They may be __dealloc__'ed, forgotten by Python, and still
67  # be rendered.
68  #
69  # The Children of each of these exists to manage update their offsets when
70  # internal order is changed (Face/Vertex removed, Face changes its Material,
71  # various order-based optimization routines run, etc). 
72
73  ############################################################################
74  #
75  # Python functions
76  #
77 
78  def __cinit__(self, *args, **keywords) :
79    self._mutex = py.PyThread_allocate_lock()
80    self._mates = soy._datatypes.MaterialList(self)
81    self._faces = soy._datatypes.FaceList(self)
82    self._verts = soy._datatypes.VertexList(self)
83
84
85  def __dealloc__(self) :
86    py.PyThread_free_lock(self._mutex)
87
88
89  def __repr__(self) :
90    return '<Mesh with %d verticies, %d faces, and %d materials>' % (
91             len(self._verts), len(self._faces), len(self._mates))
92
93
94  ############################################################################
95  #
96  # Properties
97  #
98
99  property faces :
100    '''Mesh.faces
101
102    This is a list-like object for manipulating the faces of a Mesh.
103    '''
104    def __get__(self) :
105      return self._faces
106
107
108  property verts :
109    '''Mesh.verts
110
111    This is a list-like object for manipulating the verticies of a Mesh.
112    '''
113    def __get__(self) :
114      return self._verts
115
116
117  property materials :
118    '''Mesh.materials
119
120    This is a list-like object for manipulating the materials of a Mesh.
121    '''
122    def __get__(self) :
123      return self._mates
124
125
126  ############################################################################
127  #
128  # WindowLoop Functions
129  #
130
131  cdef void _render(self, soy.bodies.Body _body) :
132    cdef gl.GLfloat _mtx[16]
133    #
134    ######################################
135    #
136    # save current matrix
137    #
138    gl.glPushMatrix()
139    #
140    ######################################
141    #
142    # set model's matrix
143    #
144    _mtx[0]  = _body._rotation[0]
145    _mtx[1]  = _body._rotation[4]
146    _mtx[2]  = _body._rotation[8]
147    _mtx[3]  = 0.0
148    _mtx[4]  = _body._rotation[1]
149    _mtx[5]  = _body._rotation[5]
150    _mtx[6]  = _body._rotation[9]
151    _mtx[7]  = 0.0
152    _mtx[8]  = _body._rotation[2]
153    _mtx[9]  = _body._rotation[6]
154    _mtx[10] = _body._rotation[10]
155    _mtx[11] = 0.0
156    _mtx[12] = _body._position[0]
157    _mtx[13] = _body._position[1]
158    _mtx[14] = _body._position[2]
159    _mtx[15] = 1.0
160    gl.glMultMatrixf(_mtx)
161    #
162    ######################################
163    #
164    # render materials - insert new code here
165    #
166    py.PyThread_acquire_lock(self._mutex, 1)
167    self._mates._render(<void*> _body)
168    py.PyThread_release_lock(self._mutex)
169    #
170    ######################################
171    #
172    # restore previous matrix
173    #
174    gl.glPopMatrix()
175    #
176    ######################################
177
178
179  #
180  # Rendering Pipeline :
181  #
182  # We start with the "original" vertex array.
183  #
184  # The next step is applying morph targets.  The product of this must be
185  # saved because, often, morph will change infrequently.  When no morphs are
186  # in use the "original" is simply copied here and updated whenever needed.
187  #
188  # After morphs we need to do bone transformations.  Bone transformations
189  # from resting to current within the coordinate system of the Mesh's Body
190  # is aquired and a comparison of transformation from the last frame (ie,
191  # how much that bone has moved since last calculated) is made.
192  #
193  # Once all the bone transformations are calculated each vertex tests against
194  # the bones that it's attached to.  First step of this is to multiply it's
195  # weight (0.0 - 1.0) against the amount of transformation and test to see if
196  # it's greater than the culling value (if it's changed enough to recalc).
197  # If so, calculate that vertex's transformation based on weights for each
198  # bone it's attached to and then apply the product of this.
199  #
200  # These are placed, one by one, into the final array with the appropriate
201  # VBO update array calculated.  If VBO, the updated subarray range is sent,
202  # and in both VA and VBO this is transformed to the body's location and
203  # then rendered.
204  #
205  ############################################################################
206
207  cdef void _calcFogCoords(self, float _depth) nogil :
208    cdef int _i
209    #cdef float* fog_coord_array
210    #fog_coord_array = ( <float*> stdlib.malloc(4 * self._bufferAlloc) )
211    #
212    for _i from 0 <= _i < self._verts._fogSize :
213      self._verts._fogArray[_i] = _depth + self._verts._array[_i].py
214    #
215    if self._verts._bufferAlloc :
216      gl.glBindBufferARB   (gl.GL_ARRAY_BUFFER_ARB, self._verts._buffer)
217      gl.glBufferSubDataARB(gl.GL_ARRAY_BUFFER_ARB,
218                            48 * self._verts._bufferAlloc,
219                            4 * self._verts._bufferAlloc,
220                            self._verts._fogArray)
221    #stdlib.free( fog_coord_array)
Note: See TracBrowser for help on using the repository browser.