mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -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));
|
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
|
// Function: RopeNode::do_recompute_bound
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -303,50 +335,80 @@ render_thread(CullTraverser *trav, CullTraverserData &data,
|
|||||||
CurveSegments curve_segments;
|
CurveSegments curve_segments;
|
||||||
get_connected_segments(curve_segments, result);
|
get_connected_segments(curve_segments, result);
|
||||||
|
|
||||||
// Now we have stored one or more sequences of vertices down the
|
if (use_qpgeom) {
|
||||||
// center strips. Go back through and calculate the vertices on
|
// Now we have stored one or more sequences of vertices down the
|
||||||
// either side.
|
// 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;
|
compute_thread_vertices(vdata, curve_segments);
|
||||||
PTA_TexCoordf uvs;
|
|
||||||
PTA_Colorf colors;
|
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
|
CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, get_thickness());
|
||||||
// line strips.
|
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 {
|
} 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
|
||||||
geom->set_lengths(lengths);
|
// 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());
|
// Finally, build the lengths array to make them into proper
|
||||||
CPT(RenderState) state = data._state->add_attrib(thick);
|
// line strips.
|
||||||
|
|
||||||
CullableObject *object = new CullableObject(geom, state,
|
PTA_int lengths;
|
||||||
data._render_transform);
|
int num_prims = 0;
|
||||||
trav->get_cull_handler()->record_object(object, trav);
|
|
||||||
|
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;
|
CurveSegments curve_segments;
|
||||||
get_connected_segments(curve_segments, result);
|
get_connected_segments(curve_segments, result);
|
||||||
|
|
||||||
// Now we have stored one or more sequences of vertices down the
|
if (use_qpgeom) {
|
||||||
// center strips. Go back through and calculate the vertices on
|
// Now we have stored one or more sequences of vertices down the
|
||||||
// either side.
|
// 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;
|
compute_billboard_vertices(vdata, -get_tube_up(),
|
||||||
PTA_TexCoordf uvs;
|
curve_segments, result);
|
||||||
PTA_Colorf colors;
|
|
||||||
|
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(),
|
PT(qpGeom) geom = new qpGeom;
|
||||||
curve_segments, result);
|
geom->set_vertex_data(vdata);
|
||||||
|
geom->add_primitive(strip);
|
||||||
|
|
||||||
// Finally, build the lengths array to make them into proper
|
CullableObject *object = new CullableObject(geom, data._state,
|
||||||
// triangle strips. We don't need a vindex array here, since the
|
data._render_transform);
|
||||||
// vertices just happened to end up in tristrip order.
|
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 {
|
} 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
|
||||||
geom->set_lengths(lengths);
|
// 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,
|
PT(Geom) geom = new GeomTristrip;
|
||||||
data._render_transform);
|
geom->set_num_prims(num_prims);
|
||||||
trav->get_cull_handler()->record_object(object, trav);
|
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;
|
CurveSegments curve_segments;
|
||||||
get_connected_segments(curve_segments, result);
|
get_connected_segments(curve_segments, result);
|
||||||
|
|
||||||
// Now we have stored one or more sequences of vertices down the
|
if (use_qpgeom) {
|
||||||
// center strips. Go back through and calculate the vertices on
|
// Now we have stored one or more sequences of vertices down the
|
||||||
// either side.
|
// 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;
|
compute_billboard_vertices(vdata, camera_vec,
|
||||||
PTA_TexCoordf uvs;
|
curve_segments, result);
|
||||||
PTA_Colorf colors;
|
|
||||||
|
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,
|
PT(qpGeom) geom = new qpGeom;
|
||||||
curve_segments, result);
|
geom->set_vertex_data(vdata);
|
||||||
|
geom->add_primitive(strip);
|
||||||
|
|
||||||
// Finally, build the lengths array to make them into proper
|
CullableObject *object = new CullableObject(geom, data._state,
|
||||||
// triangle strips. We don't need a vindex array here, since the
|
data._render_transform);
|
||||||
// vertices just happened to end up in tristrip order.
|
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 {
|
} 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_slices = get_num_slices();
|
||||||
int num_verts_per_slice;
|
int num_verts_per_slice;
|
||||||
|
|
||||||
PTA_Vertexf verts;
|
if (use_qpgeom) {
|
||||||
PTA_Normalf normals;
|
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||||
PTA_TexCoordf uvs;
|
("rope", get_format(true), qpGeomUsageHint::UH_stream);
|
||||||
PTA_Colorf colors;
|
|
||||||
|
|
||||||
compute_tube_vertices(verts, normals, uvs, colors,
|
compute_tube_vertices(vdata,
|
||||||
num_verts_per_slice, curve_segments, result);
|
num_verts_per_slice, curve_segments, result);
|
||||||
|
|
||||||
// Finally, go back one more time and build up the vindex array, to
|
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_stream);
|
||||||
// tie all the triangle strips together.
|
// Finally, go through build up the index array, to tie all the
|
||||||
|
// triangle strips together.
|
||||||
PTA_ushort vindex;
|
int vi = 0;
|
||||||
PTA_int lengths;
|
CurveSegments::const_iterator si;
|
||||||
|
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
||||||
int num_prims = 0;
|
const CurveSegment &segment = (*si);
|
||||||
int vi = 0;
|
|
||||||
CurveSegments::const_iterator si;
|
for (int s = 0; s < num_slices; ++s) {
|
||||||
for (si = curve_segments.begin(); si != curve_segments.end(); ++si) {
|
int s1 = (s + 1) % num_verts_per_slice;
|
||||||
const CurveSegment &segment = (*si);
|
|
||||||
|
for (size_t j = 0; j < segment.size(); ++j) {
|
||||||
for (int s = 0; s < num_slices; ++s) {
|
strip->add_vertex((vi + j) * num_verts_per_slice + s);
|
||||||
int s1 = (s + 1) % num_verts_per_slice;
|
strip->add_vertex((vi + j) * num_verts_per_slice + s1);
|
||||||
|
}
|
||||||
for (size_t j = 0; j < segment.size(); ++j) {
|
|
||||||
vindex.push_back((vi + j) * num_verts_per_slice + s);
|
strip->close_primitive();
|
||||||
vindex.push_back((vi + j) * num_verts_per_slice + s1);
|
|
||||||
}
|
}
|
||||||
|
vi += (int)segment.size();
|
||||||
lengths.push_back(segment.size() * 2);
|
|
||||||
num_prims++;
|
|
||||||
}
|
}
|
||||||
vi += (int)segment.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// And create a Geom for the rendering.
|
PT(qpGeom) geom = new qpGeom;
|
||||||
|
geom->set_vertex_data(vdata);
|
||||||
PT(Geom) geom = new GeomTristrip;
|
geom->add_primitive(strip);
|
||||||
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) {
|
CullableObject *object = new CullableObject(geom, data._state,
|
||||||
geom->set_normals(normals, G_PER_VERTEX, vindex);
|
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 {
|
} 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
|
// Function: RopeNode::compute_thread_vertices
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#include "nurbsCurveEvaluator.h"
|
#include "nurbsCurveEvaluator.h"
|
||||||
#include "pandaNode.h"
|
#include "pandaNode.h"
|
||||||
#include "pStatCollector.h"
|
#include "pStatCollector.h"
|
||||||
|
#include "qpgeomVertexFormat.h"
|
||||||
|
|
||||||
|
class qpGeomVertexData;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : RopeNode
|
// Class : RopeNode
|
||||||
@ -143,6 +146,8 @@ protected:
|
|||||||
virtual BoundingVolume *recompute_internal_bound();
|
virtual BoundingVolume *recompute_internal_bound();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
CPT(qpGeomVertexFormat) get_format(bool support_normals) const;
|
||||||
|
|
||||||
BoundingVolume *do_recompute_bound(const NodePath &rel_to);
|
BoundingVolume *do_recompute_bound(const NodePath &rel_to);
|
||||||
void render_thread(CullTraverser *trav, CullTraverserData &data,
|
void render_thread(CullTraverser *trav, CullTraverserData &data,
|
||||||
NurbsCurveResult *result) const;
|
NurbsCurveResult *result) const;
|
||||||
@ -165,6 +170,17 @@ private:
|
|||||||
void get_connected_segments(CurveSegments &curve_segments,
|
void get_connected_segments(CurveSegments &curve_segments,
|
||||||
const NurbsCurveResult *result) const;
|
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,
|
void compute_thread_vertices(PTA_Vertexf &verts, PTA_TexCoordf &uvs,
|
||||||
PTA_Colorf &colors,
|
PTA_Colorf &colors,
|
||||||
const CurveSegments &curve_segments) const;
|
const CurveSegments &curve_segments) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user