[Bf-blender-cvs] [0740ae9] hair_system: Added regular display options for hair systems.
Lukas Tönne
noreply at git.blender.org
Sat Aug 9 20:45:22 CEST 2014
Commit: 0740ae9fe5d25e90c6d8c4fe726a1c2d89a3bcf2
Author: Lukas Tönne
Date: Sat Aug 9 19:28:38 2014 +0200
Branches: hair_system
https://developer.blender.org/rB0740ae9fe5d25e90c6d8c4fe726a1c2d89a3bcf2
Added regular display options for hair systems.
Only has a mode setting so far, which defines the overall style of
display.
===================================================================
M release/scripts/startup/bl_ui/properties_data_modifier.py
M source/blender/editors/space_view3d/drawhair.c
M source/blender/makesdna/DNA_hair_types.h
M source/blender/makesdna/DNA_modifier_types.h
M source/blender/makesrna/intern/rna_hair.c
M source/blender/makesrna/intern/rna_modifier.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index d9b11f7..e81210a 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1225,6 +1225,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
def HAIR(self, layout, ob, md):
hsys = md.hair_system
params = hsys.params
+ display = hsys.display
col = layout.column()
col.separator()
@@ -1261,12 +1262,17 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.separator()
+ col.label("Display:")
+ row = col.row()
+ row.prop(display, "mode", expand=True)
+
+ col.separator()
+
col.prop(md, "show_debug")
col2 = col.column()
col2.active = md.show_debug
col2.prop(md, "show_debug_contacts")
col2.prop(md, "show_debug_size")
- col2.prop(md, "show_debug_cylinders")
col2.prop(md, "show_debug_roots")
col2.prop(md, "show_debug_frames")
col2.prop(md, "show_debug_smoothing")
diff --git a/source/blender/editors/space_view3d/drawhair.c b/source/blender/editors/space_view3d/drawhair.c
index 012d73e..f37e022 100644
--- a/source/blender/editors/space_view3d/drawhair.c
+++ b/source/blender/editors/space_view3d/drawhair.c
@@ -83,6 +83,203 @@ static void draw_hair_curve(HairSystem *UNUSED(hsys), HairCurve *hair)
glPointSize(1.0f);
}
+static void count_hairs(HairSystem *hsys, int *totpoints, int *validhairs)
+{
+ HairCurve *hair;
+ int i;
+
+ *totpoints = *validhairs = 0;
+ for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
+ if (hair->totpoints > 1) {
+ *totpoints += hair->totpoints;
+ *validhairs += 1;
+ }
+ }
+}
+
+/* preview of hairs as cylinders */
+/* XXX warning, computation here hurts a lot! */
+static void draw_hair_hulls(HairSystem *hsys)
+{
+ HairCurve *hair;
+ HairPoint *point, *next_point;
+ int k, i, s;
+ float upvec[] = {0.0f, 0.0f, 1.0f};
+ float sidevec[] = {1.0f, 0.0f, 0.0f};
+
+ float radius_factor = 1.0f;
+ /* number of cylinder subdivisions */
+ int subdiv = 8;
+
+ int totpoints, validhairs;
+ int tot_verts, tot_elems;
+
+ /* vertex array variables */
+ float (*vert_data)[3];
+ unsigned int *elem_data;
+ unsigned int offset = 0;
+ unsigned int elem_offset = 0;
+
+ static unsigned int hairbuf = 0;
+ static unsigned int hairelem = 0;
+
+ count_hairs(hsys, &totpoints, &validhairs);
+ /* twice for all for the normals */
+ tot_verts = totpoints * 2 * subdiv;
+ tot_elems = (totpoints - validhairs) * 6 * subdiv;
+
+ /* set up OpenGL code */
+ if (!hairbuf) {
+ glGenBuffers(1, &hairbuf);
+ glGenBuffers(1, &hairelem);
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, hairbuf);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, hairelem);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * tot_verts, NULL, GL_DYNAMIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * tot_elems, NULL, GL_DYNAMIC_DRAW);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), NULL);
+ glNormalPointer(GL_FLOAT, 6 * sizeof(float), (GLubyte *)NULL + 3 * sizeof(float));
+
+ vert_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+ elem_data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+
+ /* generate the data and copy to the display buffers */
+ for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
+ float normal[3];
+ float dir[3];
+ float tangent[3];
+ unsigned int cur_offset = offset / 2;
+
+ if (hair->totpoints == 1)
+ continue;
+ point = hair->points;
+ next_point = hair->points + 1;
+
+ sub_v3_v3v3(dir, next_point->co, point->co);
+ normalize_v3_v3(normal, dir);
+
+ /* calculate a tangent by cross product between z vector and normal */
+ if (fabs(dot_v3v3(normal, upvec)) < 0.99f) {
+ cross_v3_v3v3(tangent, normal, upvec);
+ }
+ else
+ cross_v3_v3v3(tangent, normal, sidevec);
+
+ normalize_v3(tangent);
+
+ for (k = 0; k < hair->totpoints - 1; ++point, ++next_point, ++k) {
+ float pivot_axis[3];
+ float new_normal[3];
+ float cosine;
+ /* first step is to compute a tangent vector to the surface and rotate around the normal */
+ sub_v3_v3v3(dir, next_point->co, point->co);
+ normalize_v3_v3(new_normal, dir);
+ cosine = dot_v3v3(new_normal, normal);
+
+ cur_offset = offset / 2;
+
+ /* if needed rotate the previous original tangent to the new frame by using cross product between current
+ * and previous segment */
+ if (fabs(cosine) < 0.999f) {
+ float rot_quat[4];
+ float halfcosine;
+ float halfsine;
+ /* substitute by cosine of half angle because we are doing smooth-like interpolation */
+ cosine = sqrt(0.5 + cosine * 0.5);
+
+ /* half angle cosines needed for quaternion rotation */
+ halfcosine = sqrt(0.5 + cosine * 0.5);
+ halfsine = sqrt(0.5 - cosine * 0.5);
+
+ cross_v3_v3v3(pivot_axis, normal, new_normal);
+ normalize_v3(pivot_axis);
+
+ rot_quat[0] = halfcosine;
+ rot_quat[1] = halfsine * pivot_axis[0];
+ rot_quat[2] = halfsine * pivot_axis[1];
+ rot_quat[3] = halfsine * pivot_axis[2];
+
+ mul_qt_v3(rot_quat, tangent);
+
+ /* also rotate by the half amount the rotation axis */
+ copy_v3_v3(pivot_axis, normal);
+ mul_qt_v3(rot_quat, pivot_axis);
+
+ normalize_v3(tangent);
+ }
+ else
+ copy_v3_v3(pivot_axis, normal);
+
+ copy_v3_v3(normal, new_normal);
+
+ /* and repeat */
+ copy_v3_v3(vert_data[offset], tangent);
+ mul_v3_fl(vert_data[offset], point->radius * radius_factor);
+ add_v3_v3(vert_data[offset++], point->co);
+ copy_v3_v3(vert_data[offset++], tangent);
+
+ /* create quaternion to rotate tangent around normal */
+ for (s = 1; s < subdiv; s++) {
+ float v_nor[3];
+ float rot_quat[4];
+ float half_angle = (M_PI * s) / subdiv;
+ float sine = sin(half_angle);
+
+ copy_v3_v3(v_nor, tangent);
+
+ rot_quat[0] = cos(half_angle);
+ rot_quat[1] = sine * pivot_axis[0];
+ rot_quat[2] = sine * pivot_axis[1];
+ rot_quat[3] = sine * pivot_axis[2];
+
+ mul_qt_v3(rot_quat, v_nor);
+ copy_v3_v3(vert_data[offset], v_nor);
+ mul_v3_fl(vert_data[offset], point->radius * radius_factor);
+ add_v3_v3(vert_data[offset++], point->co);
+ copy_v3_v3(vert_data[offset++], v_nor);
+ }
+
+ for (s = 0; s < subdiv; s++) {
+ elem_data[elem_offset++] = cur_offset + s;
+ elem_data[elem_offset++] = cur_offset + s + subdiv;
+ elem_data[elem_offset++] = cur_offset + (s + 1) % subdiv;
+
+ elem_data[elem_offset++] = cur_offset + s + subdiv;
+ elem_data[elem_offset++] = cur_offset + (s + 1) % subdiv;
+ elem_data[elem_offset++] = cur_offset + (s + 1) % subdiv + subdiv;
+ }
+ }
+
+ /* finally add the last point */
+ for (s = 0; s < subdiv; s++) {
+ add_v3_v3v3(vert_data[offset], vert_data[offset - 2 * subdiv], dir);
+ offset++;
+ copy_v3_v3(vert_data[offset], vert_data[offset - 2 * subdiv]);
+ offset++;
+ }
+
+ }
+
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+
+ glEnable(GL_LIGHTING);
+ /* draw */
+ glShadeModel(GL_SMOOTH);
+ glDrawElements(GL_TRIANGLES, elem_offset, GL_UNSIGNED_INT, NULL);
+ glDisable(GL_LIGHTING);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
+
/* called from drawobject.c, return true if nothing was drawn */
bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Base *base, HairSystem *hsys)
{
@@ -95,8 +292,18 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Ba
glLoadMatrixf(rv3d->viewmat);
glMultMatrixf(ob->obmat);
- for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
- draw_hair_curve(hsys, hair);
+ switch (hsys->display.mode) {
+ case HAIR_DISPLAY_LINE:
+ for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
+ draw_hair_curve(hsys, hair);
+ }
+ break;
+ case HAIR_DISPLAY_RENDER:
+ // TODO
+ break;
+ case HAIR_DISPLAY_HULL:
+ draw_hair_hulls(hsys);
+ break;
}
return retval;
@@ -109,7 +316,6 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar, Ba
#define SHOW_ROOTS
#define SHOW_FRAMES
//#define SHOW_SMOOTHING
-#define SHOW_CYLINDERS
#define SHOW_CONTACTS
static void draw_hair_debug_points(HairSystem *hsys, HAIR_SolverDebugPoint *dpoints, int dtotpoints)
@@ -353,190 +559,6 @@ static void draw_hair_debug_contacts(HairSystem *UNUSED(hsys), HAIR_SolverDebugC
#endif
}
-/* debug preview of hairs as cylinders. warning, computation here hurts a lot! */
-static void draw_hair_debug_cylinders(HairSystem *hsys, int totpoints, int valid_points)
-{
-#ifdef SHOW_CYLINDERS
- HairCurve *hair;
- HairPoint *point, *next_point;
- int k, i, s;
- float upvec[] = {0.0f, 0.0f, 1.0f};
- float sidevec[] = {1.0f, 0.0f, 0.0f};
-
- float radius_factor = 1.0f;
- /* number of cylinder subdivisions */
- int subdiv = 8;
-
- /* vertex array variables */
- float (*vert_data)[3];
- unsigned int *elem_data;
- unsigned int offset = 0;
- unsigned int elem_offset = 0;
-
- /* twive for all for the normals */
- int tot_verts = totpoints * 2 * subdiv;
- int tot_elems = (totpoints - valid_points) * 6 * subdiv;
-
- static unsigned int hairbuf = 0;
- static unsigned int hairelem = 0;
-
- /* set up OpenGL code */
- if (!hairbuf) {
- glGenBuffers(1, &hairbuf);
- glGenBuffers(1, &hairelem);
- }
- glBindBuffer(GL_ARRAY_BUFFER, hairbuf);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, hairelem);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * tot_verts, NULL, GL_DYNAMIC_DRAW);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * tot_elems, NULL, GL_DYNAMIC_DRAW);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
-
- glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), NULL);
- glNormalPointer(GL_FLOAT, 6 * sizeof(float), (GLubyte *)NULL + 3 * sizeof(float));
-
- vert_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
- elem_data = glMapB
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list