handle use_qpgeom on more internal things
This commit is contained in:
parent
67faf965c6
commit
20e9703887
|
|
@ -310,7 +310,7 @@ fill_viz_geom() {
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("collision", qpGeomVertexFormat::get_v3cp(),
|
||||
("collision", qpGeomVertexFormat::get_v3(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ fill_viz_geom() {
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("collision", qpGeomVertexFormat::get_v3cp(),
|
||||
("collision", qpGeomVertexFormat::get_v3(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
|
|
|
|||
|
|
@ -819,7 +819,7 @@ draw_polygon(GeomNode *viz_geom_node, GeomNode *bounds_viz_geom_node,
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("collision", qpGeomVertexFormat::get_v3cp(),
|
||||
("collision", qpGeomVertexFormat::get_v3(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ fill_viz_geom() {
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("collision", qpGeomVertexFormat::get_v3cp(),
|
||||
("collision", qpGeomVertexFormat::get_v3(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ fill_viz_geom() {
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("collision", qpGeomVertexFormat::get_v3cp(),
|
||||
("collision", qpGeomVertexFormat::get_v3(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@
|
|||
#include "transformState.h"
|
||||
#include "workingNodePath.h"
|
||||
#include "switchNode.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
#include "qpgeomVertexReader.h"
|
||||
#include "qpgeomVertexRewriter.h"
|
||||
|
||||
TypeHandle ProjectionScreen::_type_handle;
|
||||
|
||||
|
|
@ -193,88 +198,144 @@ generate_screen(const NodePath &projector, const string &screen_name,
|
|||
NodePath this_np(this);
|
||||
rel_mat = projector.get_mat(this_np);
|
||||
|
||||
// Create a GeomNode to hold this mesh.
|
||||
PT(GeomNode) geom_node = new GeomNode(screen_name);
|
||||
|
||||
// Now compute all the vertices for the screen. These are arranged
|
||||
// in order from left to right and bottom to top.
|
||||
int num_verts = num_x_verts * num_y_verts;
|
||||
Lens *lens = projector_node->get_lens();
|
||||
float t = (distance - lens->get_near()) / (lens->get_far() - lens->get_near());
|
||||
|
||||
PTA_Vertexf coords;
|
||||
PTA_Normalf norms;
|
||||
coords.reserve(num_verts);
|
||||
float x_scale = 2.0f / (num_x_verts - 1);
|
||||
float y_scale = 2.0f / (num_y_verts - 1);
|
||||
|
||||
for (int yi = 0; yi < num_y_verts; yi++) {
|
||||
for (int xi = 0; xi < num_x_verts; xi++) {
|
||||
LPoint2f film = LPoint2f((float)xi * x_scale - 1.0f,
|
||||
(float)yi * y_scale - 1.0f);
|
||||
|
||||
// Reduce the image by the fill ratio.
|
||||
film *= fill_ratio;
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("projectionScreen", qpGeomVertexFormat::get_v3n3(),
|
||||
qpGeomUsageHint::UH_dynamic);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter normal(vdata, InternalName::get_normal());
|
||||
|
||||
for (int yi = 0; yi < num_y_verts; yi++) {
|
||||
for (int xi = 0; xi < num_x_verts; xi++) {
|
||||
LPoint2f film = LPoint2f((float)xi * x_scale - 1.0f,
|
||||
(float)yi * y_scale - 1.0f);
|
||||
|
||||
// Reduce the image by the fill ratio.
|
||||
film *= fill_ratio;
|
||||
|
||||
LPoint3f near_point, far_point;
|
||||
lens->extrude(film, near_point, far_point);
|
||||
LPoint3f point = near_point + t * (far_point - near_point);
|
||||
|
||||
// Normals aren't often needed on projection screens, but you
|
||||
// never know.
|
||||
LVector3f norm;
|
||||
lens->extrude_vec(film, norm);
|
||||
|
||||
LPoint3f near_point, far_point;
|
||||
lens->extrude(film, near_point, far_point);
|
||||
LPoint3f point = near_point + t * (far_point - near_point);
|
||||
|
||||
// Normals aren't often needed on projection screens, but you
|
||||
// never know.
|
||||
LVector3f normal;
|
||||
lens->extrude_vec(film, normal);
|
||||
|
||||
coords.push_back(point * rel_mat);
|
||||
norms.push_back(-normalize(normal * rel_mat));
|
||||
vertex.add_data3f(point * rel_mat);
|
||||
normal.add_data3f(-normalize(norm * rel_mat));
|
||||
}
|
||||
}
|
||||
}
|
||||
nassertr((int)coords.size() == num_verts, NULL);
|
||||
nassertr(vdata->get_num_vertices() == num_verts, NULL);
|
||||
|
||||
// Now synthesize a triangle mesh. We run triangle strips
|
||||
// horizontally across the grid.
|
||||
int num_tstrips = (num_y_verts-1);
|
||||
int tstrip_length = 2*(num_x_verts-1)+2;
|
||||
|
||||
PTA_int lengths;
|
||||
PTA_ushort vindex;
|
||||
|
||||
// Set the lengths array. we are creating num_tstrips t-strips,
|
||||
// each of which has tstrip_length vertices.
|
||||
lengths.reserve(num_tstrips);
|
||||
int n;
|
||||
for (n = 0; n < num_tstrips; n++) {
|
||||
lengths.push_back(tstrip_length);
|
||||
}
|
||||
nassertr((int)lengths.size() == num_tstrips, NULL);
|
||||
|
||||
// Now fill up the index array into the vertices. This lays out the
|
||||
// order of the vertices in each t-strip.
|
||||
vindex.reserve(num_tstrips * tstrip_length);
|
||||
n = 0;
|
||||
int ti, si;
|
||||
for (ti = 1; ti < num_y_verts; ti++) {
|
||||
vindex.push_back(ti * num_x_verts);
|
||||
for (si = 1; si < num_x_verts; si++) {
|
||||
vindex.push_back((ti - 1) * num_x_verts + (si-1));
|
||||
vindex.push_back(ti * num_x_verts + si);
|
||||
// Now synthesize a triangle mesh. We run triangle strips
|
||||
// horizontally across the grid.
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
|
||||
// Fill up the index array into the vertices. This lays out the
|
||||
// order of the vertices in each tristrip.
|
||||
int ti, si;
|
||||
for (ti = 1; ti < num_y_verts; ti++) {
|
||||
strip->add_vertex(ti * num_x_verts);
|
||||
for (si = 1; si < num_x_verts; si++) {
|
||||
strip->add_vertex((ti - 1) * num_x_verts + (si-1));
|
||||
strip->add_vertex(ti * num_x_verts + si);
|
||||
}
|
||||
strip->add_vertex((ti - 1) * num_x_verts + (num_x_verts-1));
|
||||
strip->close_primitive();
|
||||
}
|
||||
vindex.push_back((ti - 1) * num_x_verts + (num_x_verts-1));
|
||||
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
geom_node->add_geom(geom);
|
||||
|
||||
} else {
|
||||
PTA_Vertexf coords;
|
||||
PTA_Normalf norms;
|
||||
coords.reserve(num_verts);
|
||||
|
||||
for (int yi = 0; yi < num_y_verts; yi++) {
|
||||
for (int xi = 0; xi < num_x_verts; xi++) {
|
||||
LPoint2f film = LPoint2f((float)xi * x_scale - 1.0f,
|
||||
(float)yi * y_scale - 1.0f);
|
||||
|
||||
// Reduce the image by the fill ratio.
|
||||
film *= fill_ratio;
|
||||
|
||||
LPoint3f near_point, far_point;
|
||||
lens->extrude(film, near_point, far_point);
|
||||
LPoint3f point = near_point + t * (far_point - near_point);
|
||||
|
||||
// Normals aren't often needed on projection screens, but you
|
||||
// never know.
|
||||
LVector3f normal;
|
||||
lens->extrude_vec(film, normal);
|
||||
|
||||
coords.push_back(point * rel_mat);
|
||||
norms.push_back(-normalize(normal * rel_mat));
|
||||
}
|
||||
}
|
||||
nassertr((int)coords.size() == num_verts, NULL);
|
||||
|
||||
// Now synthesize a triangle mesh. We run triangle strips
|
||||
// horizontally across the grid.
|
||||
int num_tstrips = (num_y_verts-1);
|
||||
int tstrip_length = 2*(num_x_verts-1)+2;
|
||||
|
||||
PTA_int lengths;
|
||||
PTA_ushort vindex;
|
||||
|
||||
// Set the lengths array. we are creating num_tstrips t-strips,
|
||||
// each of which has tstrip_length vertices.
|
||||
lengths.reserve(num_tstrips);
|
||||
int n;
|
||||
for (n = 0; n < num_tstrips; n++) {
|
||||
lengths.push_back(tstrip_length);
|
||||
}
|
||||
nassertr((int)lengths.size() == num_tstrips, NULL);
|
||||
|
||||
// Now fill up the index array into the vertices. This lays out the
|
||||
// order of the vertices in each t-strip.
|
||||
vindex.reserve(num_tstrips * tstrip_length);
|
||||
n = 0;
|
||||
int ti, si;
|
||||
for (ti = 1; ti < num_y_verts; ti++) {
|
||||
vindex.push_back(ti * num_x_verts);
|
||||
for (si = 1; si < num_x_verts; si++) {
|
||||
vindex.push_back((ti - 1) * num_x_verts + (si-1));
|
||||
vindex.push_back(ti * num_x_verts + si);
|
||||
}
|
||||
vindex.push_back((ti - 1) * num_x_verts + (num_x_verts-1));
|
||||
}
|
||||
nassertr((int)vindex.size() == num_tstrips * tstrip_length, NULL);
|
||||
|
||||
GeomTristrip *geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_tstrips);
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
geom->set_coords(coords, G_PER_VERTEX, vindex);
|
||||
geom->set_normals(norms, G_PER_VERTEX, vindex);
|
||||
|
||||
// Make it white.
|
||||
PTA_Colorf colors;
|
||||
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
|
||||
geom_node->add_geom(geom);
|
||||
}
|
||||
nassertr((int)vindex.size() == num_tstrips * tstrip_length, NULL);
|
||||
|
||||
GeomTristrip *geom = new GeomTristrip;
|
||||
geom->set_num_prims(num_tstrips);
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
geom->set_coords(coords, G_PER_VERTEX, vindex);
|
||||
geom->set_normals(norms, G_PER_VERTEX, vindex);
|
||||
|
||||
// Make it white.
|
||||
PTA_Colorf colors;
|
||||
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
|
||||
// Now create a GeomNode to hold this mesh.
|
||||
PT(GeomNode) geom_node = new GeomNode(screen_name);
|
||||
geom_node->add_geom(geom);
|
||||
|
||||
_stale = true;
|
||||
++_last_screen;
|
||||
|
|
@ -535,55 +596,106 @@ recompute_geom(Geom *geom, const LMatrix4f &rel_mat) {
|
|||
0.0f,-0.5f, 0.0f,
|
||||
0.5f, 0.5f, 1.0f);
|
||||
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_ushort color_index;
|
||||
Lens *lens = _projector_node->get_lens();
|
||||
nassertv(lens != (Lens *)NULL);
|
||||
|
||||
const LMatrix3f &to_uv = _invert_uvs ? lens_to_uv_inverted : lens_to_uv;
|
||||
|
||||
// Iterate through all the vertices in the Geom.
|
||||
int num_vertices = geom->get_num_vertices();
|
||||
Geom::VertexIterator vi = geom->make_vertex_iterator();
|
||||
if (geom->is_of_type(qpGeom::get_class_type())) {
|
||||
qpGeom *qpgeom = DCAST(qpGeom, geom);
|
||||
// Iterate through all the vertices in the Geom.
|
||||
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
const Vertexf &vert = geom->get_next_vertex(vi);
|
||||
|
||||
// For each vertex, project to the film plane.
|
||||
LPoint2f film(0.0, 0.0);
|
||||
bool good = lens->project(vert * rel_mat, film);
|
||||
|
||||
// Now the lens gives us coordinates in the range [-1, 1].
|
||||
// Rescale these to [0, 1].
|
||||
uvs.push_back(film * to_uv);
|
||||
|
||||
// If we have vignette color in effect, color the vertex according
|
||||
// to whether it fell in front of the lens or not.
|
||||
if (_vignette_on) {
|
||||
color_index.push_back(good ? 1 : 0);
|
||||
CPT(qpGeomVertexData) vdata = qpgeom->get_vertex_data();
|
||||
if (!vdata->has_column(_texcoord_name)) {
|
||||
// We need to add a new column for the new texcoords.
|
||||
vdata = vdata->replace_column
|
||||
(_texcoord_name, 2, qpGeomVertexColumn::NT_float32,
|
||||
qpGeomVertexColumn::C_texcoord, qpGeomUsageHint::UH_dynamic, true);
|
||||
qpgeom->set_vertex_data(vdata);
|
||||
}
|
||||
if (_vignette_on && !vdata->has_column(InternalName::get_color())) {
|
||||
// We need to add a column for color.
|
||||
vdata = vdata->replace_column
|
||||
(InternalName::get_color(), 1, qpGeomVertexColumn::NT_packed_dabc,
|
||||
qpGeomVertexColumn::C_color, qpGeomUsageHint::UH_dynamic, true);
|
||||
qpgeom->set_vertex_data(vdata);
|
||||
}
|
||||
}
|
||||
|
||||
// Now set the UV's. If the geom already has indexed UV's, we need
|
||||
// to make a new index for the geom.
|
||||
geom->remove_texcoords(_texcoord_name);
|
||||
if (!geom->are_texcoords_indexed()) {
|
||||
// Simple case: no indexing needed.
|
||||
geom->set_texcoords(_texcoord_name, uvs);
|
||||
qpGeomVertexWriter texcoord(qpgeom->modify_vertex_data(), _texcoord_name);
|
||||
qpGeomVertexWriter color(qpgeom->modify_vertex_data());
|
||||
qpGeomVertexReader vertex(qpgeom->get_vertex_data(), InternalName::get_vertex());
|
||||
|
||||
if (_vignette_on) {
|
||||
color.set_column(InternalName::get_color());
|
||||
}
|
||||
|
||||
while (!vertex.is_at_end()) {
|
||||
Vertexf vert = vertex.get_data3f();
|
||||
|
||||
// For each vertex, project to the film plane.
|
||||
LPoint2f film(0.0, 0.0);
|
||||
bool good = lens->project(vert * rel_mat, film);
|
||||
|
||||
// Now the lens gives us coordinates in the range [-1, 1].
|
||||
// Rescale these to [0, 1].
|
||||
texcoord.set_data2f(film * to_uv);
|
||||
|
||||
// If we have vignette color in effect, color the vertex according
|
||||
// to whether it fell in front of the lens or not.
|
||||
if (_vignette_on) {
|
||||
if (good) {
|
||||
color.set_data4f(_frame_color);
|
||||
} else {
|
||||
color.set_data4f(_vignette_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Harder case: we need to make up an index. But this isn't
|
||||
// terribly hard.
|
||||
PTA_ushort index = PTA_ushort::empty_array(num_vertices);
|
||||
// Iterate through all the vertices in the Geom.
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_ushort color_index;
|
||||
int num_vertices = geom->get_num_vertices();
|
||||
Geom::VertexIterator vi = geom->make_vertex_iterator();
|
||||
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
index[i] = i;
|
||||
const Vertexf &vert = geom->get_next_vertex(vi);
|
||||
|
||||
// For each vertex, project to the film plane.
|
||||
LPoint2f film(0.0, 0.0);
|
||||
bool good = lens->project(vert * rel_mat, film);
|
||||
|
||||
// Now the lens gives us coordinates in the range [-1, 1].
|
||||
// Rescale these to [0, 1].
|
||||
uvs.push_back(film * to_uv);
|
||||
|
||||
// If we have vignette color in effect, color the vertex according
|
||||
// to whether it fell in front of the lens or not.
|
||||
if (_vignette_on) {
|
||||
color_index.push_back(good ? 1 : 0);
|
||||
}
|
||||
}
|
||||
geom->set_texcoords(_texcoord_name, uvs, index);
|
||||
}
|
||||
|
||||
// Now set the UV's. If the geom already has indexed UV's, we need
|
||||
// to make a new index for the geom.
|
||||
geom->remove_texcoords(_texcoord_name);
|
||||
if (!geom->are_texcoords_indexed()) {
|
||||
// Simple case: no indexing needed.
|
||||
geom->set_texcoords(_texcoord_name, uvs);
|
||||
|
||||
} else {
|
||||
// Harder case: we need to make up an index. But this isn't
|
||||
// terribly hard.
|
||||
PTA_ushort index = PTA_ushort::empty_array(num_vertices);
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
index[i] = i;
|
||||
}
|
||||
geom->set_texcoords(_texcoord_name, uvs, index);
|
||||
}
|
||||
|
||||
if (_vignette_on) {
|
||||
geom->set_colors(_colors, G_PER_VERTEX, color_index);
|
||||
if (_vignette_on) {
|
||||
geom->set_colors(_colors, G_PER_VERTEX, color_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -702,29 +814,49 @@ make_mesh_geom_node(const WorkingNodePath &np, const NodePath &camera,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PT(Geom) ProjectionScreen::
|
||||
make_mesh_geom(const Geom *geom, Lens *lens, LMatrix4f &rel_mat) {
|
||||
Geom *new_geom = geom->make_copy();
|
||||
PT(Geom) result = new_geom;
|
||||
if (geom->is_of_type(qpGeom::get_class_type())) {
|
||||
PT(qpGeom) new_geom = new qpGeom(*DCAST(qpGeom, geom));
|
||||
|
||||
PTA_Vertexf coords;
|
||||
GeomBindType bind;
|
||||
PTA_ushort vindex;
|
||||
qpGeomVertexRewriter vertex(new_geom->modify_vertex_data(),
|
||||
InternalName::get_vertex());
|
||||
while (!vertex.is_at_end()) {
|
||||
Vertexf vert = vertex.get_data3f();
|
||||
|
||||
// Project each vertex into the film plane, but use three
|
||||
// dimensions so the Z coordinate remains meaningful.
|
||||
LPoint3f film(0.0f, 0.0f, 0.0f);
|
||||
lens->project(vert * rel_mat, film);
|
||||
|
||||
vertex.set_data3f(film);
|
||||
}
|
||||
|
||||
new_geom->get_coords(coords, bind, vindex);
|
||||
return new_geom.p();
|
||||
|
||||
} else {
|
||||
Geom *new_geom = geom->make_copy();
|
||||
PT(Geom) result = new_geom;
|
||||
|
||||
PTA_Vertexf new_coords;
|
||||
new_coords.reserve(coords.size());
|
||||
for (int i = 0; i < (int)coords.size(); i++) {
|
||||
const Vertexf &vert = coords[i];
|
||||
PTA_Vertexf coords;
|
||||
GeomBindType bind;
|
||||
PTA_ushort vindex;
|
||||
|
||||
new_geom->get_coords(coords, bind, vindex);
|
||||
|
||||
PTA_Vertexf new_coords;
|
||||
new_coords.reserve(coords.size());
|
||||
for (int i = 0; i < (int)coords.size(); i++) {
|
||||
const Vertexf &vert = coords[i];
|
||||
|
||||
// Project each vertex into the film plane, but use three
|
||||
// dimensions so the Z coordinate remains meaningful.
|
||||
LPoint3f film(0.0f, 0.0f, 0.0f);
|
||||
lens->project(vert * rel_mat, film);
|
||||
|
||||
new_coords.push_back(film);
|
||||
}
|
||||
|
||||
new_geom->set_coords(new_coords, bind, vindex);
|
||||
|
||||
// Project each vertex into the film plane, but use three
|
||||
// dimensions so the Z coordinate remains meaningful.
|
||||
LPoint3f film(0.0f, 0.0f, 0.0f);
|
||||
lens->project(vert * rel_mat, film);
|
||||
|
||||
new_coords.push_back(film);
|
||||
return result;
|
||||
}
|
||||
|
||||
new_geom->set_coords(new_coords, bind, vindex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,6 +250,28 @@ has_colors() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggVertexPool::has_nonwhite_colors
|
||||
// Access: Public
|
||||
// Description: Returns true if any vertex in the pool has a color
|
||||
// defined other than white, false if no vertices have
|
||||
// colors, or if all colors are white.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggVertexPool::
|
||||
has_nonwhite_colors() const {
|
||||
IndexVertices::const_iterator ivi;
|
||||
for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
|
||||
EggVertex *vertex = (*ivi).second;
|
||||
if (vertex->has_color() &&
|
||||
(vertex->get_color() != Colorf(1.0, 1.0, 1.0, 1.0) ||
|
||||
!vertex->_drgbas.empty())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggVertexPool::has_uvs
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ PUBLISHED:
|
|||
int get_num_dimensions() const;
|
||||
bool has_normals() const;
|
||||
bool has_colors() const;
|
||||
bool has_nonwhite_colors() const;
|
||||
bool has_uvs() const;
|
||||
void get_uv_names(vector_string &uv_names) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include "eggBinner.h"
|
||||
#include "eggRenderState.h"
|
||||
#include "eggPrimitive.h"
|
||||
#include "eggNurbsSurface.h"
|
||||
#include "eggNurbsCurve.h"
|
||||
#include "eggSwitchCondition.h"
|
||||
#include "eggGroup.h"
|
||||
#include "dcast.h"
|
||||
|
|
@ -58,7 +60,13 @@ prepare_node(EggNode *node) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
int EggBinner::
|
||||
get_bin_number(const EggNode *node) {
|
||||
if (node->is_of_type(EggPrimitive::get_class_type())) {
|
||||
if (node->is_of_type(EggNurbsSurface::get_class_type())) {
|
||||
return (int)BN_nurbs_surface;
|
||||
|
||||
} else if (node->is_of_type(EggNurbsCurve::get_class_type())) {
|
||||
return (int)BN_nurbs_curve;
|
||||
|
||||
} else if (node->is_of_type(EggPrimitive::get_class_type())) {
|
||||
return (int)BN_polyset;
|
||||
|
||||
} else if (node->is_of_type(EggGroup::get_class_type())) {
|
||||
|
|
@ -115,6 +123,11 @@ sorts_less(int bin_number, const EggNode *a, const EggNode *b) {
|
|||
// Group LOD nodes in order by switching center.
|
||||
return (swda._center.compare_to(swdb._center) < 0);
|
||||
}
|
||||
|
||||
case BN_nurbs_surface:
|
||||
case BN_nurbs_curve:
|
||||
// Nurbs curves and surfaces are always binned individually.
|
||||
return a < b;
|
||||
|
||||
case BN_none:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ public:
|
|||
BN_none = 0,
|
||||
BN_polyset,
|
||||
BN_lod,
|
||||
BN_nurbs_surface,
|
||||
BN_nurbs_curve,
|
||||
};
|
||||
|
||||
EggBinner(EggLoader &loader);
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ make_indexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
|
|||
|
||||
int nindex =
|
||||
comp_verts_maker.add_normal(egg_prim->get_normal(),
|
||||
egg_prim->_dnormals, mat);
|
||||
egg_prim->_dnormals, mat);
|
||||
|
||||
bprim.set_normal(nindex);
|
||||
}
|
||||
|
|
@ -428,7 +428,7 @@ make_indexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
|
|||
if (egg_prim->has_color() && !egg_false_color) {
|
||||
int cindex =
|
||||
comp_verts_maker.add_color(egg_prim->get_color(),
|
||||
egg_prim->_drgbas);
|
||||
egg_prim->_drgbas);
|
||||
bprim.set_color(cindex);
|
||||
}
|
||||
|
||||
|
|
@ -1541,6 +1541,28 @@ make_node(EggBin *egg_bin, PandaNode *parent) {
|
|||
case EggBinner::BN_lod:
|
||||
return make_lod(egg_bin, parent);
|
||||
|
||||
case EggBinner::BN_nurbs_surface:
|
||||
{
|
||||
nassertr(!egg_bin->empty(), NULL);
|
||||
EggNode *child = egg_bin->get_first_child();
|
||||
EggNurbsSurface *egg_nurbs;
|
||||
DCAST_INTO_R(egg_nurbs, child, NULL);
|
||||
const LMatrix4d &mat = egg_nurbs->get_vertex_to_node();
|
||||
make_nurbs_surface(egg_nurbs, parent, mat);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
case EggBinner::BN_nurbs_curve:
|
||||
{
|
||||
nassertr(!egg_bin->empty(), NULL);
|
||||
EggNode *child = egg_bin->get_first_child();
|
||||
EggNurbsCurve *egg_nurbs;
|
||||
DCAST_INTO_R(egg_nurbs, child, NULL);
|
||||
const LMatrix4d &mat = egg_nurbs->get_vertex_to_node();
|
||||
make_nurbs_curve(egg_nurbs, parent, mat);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
case EggBinner::BN_none:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1929,7 +1951,8 @@ make_vertex_data(const EggRenderState *render_state,
|
|||
qpGeomVertexColumn::NT_float32, qpGeomVertexColumn::C_vector);
|
||||
}
|
||||
|
||||
if (vertex_pool->has_colors()) {
|
||||
bool has_colors = vertex_pool->has_nonwhite_colors();
|
||||
if (has_colors) {
|
||||
array_format->add_column
|
||||
(InternalName::get_color(), 1,
|
||||
qpGeomVertexColumn::NT_packed_dabc, qpGeomVertexColumn::C_color);
|
||||
|
|
@ -1994,7 +2017,7 @@ make_vertex_data(const EggRenderState *render_state,
|
|||
InternalName::get_normal(), 3);
|
||||
}
|
||||
}
|
||||
if (vertex->has_color()) {
|
||||
if (has_colors && vertex->has_color()) {
|
||||
EggMorphColorList::const_iterator mci;
|
||||
for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
|
||||
slider_names.insert((*mci).get_name());
|
||||
|
|
@ -2090,7 +2113,7 @@ make_vertex_data(const EggRenderState *render_state,
|
|||
}
|
||||
}
|
||||
|
||||
if (vertex->has_color()) {
|
||||
if (has_colors && vertex->has_color()) {
|
||||
gvw.set_column(InternalName::get_color());
|
||||
gvw.add_data4f(vertex->get_color());
|
||||
|
||||
|
|
@ -2372,13 +2395,8 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
|||
//egg2pg_cat.debug() << "make_sphere radius: " << radius << "\n";
|
||||
vi = vertices.begin();
|
||||
EggVertex *clr_vtx = (*vi);
|
||||
if (clr_vtx->has_color()) {
|
||||
color = clr_vtx->get_color();
|
||||
} else {
|
||||
color = Colorf(1.0,1.0,1.0,1.0);
|
||||
}
|
||||
color = clr_vtx->get_color();
|
||||
success = true;
|
||||
|
||||
}
|
||||
}
|
||||
return success;
|
||||
|
|
|
|||
|
|
@ -1060,7 +1060,7 @@ load_image_as_model(const Filename &filename) {
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
(string(), qpGeomVertexFormat::get_v3cpt2(),
|
||||
(string(), qpGeomVertexFormat::get_v3t2(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
|
|
|
|||
|
|
@ -2324,6 +2324,10 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
|
|||
GLP(EnableClientState)(GL_COLOR_ARRAY);
|
||||
} else {
|
||||
GLP(DisableClientState)(GL_COLOR_ARRAY);
|
||||
|
||||
// Since we don't have per-vertex color, the implicit color is
|
||||
// white.
|
||||
GLP(Color4f)(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
// Now set up each of the active texture coordinate stages--or at
|
||||
|
|
|
|||
|
|
@ -329,6 +329,17 @@ transform_vertices(const LMatrix4f &mat) {
|
|||
set_coords(new_coords, index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::check_valid
|
||||
// Access: Published
|
||||
// Description: This is only here temporarily; it has meaning at the
|
||||
// qpGeom level.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Geom::
|
||||
check_valid() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::set_coords
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ public:
|
|||
|
||||
PUBLISHED:
|
||||
virtual void transform_vertices(const LMatrix4f &mat);
|
||||
virtual bool check_valid() const;
|
||||
|
||||
void set_coords(const PTA_Vertexf &coords,
|
||||
const PTA_ushort &vindex = PTA_ushort());
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@
|
|||
#include "compose_matrix.h"
|
||||
#include "look_at.h"
|
||||
#include "geomLinestrip.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomLinestrips.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
#include "boundingHexahedron.h"
|
||||
#include "indent.h"
|
||||
#include "config_gobj.h"
|
||||
|
|
@ -67,8 +70,7 @@ operator = (const Lens ©) {
|
|||
_user_flags = copy._user_flags;
|
||||
_comp_flags = 0;
|
||||
|
||||
// We don't copy the _geom_coords array. That's unique to each
|
||||
// Lens.
|
||||
// We don't copy the _geom_data. That's unique to each Lens.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -873,74 +875,137 @@ PT(Geom) Lens::
|
|||
make_geometry() {
|
||||
// The default behavior for make_geometry() will be to draw a
|
||||
// hexahedron around the eight vertices of the frustum. If the lens
|
||||
// is non-linear, the hexahedron will be curved; in this case, we'll
|
||||
// is non-linear, the hexahedron will be curved; in that case, we'll
|
||||
// subdivide the lines into several segments to get an approximation
|
||||
// of the curve.
|
||||
|
||||
// First, define all the points we'll use in this Geom. That's one
|
||||
// point at each corner of the near and far planes (and possibly
|
||||
// more points along the edges).
|
||||
int num_segments = define_geom_coords();
|
||||
if (num_segments == 0) {
|
||||
// Can't do a frustum.
|
||||
_geom_coords.clear();
|
||||
return (Geom *)NULL;
|
||||
if (use_qpgeom) {
|
||||
// First, define all the points we'll use in this Geom. That's one
|
||||
// point at each corner of the near and far planes (and possibly
|
||||
// more points along the edges).
|
||||
int num_segments = define_geom_data();
|
||||
if (num_segments == 0) {
|
||||
// Can't do a frustum.
|
||||
_geom_data.clear();
|
||||
return (Geom *)NULL;
|
||||
}
|
||||
|
||||
// Now string together the line segments.
|
||||
PT(qpGeomLinestrips) line = new qpGeomLinestrips(qpGeomUsageHint::UH_static);
|
||||
|
||||
// Draw a frame around the near plane.
|
||||
int i, si;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (si = 0; si < num_segments; ++si) {
|
||||
line->add_vertex(i * 2 + si * (4 * 2) + 0);
|
||||
}
|
||||
}
|
||||
line->add_vertex(0);
|
||||
line->close_primitive();
|
||||
|
||||
// Draw a frame around the far plane.
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (si = 0; si < num_segments; ++si) {
|
||||
line->add_vertex(i * 2 + si * (4 * 2) + 1);
|
||||
}
|
||||
}
|
||||
line->add_vertex(1);
|
||||
line->close_primitive();
|
||||
|
||||
// Draw connecting lines at the corners.
|
||||
line->add_vertex(0 * 2 + 0);
|
||||
line->add_vertex(0 * 2 + 1);
|
||||
line->close_primitive();
|
||||
|
||||
line->add_vertex(1 * 2 + 0);
|
||||
line->add_vertex(1 * 2 + 1);
|
||||
line->close_primitive();
|
||||
|
||||
line->add_vertex(2 * 2 + 0);
|
||||
line->add_vertex(2 * 2 + 1);
|
||||
line->close_primitive();
|
||||
|
||||
line->add_vertex(3 * 2 + 0);
|
||||
line->add_vertex(3 * 2 + 1);
|
||||
line->close_primitive();
|
||||
|
||||
// And one more line for the viewing axis.
|
||||
line->add_vertex(num_segments * (4 * 2) + 0);
|
||||
line->add_vertex(num_segments * (4 * 2) + 1);
|
||||
line->close_primitive();
|
||||
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(_geom_data);
|
||||
geom->add_primitive(line);
|
||||
|
||||
return geom.p();
|
||||
|
||||
} else {
|
||||
// First, define all the points we'll use in this Geom. That's one
|
||||
// point at each corner of the near and far planes (and possibly
|
||||
// more points along the edges).
|
||||
int num_segments = define_geom_coords();
|
||||
if (num_segments == 0) {
|
||||
// Can't do a frustum.
|
||||
_geom_coords.clear();
|
||||
return (Geom *)NULL;
|
||||
}
|
||||
|
||||
// Now string together the line segments.
|
||||
PTA_ushort vindex;
|
||||
PTA_int lengths;
|
||||
PTA_Colorf colors;
|
||||
|
||||
int num_points = num_segments * 4;
|
||||
|
||||
// Draw a frame around the near plane.
|
||||
int i;
|
||||
for (i = 0; i < num_points; i++) {
|
||||
vindex.push_back(i * num_segments * 2);
|
||||
}
|
||||
vindex.push_back(0);
|
||||
lengths.push_back(num_points + 1);
|
||||
|
||||
// Draw a frame around the far plane.
|
||||
for (i = 0; i < num_points; i++) {
|
||||
vindex.push_back(i * num_segments * 2 + 1);
|
||||
}
|
||||
vindex.push_back(1);
|
||||
lengths.push_back(num_points + 1);
|
||||
|
||||
// Draw connecting lines at the corners.
|
||||
vindex.push_back(0);
|
||||
vindex.push_back(1);
|
||||
lengths.push_back(2);
|
||||
|
||||
vindex.push_back(num_segments * 2 + 0);
|
||||
vindex.push_back(num_segments * 2+ 1);
|
||||
lengths.push_back(2);
|
||||
|
||||
vindex.push_back(num_segments * 4 + 0);
|
||||
vindex.push_back(num_segments * 4 + 1);
|
||||
lengths.push_back(2);
|
||||
|
||||
vindex.push_back(num_segments * 6 + 0);
|
||||
vindex.push_back(num_segments * 6 + 1);
|
||||
lengths.push_back(2);
|
||||
|
||||
// And one more line for the viewing axis.
|
||||
vindex.push_back(num_segments * 8 + 0);
|
||||
vindex.push_back(num_segments * 8 + 1);
|
||||
lengths.push_back(2);
|
||||
|
||||
// We just specify overall color.
|
||||
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
GeomLinestrip *gline = new GeomLinestrip;
|
||||
gline->set_coords(_geom_coords, vindex);
|
||||
gline->set_colors(colors, G_OVERALL);
|
||||
gline->set_lengths(lengths);
|
||||
gline->set_num_prims(lengths.size());
|
||||
|
||||
return gline;
|
||||
}
|
||||
|
||||
// Now string together the line segments.
|
||||
PTA_ushort vindex;
|
||||
PTA_int lengths;
|
||||
PTA_Colorf colors;
|
||||
|
||||
int num_points = num_segments * 4;
|
||||
|
||||
// Draw a frame around the near plane.
|
||||
int i;
|
||||
for (i = 0; i < num_points; i++) {
|
||||
vindex.push_back(i * num_segments * 2);
|
||||
}
|
||||
vindex.push_back(0);
|
||||
lengths.push_back(num_points + 1);
|
||||
|
||||
// Draw a frame around the far plane.
|
||||
for (i = 0; i < num_points; i++) {
|
||||
vindex.push_back(i * num_segments * 2 + 1);
|
||||
}
|
||||
vindex.push_back(1);
|
||||
lengths.push_back(num_points + 1);
|
||||
|
||||
// Draw connecting lines at the corners.
|
||||
vindex.push_back(0);
|
||||
vindex.push_back(1);
|
||||
lengths.push_back(2);
|
||||
|
||||
vindex.push_back(num_segments * 2 + 0);
|
||||
vindex.push_back(num_segments * 2+ 1);
|
||||
lengths.push_back(2);
|
||||
|
||||
vindex.push_back(num_segments * 4 + 0);
|
||||
vindex.push_back(num_segments * 4 + 1);
|
||||
lengths.push_back(2);
|
||||
|
||||
vindex.push_back(num_segments * 6 + 0);
|
||||
vindex.push_back(num_segments * 6 + 1);
|
||||
lengths.push_back(2);
|
||||
|
||||
// And one more line for the viewing axis.
|
||||
vindex.push_back(num_segments * 8 + 0);
|
||||
vindex.push_back(num_segments * 8 + 1);
|
||||
lengths.push_back(2);
|
||||
|
||||
// We just specify overall color.
|
||||
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
GeomLinestrip *gline = new GeomLinestrip;
|
||||
gline->set_coords(_geom_coords, vindex);
|
||||
gline->set_colors(colors, G_OVERALL);
|
||||
gline->set_lengths(lengths);
|
||||
gline->set_num_prims(lengths.size());
|
||||
|
||||
return gline;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1070,6 +1135,18 @@ throw_change_event() {
|
|||
define_geom_coords();
|
||||
}
|
||||
}
|
||||
if (!_geom_data.is_null()) {
|
||||
if (_geom_data->get_ref_count() == 1) {
|
||||
// No one's using the data any more (there are no references to
|
||||
// it other than this one), so don't bother to recompute it;
|
||||
// just release it.
|
||||
_geom_data.clear();
|
||||
} else {
|
||||
// Someone still has a handle to the data, so recompute it for
|
||||
// them.
|
||||
define_geom_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1659,6 +1736,83 @@ define_geom_coords() {
|
|||
return num_segments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::define_geom_data
|
||||
// Access: Private
|
||||
// Description: Adjusts (or defines for the first time) all the
|
||||
// vertices in the _geom_data to match the properties of
|
||||
// the lens. This will update the visual representation
|
||||
// of the lens's frustum to match the changing
|
||||
// parameters. Returns the number of line segments per
|
||||
// edge.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Lens::
|
||||
define_geom_data() {
|
||||
int num_segments = 1;
|
||||
if (!is_linear()) {
|
||||
num_segments = 10;
|
||||
}
|
||||
|
||||
if (_geom_data == (qpGeomVertexData *)NULL) {
|
||||
_geom_data = new qpGeomVertexData
|
||||
("lens", qpGeomVertexFormat::get_v3(),
|
||||
qpGeomUsageHint::UH_dynamic);
|
||||
}
|
||||
|
||||
qpGeomVertexWriter vertex(_geom_data, InternalName::get_vertex());
|
||||
LPoint3f near_point, far_point;
|
||||
for (int si = 0; si < num_segments; si++) {
|
||||
float t = 2.0f * (float)si / (float)num_segments;
|
||||
|
||||
// Upper left, top edge.
|
||||
LPoint2f p1(-1.0f + t, 1.0f);
|
||||
if (!extrude(p1, near_point, far_point)) {
|
||||
// Hey, this point is off the lens! Can't do a frustum.
|
||||
return 0;
|
||||
}
|
||||
vertex.add_data3f(near_point);
|
||||
vertex.add_data3f(far_point);
|
||||
|
||||
// Upper right, right edge.
|
||||
LPoint2f p2(1.0f, 1.0f - t);
|
||||
if (!extrude(p2, near_point, far_point)) {
|
||||
// Hey, this point is off the lens! Can't do a frustum.
|
||||
return 0;
|
||||
}
|
||||
vertex.add_data3f(near_point);
|
||||
vertex.add_data3f(far_point);
|
||||
|
||||
// Lower right, bottom edge.
|
||||
LPoint2f p3(1.0f - t, -1.0f);
|
||||
if (!extrude(p3, near_point, far_point)) {
|
||||
// Hey, this point is off the lens! Can't do a frustum.
|
||||
return 0;
|
||||
}
|
||||
vertex.add_data3f(near_point);
|
||||
vertex.add_data3f(far_point);
|
||||
|
||||
// Lower left, left edge.
|
||||
LPoint2f p4(-1.0f, -1.0f + t);
|
||||
if (!extrude(p4, near_point, far_point)) {
|
||||
// Hey, this point is off the lens! Can't do a frustum.
|
||||
return 0;
|
||||
}
|
||||
vertex.add_data3f(near_point);
|
||||
vertex.add_data3f(far_point);
|
||||
}
|
||||
|
||||
// Finally, add one more pair for the viewing axis.
|
||||
LPoint3f near_axis = LPoint3f::origin(_cs) + LVector3f::forward(_cs) * _near_distance;
|
||||
LPoint3f far_axis = LPoint3f::origin(_cs) + LVector3f::forward(_cs) * _far_distance;
|
||||
const LMatrix4f &lens_mat = get_lens_mat();
|
||||
near_axis = near_axis * lens_mat;
|
||||
far_axis = far_axis * lens_mat;
|
||||
vertex.add_data3f(near_axis);
|
||||
vertex.add_data3f(far_axis);
|
||||
|
||||
return num_segments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::build_shear_mat
|
||||
// Access: Private, Static
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include "luse.h"
|
||||
#include "geom.h"
|
||||
#include "updateSeq.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
class BoundingVolume;
|
||||
|
||||
|
|
@ -182,6 +184,7 @@ protected:
|
|||
private:
|
||||
static void resequence_fov_triad(char &newest, char &older_a, char &older_b);
|
||||
int define_geom_coords();
|
||||
int define_geom_data();
|
||||
static void build_shear_mat(LMatrix4f &shear_mat,
|
||||
const LPoint3f &cul, const LPoint3f &cur,
|
||||
const LPoint3f &cll, const LPoint3f &clr);
|
||||
|
|
@ -252,6 +255,7 @@ protected:
|
|||
char _focal_length_seq, _fov_seq, _film_size_seq;
|
||||
|
||||
PTA_Vertexf _geom_coords;
|
||||
PT(qpGeomVertexData) _geom_data;
|
||||
|
||||
public:
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
|
|
|||
|
|
@ -107,40 +107,6 @@ modify_primitive(int i) {
|
|||
return cdata->_primitives[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::set_primitive
|
||||
// Access: Published
|
||||
// Description: Replaces the ith GeomPrimitive object stored within
|
||||
// the Geom with the new object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeom::
|
||||
set_primitive(int i, const qpGeomPrimitive *primitive) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
||||
|
||||
// All primitives within a particular Geom must have the same
|
||||
// primitive type.
|
||||
nassertv(cdata->_primitive_type == qpGeomPrimitive::PT_none ||
|
||||
cdata->_primitive_type == primitive->get_primitive_type());
|
||||
if (cdata->_got_usage_hint &&
|
||||
cdata->_primitives[i]->get_usage_hint() != primitive->get_usage_hint()) {
|
||||
if (cdata->_primitives[i]->get_usage_hint() < primitive->get_usage_hint()) {
|
||||
// If we're reducing the usage hint, we might also be reducing
|
||||
// the minimum usage hit.
|
||||
cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint());
|
||||
} else { // (cdata->_primitives[i]->get_usage_hint() > primitive->get_usage_hint())
|
||||
// If we're increasing it, we might have to rederive the minimum.
|
||||
if (cdata->_usage_hint == cdata->_primitives[i]->get_usage_hint()) {
|
||||
cdata->_got_usage_hint = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
cdata->_primitives[i] = (qpGeomPrimitive *)primitive;
|
||||
cdata->_primitive_type = primitive->get_primitive_type();
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_modified
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -133,12 +133,49 @@ modify_vertex_data() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
set_vertex_data(const qpGeomVertexData *data) {
|
||||
nassertv(check_will_be_valid(data));
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_data = (qpGeomVertexData *)data;
|
||||
mark_bound_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::set_primitive
|
||||
// Access: Published
|
||||
// Description: Replaces the ith GeomPrimitive object stored within
|
||||
// the Geom with the new object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
set_primitive(int i, const qpGeomPrimitive *primitive) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
||||
nassertv(primitive->check_valid(cdata->_data));
|
||||
|
||||
// All primitives within a particular Geom must have the same
|
||||
// fundamental primitive type (triangles, points, or lines).
|
||||
nassertv(cdata->_primitive_type == qpGeomPrimitive::PT_none ||
|
||||
cdata->_primitive_type == primitive->get_primitive_type());
|
||||
|
||||
if (cdata->_got_usage_hint &&
|
||||
cdata->_primitives[i]->get_usage_hint() != primitive->get_usage_hint()) {
|
||||
if (cdata->_primitives[i]->get_usage_hint() < primitive->get_usage_hint()) {
|
||||
// If we're reducing the usage hint, we might also be reducing
|
||||
// the minimum usage hit.
|
||||
cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint());
|
||||
} else { // (cdata->_primitives[i]->get_usage_hint() > primitive->get_usage_hint())
|
||||
// If we're increasing it, we might have to rederive the minimum.
|
||||
if (cdata->_usage_hint == cdata->_primitives[i]->get_usage_hint()) {
|
||||
cdata->_got_usage_hint = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
cdata->_primitives[i] = (qpGeomPrimitive *)primitive;
|
||||
cdata->_primitive_type = primitive->get_primitive_type();
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::add_primitive
|
||||
// Access: Published
|
||||
|
|
@ -151,8 +188,11 @@ void qpGeom::
|
|||
add_primitive(const qpGeomPrimitive *primitive) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
nassertv(primitive->check_valid(cdata->_data));
|
||||
|
||||
// All primitives within a particular Geom must have the same
|
||||
// primitive type.
|
||||
// fundamental primitive type (triangles, points, or lines).
|
||||
nassertv(cdata->_primitive_type == qpGeomPrimitive::PT_none ||
|
||||
cdata->_primitive_type == primitive->get_primitive_type());
|
||||
|
||||
|
|
@ -340,6 +380,30 @@ munge_geom(const qpGeomMunger *munger,
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::check_valid
|
||||
// Access: Published
|
||||
// Description: Verifies that the all of the primitives within the
|
||||
// geom reference vertices that actually exist within
|
||||
// the geom's GeomVertexData. Returns true if the geom
|
||||
// appears to be valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeom::
|
||||
check_valid() const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
if (!(*pi)->check_valid(cdata->_data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::output
|
||||
// Access: Published
|
||||
|
|
@ -523,6 +587,32 @@ recompute_bound() {
|
|||
return bound;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::check_will_be_valid
|
||||
// Access: Private
|
||||
// Description: Verifies that the all of the primitives within the
|
||||
// geom reference vertices that actually exist within
|
||||
// the indicated GeomVertexData (presumably in
|
||||
// preparation for assigning the geom to use this data).
|
||||
// Returns true if the data appears to be valid, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeom::
|
||||
check_will_be_valid(const qpGeomVertexData *vertex_data) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
if (!(*pi)->check_valid(vertex_data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::reset_usage_hint
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ PUBLISHED:
|
|||
INLINE int get_num_primitives() const;
|
||||
INLINE const qpGeomPrimitive *get_primitive(int i) const;
|
||||
INLINE qpGeomPrimitive *modify_primitive(int i);
|
||||
INLINE void set_primitive(int i, const qpGeomPrimitive *primitive);
|
||||
void set_primitive(int i, const qpGeomPrimitive *primitive);
|
||||
void add_primitive(const qpGeomPrimitive *primitive);
|
||||
void remove_primitive(int i);
|
||||
void clear_primitives();
|
||||
|
|
@ -84,11 +84,15 @@ PUBLISHED:
|
|||
int get_num_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
// Temporarily virtual.
|
||||
virtual void transform_vertices(const LMatrix4f &mat);
|
||||
|
||||
void munge_geom(const qpGeomMunger *munger,
|
||||
CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const;
|
||||
|
||||
// Temporarily virtual.
|
||||
virtual bool check_valid() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
|
|
@ -109,6 +113,9 @@ public:
|
|||
protected:
|
||||
virtual BoundingVolume *recompute_bound();
|
||||
|
||||
private:
|
||||
bool check_will_be_valid(const qpGeomVertexData *vertex_data) const;
|
||||
|
||||
private:
|
||||
typedef pvector<PT(qpGeomPrimitive) > Primitives;
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,17 @@ get_num_vertices_per_primitive() const {
|
|||
return 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomLines::get_min_num_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the minimum number of vertices that must be
|
||||
// added before close_primitive() may legally be called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomLines::
|
||||
get_min_num_vertices_per_primitive() const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomLines::draw
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
virtual PrimitiveType get_primitive_type() const;
|
||||
|
||||
virtual int get_num_vertices_per_primitive() const;
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
|
|
|
|||
|
|
@ -79,6 +79,17 @@ get_primitive_type() const {
|
|||
return PT_lines;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomLinestrips::get_min_num_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the minimum number of vertices that must be
|
||||
// added before close_primitive() may legally be called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomLinestrips::
|
||||
get_min_num_vertices_per_primitive() const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomLinestrips::draw
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ public:
|
|||
virtual PT(qpGeomPrimitive) make_copy() const;
|
||||
virtual PrimitiveType get_primitive_type() const;
|
||||
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,17 @@ get_num_vertices_per_primitive() const {
|
|||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPoints::get_min_num_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the minimum number of vertices that must be
|
||||
// added before close_primitive() may legally be called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPoints::
|
||||
get_min_num_vertices_per_primitive() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPoints::draw
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
virtual PrimitiveType get_primitive_type() const;
|
||||
|
||||
virtual int get_num_vertices_per_primitive() const;
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
|
|
|
|||
|
|
@ -462,6 +462,19 @@ get_num_bytes() const {
|
|||
cdata->_ends.size() * sizeof(int) + sizeof(qpGeomPrimitive);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::check_valid
|
||||
// Access: Published
|
||||
// Description: Verifies that the primitive only references vertices
|
||||
// that actually exist within the indicated
|
||||
// GeomVertexData. Returns true if the primitive
|
||||
// appears to be valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomPrimitive::
|
||||
check_valid(const qpGeomVertexData *vertex_data) const {
|
||||
return get_max_vertex() < vertex_data->get_num_vertices();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::output
|
||||
// Access: Published, Virtual
|
||||
|
|
|
|||
|
|
@ -139,6 +139,8 @@ PUBLISHED:
|
|||
INLINE int get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
bool check_valid(const qpGeomVertexData *vertex_data) const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -590,6 +590,9 @@ convert_to(const qpGeomVertexFormat *new_format) const {
|
|||
// Access: Published
|
||||
// Description: Returns a new GeomVertexData object with the color
|
||||
// table modified in-place to apply the indicated scale.
|
||||
//
|
||||
// If the vertex data does not include a color column, a
|
||||
// new one will not be added.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexData) qpGeomVertexData::
|
||||
scale_color(const LVecBase4f &color_scale) const {
|
||||
|
|
@ -665,6 +668,9 @@ scale_color(const LVecBase4f &color_scale, int num_components,
|
|||
// Access: Published
|
||||
// Description: Returns a new GeomVertexData object with the color
|
||||
// data modified in-place with the new value.
|
||||
//
|
||||
// If the vertex data does not include a color column, a
|
||||
// new one will not be added.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexData) qpGeomVertexData::
|
||||
set_color(const Colorf &color) const {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
#include "transformState.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "sceneGraphReducer.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -55,39 +58,82 @@ generate() {
|
|||
}
|
||||
|
||||
PT(GeomNode) gnode = new GeomNode(get_name());
|
||||
Geom *geom = new GeomTristrip;
|
||||
gnode->add_geom(geom);
|
||||
|
||||
float left = _frame[0];
|
||||
float right = _frame[1];
|
||||
float bottom = _frame[2];
|
||||
float top = _frame[3];
|
||||
|
||||
PTA_int lengths=PTA_int::empty_array(0);
|
||||
lengths.push_back(4);
|
||||
if (use_qpgeom) {
|
||||
CPT(qpGeomVertexFormat) format;
|
||||
if (_has_uvs) {
|
||||
format = qpGeomVertexFormat::get_v3cpt2();
|
||||
} else {
|
||||
format = qpGeomVertexFormat::get_v3cp();
|
||||
}
|
||||
|
||||
PTA_Vertexf verts;
|
||||
verts.push_back(Vertexf::rfu(left, 0.0f, top));
|
||||
verts.push_back(Vertexf::rfu(left, 0.0f, bottom));
|
||||
verts.push_back(Vertexf::rfu(right, 0.0f, top));
|
||||
verts.push_back(Vertexf::rfu(right, 0.0f, bottom));
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("card", format, qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
|
||||
geom->set_num_prims(1);
|
||||
geom->set_lengths(lengths);
|
||||
vertex.add_data3f(Vertexf::rfu(left, 0.0f, top));
|
||||
vertex.add_data3f(Vertexf::rfu(left, 0.0f, bottom));
|
||||
vertex.add_data3f(Vertexf::rfu(right, 0.0f, top));
|
||||
vertex.add_data3f(Vertexf::rfu(right, 0.0f, bottom));
|
||||
|
||||
geom->set_coords(verts);
|
||||
color.add_data4f(_color);
|
||||
color.add_data4f(_color);
|
||||
color.add_data4f(_color);
|
||||
color.add_data4f(_color);
|
||||
|
||||
PTA_Colorf colors;
|
||||
colors.push_back(_color);
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
if (_has_uvs) {
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
texcoord.add_data2f(_ll[0], _ur[1]);
|
||||
texcoord.add_data2f(_ll[0], _ll[1]);
|
||||
texcoord.add_data2f(_ur[0], _ur[1]);
|
||||
texcoord.add_data2f(_ur[0], _ll[1]);
|
||||
}
|
||||
|
||||
if (_has_uvs) {
|
||||
PTA_TexCoordf uvs;
|
||||
uvs.push_back(TexCoordf(_ll[0], _ur[1]));
|
||||
uvs.push_back(TexCoordf(_ll[0], _ll[1]));
|
||||
uvs.push_back(TexCoordf(_ur[0], _ur[1]));
|
||||
uvs.push_back(TexCoordf(_ur[0], _ll[1]));
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
|
||||
strip->add_next_vertices(4);
|
||||
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
gnode->add_geom(geom);
|
||||
|
||||
} else {
|
||||
Geom *geom = new GeomTristrip;
|
||||
gnode->add_geom(geom);
|
||||
|
||||
PTA_int lengths = PTA_int::empty_array(0);
|
||||
lengths.push_back(4);
|
||||
|
||||
PTA_Vertexf verts;
|
||||
verts.push_back(Vertexf::rfu(left, 0.0f, top));
|
||||
verts.push_back(Vertexf::rfu(left, 0.0f, bottom));
|
||||
verts.push_back(Vertexf::rfu(right, 0.0f, top));
|
||||
verts.push_back(Vertexf::rfu(right, 0.0f, bottom));
|
||||
|
||||
geom->set_num_prims(1);
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
geom->set_coords(verts);
|
||||
|
||||
PTA_Colorf colors;
|
||||
colors.push_back(_color);
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
|
||||
if (_has_uvs) {
|
||||
PTA_TexCoordf uvs;
|
||||
uvs.push_back(TexCoordf(_ll[0], _ur[1]));
|
||||
uvs.push_back(TexCoordf(_ll[0], _ll[1]));
|
||||
uvs.push_back(TexCoordf(_ur[0], _ur[1]));
|
||||
uvs.push_back(TexCoordf(_ur[0], _ll[1]));
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
}
|
||||
}
|
||||
|
||||
return gnode.p();
|
||||
|
|
|
|||
|
|
@ -133,15 +133,14 @@ draw_to(float x, float y, float z) {
|
|||
// created with the color and thickness established by
|
||||
// calls to set_color() and set_thick().
|
||||
//
|
||||
// If frame_accurate is true, the line segments will be
|
||||
// created as a frame-accurate index, so that later
|
||||
// calls to set_vertex or set_vertex_color will be
|
||||
// visually correct.
|
||||
// If dynamic is true, the line segments will be created
|
||||
// with the dynamic Geom setting, optimizing them for
|
||||
// runtime vertex animation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomNode *LineSegs::
|
||||
create(bool frame_accurate) {
|
||||
create(bool dynamic) {
|
||||
GeomNode *gnode = new GeomNode(get_name());
|
||||
return create(gnode, frame_accurate);
|
||||
return create(gnode, dynamic);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
#include "lineSegs.h"
|
||||
#include "renderState.h"
|
||||
#include "renderModeAttrib.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomLinestrips.h"
|
||||
#include "qpgeomPoints.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LineSegs::Constructor
|
||||
|
|
@ -140,86 +144,141 @@ get_current_position() {
|
|||
// thickness established by calls to set_color() and
|
||||
// set_thick().
|
||||
//
|
||||
// If frame_accurate is true, the line segments will be
|
||||
// created as a frame-accurate index, so that later
|
||||
// calls to set_vertex or set_vertex_color will be
|
||||
// visually correct.
|
||||
// If dynamic is true, the line segments will be created
|
||||
// with the dynamic Geom setting, optimizing them for
|
||||
// runtime vertex animation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomNode *LineSegs::
|
||||
create(GeomNode *previous, bool) {
|
||||
create(GeomNode *previous, bool dynamic) {
|
||||
if (!_list.empty()) {
|
||||
_created_verts.clear();
|
||||
_created_colors.clear();
|
||||
|
||||
// One array each for the indices into these arrays for points
|
||||
// and lines, and one for our line-segment lengths array.
|
||||
PTA_ushort point_index;
|
||||
PTA_ushort line_index;
|
||||
PTA_int lengths;
|
||||
|
||||
// Now fill up the arrays.
|
||||
int v = 0;
|
||||
LineList::const_iterator ll;
|
||||
SegmentList::const_iterator sl;
|
||||
|
||||
for (ll = _list.begin(); ll != _list.end(); ll++) {
|
||||
const SegmentList &segs = (*ll);
|
||||
|
||||
if (segs.size() < 2) {
|
||||
point_index.push_back(v);
|
||||
} else {
|
||||
lengths.push_back(segs.size());
|
||||
}
|
||||
|
||||
for (sl = segs.begin(); sl != segs.end(); sl++) {
|
||||
if (segs.size() >= 2) {
|
||||
line_index.push_back(v);
|
||||
}
|
||||
_created_verts.push_back((*sl)._point);
|
||||
_created_colors.push_back((*sl)._color);
|
||||
v++;
|
||||
nassertr(v == (int)_created_verts.size(), previous);
|
||||
}
|
||||
}
|
||||
|
||||
_created_data = NULL;
|
||||
|
||||
CPT(RenderAttrib) thick = RenderModeAttrib::make(RenderModeAttrib::M_unchanged, _thick);
|
||||
CPT(RenderState) state = RenderState::make(thick);
|
||||
|
||||
// Now create the lines.
|
||||
if (line_index.size() > 0) {
|
||||
// Create a new Geom and add the line segments.
|
||||
Geom *geom;
|
||||
if (line_index.size() <= 2) {
|
||||
// Here's a special case: just one line segment.
|
||||
GeomLine *geom_line = new GeomLine;
|
||||
geom_line->set_num_prims(1);
|
||||
geom = geom_line;
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("lineSegs", qpGeomVertexFormat::get_v3cp(),
|
||||
dynamic ? qpGeomUsageHint::UH_dynamic : qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
|
||||
} else {
|
||||
// The more normal case: multiple line segments, connected
|
||||
// end-to-end like a series of linestrips.
|
||||
GeomLinestrip *geom_linestrip = new GeomLinestrip;
|
||||
geom_linestrip->set_num_prims(lengths.size());
|
||||
geom_linestrip->set_lengths(lengths);
|
||||
geom = geom_linestrip;
|
||||
PT(qpGeomLinestrips) lines = new qpGeomLinestrips(qpGeomUsageHint::UH_static);
|
||||
PT(qpGeomPoints) points = new qpGeomPoints(qpGeomUsageHint::UH_static);
|
||||
|
||||
int v = 0;
|
||||
LineList::const_iterator ll;
|
||||
SegmentList::const_iterator sl;
|
||||
|
||||
for (ll = _list.begin(); ll != _list.end(); ll++) {
|
||||
const SegmentList &segs = (*ll);
|
||||
|
||||
if (segs.size() < 2) {
|
||||
// A segment of length 1 is just a point.
|
||||
for (sl = segs.begin(); sl != segs.end(); sl++) {
|
||||
points->add_vertex(v);
|
||||
vertex.add_data3f((*sl)._point);
|
||||
color.add_data4f((*sl)._color);
|
||||
v++;
|
||||
}
|
||||
points->close_primitive();
|
||||
|
||||
} else {
|
||||
// A segment of length 2 or more is a line segment or
|
||||
// segments.
|
||||
for (sl = segs.begin(); sl != segs.end(); sl++) {
|
||||
lines->add_vertex(v);
|
||||
vertex.add_data3f((*sl)._point);
|
||||
color.add_data4f((*sl)._color);
|
||||
v++;
|
||||
}
|
||||
lines->close_primitive();
|
||||
}
|
||||
}
|
||||
|
||||
geom->set_colors(_created_colors, G_PER_VERTEX, line_index);
|
||||
geom->set_coords(_created_verts, line_index);
|
||||
if (lines->get_num_vertices() != 0) {
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(lines);
|
||||
previous->add_geom(geom, state);
|
||||
}
|
||||
if (points->get_num_vertices() != 0) {
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(points);
|
||||
previous->add_geom(geom, state);
|
||||
}
|
||||
|
||||
previous->add_geom(geom, state);
|
||||
}
|
||||
} else {
|
||||
// One array each for the indices into these arrays for points
|
||||
// and lines, and one for our line-segment lengths array.
|
||||
PTA_ushort point_index;
|
||||
PTA_ushort line_index;
|
||||
PTA_int lengths;
|
||||
|
||||
// Now fill up the arrays.
|
||||
int v = 0;
|
||||
LineList::const_iterator ll;
|
||||
SegmentList::const_iterator sl;
|
||||
|
||||
for (ll = _list.begin(); ll != _list.end(); ll++) {
|
||||
const SegmentList &segs = (*ll);
|
||||
|
||||
if (segs.size() < 2) {
|
||||
point_index.push_back(v);
|
||||
} else {
|
||||
lengths.push_back(segs.size());
|
||||
}
|
||||
|
||||
for (sl = segs.begin(); sl != segs.end(); sl++) {
|
||||
if (segs.size() >= 2) {
|
||||
line_index.push_back(v);
|
||||
}
|
||||
_created_verts.push_back((*sl)._point);
|
||||
_created_colors.push_back((*sl)._color);
|
||||
v++;
|
||||
nassertr(v == (int)_created_verts.size(), previous);
|
||||
}
|
||||
}
|
||||
|
||||
// Now create the lines.
|
||||
if (line_index.size() > 0) {
|
||||
// Create a new Geom and add the line segments.
|
||||
Geom *geom;
|
||||
if (line_index.size() <= 2) {
|
||||
// Here's a special case: just one line segment.
|
||||
GeomLine *geom_line = new GeomLine;
|
||||
geom_line->set_num_prims(1);
|
||||
geom = geom_line;
|
||||
|
||||
} else {
|
||||
// The more normal case: multiple line segments, connected
|
||||
// end-to-end like a series of linestrips.
|
||||
GeomLinestrip *geom_linestrip = new GeomLinestrip;
|
||||
geom_linestrip->set_num_prims(lengths.size());
|
||||
geom_linestrip->set_lengths(lengths);
|
||||
geom = geom_linestrip;
|
||||
}
|
||||
|
||||
geom->set_colors(_created_colors, G_PER_VERTEX, line_index);
|
||||
geom->set_coords(_created_verts, line_index);
|
||||
|
||||
previous->add_geom(geom, state);
|
||||
}
|
||||
|
||||
// And now create the points.
|
||||
if (point_index.size() > 0) {
|
||||
// Create a new Geom and add the points.
|
||||
GeomPoint *geom = new GeomPoint;
|
||||
|
||||
geom->set_num_prims(point_index.size());
|
||||
geom->set_colors(_created_colors, G_PER_VERTEX, point_index);
|
||||
geom->set_coords(_created_verts, point_index);
|
||||
|
||||
previous->add_geom(geom, state);
|
||||
// And now create the points.
|
||||
if (point_index.size() > 0) {
|
||||
// Create a new Geom and add the points.
|
||||
GeomPoint *geom = new GeomPoint;
|
||||
|
||||
geom->set_num_prims(point_index.size());
|
||||
geom->set_colors(_created_colors, G_PER_VERTEX, point_index);
|
||||
geom->set_coords(_created_verts, point_index);
|
||||
|
||||
previous->add_geom(geom, state);
|
||||
}
|
||||
}
|
||||
|
||||
// And reset for next time.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "geomLine.h"
|
||||
#include "geomLinestrip.h"
|
||||
#include "geomNode.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "namable.h"
|
||||
|
||||
#include "pvector.h"
|
||||
|
|
@ -58,8 +59,8 @@ PUBLISHED:
|
|||
const Vertexf &get_current_position();
|
||||
bool is_empty();
|
||||
|
||||
INLINE GeomNode *create(bool frame_accurate = false);
|
||||
GeomNode *create(GeomNode *previous, bool frame_accurate = false);
|
||||
INLINE GeomNode *create(bool dynamic = false);
|
||||
GeomNode *create(GeomNode *previous, bool dynamic = false);
|
||||
|
||||
// Functions to move the line vertices after they have been created.
|
||||
INLINE int get_num_vertices() const;
|
||||
|
|
@ -93,6 +94,7 @@ private:
|
|||
|
||||
PTA_Vertexf _created_verts;
|
||||
PTA_Colorf _created_colors;
|
||||
PT(qpGeomVertexData) _created_data;
|
||||
};
|
||||
|
||||
#include "lineSegs.I"
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@
|
|||
#include "config_grutil.h"
|
||||
#include "config_gobj.h"
|
||||
#include "dcast.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
#include "qpgeomVertexReader.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MultitexReducer::Constructor
|
||||
|
|
@ -804,25 +807,39 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
|
|||
GeomList::const_iterator gi;
|
||||
for (gi = geom_list.begin(); gi != geom_list.end(); ++gi) {
|
||||
const GeomInfo &geom_info = (*gi);
|
||||
|
||||
PT(Geom) geom =
|
||||
geom_info._geom_node->get_geom(geom_info._index)->make_copy();
|
||||
const Geom *orig_geom = geom_info._geom_node->get_geom(geom_info._index);
|
||||
|
||||
PTA_Vertexf coords = PTA_Vertexf::empty_array(0);
|
||||
PTA_TexCoordf texcoords = geom->get_texcoords_array(_target_stage->get_texcoord_name());
|
||||
if (!texcoords.empty()) {
|
||||
coords.reserve(texcoords.size());
|
||||
for (size_t i = 0; i < texcoords.size(); i++) {
|
||||
const TexCoordf &tc = texcoords[i];
|
||||
Vertexf v(tc[0], 0.0f, tc[1]);
|
||||
coords.push_back(v);
|
||||
if (orig_geom->is_of_type(qpGeom::get_class_type())) {
|
||||
PT(qpGeom) geom = new qpGeom(*DCAST(qpGeom, orig_geom));
|
||||
PT(qpGeomVertexData) vdata = geom->modify_vertex_data();
|
||||
|
||||
if (vdata->has_column(_target_stage->get_texcoord_name())) {
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexReader texcoord(vdata, _target_stage->get_texcoord_name());
|
||||
|
||||
while (!texcoord.is_at_end()) {
|
||||
const LVecBase2f &tc = texcoord.get_data2f();
|
||||
vertex.set_data3f(tc[0], 0.0f, tc[1]);
|
||||
}
|
||||
}
|
||||
|
||||
geom->set_coords(coords, geom->get_texcoords_index(_target_stage->get_texcoord_name()));
|
||||
if (texcoord_name != (const InternalName *)NULL) {
|
||||
geom->set_texcoords(InternalName::get_texcoord(),
|
||||
geom->get_texcoords_array(texcoord_name),
|
||||
geom->get_texcoords_index(texcoord_name));
|
||||
|
||||
if (texcoord_name != (const InternalName *)NULL &&
|
||||
texcoord_name != InternalName::get_texcoord()) {
|
||||
// Copy the texture coordinates from the indicated name over
|
||||
// to the default name.
|
||||
const qpGeomVertexColumn *column =
|
||||
vdata->get_format()->get_column(texcoord_name);
|
||||
vdata = vdata->replace_column
|
||||
(InternalName::get_texcoord(), column->get_num_components(),
|
||||
column->get_numeric_type(), column->get_contents(),
|
||||
qpGeomUsageHint::UH_stream, true);
|
||||
geom->set_vertex_data(vdata);
|
||||
|
||||
qpGeomVertexReader from(vdata, texcoord_name);
|
||||
qpGeomVertexWriter to(vdata, InternalName::get_texcoord());
|
||||
while (!from.is_at_end()) {
|
||||
to.add_data2f(from.get_data2f());
|
||||
}
|
||||
}
|
||||
|
||||
CPT(RenderState) geom_state = RenderState::make_empty();
|
||||
|
|
@ -839,6 +856,42 @@ transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
|
|||
}
|
||||
|
||||
geom_node->add_geom(geom, geom_state);
|
||||
|
||||
} else {
|
||||
PT(Geom) geom = orig_geom->make_copy();
|
||||
|
||||
PTA_Vertexf coords = PTA_Vertexf::empty_array(0);
|
||||
PTA_TexCoordf texcoords = geom->get_texcoords_array(_target_stage->get_texcoord_name());
|
||||
if (!texcoords.empty()) {
|
||||
coords.reserve(texcoords.size());
|
||||
for (size_t i = 0; i < texcoords.size(); i++) {
|
||||
const TexCoordf &tc = texcoords[i];
|
||||
Vertexf v(tc[0], 0.0f, tc[1]);
|
||||
coords.push_back(v);
|
||||
}
|
||||
|
||||
geom->set_coords(coords, geom->get_texcoords_index(_target_stage->get_texcoord_name()));
|
||||
if (texcoord_name != (const InternalName *)NULL) {
|
||||
geom->set_texcoords(InternalName::get_texcoord(),
|
||||
geom->get_texcoords_array(texcoord_name),
|
||||
geom->get_texcoords_index(texcoord_name));
|
||||
}
|
||||
|
||||
CPT(RenderState) geom_state = RenderState::make_empty();
|
||||
if (preserve_color) {
|
||||
// Be sure to preserve whatever colors are on the geom.
|
||||
const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_type());
|
||||
if (ca != (const RenderAttrib *)NULL) {
|
||||
geom_state = geom_state->add_attrib(ca);
|
||||
}
|
||||
const RenderAttrib *csa = geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type());
|
||||
if (csa != (const RenderAttrib *)NULL) {
|
||||
geom_state = geom_state->add_attrib(csa);
|
||||
}
|
||||
}
|
||||
|
||||
geom_node->add_geom(geom, geom_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@
|
|||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomLinestrips.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
|
||||
TypeHandle RopeNode::_type_handle;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@
|
|||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
|
||||
TypeHandle SheetNode::_type_handle;
|
||||
|
||||
|
|
@ -261,82 +264,148 @@ do_recompute_bound(const NodePath &rel_to) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void SheetNode::
|
||||
render_sheet(CullTraverser *trav, CullTraverserData &data,
|
||||
NurbsSurfaceResult *result) {
|
||||
NurbsSurfaceResult *result) {
|
||||
bool use_vertex_color = get_use_vertex_color();
|
||||
|
||||
PTA_Vertexf verts;
|
||||
PTA_Normalf normals;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
PTA_int lengths;
|
||||
|
||||
// We define a series of triangle strips, parallel to the V
|
||||
// direction.
|
||||
|
||||
int num_u_segments = result->get_num_u_segments();
|
||||
int num_v_segments = result->get_num_v_segments();
|
||||
int num_u_verts = get_num_u_subdiv() + 1;
|
||||
int num_v_verts = get_num_v_subdiv() + 1;
|
||||
|
||||
for (int ui = 0; ui < num_u_segments; ui++) {
|
||||
for (int uni = 0; uni < num_u_verts; uni++) {
|
||||
float u0 = (float)uni / (float)num_u_verts;
|
||||
float u1 = (float)(uni + 1) / (float)num_u_verts;
|
||||
float u0_tc = result->get_segment_u(ui, u0);
|
||||
float u1_tc = result->get_segment_u(ui, u1);
|
||||
if (use_qpgeom) {
|
||||
CPT(qpGeomVertexFormat) format;
|
||||
if (use_vertex_color) {
|
||||
format = qpGeomVertexFormat::get_v3n3cpt2();
|
||||
} else {
|
||||
format = qpGeomVertexFormat::get_v3n3t2();
|
||||
}
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("sheet", format, qpGeomUsageHint::UH_stream);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter normal(vdata, InternalName::get_normal());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_stream);
|
||||
for (int ui = 0; ui < num_u_segments; ui++) {
|
||||
for (int uni = 0; uni < num_u_verts; uni++) {
|
||||
float u0 = (float)uni / (float)num_u_verts;
|
||||
float u1 = (float)(uni + 1) / (float)num_u_verts;
|
||||
float u0_tc = result->get_segment_u(ui, u0);
|
||||
float u1_tc = result->get_segment_u(ui, u1);
|
||||
|
||||
for (int vi = 0; vi < num_v_segments; vi++) {
|
||||
for (int vni = 0; vni < num_v_verts; vni++) {
|
||||
float v = (float)vni / (float)(num_v_verts - 1);
|
||||
float v_tc = result->get_segment_v(vi, v);
|
||||
for (int vi = 0; vi < num_v_segments; vi++) {
|
||||
for (int vni = 0; vni < num_v_verts; vni++) {
|
||||
float v = (float)vni / (float)(num_v_verts - 1);
|
||||
float v_tc = result->get_segment_v(vi, v);
|
||||
|
||||
LPoint3f point;
|
||||
LVector3f normal;
|
||||
result->eval_segment_point(ui, vi, u0, v, point);
|
||||
result->eval_segment_normal(ui, vi, u0, v, normal);
|
||||
verts.push_back(point);
|
||||
normals.push_back(normal);
|
||||
uvs.push_back(TexCoordf(u0_tc, v_tc));
|
||||
LPoint3f point;
|
||||
LVector3f norm;
|
||||
result->eval_segment_point(ui, vi, u0, v, point);
|
||||
result->eval_segment_normal(ui, vi, u0, v, norm);
|
||||
vertex.add_data3f(point);
|
||||
normal.add_data3f(norm);
|
||||
texcoord.add_data2f(u0_tc, v_tc);
|
||||
|
||||
result->eval_segment_point(ui, vi, u1, v, point);
|
||||
result->eval_segment_normal(ui, vi, u1, v, normal);
|
||||
verts.push_back(point);
|
||||
normals.push_back(normal);
|
||||
uvs.push_back(TexCoordf(u1_tc, v_tc));
|
||||
result->eval_segment_point(ui, vi, u1, v, point);
|
||||
result->eval_segment_normal(ui, vi, u1, v, norm);
|
||||
vertex.add_data3f(point);
|
||||
normal.add_data3f(norm);
|
||||
texcoord.add_data2f(u1_tc, v_tc);
|
||||
|
||||
if (use_vertex_color) {
|
||||
Colorf c0, c1;
|
||||
result->eval_segment_extended_points(ui, vi, u0, v, 0, &c0[0], 4);
|
||||
result->eval_segment_extended_points(ui, vi, u1, v, 0, &c1[0], 4);
|
||||
if (use_vertex_color) {
|
||||
Colorf c0, c1;
|
||||
result->eval_segment_extended_points(ui, vi, u0, v, 0, &c0[0], 4);
|
||||
result->eval_segment_extended_points(ui, vi, u1, v, 0, &c1[0], 4);
|
||||
|
||||
colors.push_back(c0);
|
||||
colors.push_back(c1);
|
||||
color.add_data4f(c0);
|
||||
color.add_data4f(c1);
|
||||
}
|
||||
}
|
||||
strip->add_next_vertices(num_v_verts * 2);
|
||||
strip->close_primitive();
|
||||
}
|
||||
lengths.push_back(num_v_verts * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
PT(GeomTristrip) geom = new GeomTristrip;
|
||||
geom->set_num_prims(lengths.size());
|
||||
geom->set_coords(verts);
|
||||
geom->set_normals(normals, G_PER_VERTEX);
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
CullableObject *object = new CullableObject(geom, data._state,
|
||||
data._render_transform);
|
||||
trav->get_cull_handler()->record_object(object);
|
||||
|
||||
if (use_vertex_color) {
|
||||
geom->set_colors(colors, G_PER_VERTEX);
|
||||
} else {
|
||||
PTA_Vertexf verts;
|
||||
PTA_Normalf normals;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Colorf colors;
|
||||
PTA_int lengths;
|
||||
|
||||
// We define a series of triangle strips, parallel to the V
|
||||
// direction.
|
||||
|
||||
for (int ui = 0; ui < num_u_segments; ui++) {
|
||||
for (int uni = 0; uni < num_u_verts; uni++) {
|
||||
float u0 = (float)uni / (float)num_u_verts;
|
||||
float u1 = (float)(uni + 1) / (float)num_u_verts;
|
||||
float u0_tc = result->get_segment_u(ui, u0);
|
||||
float u1_tc = result->get_segment_u(ui, u1);
|
||||
|
||||
for (int vi = 0; vi < num_v_segments; vi++) {
|
||||
for (int vni = 0; vni < num_v_verts; vni++) {
|
||||
float v = (float)vni / (float)(num_v_verts - 1);
|
||||
float v_tc = result->get_segment_v(vi, v);
|
||||
|
||||
LPoint3f point;
|
||||
LVector3f normal;
|
||||
result->eval_segment_point(ui, vi, u0, v, point);
|
||||
result->eval_segment_normal(ui, vi, u0, v, normal);
|
||||
verts.push_back(point);
|
||||
normals.push_back(normal);
|
||||
uvs.push_back(TexCoordf(u0_tc, v_tc));
|
||||
|
||||
result->eval_segment_point(ui, vi, u1, v, point);
|
||||
result->eval_segment_normal(ui, vi, u1, v, normal);
|
||||
verts.push_back(point);
|
||||
normals.push_back(normal);
|
||||
uvs.push_back(TexCoordf(u1_tc, v_tc));
|
||||
|
||||
if (use_vertex_color) {
|
||||
Colorf c0, c1;
|
||||
result->eval_segment_extended_points(ui, vi, u0, v, 0, &c0[0], 4);
|
||||
result->eval_segment_extended_points(ui, vi, u1, v, 0, &c1[0], 4);
|
||||
|
||||
colors.push_back(c0);
|
||||
colors.push_back(c1);
|
||||
}
|
||||
}
|
||||
lengths.push_back(num_v_verts * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
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);
|
||||
PT(GeomTristrip) geom = new GeomTristrip;
|
||||
geom->set_num_prims(lengths.size());
|
||||
geom->set_coords(verts);
|
||||
geom->set_normals(normals, G_PER_VERTEX);
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
|
||||
if (use_vertex_color) {
|
||||
geom->set_colors(colors, G_PER_VERTEX);
|
||||
} else {
|
||||
colors.push_back(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@
|
|||
#include "boundingHexahedron.h"
|
||||
#include "geomSphere.h"
|
||||
#include "portalClipper.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
|
||||
PStatCollector CullTraverser::_nodes_pcollector("Nodes");
|
||||
PStatCollector CullTraverser::_geom_nodes_pcollector("Nodes:GeomNodes");
|
||||
|
|
@ -293,15 +296,47 @@ make_bounds_viz(const BoundingVolume &vol) {
|
|||
|
||||
} else if (vol.is_of_type(BoundingSphere::get_class_type())) {
|
||||
const BoundingSphere *sphere = DCAST(BoundingSphere, &vol);
|
||||
|
||||
geom = new GeomSphere;
|
||||
PTA_Vertexf verts;
|
||||
LPoint3f center = sphere->get_center();
|
||||
verts.push_back(center);
|
||||
center[0] += sphere->get_radius();
|
||||
verts.push_back(center);
|
||||
geom->set_coords(verts);
|
||||
geom->set_num_prims(1);
|
||||
|
||||
if (use_qpgeom) {
|
||||
static const int num_slices = 16;
|
||||
static const int num_stacks = 8;
|
||||
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("collision", qpGeomVertexFormat::get_v3(),
|
||||
qpGeomUsageHint::UH_stream);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_stream);
|
||||
for (int sl = 0; sl < num_slices; ++sl) {
|
||||
float longitude0 = (float)sl / (float)num_slices;
|
||||
float longitude1 = (float)(sl + 1) / (float)num_slices;
|
||||
vertex.add_data3f(compute_point(sphere, 0.0, longitude0));
|
||||
for (int st = 1; st < num_stacks; ++st) {
|
||||
float latitude = (float)st / (float)num_stacks;
|
||||
vertex.add_data3f(compute_point(sphere, latitude, longitude0));
|
||||
vertex.add_data3f(compute_point(sphere, latitude, longitude1));
|
||||
}
|
||||
vertex.add_data3f(compute_point(sphere, 1.0, longitude0));
|
||||
|
||||
strip->add_next_vertices(num_stacks * 2);
|
||||
strip->close_primitive();
|
||||
}
|
||||
|
||||
PT(qpGeom) qpgeom = new qpGeom;
|
||||
qpgeom->set_vertex_data(vdata);
|
||||
qpgeom->add_primitive(strip);
|
||||
geom = qpgeom.p();
|
||||
|
||||
} else {
|
||||
geom = new GeomSphere;
|
||||
PTA_Vertexf verts;
|
||||
LPoint3f center = sphere->get_center();
|
||||
verts.push_back(center);
|
||||
center[0] += sphere->get_radius();
|
||||
verts.push_back(center);
|
||||
geom->set_coords(verts);
|
||||
geom->set_num_prims(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
pgraph_cat.warning()
|
||||
|
|
@ -312,6 +347,25 @@ make_bounds_viz(const BoundingVolume &vol) {
|
|||
return geom;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::compute_point
|
||||
// Access: Private, Static
|
||||
// Description: Returns a point on the surface of the sphere.
|
||||
// latitude and longitude range from 0.0 to 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Vertexf CullTraverser::
|
||||
compute_point(const BoundingSphere *sphere,
|
||||
float latitude, float longitude) {
|
||||
float s1, c1;
|
||||
csincos(latitude * MathNumbers::pi_f, &s1, &c1);
|
||||
|
||||
float s2, c2;
|
||||
csincos(longitude * 2.0f * MathNumbers::pi_f, &s2, &c2);
|
||||
|
||||
Vertexf p(s1 * c2, s1 * s2, c1);
|
||||
return p * sphere->get_radius() + sphere->get_center();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullTraverser::get_bounds_outer_viz_state
|
||||
// Access: Private, Static
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ public:
|
|||
private:
|
||||
void show_bounds(CullTraverserData &data);
|
||||
PT(Geom) make_bounds_viz(const BoundingVolume &vol);
|
||||
static Vertexf compute_point(const BoundingSphere *sphere,
|
||||
float latitude, float longitude);
|
||||
CPT(RenderState) get_bounds_outer_viz_state();
|
||||
CPT(RenderState) get_bounds_inner_viz_state();
|
||||
CPT(RenderState) get_depth_offset_state();
|
||||
|
|
|
|||
|
|
@ -121,27 +121,6 @@ set_geom_state(int n, const RenderState *state) {
|
|||
cdata->_geoms[n]._state = state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::add_geom
|
||||
// Access: Published
|
||||
// Description: Adds a new Geom to the node. The geom is given the
|
||||
// indicated state (which may be
|
||||
// RenderState::make_empty(), to completely inherit its
|
||||
// state from the scene graph).
|
||||
//
|
||||
// The return value is the index number of the new Geom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomNode::
|
||||
add_geom(Geom *geom, const RenderState *state) {
|
||||
nassertr(geom != (Geom *)NULL, -1);
|
||||
nassertr(state != (RenderState *)NULL, -1);
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
cdata->_geoms.push_back(GeomEntry(geom, state));
|
||||
mark_bound_stale();
|
||||
return cdata->_geoms.size() - 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::remove_geom
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -405,6 +405,28 @@ get_legal_collide_mask() const {
|
|||
return CollideMask::all_on();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::add_geom
|
||||
// Access: Published
|
||||
// Description: Adds a new Geom to the node. The geom is given the
|
||||
// indicated state (which may be
|
||||
// RenderState::make_empty(), to completely inherit its
|
||||
// state from the scene graph).
|
||||
//
|
||||
// The return value is the index number of the new Geom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomNode::
|
||||
add_geom(Geom *geom, const RenderState *state) {
|
||||
nassertr(geom != (Geom *)NULL, -1);
|
||||
nassertr(geom->check_valid(), -1);
|
||||
nassertr(state != (RenderState *)NULL, -1);
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
cdata->_geoms.push_back(GeomEntry(geom, state));
|
||||
mark_bound_stale();
|
||||
return cdata->_geoms.size() - 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::add_geoms_from
|
||||
// Access: Published
|
||||
|
|
@ -415,15 +437,16 @@ void GeomNode::
|
|||
add_geoms_from(const GeomNode *other) {
|
||||
CDReader cdata_other(other->_cycler);
|
||||
CDWriter cdata(_cycler);
|
||||
mark_bound_stale();
|
||||
|
||||
Geoms::const_iterator gi;
|
||||
for (gi = cdata_other->_geoms.begin();
|
||||
gi != cdata_other->_geoms.end();
|
||||
++gi) {
|
||||
const GeomEntry &entry = (*gi);
|
||||
nassertv(entry._geom->check_valid());
|
||||
cdata->_geoms.push_back(entry);
|
||||
}
|
||||
mark_bound_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ PUBLISHED:
|
|||
INLINE const RenderState *get_geom_state(int n) const;
|
||||
INLINE void set_geom_state(int n, const RenderState *state);
|
||||
|
||||
INLINE int add_geom(Geom *geom, const RenderState *state = RenderState::make_empty());
|
||||
int add_geom(Geom *geom, const RenderState *state = RenderState::make_empty());
|
||||
void add_geoms_from(const GeomNode *other);
|
||||
INLINE void remove_geom(int n);
|
||||
INLINE void remove_all_geoms();
|
||||
|
|
|
|||
|
|
@ -324,7 +324,13 @@ set_color(Geom *geom, const Colorf &color) {
|
|||
CPT(qpGeomVertexData) &new_data = _qpfcolors[sc];
|
||||
if (new_data.is_null()) {
|
||||
// We have not yet converted these colors. Do so now.
|
||||
new_data = sc._vertex_data->set_color(color);
|
||||
if (sc._vertex_data->has_column(InternalName::get_color())) {
|
||||
new_data = sc._vertex_data->set_color(color);
|
||||
} else {
|
||||
new_data = sc._vertex_data->set_color
|
||||
(color, 1, qpGeomVertexColumn::NT_packed_dabc,
|
||||
qpGeomVertexColumn::C_color);
|
||||
}
|
||||
}
|
||||
|
||||
qpgeom->set_vertex_data(new_data);
|
||||
|
|
@ -399,7 +405,13 @@ transform_colors(Geom *geom, const LVecBase4f &scale) {
|
|||
CPT(qpGeomVertexData) &new_data = _qptcolors[sc];
|
||||
if (new_data.is_null()) {
|
||||
// We have not yet converted these colors. Do so now.
|
||||
new_data = sc._vertex_data->scale_color(scale);
|
||||
if (sc._vertex_data->has_column(InternalName::get_color())) {
|
||||
new_data = sc._vertex_data->scale_color(scale);
|
||||
} else {
|
||||
new_data = sc._vertex_data->set_color
|
||||
(scale, 1, qpGeomVertexColumn::NT_packed_dabc,
|
||||
qpGeomVertexColumn::C_color);
|
||||
}
|
||||
}
|
||||
|
||||
qpgeom->set_vertex_data(new_data);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
#include "nodePath.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "renderState.h"
|
||||
#include "shadeModelAttrib.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
|
||||
// Specifies the UV range of textures applied to the frame. Maybe
|
||||
// we'll have a reason to make this a parameter of the frame style one
|
||||
|
|
@ -170,49 +174,98 @@ generate_into(const NodePath &parent, const LVecBase4f &frame) {
|
|||
PT(PandaNode) PGFrameStyle::
|
||||
generate_flat_geom(const LVecBase4f &frame) {
|
||||
PT(GeomNode) gnode = new GeomNode("flat");
|
||||
Geom *geom = new GeomTristrip;
|
||||
gnode->add_geom(geom);
|
||||
|
||||
float left = frame[0];
|
||||
float right = frame[1];
|
||||
float bottom = frame[2];
|
||||
float top = frame[3];
|
||||
|
||||
PTA_int lengths;
|
||||
lengths.push_back(4);
|
||||
if (use_qpgeom) {
|
||||
CPT(qpGeomVertexFormat) format;
|
||||
if (has_texture()) {
|
||||
format = qpGeomVertexFormat::get_v3cpt2();
|
||||
} else {
|
||||
format = qpGeomVertexFormat::get_v3cp();
|
||||
}
|
||||
|
||||
PTA_Vertexf verts;
|
||||
verts.push_back(Vertexf(left, 0.0f, top));
|
||||
verts.push_back(Vertexf(left, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("PGFrame", format, qpGeomUsageHint::UH_static);
|
||||
|
||||
geom->set_num_prims(1);
|
||||
geom->set_lengths(lengths);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
vertex.add_data3f(left, 0.0f, top);
|
||||
vertex.add_data3f(left, 0.0f, bottom);
|
||||
vertex.add_data3f(right, 0.0f, top);
|
||||
vertex.add_data3f(right, 0.0f, bottom);
|
||||
|
||||
geom->set_coords(verts);
|
||||
|
||||
PTA_Colorf colors;
|
||||
colors.push_back(_color);
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
|
||||
if (has_texture()) {
|
||||
// Generate UV's.
|
||||
left = uv_range[0];
|
||||
right = uv_range[1];
|
||||
bottom = uv_range[2];
|
||||
top = uv_range[3];
|
||||
if (has_texture()) {
|
||||
// Generate UV's.
|
||||
left = uv_range[0];
|
||||
right = uv_range[1];
|
||||
bottom = uv_range[2];
|
||||
top = uv_range[3];
|
||||
|
||||
PTA_TexCoordf uvs;
|
||||
uvs.push_back(TexCoordf(left, top));
|
||||
uvs.push_back(TexCoordf(left, bottom));
|
||||
uvs.push_back(TexCoordf(right, top));
|
||||
uvs.push_back(TexCoordf(right, bottom));
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
texcoord.add_data2f(left, top);
|
||||
texcoord.add_data2f(left, bottom);
|
||||
texcoord.add_data2f(right, top);
|
||||
texcoord.add_data2f(right, bottom);
|
||||
}
|
||||
|
||||
CPT(RenderState) state =
|
||||
RenderState::make(TextureAttrib::make(get_texture()));
|
||||
gnode->set_geom_state(0, state);
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
|
||||
strip->add_next_vertices(4);
|
||||
strip->close_primitive();
|
||||
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
gnode->add_geom(geom);
|
||||
|
||||
if (has_texture()) {
|
||||
CPT(RenderState) state =
|
||||
RenderState::make(TextureAttrib::make(get_texture()));
|
||||
gnode->set_geom_state(0, state);
|
||||
}
|
||||
|
||||
} else {
|
||||
Geom *geom = new GeomTristrip;
|
||||
gnode->add_geom(geom);
|
||||
|
||||
PTA_int lengths;
|
||||
lengths.push_back(4);
|
||||
|
||||
PTA_Vertexf verts;
|
||||
verts.push_back(Vertexf(left, 0.0f, top));
|
||||
verts.push_back(Vertexf(left, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
|
||||
geom->set_num_prims(1);
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
geom->set_coords(verts);
|
||||
|
||||
PTA_Colorf colors;
|
||||
colors.push_back(_color);
|
||||
geom->set_colors(colors, G_OVERALL);
|
||||
|
||||
if (has_texture()) {
|
||||
// Generate UV's.
|
||||
left = uv_range[0];
|
||||
right = uv_range[1];
|
||||
bottom = uv_range[2];
|
||||
top = uv_range[3];
|
||||
|
||||
PTA_TexCoordf uvs;
|
||||
uvs.push_back(TexCoordf(left, top));
|
||||
uvs.push_back(TexCoordf(left, bottom));
|
||||
uvs.push_back(TexCoordf(right, top));
|
||||
uvs.push_back(TexCoordf(right, bottom));
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
|
||||
CPT(RenderState) state =
|
||||
RenderState::make(TextureAttrib::make(get_texture()));
|
||||
gnode->set_geom_state(0, state);
|
||||
}
|
||||
}
|
||||
|
||||
return gnode.p();
|
||||
|
|
@ -328,52 +381,109 @@ generate_bevel_geom(const LVecBase4f &frame, bool in) {
|
|||
min(_color[2] * top_color_scale, 1.0f),
|
||||
_color[3]);
|
||||
|
||||
// Now make the tristrips.
|
||||
Geom *geom = new GeomTristrip;
|
||||
gnode->add_geom(geom);
|
||||
|
||||
PTA_int lengths;
|
||||
PTA_Vertexf verts;
|
||||
PTA_Colorf colors;
|
||||
if (use_qpgeom) {
|
||||
CPT(qpGeomVertexFormat) format = qpGeomVertexFormat::get_v3cp();
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("PGFrame", format, qpGeomUsageHint::UH_static);
|
||||
|
||||
// Tristrip 1.
|
||||
lengths.push_back(8);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
|
||||
// Tristrip 1.
|
||||
vertex.add_data3f(right, 0.0f, bottom);
|
||||
vertex.add_data3f(inner_right, 0.0f, inner_bottom);
|
||||
vertex.add_data3f(left, 0.0f, bottom);
|
||||
vertex.add_data3f(inner_left, 0.0f, inner_bottom);
|
||||
vertex.add_data3f(left, 0.0f, top);
|
||||
vertex.add_data3f(inner_left, 0.0f, inner_top);
|
||||
vertex.add_data3f(right, 0.0f, top);
|
||||
vertex.add_data3f(inner_right, 0.0f, inner_top);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cleft);
|
||||
color.add_data4f(cleft);
|
||||
color.add_data4f(ctop);
|
||||
color.add_data4f(ctop);
|
||||
|
||||
strip->add_next_vertices(8);
|
||||
strip->close_primitive();
|
||||
|
||||
// Tristrip 2.
|
||||
vertex.add_data3f(right, 0.0f, bottom);
|
||||
vertex.add_data3f(right, 0.0f, top);
|
||||
vertex.add_data3f(inner_right, 0.0f, inner_bottom);
|
||||
vertex.add_data3f(inner_right, 0.0f, inner_top);
|
||||
vertex.add_data3f(inner_left, 0.0f, inner_bottom);
|
||||
vertex.add_data3f(inner_left, 0.0f, inner_top);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(_color);
|
||||
color.add_data4f(_color);
|
||||
|
||||
strip->add_next_vertices(6);
|
||||
strip->close_primitive();
|
||||
strip->set_shade_model(qpGeomPrimitive::SM_flat_last_vertex);
|
||||
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
CPT(RenderState) flat_state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_flat));
|
||||
gnode->add_geom(geom, flat_state);
|
||||
|
||||
} else {
|
||||
// Now make the tristrips.
|
||||
Geom *geom = new GeomTristrip;
|
||||
gnode->add_geom(geom);
|
||||
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(left, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(left, 0.0f, top));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
|
||||
PTA_int lengths;
|
||||
PTA_Vertexf verts;
|
||||
PTA_Colorf colors;
|
||||
|
||||
// Tristrip 1.
|
||||
lengths.push_back(8);
|
||||
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(left, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(left, 0.0f, top));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
|
||||
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(ctop);
|
||||
|
||||
// Tristrip 2.
|
||||
lengths.push_back(6);
|
||||
// Tristrip 2.
|
||||
lengths.push_back(6);
|
||||
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
|
||||
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(_color);
|
||||
colors.push_back(_color);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(_color);
|
||||
colors.push_back(_color);
|
||||
|
||||
geom->set_num_prims(2);
|
||||
geom->set_lengths(lengths);
|
||||
geom->set_coords(verts);
|
||||
geom->set_colors(colors, G_PER_COMPONENT);
|
||||
geom->set_num_prims(2);
|
||||
geom->set_lengths(lengths);
|
||||
geom->set_coords(verts);
|
||||
geom->set_colors(colors, G_PER_COMPONENT);
|
||||
}
|
||||
|
||||
// For now, beveled and grooved geoms don't support textures. Easy
|
||||
// to add if anyone really wants this.
|
||||
|
|
@ -537,75 +647,158 @@ generate_groove_geom(const LVecBase4f &frame, bool in) {
|
|||
min(_color[2] * top_color_scale, 1.0f),
|
||||
_color[3]);
|
||||
|
||||
// Now make the tristrips.
|
||||
Geom *geom = new GeomTristrip;
|
||||
gnode->add_geom(geom);
|
||||
|
||||
PTA_int lengths;
|
||||
PTA_Vertexf verts;
|
||||
PTA_Colorf colors;
|
||||
if (use_qpgeom) {
|
||||
CPT(qpGeomVertexFormat) format = qpGeomVertexFormat::get_v3cp();
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("PGFrame", format, qpGeomUsageHint::UH_static);
|
||||
|
||||
// Tristrip 1.
|
||||
lengths.push_back(8);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
|
||||
// Tristrip 1.
|
||||
vertex.add_data3f(right, 0.0f, bottom);
|
||||
vertex.add_data3f(mid_right, 0.0f, mid_bottom);
|
||||
vertex.add_data3f(left, 0.0f, bottom);
|
||||
vertex.add_data3f(mid_left, 0.0f, mid_bottom);
|
||||
vertex.add_data3f(left, 0.0f, top);
|
||||
vertex.add_data3f(mid_left, 0.0f, mid_top);
|
||||
vertex.add_data3f(right, 0.0f, top);
|
||||
vertex.add_data3f(mid_right, 0.0f, mid_top);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cleft);
|
||||
color.add_data4f(cleft);
|
||||
color.add_data4f(ctop);
|
||||
color.add_data4f(ctop);
|
||||
|
||||
strip->add_next_vertices(8);
|
||||
strip->close_primitive();
|
||||
|
||||
// Tristrip 2.
|
||||
vertex.add_data3f(mid_right, 0.0f, mid_bottom);
|
||||
vertex.add_data3f(inner_right, 0.0f, inner_bottom);
|
||||
vertex.add_data3f(mid_left, 0.0f, mid_bottom);
|
||||
vertex.add_data3f(inner_left, 0.0f, inner_bottom);
|
||||
vertex.add_data3f(mid_left, 0.0f, mid_top);
|
||||
vertex.add_data3f(inner_left, 0.0f, inner_top);
|
||||
vertex.add_data3f(mid_right, 0.0f, mid_top);
|
||||
vertex.add_data3f(inner_right, 0.0f, inner_top);
|
||||
color.add_data4f(ctop);
|
||||
color.add_data4f(ctop);
|
||||
color.add_data4f(ctop);
|
||||
color.add_data4f(ctop);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cbottom);
|
||||
color.add_data4f(cbottom);
|
||||
|
||||
strip->add_next_vertices(8);
|
||||
strip->close_primitive();
|
||||
|
||||
// Tristrip 3.
|
||||
vertex.add_data3f(right, 0.0f, bottom);
|
||||
vertex.add_data3f(right, 0.0f, top);
|
||||
vertex.add_data3f(mid_right, 0.0f, mid_bottom);
|
||||
vertex.add_data3f(mid_right, 0.0f, mid_top);
|
||||
vertex.add_data3f(inner_right, 0.0f, inner_bottom);
|
||||
vertex.add_data3f(inner_right, 0.0f, inner_top);
|
||||
vertex.add_data3f(inner_left, 0.0f, inner_bottom);
|
||||
vertex.add_data3f(inner_left, 0.0f, inner_top);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cright);
|
||||
color.add_data4f(cleft);
|
||||
color.add_data4f(cleft);
|
||||
color.add_data4f(_color);
|
||||
color.add_data4f(_color);
|
||||
|
||||
strip->add_next_vertices(8);
|
||||
strip->close_primitive();
|
||||
|
||||
strip->set_shade_model(qpGeomPrimitive::SM_flat_last_vertex);
|
||||
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
CPT(RenderState) flat_state = RenderState::make(ShadeModelAttrib::make(ShadeModelAttrib::M_flat));
|
||||
gnode->add_geom(geom, flat_state);
|
||||
|
||||
} else {
|
||||
// Now make the tristrips.
|
||||
Geom *geom = new GeomTristrip;
|
||||
gnode->add_geom(geom);
|
||||
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(left, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(mid_left, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(left, 0.0f, top));
|
||||
verts.push_back(Vertexf(mid_left, 0.0f, mid_top));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
|
||||
PTA_int lengths;
|
||||
PTA_Vertexf verts;
|
||||
PTA_Colorf colors;
|
||||
|
||||
// Tristrip 1.
|
||||
lengths.push_back(8);
|
||||
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(left, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(mid_left, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(left, 0.0f, top));
|
||||
verts.push_back(Vertexf(mid_left, 0.0f, mid_top));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
|
||||
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(ctop);
|
||||
|
||||
// Tristrip 2.
|
||||
lengths.push_back(8);
|
||||
// Tristrip 2.
|
||||
lengths.push_back(8);
|
||||
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(mid_left, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(mid_left, 0.0f, mid_top));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(mid_left, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(mid_left, 0.0f, mid_top));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
|
||||
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(ctop);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cbottom);
|
||||
colors.push_back(cbottom);
|
||||
|
||||
// Tristrip 3.
|
||||
lengths.push_back(8);
|
||||
// Tristrip 3.
|
||||
lengths.push_back(8);
|
||||
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(right, 0.0f, bottom));
|
||||
verts.push_back(Vertexf(right, 0.0f, top));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_bottom));
|
||||
verts.push_back(Vertexf(mid_right, 0.0f, mid_top));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(inner_right, 0.0f, inner_top));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_bottom));
|
||||
verts.push_back(Vertexf(inner_left, 0.0f, inner_top));
|
||||
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(_color);
|
||||
colors.push_back(_color);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cright);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(cleft);
|
||||
colors.push_back(_color);
|
||||
colors.push_back(_color);
|
||||
|
||||
geom->set_num_prims(3);
|
||||
geom->set_lengths(lengths);
|
||||
geom->set_coords(verts);
|
||||
geom->set_colors(colors, G_PER_COMPONENT);
|
||||
geom->set_num_prims(3);
|
||||
geom->set_lengths(lengths);
|
||||
geom->set_coords(verts);
|
||||
geom->set_colors(colors, G_PER_COMPONENT);
|
||||
}
|
||||
|
||||
// For now, beveled and grooved geoms don't support textures. Easy
|
||||
// to add if anyone really wants this.
|
||||
|
|
|
|||
|
|
@ -125,21 +125,15 @@ make_geom(int bitmap_top, int bitmap_left, float advance, float poly_margin,
|
|||
// Create a corresponding tristrip.
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
(string(), qpGeomVertexFormat::get_v3cpt2(),
|
||||
(string(), qpGeomVertexFormat::get_v3t2(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter color(vdata, InternalName::get_color());
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
vertex.add_data3f(left, 0, top);
|
||||
vertex.add_data3f(left, 0, bottom);
|
||||
vertex.add_data3f(right, 0, top);
|
||||
vertex.add_data3f(right, 0, bottom);
|
||||
|
||||
color.add_data4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
color.add_data4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
color.add_data4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
color.add_data4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
texcoord.add_data2f(uv_left, uv_top);
|
||||
texcoord.add_data2f(uv_left, uv_bottom);
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ make_frame() {
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("text", qpGeomVertexFormat::get_v3cp(),
|
||||
("text", qpGeomVertexFormat::get_v3(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
|
||||
|
|
@ -681,7 +681,7 @@ make_card() {
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("text", qpGeomVertexFormat::get_v3cpt2(),
|
||||
("text", qpGeomVertexFormat::get_v3t2(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
|
|
@ -766,7 +766,7 @@ make_card_with_border() {
|
|||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
("text", qpGeomVertexFormat::get_v3cpt2(),
|
||||
("text", qpGeomVertexFormat::get_v3t2(),
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexWriter vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
|
||||
|
|
|
|||
Loading…
Reference in New Issue