15 #include "meshDrawer.h"
17 #include "geomVertexFormat.h"
18 #include "geomVertexArrayFormat.h"
19 #include "geomVertexData.h"
20 #include "geomVertexWriter.h"
21 #include "geomVertexRewriter.h"
23 #include "boundingSphere.h"
24 #include "geomTristrips.h"
25 #include "geomTriangles.h"
28 #include "pnmPainter.h"
30 #include "lvecBase4.h"
32 #include "pandaNode.h"
36 PN_stdfloat randFloat() {
37 return ((PN_stdfloat) rand() / (PN_stdfloat) 0x7fffffff);
45 void MeshDrawer::generator(
int budget) {
56 for(
int i = 0; i < budget; i++) {
57 for(
int vert = 0; vert < 3; vert++) {
61 tvertex->add_data3(vec3);
66 _prim->add_vertices(i * 3, i * 3 + 1, i * 3 + 2);
69 _prim->close_primitive();
70 _geom =
new Geom(_vdata);
71 _geom->add_primitive(_prim);
72 _geomnode =
new GeomNode(
"__MeshDrawer_GeomNode");
73 _geomnode->add_geom(_geom);
75 _last_clear_index = budget;
103 _b1 = - _right - _up;
106 _b4 = - _right + _up;
109 if (_vertex != NULL)
delete _vertex;
110 if (_normal != NULL)
delete _normal;
111 if (_uv != NULL)
delete _uv;
112 if (_color != NULL)
delete _color;
114 if (_vdata == NULL) {
122 _dprim = _prim->decompose();
125 _start_clear_index = 0;
126 _end_clear_index = _budget;
127 _clear_index = _start_clear_index;
140 for(
int i = _clear_index ; i < _last_clear_index; i ++ ) {
146 _last_clear_index = _clear_index;
149 delete _vertex; _vertex = NULL;
150 delete _uv; _uv = NULL;
151 delete _normal; _normal = NULL;
152 delete _color; _color = NULL;
166 rotation = rotation / 57.29578;
168 LVector3 v1 = pos + _b1*size*sin(rotation) + _b2*size*cos(rotation);
169 LVector3 v2 = pos + _b2*size*sin(rotation) + _b3*size*cos(rotation);
170 LVector3 v3 = pos + _b3*size*sin(rotation) + _b4*size*cos(rotation);
171 LVector3 v4 = pos + _b4*size*sin(rotation) + _b1*size*cos(rotation);
173 PN_stdfloat u = frame.get_x();
174 PN_stdfloat v = frame.get_y();
175 PN_stdfloat us = frame.get_z();
176 PN_stdfloat vs = frame.get_w();
196 const LVector4 &frame2, PN_stdfloat blend, PN_stdfloat size,
const LVector4 &
color, PN_stdfloat rotation) {
199 PN_stdfloat original_w = c2.get_w();
200 c2.set_w((1.f-blend)*original_w);
201 particle(pos,frame1,size,c2,rotation);
202 c2.set_w(blend*original_w);
203 particle(pos,frame2,size,c2,rotation);
222 PN_stdfloat u = frame.get_x();
223 PN_stdfloat v = frame.get_y();
224 PN_stdfloat us = frame.get_z();
225 PN_stdfloat vs = frame.get_w();
263 PN_stdfloat u = frame.get_x();
264 PN_stdfloat v = frame.get_y();
265 PN_stdfloat us = frame.get_z();
266 PN_stdfloat vs = frame.get_w();
268 LVector3 v1 = start - _up*thickness;
271 LVector3 v4 = start + _up*thickness;
280 v1 = start - _right*thickness;
281 v2 = stop - _right*thickness;
282 v3 = stop + _right*thickness;
283 v4 = start + _right*thickness;
306 const LVector4 &frame, PN_stdfloat thickness_start,
const LVector4 &color_start,
307 PN_stdfloat thickness_stop,
const LVector4 &color_stop) {
309 PN_stdfloat u = frame.get_x();
310 PN_stdfloat v = frame.get_y();
311 PN_stdfloat us = frame.get_z();
312 PN_stdfloat vs = frame.get_w();
314 LVector3 v1 = start - _up*thickness_start;
315 LVector3 v2 = stop - _up*thickness_stop;
316 LVector3 v3 = stop + _up*thickness_stop;
317 LVector3 v4 = start + _up*thickness_start;
321 v3, color_stop,
LVector2(u+us,v+vs));
326 v1 = start - _right*thickness_start;
327 v2 = stop - _right*thickness_stop;
328 v3 = stop + _right*thickness_stop;
329 v4 = start + _right*thickness_start;
333 v3, color_stop,
LVector2(u+us,v+vs));
347 int seed,
int number, PN_stdfloat distance) {
350 for(
int i = 0; i < number; i++) {
351 relative_pos =
LVector3(randFloat()-.5f,randFloat()-.5f,randFloat()-.5f);
353 relative_pos *= randFloat()*distance;
354 particle(relative_pos+pos,frame,size,_color,randFloat()*360.0f);
366 int number, PN_stdfloat offset) {
368 offset = offset-floor(offset);
371 PN_stdfloat distance = vec.
length();
373 for(
int i = 0; i < number; i++) {
374 relative_pos = start + vec * ((i+offset)*(distance/PN_stdfloat(number)));
375 billboard(relative_pos,frame,size,_color);
405 for(
int j=0; j<geomNode->get_num_geoms(); j++) {
406 CPT(
Geom) geom = geomNode->get_geom(j);
410 for(
int k=0; k <geom->get_num_primitives(); k++) {
415 for(
int p=0; p < _prim->get_num_primitives();p++) {
416 int s = _prim->get_primitive_start(p);
417 int e = _prim->get_primitive_end(p);
421 for(
int idx=s; idx<e; idx++) {
422 int vidx = _prim->get_vertex(idx);
426 current_node_path,prim_vertex_reader->
get_data3());
427 uv[indx_over] = prim_uv_reader->
get_data2();
429 if (indx_over > 2)
break;
433 tri(vec[0],color,uv[0],
438 if( _clear_index > _end_clear_index)
return;
441 delete prim_vertex_reader;
442 delete prim_uv_reader;
481 _last_thickness = thickness;
496 PT(
Lens) lens = camera->get_lens();
498 lens->project(cam_start3d, cam_start2d);
499 lens->project(cam_stop3d, cam_stop2d);
501 LVector2 dif = cam_stop2d - cam_start2d;
502 PN_stdfloat rotation = atan2(dif.get_x(),dif.get_y());
504 LVector3 now_v1 = start + _b1*(PN_stdfloat)(thickness*sin(rotation)) + _b2*(PN_stdfloat)(thickness*cos(rotation));
505 LVector3 now_v4 = start + _b4*(PN_stdfloat)(thickness*sin(rotation)) + _b1*(PN_stdfloat)(thickness*cos(rotation));
506 LVector3 now_v2 = stop + _b2*(PN_stdfloat)(thickness*sin(rotation)) + _b3*(PN_stdfloat)(thickness*cos(rotation));
507 LVector3 now_v3 = stop + _b3*(PN_stdfloat)(thickness*sin(rotation)) + _b4*(PN_stdfloat)(thickness*cos(rotation));
523 LVector3 v2 = (_last_v2+now_v1)/2.0f;
524 LVector3 v3 = (_last_v3+now_v4)/2.0f;
528 PN_stdfloat u = frame.get_x();
529 PN_stdfloat v = frame.get_y();
530 PN_stdfloat us = frame.get_z();
531 PN_stdfloat vs = frame.get_w();
548 _last_thickness = thickness;
562 PN_stdfloat u = frame.get_x();
563 PN_stdfloat v = frame.get_y();
564 PN_stdfloat us = frame.get_z();
565 PN_stdfloat vs = frame.get_w();
569 _last_v3, color,
LVector2(u+us,v+vs));
571 _last_v4, _last_color,
LVector2(u,v+vs),
572 _last_v1, _last_color,
LVector2(u,v));
void segment(const LVector3 &start, const LVector3 &stop, const LVector4 &frame, PN_stdfloat thickness, const LVector4 &color)
Draws a segment a line with a thickness.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void explosion(const LVector3 &pos, const LVector4 &frame, PN_stdfloat size, const LVector4 &color, int seed, int number, PN_stdfloat distance)
Draws number of particles in a sphere like emitter.
A base class for any number of different kinds of lenses, linear and otherwise.
void billboard(const LVector3 &pos, const LVector4 &frame, PN_stdfloat size, const LVector4 &color)
Draws a billboard - particle with no rotation.
void end()
Finish the drawing and clearing off the remaining vertexes.
const LVecBase2 & get_data2()
Returns the data associated with the read row, expressed as a 2-component value, and advances the rea...
NodePath get_path(int index) const
Returns the nth NodePath in the collection.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
void add_data2(PN_stdfloat x, PN_stdfloat y)
Sets the write row to a particular 2-component value, and advances the write row. ...
PandaNode * node() const
Returns the referenced node of the path.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
int get_num_paths() const
Returns the number of NodePaths in the collection.
ErrorType get_error_type() const
If is_empty() is true, this returns a code that represents the reason why the NodePath is empty...
void add_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row. ...
float length() const
Returns the length of the vector, by the Pythagorean theorem.
LPoint3 get_pos() const
Retrieves the translation component of the transform.
string get_name() const
Returns the name of the referenced node.
void stream(const LVector3 &start, const LVector3 &stop, const LVector4 &frame, PN_stdfloat size, const LVector4 &color, int number, PN_stdfloat offset)
Draws a number of particles in a big line with a shift dictated by the offset.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
A container for geometry primitives.
const LVecBase3 & get_data3()
Returns the data associated with the read row, expressed as a 3-component value, and advances the rea...
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
This is a four-component vector distance.
void blended_particle(const LVector3 &pos, const LVector4 &frame1, const LVector4 &frame2, PN_stdfloat blend, PN_stdfloat size, const LVector4 &color, PN_stdfloat rotation)
Works just like particle but accepts 2 frames and a blend (from 0 to 1) component between them Frame ...
void cross_segment(const LVector3 &start, const LVector3 &stop, const LVector4 &frame, PN_stdfloat thickness, const LVector4 &color)
Draws a segment a line with a thickness.
LVector3 get_relative_vector(const NodePath &other, const LVecBase3 &vec) const
Given that the indicated vector is in the coordinate system of the other node, returns the same vecto...
void tri(const LVector3 &v1, const LVector4 &c1, const LVector2 &uv1, const LVector3 &v2, const LVector4 &c2, const LVector2 &uv2, const LVector3 &v3, const LVector4 &c3, const LVector2 &uv3)
Draws a triangle with the given parameters.
This is a two-component vector offset.
void particle(const LVector3 &pos, const LVector4 &frame, PN_stdfloat size, const LVector4 &color, PN_stdfloat rotation)
Draws a particle that is sort of like a bill board but has an extra rotation component.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
NodePathCollection find_all_matches(const string &path) const
Returns the complete set of all NodePaths that begin with this NodePath and can be extended by path...
Defines a series of disconnected triangles.
void link_segment_end(const LVector4 &frame, const LVector4 &color)
Finish drawing linked segments, needs at least two calls to link_segment before it can end the linked...
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
LPoint3 get_relative_point(const NodePath &other, const LVecBase3 &point) const
Given that the indicated point is in the coordinate system of the other node, returns the same point ...
This is a two-component point in space.
TypeHandle is the identifier used to differentiate C++ class types.
A node that can be positioned around in the scene graph to represent a point of view for rendering a ...
void begin(NodePath camera, NodePath render)
Pass the current camera node and the root node.
void uneven_segment(const LVector3 &start, const LVector3 &stop, const LVector4 &frame, PN_stdfloat thickness_start, const LVector4 &color_start, PN_stdfloat thickness_stop, const LVector4 &color_stop)
Draws a segment a line with different thickness and color on both sides.
void geometry(NodePath node)
Draws the geometry that is inside this node path into the MeshDrawer object.
bool normalize()
Normalizes the vector in place.
void link_segment(const LVector3 &pos, const LVector4 &frame, PN_stdfloat thickness, const LVector4 &color)
Stars or continues linked segment.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
A node that holds Geom objects, renderable pieces of geometry.
NodePath attach_new_node(PandaNode *node, int sort=0, Thread *current_thread=Thread::get_current_thread()) const
Attaches a new node, with or without existing parents, to the scene graph below the referenced node o...
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter, combined together into one convenient package.
This is a set of zero or more NodePaths.