# -*- indent-tabs-mode: t -*- # Soya 3D # Copyright (C) 2003-2004 Jean-Baptiste LAMY -- jiba@tuxfamily.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA cdef class _SolidModel(_SimpleModel): cdef void _render(self, _Body body): cdef float pos[3] cdef int v2[3] cdef ModelFace* face cdef DisplayList* display_list cdef int i, j, start, end point_by_matrix_copy(pos, self._sphere, body._render_matrix) #print "pos", pos[0], pos[1], pos[2] #print self._sphere[0], self._sphere[1], self._sphere[2], self._sphere[3] if pos[2] + self._sphere[3] < -renderer.current_camera._front: #print "en dehors" _SimpleModel._render(self, body) else: #print "dedans" if not(self._option & MODEL_INITED): self._init_display_list() model_option_activate(self._option) if body._option & LEFTHANDED: glFrontFace(GL_CW) glLoadIdentity() if renderer.state == RENDERER_STATE_OPAQUE: start = 0 end = self._display_lists.nb_opaque_list else: start = self._display_lists.nb_opaque_list end = start + self._display_lists.nb_alpha_list display_list = self._display_lists.display_lists for i from start <= i < end: display_list = self._display_lists.display_lists + i (<_Material> (display_list.material_id))._activate() face_option_activate(display_list.option) for j from 0 <= j < self._nb_faces: face = self._faces + j if ((face.option & DISPLAY_LIST_OPTIONS) == display_list.option) and (face.pack.material_id == display_list.material_id): if face.option & FACE_QUAD: self._render_triangle_solid(face, body, face.v) v2[0] = face.v[0] v2[1] = face.v[2] v2[2] = face.v[3] self._render_triangle_solid(face, body, v2) else: self._render_triangle_solid(face, body, face.v) face_option_inactivate(display_list.option) model_option_inactivate(self._option) if body._option & LEFTHANDED: glFrontFace(GL_CCW) cdef void _render_triangle_solid(self, ModelFace* face, CoordSyst coord_syst, int vertex_indices[3]): cdef int i, i3, j, j3, cur_inter3, nb_inter cdef float f, f1, n[3], p[9], inter[4 * (3 + 2 + 4 + 4)] cur_inter3 = 0 nb_inter = 0 if not(face.option & FACE_SMOOTH_LIT): glNormal3fv(self._values + face.normal) # face normal glBegin(GL_TRIANGLES) for i from 0 <= i < 3: point_by_matrix_copy(&p[0] + 3 * i, self._coords + self._vertex_coords[vertex_indices[i]], coord_syst._render_matrix) if self._option & MODEL_DIFFUSES : glColor4fv (self._colors + self._vertex_diffuses [vertex_indices[i]]) if self._option & MODEL_EMISSIVES: glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, self._colors + self._vertex_emissives[vertex_indices[i]]) # XXX use glColorMaterial when emissive color but no diffuse ? if self._option & MODEL_TEXCOORDS: glTexCoord2fv(self._values + self._vertex_texcoords[vertex_indices[i]]) if face.option & FACE_SMOOTH_LIT : vector_by_matrix_copy(n, self._vnormals + self._vertex_coords[vertex_indices[i]], coord_syst._render_matrix) glNormal3fv(n) glVertex3fv(&p[0] + 3 * i) glEnd() for i from 0 <= i < 3: i3 = 3 * i if i == 2: j = 0 ; j3 = 0 else: j = i + 1; j3 = 3 * j if p[i3 + 2] > -renderer.current_camera._front: inter[cur_inter3 ] = p[i3 ] inter[cur_inter3 + 1] = p[i3 + 1] inter[cur_inter3 + 2] = -renderer.current_camera._front - 0.0001 if self._option & MODEL_DIFFUSES : memcpy(&inter[0] + (cur_inter3 + 3), self._colors + self._vertex_diffuses [vertex_indices[i]], 4 * sizeof(float)) if self._option & MODEL_EMISSIVES: memcpy(&inter[0] + (cur_inter3 + 7), self._colors + self._vertex_emissives[vertex_indices[i]], 4 * sizeof(float)) if self._option & MODEL_TEXCOORDS: memcpy(&inter[0] + (cur_inter3 + 11), self._values + self._vertex_texcoords[vertex_indices[i]], 2 * sizeof(float)) cur_inter3 = cur_inter3 + 13 nb_inter = nb_inter + 1 if ((p[i3 + 2] + renderer.current_camera._front) * (p[j3 + 2] + renderer.current_camera._front) < 0.0) and (nb_inter < 4): # Change side of the camera front plane n[0] = p[i3 ] - p[j3 ] n[1] = p[i3 + 1] - p[j3 + 1] n[2] = p[i3 + 2] - p[j3 + 2] f = -(p[i3 + 2] + renderer.current_camera._front) / n[2] f1 = 1.0 - f inter[cur_inter3 ] = p[i3 ] + f * n[0] inter[cur_inter3 + 1] = p[i3 + 1] + f * n[1] inter[cur_inter3 + 2] = -renderer.current_camera._front - 0.0001 if self._option & MODEL_DIFFUSES : inter[cur_inter3 + 3] = f * self._colors[self._vertex_diffuses[vertex_indices[i]] ] + f1 * self._colors[self._vertex_diffuses[vertex_indices[j]] ] inter[cur_inter3 + 4] = f * self._colors[self._vertex_diffuses[vertex_indices[i]] + 1] + f1 * self._colors[self._vertex_diffuses[vertex_indices[j]] + 1] inter[cur_inter3 + 5] = f * self._colors[self._vertex_diffuses[vertex_indices[i]] + 2] + f1 * self._colors[self._vertex_diffuses[vertex_indices[j]] + 2] inter[cur_inter3 + 6] = f * self._colors[self._vertex_diffuses[vertex_indices[i]] + 3] + f1 * self._colors[self._vertex_diffuses[vertex_indices[j]] + 3] if self._option & MODEL_EMISSIVES: inter[cur_inter3 + 3] = f * self._colors[self._vertex_emissives[vertex_indices[i]] ] + f1 * self._colors[self._vertex_emissives[vertex_indices[j]] ] inter[cur_inter3 + 4] = f * self._colors[self._vertex_emissives[vertex_indices[i]] + 1] + f1 * self._colors[self._vertex_emissives[vertex_indices[j]] + 1] inter[cur_inter3 + 5] = f * self._colors[self._vertex_emissives[vertex_indices[i]] + 2] + f1 * self._colors[self._vertex_emissives[vertex_indices[j]] + 2] inter[cur_inter3 + 6] = f * self._colors[self._vertex_emissives[vertex_indices[i]] + 3] + f1 * self._colors[self._vertex_emissives[vertex_indices[j]] + 3] if self._option & MODEL_TEXCOORDS: inter[cur_inter3 + 11] = f * self._values[self._vertex_texcoords[vertex_indices[i]] ] + f1 * self._values[self._vertex_texcoords[vertex_indices[j]] ] inter[cur_inter3 + 12] = f * self._values[self._vertex_texcoords[vertex_indices[i]] + 1] + f1 * self._values[self._vertex_texcoords[vertex_indices[j]] + 1] cur_inter3 = cur_inter3 + 13 nb_inter = nb_inter + 1 if cur_inter3 != 0: if not face.option & FACE_DOUBLE_SIDED: glDisable(GL_CULL_FACE) glBegin(GL_POLYGON) glNormal3f(0.0, 0.0, 1.0) for i from 0 <= i < nb_inter: cur_inter3 = i * 13 if self._option & MODEL_DIFFUSES : glColor4fv (&inter[0] + (cur_inter3 + 3)) if self._option & MODEL_EMISSIVES: glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, &inter[0] + (cur_inter3 + 7)) if self._option & MODEL_TEXCOORDS: glTexCoord2fv(&inter[0] + (cur_inter3 + 11)) glVertex3fv(&inter[0] + cur_inter3) glEnd() if not face.option & FACE_DOUBLE_SIDED: glEnable(GL_CULL_FACE)