mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
render RopeNode with qpgeom
This commit is contained in:
parent
9254a675f8
commit
7ec6a915bd
@ -252,6 +252,38 @@ recompute_internal_bound() {
|
||||
return do_recompute_bound(NodePath(this));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::get_format
|
||||
// Access: Private
|
||||
// Description: Returns the appropriate GeomVertexFormat for
|
||||
// rendering, according to the user-specified
|
||||
// requirements.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexFormat) RopeNode::
|
||||
get_format(bool support_normals) const {
|
||||
PT(qpGeomVertexArrayFormat) array_format = new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexColumn::NT_float32,
|
||||
qpGeomVertexColumn::C_point);
|
||||
|
||||
if (support_normals && get_normal_mode() == NM_vertex) {
|
||||
array_format->add_column
|
||||
(InternalName::get_normal(), 3, qpGeomVertexColumn::NT_float32,
|
||||
qpGeomVertexColumn::C_vector);
|
||||
}
|
||||
if (get_use_vertex_color()) {
|
||||
array_format->add_column
|
||||
(InternalName::get_color(), 1, qpGeomVertexColumn::NT_packed_dabc,
|
||||
qpGeomVertexColumn::C_color);
|
||||
}
|
||||
if (get_uv_mode() != UV_none) {
|
||||
array_format->add_column
|
||||
(InternalName::get_texcoord(), 2, qpGeomVertexColumn::NT_float32,
|
||||
qpGeomVertexColumn::C_texcoord);
|
||||
}
|
||||
|
||||
return qpGeomVertexFormat::register_format(array_format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::do_recompute_bound
|
||||
// Access: Private
|
||||
@ -303,50 +335,80 @@ render_thread(CullTraverser *trav, CullTraverserData &data,
|
||||
CurveSegments curve_segments;
|
||||
get_connected_segments(curve_segments, result);
|
||||
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
if (use_qpgeom) {
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("rope", get_format(false), qpGeomUsageHint::UH_stream);
|
||||
|
||||
PTA_Vertexf verts;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
compute_thread_vertices(vdata, curve_segments);
|
||||
|
||||
PT(qpGeomLinestrips) strip = new qpGeomLinestrips(qpGeomUsageHint::UH_stream);
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
strip->add_next_vertices(segment.size());
|
||||
strip->close_primitive();
|
||||
}
|
||||
|
||||
compute_thread_vertices(verts, uvs, colors, curve_segments);
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
// Finally, build the lengths array to make them into proper
|
||||
// line strips.
|
||||
CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, get_thickness());
|
||||
CPT(RenderState) state = data._state->add_attrib(thick);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
|
||||
PTA_int lengths;
|
||||
int num_prims = 0;
|
||||
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
lengths.push_back(segment.size());
|
||||
num_prims++;
|
||||
}
|
||||
|
||||
PT(GeomLinestrip) geom = new GeomLinestrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts);
|
||||
if (get_uv_mode() != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
}
|
||||
|
||||
if (get_use_vertex_color()) {
|
||||
geom->set_colors(colors, G_PER_VERTEX);
|
||||
} else {
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
PTA_Vertexf verts;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
|
||||
compute_thread_vertices(verts, uvs, colors, curve_segments);
|
||||
|
||||
CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, get_thickness());
|
||||
CPT(RenderState) state = data._state->add_attrib(thick);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
// Finally, build the lengths array to make them into proper
|
||||
// line strips.
|
||||
|
||||
PTA_int lengths;
|
||||
int num_prims = 0;
|
||||
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
lengths.push_back(segment.size());
|
||||
num_prims++;
|
||||
}
|
||||
|
||||
PT(GeomLinestrip) geom = new GeomLinestrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts);
|
||||
if (get_uv_mode() != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
}
|
||||
|
||||
if (get_use_vertex_color()) {
|
||||
geom->set_colors(colors, G_PER_VERTEX);
|
||||
} else {
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, get_thickness());
|
||||
CPT(RenderState) state = data._state->add_attrib(thick);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -365,50 +427,79 @@ render_tape(CullTraverser *trav, CullTraverserData &data,
|
||||
CurveSegments curve_segments;
|
||||
get_connected_segments(curve_segments, result);
|
||||
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
if (use_qpgeom) {
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("rope", get_format(false), qpGeomUsageHint::UH_stream);
|
||||
|
||||
PTA_Vertexf verts;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
compute_billboard_vertices(vdata, -get_tube_up(),
|
||||
curve_segments, result);
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_stream);
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
strip->add_next_vertices(segment.size() * 2);
|
||||
strip->close_primitive();
|
||||
}
|
||||
|
||||
compute_billboard_vertices(verts, uvs, colors, -get_tube_up(),
|
||||
curve_segments, result);
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
// Finally, build the lengths array to make them into proper
|
||||
// triangle strips. We don't need a vindex array here, since the
|
||||
// vertices just happened to end up in tristrip order.
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
|
||||
PTA_int lengths;
|
||||
int num_prims = 0;
|
||||
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
lengths.push_back(segment.size() * 2);
|
||||
num_prims++;
|
||||
}
|
||||
|
||||
// And create a Geom for the rendering.
|
||||
|
||||
PT(Geom) geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts);
|
||||
if (get_uv_mode() != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
}
|
||||
if (get_use_vertex_color()) {
|
||||
geom->set_colors(colors, G_PER_VERTEX);
|
||||
} else {
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
|
||||
PTA_Vertexf verts;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
|
||||
compute_billboard_vertices(verts, uvs, colors, -get_tube_up(),
|
||||
curve_segments, result);
|
||||
|
||||
// Finally, build the lengths array to make them into proper
|
||||
// triangle strips. We don't need a vindex array here, since the
|
||||
// vertices just happened to end up in tristrip order.
|
||||
|
||||
PTA_int lengths;
|
||||
int num_prims = 0;
|
||||
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
lengths.push_back(segment.size() * 2);
|
||||
num_prims++;
|
||||
}
|
||||
|
||||
// And create a Geom for the rendering.
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
PT(Geom) geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts);
|
||||
if (get_uv_mode() != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
}
|
||||
if (get_use_vertex_color()) {
|
||||
geom->set_colors(colors, G_PER_VERTEX);
|
||||
} else {
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -434,50 +525,79 @@ render_billboard(CullTraverser *trav, CullTraverserData &data,
|
||||
CurveSegments curve_segments;
|
||||
get_connected_segments(curve_segments, result);
|
||||
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
if (use_qpgeom) {
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("rope", get_format(false), qpGeomUsageHint::UH_stream);
|
||||
|
||||
PTA_Vertexf verts;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
compute_billboard_vertices(vdata, camera_vec,
|
||||
curve_segments, result);
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_stream);
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
strip->add_next_vertices(segment.size() * 2);
|
||||
strip->close_primitive();
|
||||
}
|
||||
|
||||
compute_billboard_vertices(verts, uvs, colors, camera_vec,
|
||||
curve_segments, result);
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
// Finally, build the lengths array to make them into proper
|
||||
// triangle strips. We don't need a vindex array here, since the
|
||||
// vertices just happened to end up in tristrip order.
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
|
||||
PTA_int lengths;
|
||||
int num_prims = 0;
|
||||
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
lengths.push_back(segment.size() * 2);
|
||||
num_prims++;
|
||||
}
|
||||
|
||||
// And create a Geom for the rendering.
|
||||
|
||||
PT(Geom) geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts);
|
||||
if (get_uv_mode() != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
}
|
||||
if (get_use_vertex_color()) {
|
||||
geom->set_colors(colors, G_PER_VERTEX);
|
||||
} else {
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
// Now we have stored one or more sequences of vertices down the
|
||||
// center strips. Go back through and calculate the vertices on
|
||||
// either side.
|
||||
|
||||
PTA_Vertexf verts;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
|
||||
compute_billboard_vertices(verts, uvs, colors, camera_vec,
|
||||
curve_segments, result);
|
||||
|
||||
// Finally, build the lengths array to make them into proper
|
||||
// triangle strips. We don't need a vindex array here, since the
|
||||
// vertices just happened to end up in tristrip order.
|
||||
|
||||
PTA_int lengths;
|
||||
int num_prims = 0;
|
||||
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
lengths.push_back(segment.size() * 2);
|
||||
num_prims++;
|
||||
}
|
||||
|
||||
// And create a Geom for the rendering.
|
||||
|
||||
PT(Geom) geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts);
|
||||
if (get_uv_mode() != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
}
|
||||
if (get_use_vertex_color()) {
|
||||
geom->set_colors(colors, G_PER_VERTEX);
|
||||
} else {
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -501,63 +621,101 @@ render_tube(CullTraverser *trav, CullTraverserData &data,
|
||||
int num_slices = get_num_slices();
|
||||
int num_verts_per_slice;
|
||||
|
||||
PTA_Vertexf verts;
|
||||
PTA_Normalf normals;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("rope", get_format(true), qpGeomUsageHint::UH_stream);
|
||||
|
||||
compute_tube_vertices(verts, normals, uvs, colors,
|
||||
num_verts_per_slice, curve_segments, result);
|
||||
|
||||
// Finally, go back one more time and build up the vindex array, to
|
||||
// tie all the triangle strips together.
|
||||
|
||||
PTA_ushort vindex;
|
||||
PTA_int lengths;
|
||||
|
||||
int num_prims = 0;
|
||||
int vi = 0;
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
for (int s = 0; s < num_slices; ++s) {
|
||||
int s1 = (s + 1) % num_verts_per_slice;
|
||||
|
||||
for (size_t j = 0; j < segment.size(); ++j) {
|
||||
vindex.push_back((vi + j) * num_verts_per_slice + s);
|
||||
vindex.push_back((vi + j) * num_verts_per_slice + s1);
|
||||
compute_tube_vertices(vdata,
|
||||
num_verts_per_slice, curve_segments, result);
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_stream);
|
||||
// Finally, go through build up the index array, to tie all the
|
||||
// triangle strips together.
|
||||
int vi = 0;
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
for (int s = 0; s < num_slices; ++s) {
|
||||
int s1 = (s + 1) % num_verts_per_slice;
|
||||
|
||||
for (size_t j = 0; j < segment.size(); ++j) {
|
||||
strip->add_vertex((vi + j) * num_verts_per_slice + s);
|
||||
strip->add_vertex((vi + j) * num_verts_per_slice + s1);
|
||||
}
|
||||
|
||||
strip->close_primitive();
|
||||
}
|
||||
|
||||
lengths.push_back(segment.size() * 2);
|
||||
num_prims++;
|
||||
vi += (int)segment.size();
|
||||
}
|
||||
vi += (int)segment.size();
|
||||
}
|
||||
|
||||
// And create a Geom for the rendering.
|
||||
|
||||
PT(Geom) geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts, vindex);
|
||||
if (get_uv_mode() != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX, vindex);
|
||||
}
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
if (get_normal_mode() == NM_vertex) {
|
||||
geom->set_normals(normals, G_PER_VERTEX, vindex);
|
||||
}
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
|
||||
if (get_use_vertex_color()) {
|
||||
geom->set_colors(colors, G_PER_VERTEX, vindex);
|
||||
} else {
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
PTA_Vertexf verts;
|
||||
PTA_Normalf normals;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
|
||||
compute_tube_vertices(verts, normals, uvs, colors,
|
||||
num_verts_per_slice, curve_segments, result);
|
||||
|
||||
// Finally, go back one more time and build up the vindex array, to
|
||||
// tie all the triangle strips together.
|
||||
|
||||
PTA_ushort vindex;
|
||||
PTA_int lengths;
|
||||
|
||||
int num_prims = 0;
|
||||
int vi = 0;
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
|
||||
for (int s = 0; s < num_slices; ++s) {
|
||||
int s1 = (s + 1) % num_verts_per_slice;
|
||||
|
||||
for (size_t j = 0; j < segment.size(); ++j) {
|
||||
vindex.push_back((vi + j) * num_verts_per_slice + s);
|
||||
vindex.push_back((vi + j) * num_verts_per_slice + s1);
|
||||
}
|
||||
|
||||
lengths.push_back(segment.size() * 2);
|
||||
num_prims++;
|
||||
}
|
||||
vi += (int)segment.size();
|
||||
}
|
||||
|
||||
// And create a Geom for the rendering.
|
||||
|
||||
PT(Geom) geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_prims);
|
||||
geom->set_coords(verts, vindex);
|
||||
if (get_uv_mode() != UV_none) {
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX, vindex);
|
||||
}
|
||||
|
||||
if (get_normal_mode() == NM_vertex) {
|
||||
geom->set_normals(normals, G_PER_VERTEX, vindex);
|
||||
}
|
||||
|
||||
if (get_use_vertex_color()) {
|
||||
geom->set_colors(colors, G_PER_VERTEX, vindex);
|
||||
} else {
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
}
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object, trav);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -623,6 +781,186 @@ get_connected_segments(RopeNode::CurveSegments &curve_segments,
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::compute_thread_vertices
|
||||
// Access: Private
|
||||
// Description: Calculates the vertices for a RM_thread render. This
|
||||
// just copies the vertices more-or-less directly into
|
||||
// the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RopeNode::
|
||||
compute_thread_vertices(qpGeomVertexData *vdata,
|
||||
const RopeNode::CurveSegments &curve_segments) const {
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
UVMode uv_mode = get_uv_mode();
|
||||
float uv_scale = get_uv_scale();
|
||||
bool u_dominant = get_uv_direction();
|
||||
bool use_vertex_color = get_use_vertex_color();
|
||||
|
||||
float dist = 0.0f;
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
for (size_t j = 0; j < segment.size(); ++j) {
|
||||
vertex.add_data3f(segment[j]._p);
|
||||
|
||||
if (use_vertex_color) {
|
||||
color.add_data4f(segment[j]._c);
|
||||
}
|
||||
|
||||
float uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
|
||||
|
||||
if (uv_mode != UV_none) {
|
||||
if (u_dominant) {
|
||||
texcoord.add_data2f(uv_t, 0.0f);
|
||||
} else {
|
||||
texcoord.add_data2f(0.0f, uv_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::compute_billboard_vertices
|
||||
// Access: Private
|
||||
// Description: Calculates the vertices for a RM_billboard render. This
|
||||
// puts a pair of vertices on either side of each
|
||||
// computed point in curve_segments.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RopeNode::
|
||||
compute_billboard_vertices(qpGeomVertexData *vdata,
|
||||
const LVector3f &camera_vec,
|
||||
const RopeNode::CurveSegments &curve_segments,
|
||||
NurbsCurveResult *result) const {
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
float thickness = get_thickness();
|
||||
float radius = thickness * 0.5f;
|
||||
UVMode uv_mode = get_uv_mode();
|
||||
float uv_scale = get_uv_scale();
|
||||
bool u_dominant = get_uv_direction();
|
||||
bool use_vertex_color = get_use_vertex_color();
|
||||
|
||||
float dist = 0.0f;
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
for (size_t j = 0; j < segment.size(); ++j) {
|
||||
LVector3f tangent;
|
||||
compute_tangent(tangent, segment, j, result);
|
||||
|
||||
LVector3f norm = cross(tangent, camera_vec);
|
||||
norm.normalize();
|
||||
|
||||
vertex.add_data3f(segment[j]._p + norm * radius);
|
||||
vertex.add_data3f(segment[j]._p - norm * radius);
|
||||
|
||||
if (use_vertex_color) {
|
||||
color.add_data4f(segment[j]._c);
|
||||
color.add_data4f(segment[j]._c);
|
||||
}
|
||||
|
||||
float uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
|
||||
|
||||
if (uv_mode != UV_none) {
|
||||
if (u_dominant) {
|
||||
texcoord.add_data2f(uv_t, 1.0f);
|
||||
texcoord.add_data2f(uv_t, 0.0f);
|
||||
} else {
|
||||
texcoord.add_data2f(1.0f, uv_t);
|
||||
texcoord.add_data2f(0.0f, uv_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::compute_tube_vertices
|
||||
// Access: Private
|
||||
// Description: Calculates the vertices for a RM_tube render. This
|
||||
// puts a ring of vertices around each computed point in
|
||||
// curve_segments.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void RopeNode::
|
||||
compute_tube_vertices(qpGeomVertexData *vdata,
|
||||
int &num_verts_per_slice,
|
||||
const RopeNode::CurveSegments &curve_segments,
|
||||
NurbsCurveResult *result) const {
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter normal(vdata, InternalName::get_normal());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
int num_slices = get_num_slices();
|
||||
num_verts_per_slice = num_slices;
|
||||
|
||||
float thickness = get_thickness();
|
||||
float radius = thickness * 0.5f;
|
||||
UVMode uv_mode = get_uv_mode();
|
||||
float uv_scale = get_uv_scale();
|
||||
bool u_dominant = get_uv_direction();
|
||||
NormalMode normal_mode = get_normal_mode();
|
||||
bool use_vertex_color = get_use_vertex_color();
|
||||
|
||||
// If we are generating UV's, we will need to duplicate the vertices
|
||||
// along the seam so that the UV's go through the whole range of
|
||||
// 0..1 instead of reflecting in the last polygon before the seam.
|
||||
if (uv_mode != UV_none) {
|
||||
++num_verts_per_slice;
|
||||
}
|
||||
|
||||
LVector3f up = get_tube_up();
|
||||
|
||||
float dist = 0.0f;
|
||||
CurveSegments::const_iterator si;
|
||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||
const CurveSegment &segment = (*si);
|
||||
for (size_t j = 0; j < segment.size(); ++j) {
|
||||
LVector3f tangent;
|
||||
compute_tangent(tangent, segment, j, result);
|
||||
|
||||
LVector3f norm = cross(tangent, up);
|
||||
norm.normalize();
|
||||
up = cross(norm, tangent);
|
||||
|
||||
LMatrix3f rotate = LMatrix3f::rotate_mat(360.0f / (float)num_slices,
|
||||
tangent);
|
||||
|
||||
float uv_t = compute_uv_t(dist, uv_mode, uv_scale, segment, j);
|
||||
|
||||
for (int s = 0; s < num_verts_per_slice; ++s) {
|
||||
vertex.add_data3f(segment[j]._p + norm * radius);
|
||||
|
||||
if (normal_mode == NM_vertex) {
|
||||
normal.add_data3f(norm);
|
||||
}
|
||||
|
||||
if (use_vertex_color) {
|
||||
color.add_data4f(segment[j]._c);
|
||||
}
|
||||
|
||||
norm = norm * rotate;
|
||||
|
||||
if (uv_mode != UV_none) {
|
||||
float uv_s = (float)s / (float)num_slices;
|
||||
if (u_dominant) {
|
||||
texcoord.add_data2f(uv_t, uv_s);
|
||||
} else {
|
||||
texcoord.add_data2f(uv_s, uv_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RopeNode::compute_thread_vertices
|
||||
// Access: Private
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include "nurbsCurveEvaluator.h"
|
||||
#include "pandaNode.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "qpgeomVertexFormat.h"
|
||||
|
||||
class qpGeomVertexData;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : RopeNode
|
||||
@ -143,6 +146,8 @@ protected:
|
||||
virtual BoundingVolume *recompute_internal_bound();
|
||||
|
||||
private:
|
||||
CPT(qpGeomVertexFormat) get_format(bool support_normals) const;
|
||||
|
||||
BoundingVolume *do_recompute_bound(const NodePath &rel_to);
|
||||
void render_thread(CullTraverser *trav, CullTraverserData &data,
|
||||
NurbsCurveResult *result) const;
|
||||
@ -165,6 +170,17 @@ private:
|
||||
void get_connected_segments(CurveSegments &curve_segments,
|
||||
const NurbsCurveResult *result) const;
|
||||
|
||||
void compute_thread_vertices(qpGeomVertexData *vdata,
|
||||
const CurveSegments &curve_segments) const;
|
||||
void compute_billboard_vertices(qpGeomVertexData *vdata,
|
||||
const LVector3f &camera_vec,
|
||||
const CurveSegments &curve_segments,
|
||||
NurbsCurveResult *result) const;
|
||||
void compute_tube_vertices(qpGeomVertexData *vdata,
|
||||
int &num_verts_per_slice,
|
||||
const CurveSegments &curve_segments,
|
||||
NurbsCurveResult *result) const;
|
||||
|
||||
void compute_thread_vertices(PTA_Vertexf &verts, PTA_TexCoordf &uvs,
|
||||
PTA_Colorf &colors,
|
||||
const CurveSegments &curve_segments) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user