4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributor(s): Daniel Genrich
25 * ***** END GPL LICENSE BLOCK *****
36 #include "MEM_guardedalloc.h"
38 #include "IMB_imbuf.h"
41 #include "MTC_matrixops.h"
43 #include "DNA_armature_types.h"
44 #include "DNA_boid_types.h"
45 #include "DNA_camera_types.h"
46 #include "DNA_curve_types.h"
47 #include "DNA_constraint_types.h" // for drawing constraint
48 #include "DNA_effect_types.h"
49 #include "DNA_lamp_types.h"
50 #include "DNA_lattice_types.h"
51 #include "DNA_material_types.h"
52 #include "DNA_mesh_types.h"
53 #include "DNA_meshdata_types.h"
54 #include "DNA_meta_types.h"
55 #include "DNA_modifier_types.h"
56 #include "DNA_object_types.h"
57 #include "DNA_object_force.h"
58 #include "DNA_object_fluidsim.h"
59 #include "DNA_particle_types.h"
60 #include "DNA_space_types.h"
61 #include "DNA_scene_types.h"
62 #include "DNA_screen_types.h"
63 #include "DNA_smoke_types.h"
64 #include "DNA_userdef_types.h"
65 #include "DNA_view3d_types.h"
66 #include "DNA_world_types.h"
68 #include "BLI_blenlib.h"
69 #include "BLI_arithb.h"
70 #include "BLI_editVert.h"
71 #include "BLI_edgehash.h"
74 #include "BKE_anim.h" //for the where_on_path function
75 #include "BKE_curve.h"
76 #include "BKE_constraint.h" // for the get_constraint_target function
77 #include "BKE_DerivedMesh.h"
78 #include "BKE_deform.h"
79 #include "BKE_displist.h"
80 #include "BKE_effect.h"
82 #include "BKE_global.h"
83 #include "BKE_image.h"
85 #include "BKE_lattice.h"
87 #include "BKE_material.h"
88 #include "BKE_mball.h"
89 #include "BKE_modifier.h"
90 #include "BKE_object.h"
91 #include "BKE_paint.h"
92 #include "BKE_particle.h"
93 #include "BKE_property.h"
94 #include "BKE_smoke.h"
96 #include "BKE_utildefines.h"
97 #include "smoke_API.h"
100 #include "BIF_glutil.h"
102 #include "GPU_draw.h"
103 #include "GPU_material.h"
104 #include "GPU_extensions.h"
107 #include "ED_particle.h"
108 #include "ED_screen.h"
109 #include "ED_types.h"
112 #include "UI_resources.h"
113 #include "UI_interface_icons.h"
118 #include "GPU_extensions.h"
120 #include "view3d_intern.h" // own include
124 /* draw slices of smoke is adapted from c++ code authored by: Johannes Schmid and Ingemar Rask, 2006, johnny@grob.org */
125 static float cv[][3] = {
126 {1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, 1.0f},
127 {1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, {-1.0f, -1.0f, -1.0f}, {1.0f, -1.0f, -1.0f}
130 // edges have the form edges[n][0][xyz] + t*edges[n][1][xyz]
131 static float edges[12][2][3] = {
132 {{1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
133 {{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
134 {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
135 {{1.0f, -1.0f, -1.0f}, {0.0f, 0.0f, 1.0f}},
137 {{1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
138 {{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f, 0.0f}},
139 {{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
140 {{1.0f, -1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
142 {{-1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
143 {{-1.0f, -1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}},
144 {{-1.0f, -1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
145 {{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}}
148 int intersect_edges(float *points, float a, float b, float c, float d)
154 for (i=0; i<12; i++) {
155 t = -(a*edges[i][0][0] + b*edges[i][0][1] + c*edges[i][0][2] + d)
156 / (a*edges[i][1][0] + b*edges[i][1][1] + c*edges[i][1][2]);
158 points[numpoints * 3 + 0] = edges[i][0][0] + edges[i][1][0]*t;
159 points[numpoints * 3 + 1] = edges[i][0][1] + edges[i][1][1]*t;
160 points[numpoints * 3 + 2] = edges[i][0][2] + edges[i][1][2]*t;
167 static int convex(float *p0, float *up, float *a, float *b)
169 // Vec3 va = a-p0, vb = b-p0;
170 float va[3], vb[3], tmp[3];
174 return INPR(up, tmp) >= 0;
177 // copied from gpu_extension.c
178 static int is_pow2(int n)
180 return ((n)&(n-1))==0;
183 static int larger_pow2(int n)
194 void draw_volume(Scene *scene, ARegion *ar, View3D *v3d, Base *base, GPUTexture *tex, int res[3])
196 Object *ob = base->object;
197 RegionView3D *rv3d= ar->regiondata;
202 float *points = NULL;
204 float cor[3] = {1.,1.,1.};
205 int gl_depth = 0, gl_blend = 0;
207 glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend);
208 glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth);
210 wmLoadMatrix(rv3d->viewmat);
211 wmMultMatrix(ob->obmat);
213 glDepthMask(GL_FALSE);
214 glDisable(GL_DEPTH_TEST);
216 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
219 VECCOPY(viewnormal, rv3d->viewinv[2]);
220 Normalize(viewnormal);
222 // find cube vertex that is closest to the viewer
223 for (i=0; i<8; i++) {
226 x = cv[i][0] + viewnormal[0];
227 y = cv[i][1] + viewnormal[1];
228 z = cv[i][2] + viewnormal[2];
230 if ((x>=-1.0f)&&(x<=1.0f)
231 &&(y>=-1.0f)&&(y<=1.0f)
232 &&(z>=-1.0f)&&(z<=1.0f)) {
237 GPU_texture_bind(tex, 0);
239 if (!GLEW_ARB_texture_non_power_of_two)
241 cor[0] = (float)res[0]/(float)larger_pow2(res[0]);
242 cor[1] = (float)res[1]/(float)larger_pow2(res[1]);
243 cor[2] = (float)res[2]/(float)larger_pow2(res[2]);
246 // our slices are defined by the plane equation a*x + b*y +c*z + d = 0
247 // (a,b,c), the plane normal, are given by viewdir
248 // d is the parameter along the view direction. the first d is given by
249 // inserting previously found vertex into the plane equation
250 d0 = -(viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]);
254 // printf("d0: %f, dd: %f\n", d0, dd);
256 points = MEM_callocN(sizeof(float)*12*3, "smoke_points_preview");
258 for (d = d0; d > -d0; d -= dd) {
260 // intersect_edges returns the intersection points of all cube edges with
261 // the given plane that lie within the cube
262 numpoints = intersect_edges(points, viewnormal[0], viewnormal[1], viewnormal[2], d);
267 // sort points to get a convex polygon
268 for(i = 1; i < numpoints - 1; i++)
270 for(j = i + 1; j < numpoints; j++)
272 if(convex(p0, viewnormal, &points[j * 3], &points[i * 3]))
275 VECCOPY(tmp2, &points[i * 3]);
276 VECCOPY(&points[i * 3], &points[j * 3]);
277 VECCOPY(&points[j * 3], tmp2);
283 for (i = 0; i < numpoints; i++) {
284 glColor3f(1.0, 1.0, 1.0);
285 glTexCoord3d((points[i * 3 + 0] + 1.0)*cor[0]/2.0, (points[i * 3 + 1] + 1)*cor[1]/2.0, (points[i * 3 + 2] + 1.0)*cor[2]/2.0);
286 glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]);
293 GPU_texture_unbind(tex);
301 glEnable(GL_DEPTH_TEST);
302 glDepthMask(GL_TRUE);