mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 18:03:56 -04:00
Added code from treeform
This commit is contained in:
parent
6c16f96c94
commit
6d4d8f8ea9
@ -19,6 +19,7 @@
|
||||
movieTexture.I movieTexture.h \
|
||||
fisheyeMaker.I fisheyeMaker.h \
|
||||
frameRateMeter.I frameRateMeter.h \
|
||||
meshDrawer.I meshDrawer.h \
|
||||
geoMipTerrain.I geoMipTerrain.h \
|
||||
heightfieldTesselator.I heightfieldTesselator.h \
|
||||
lineSegs.I lineSegs.h \
|
||||
@ -35,6 +36,7 @@
|
||||
fisheyeMaker.cxx \
|
||||
config_grutil.cxx \
|
||||
frameRateMeter.cxx \
|
||||
meshDrawer.cxx \
|
||||
geoMipTerrain.cxx \
|
||||
heightfieldTesselator.cxx \
|
||||
nodeVertexTransform.cxx \
|
||||
@ -50,6 +52,7 @@
|
||||
movieTexture.I movieTexture.h \
|
||||
fisheyeMaker.I fisheyeMaker.h \
|
||||
frameRateMeter.I frameRateMeter.h \
|
||||
meshDrawer.I meshDrawer.h \
|
||||
geoMipTerrain.I geoMipTerrain.h \
|
||||
heightfieldTesselator.I heightfieldTesselator.h \
|
||||
lineSegs.I lineSegs.h \
|
||||
|
@ -4,3 +4,4 @@
|
||||
#include "nodeVertexTransform.cxx"
|
||||
#include "pipeOcclusionCullTraverser.cxx"
|
||||
#include "rigidBodyCombiner.cxx"
|
||||
#include "meshDrawer.cxx"
|
||||
|
129
panda/src/grutil/meshDrawer.I
Normal file
129
panda/src/grutil/meshDrawer.I
Normal file
@ -0,0 +1,129 @@
|
||||
// Filename: meshDrawer.I
|
||||
// Created by: treeform (19dec08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lpoint2.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::Constructor
|
||||
// Access: Published
|
||||
// Description: Creates the MeshDrawer low level system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE MeshDrawer::
|
||||
MeshDrawer() {
|
||||
_root = NodePath("MeshDrawer");
|
||||
_at_start = 0;
|
||||
_bv = NULL;
|
||||
_vertex = NULL;
|
||||
_normal = NULL;
|
||||
_uv = NULL;
|
||||
_color = NULL;
|
||||
_budget = 5000;
|
||||
_plate_size = 16;
|
||||
_frame_size = 1.0f / float(_plate_size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::Destructor
|
||||
// Access: Published
|
||||
// Description: Destroys the MeshDrawer low level system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE MeshDrawer::
|
||||
~MeshDrawer() {
|
||||
_root.remove_node();
|
||||
if (_vertex != NULL) delete _vertex;
|
||||
if (_normal != NULL) delete _normal;
|
||||
if (_uv != NULL) delete _uv;
|
||||
if (_color != NULL) delete _color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::set_plate_size
|
||||
// Access: Published
|
||||
// Description: Sets the number of images are on one side
|
||||
// of a sqare plate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void MeshDrawer::
|
||||
set_plate_size(int one_side_size) {
|
||||
_plate_size = one_side_size;
|
||||
_frame_size = 1.0f / float(_plate_size);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::get_plate_size
|
||||
// Access: Published
|
||||
// Description: Gets the number of images are on one side
|
||||
// of a sqare plate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int MeshDrawer::
|
||||
get_plate_size() {
|
||||
return _plate_size;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::get_root
|
||||
// Access: Published
|
||||
// Description: Returns the root NodePath.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE NodePath MeshDrawer::
|
||||
get_root() {
|
||||
return _root;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::set_budget
|
||||
// Access: Published
|
||||
// Description: Sets the total budget of particles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void MeshDrawer::
|
||||
set_budget(int total_budget) {
|
||||
_budget = total_budget;
|
||||
generator(_budget);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::get_budget()
|
||||
// Access: Published
|
||||
// Description: Gets the total budget of particles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int MeshDrawer::
|
||||
get_budget() {
|
||||
return _budget;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::tri
|
||||
// Access: Published
|
||||
// Description: Draws a triangle with the given parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void MeshDrawer::tri(LVector3f v1, LVector4f c1, LVector2f uv1,
|
||||
LVector3f v2, LVector4f c2, LVector2f uv2,
|
||||
LVector3f v3, LVector4f c3, LVector2f uv3) {
|
||||
|
||||
if( _clear_index > _end_clear_index) return;
|
||||
|
||||
_vertex->add_data3f(v1);
|
||||
_color->add_data4f(c1);
|
||||
_uv->add_data2f(uv1);
|
||||
|
||||
_vertex->add_data3f(v2);
|
||||
_color->add_data4f(c2);
|
||||
_uv->add_data2f(uv2);
|
||||
|
||||
_vertex->add_data3f(v3);
|
||||
_color->add_data4f(c3);
|
||||
_uv->add_data2f(uv3);
|
||||
|
||||
_clear_index += 1;
|
||||
}
|
509
panda/src/grutil/meshDrawer.cxx
Normal file
509
panda/src/grutil/meshDrawer.cxx
Normal file
@ -0,0 +1,509 @@
|
||||
// Filename: meshDrawer.cxx
|
||||
// Created by: treeform (19dec08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "meshDrawer.h"
|
||||
|
||||
#include "geomVertexFormat.h"
|
||||
#include "geomVertexArrayFormat.h"
|
||||
#include "geomVertexData.h"
|
||||
#include "geomVertexWriter.h"
|
||||
#include "geomVertexRewriter.h"
|
||||
#include "camera.h"
|
||||
#include "boundingSphere.h"
|
||||
#include "geomTristrips.h"
|
||||
#include "geomTriangles.h"
|
||||
#include "geom.h"
|
||||
#include "geomNode.h"
|
||||
#include "pnmPainter.h"
|
||||
#include "pnmBrush.h"
|
||||
#include "lvecBase4.h"
|
||||
#include "lvector3.h"
|
||||
#include "pandaNode.h"
|
||||
|
||||
TypeHandle MeshDrawer::_type_handle;
|
||||
|
||||
float randFloat() {
|
||||
return ((float) rand() / (float) 0x7fffffff);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::generator
|
||||
// Access: Private
|
||||
// Description: Creates a system with a given budget.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::generator(int budget) {
|
||||
// create enough triangles for budget:
|
||||
_vdata = new GeomVertexData(_root.get_name(), GeomVertexFormat::get_v3n3c4t2(), Geom::UH_static);//UH_dynamic);
|
||||
GeomVertexWriter *tvertex = new GeomVertexWriter(_vdata, "vertex");
|
||||
GeomVertexWriter *tnormal = new GeomVertexWriter(_vdata, "normal");
|
||||
GeomVertexWriter *tuv = new GeomVertexWriter(_vdata, "texcoord");
|
||||
GeomVertexWriter *tcolor = new GeomVertexWriter(_vdata, "color");
|
||||
_prim = new GeomTriangles(Geom::UH_static);
|
||||
|
||||
// iterate and fill _up a geom with random data so that it will
|
||||
// not be optimized out by panda3d system
|
||||
for(int i = 0; i < budget; i++) {
|
||||
for( int vert = 0; vert < 3; vert++) {
|
||||
LVector3f vec3 = LVector3f(randFloat()+1000,randFloat(),randFloat())*.001;
|
||||
LVector4f vec4 = LVector4f(1,1,1,randFloat());
|
||||
LVector2f vec2 = LVector2f(0,randFloat());
|
||||
tvertex->add_data3f(vec3);
|
||||
tcolor->add_data4f(vec4);
|
||||
tuv->add_data2f(vec2);
|
||||
tnormal->add_data3f(vec3);
|
||||
}
|
||||
_prim->add_vertices(i * 3, i * 3 + 1, i * 3 + 2);
|
||||
}
|
||||
// create our node and attach it to this node path
|
||||
_prim->close_primitive();
|
||||
_geom = new Geom(_vdata);
|
||||
_geom->add_primitive(_prim);
|
||||
_geomnode = new GeomNode("__MeshDrawer_GeomNode");
|
||||
_geomnode->add_geom(_geom);
|
||||
_root.attach_new_node(_geomnode);
|
||||
_last_clear_index = budget;
|
||||
|
||||
delete tvertex;
|
||||
delete tnormal;
|
||||
delete tuv;
|
||||
delete tcolor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::begin
|
||||
// Access: Published
|
||||
// Description: Pass the current camera node and the root node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::begin(NodePath camera, NodePath render) {
|
||||
// sanity check
|
||||
assert(render.get_error_type() == NodePath::ET_ok);
|
||||
assert(camera.get_error_type() == NodePath::ET_ok);
|
||||
|
||||
// remember our arguments
|
||||
_camera = camera;
|
||||
_render = render;
|
||||
|
||||
// compute some help vectors
|
||||
_eyePos = camera.get_pos();
|
||||
_up = _render.get_relative_vector(camera, LVector3f(0, 0, 1));
|
||||
_right = _render.get_relative_vector(camera, LVector3f(1, 0, 0));
|
||||
_b1 = - _right - _up;
|
||||
_b2 = _right - _up;
|
||||
_b3 = _right + _up;
|
||||
_b4 = - _right + _up;
|
||||
|
||||
// recreate our rewriters
|
||||
if (_vertex != NULL) delete _vertex;
|
||||
if (_normal != NULL) delete _normal;
|
||||
if (_uv != NULL) delete _uv;
|
||||
if (_color != NULL) delete _color;
|
||||
_vertex = new GeomVertexRewriter(_vdata, "vertex");
|
||||
_uv = new GeomVertexRewriter(_vdata, "texcoord");
|
||||
_normal = new GeomVertexRewriter(_vdata, "normal");
|
||||
_color = new GeomVertexRewriter(_vdata, "color");
|
||||
_dprim = _prim->decompose();
|
||||
|
||||
// reseta our clearning indexes
|
||||
_start_clear_index = 0;
|
||||
_end_clear_index = _budget;
|
||||
_clear_index = _start_clear_index;
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::end
|
||||
// Access: Published
|
||||
// Description: Finish the drawing and clearing off the remaining
|
||||
// vertexes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::end() {
|
||||
|
||||
// clear the unused triangles at the end of the buffer
|
||||
for(int i = _clear_index ; i < _last_clear_index; i ++ ) {
|
||||
_vertex->add_data3f(0,0,0);
|
||||
_vertex->add_data3f(0,0,0);
|
||||
_vertex->add_data3f(0,0,0);
|
||||
}
|
||||
// dont clear more then you have too
|
||||
_last_clear_index = _clear_index;
|
||||
|
||||
// delete the re writers
|
||||
delete _vertex; _vertex = NULL;
|
||||
delete _uv; _uv = NULL;
|
||||
delete _normal; _normal = NULL;
|
||||
delete _color; _color = NULL;
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::particle
|
||||
// Access: Published
|
||||
// Description: Draws a particle that is sort of like a bill board
|
||||
// but has an extra rotation component.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::particle(LVector3f pos, int frame, float size, LVector4f _color, float rotation) {
|
||||
|
||||
rotation = rotation / 57.29578;
|
||||
|
||||
LVector3f v1 = pos + _b1*size*sin(rotation) + _b2*size*cos(rotation);
|
||||
LVector3f v2 = pos + _b2*size*sin(rotation) + _b3*size*cos(rotation);
|
||||
LVector3f v3 = pos + _b3*size*sin(rotation) + _b4*size*cos(rotation);
|
||||
LVector3f v4 = pos + _b4*size*sin(rotation) + _b1*size*cos(rotation);
|
||||
|
||||
float u = float(int(frame%_plate_size))*_frame_size;
|
||||
float v = 1.0f-float(int(frame/_plate_size+1))*_frame_size;
|
||||
|
||||
tri(
|
||||
v1, _color, LVector2f(u,v),
|
||||
v2, _color, LVector2f(u+_frame_size,v),
|
||||
v3, _color, LVector2f(u+_frame_size,v+_frame_size));
|
||||
tri(
|
||||
v3, _color, LVector2f(u+_frame_size,v+_frame_size),
|
||||
v4, _color, LVector2f(u,v+_frame_size),
|
||||
v1, _color, LVector2f(u,v));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::billboard
|
||||
// Access: Published
|
||||
// Description: Draws a billboard - particle with no rotation.
|
||||
// Billboards always face the camera.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::billboard(LVector3f pos, int frame, float size, LVector4f _color) {
|
||||
|
||||
LVector3f v1 = pos + _b1*size;
|
||||
LVector3f v2 = pos + _b2*size;
|
||||
LVector3f v3 = pos + _b3*size;
|
||||
LVector3f v4 = pos + _b4*size;
|
||||
|
||||
float u = float(int(frame%_plate_size))*_frame_size;
|
||||
float v = 1.0f-float(int(frame/_plate_size+1))*_frame_size;
|
||||
|
||||
tri(
|
||||
v1, _color, LVector2f(u,v),
|
||||
v2, _color, LVector2f(u+_frame_size,v),
|
||||
v3, _color, LVector2f(u+_frame_size,v+_frame_size));
|
||||
tri(
|
||||
v3, _color, LVector2f(u+_frame_size,v+_frame_size),
|
||||
v4, _color, LVector2f(u,v+_frame_size),
|
||||
v1, _color, LVector2f(u,v));
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::segment
|
||||
// Access: Published
|
||||
// Description: Draws a segment a line with a thickness.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::segment(LVector3f start, LVector3f stop, int frame,
|
||||
float thickness, LVector4f color) {
|
||||
|
||||
float u = float(int(frame%_plate_size))*_frame_size;
|
||||
float v = 1.0f-float(int(frame/_plate_size+1))*_frame_size;
|
||||
|
||||
LVector3f v1 = start - _up*thickness;
|
||||
LVector3f v2 = stop - _up*thickness;
|
||||
LVector3f v3 = stop + _up*thickness;
|
||||
LVector3f v4 = start + _up*thickness;
|
||||
|
||||
tri(v1, color, LVector2f(u,v),
|
||||
v2, color, LVector2f(u+_frame_size,v),
|
||||
v3, color, LVector2f(u+_frame_size,v+_frame_size));
|
||||
tri(v3, color, LVector2f(u+_frame_size,v+_frame_size),
|
||||
v4, color, LVector2f(u,v+_frame_size),
|
||||
v1, color, LVector2f(u,v));
|
||||
|
||||
v1 = start - _right*thickness;
|
||||
v2 = stop - _right*thickness;
|
||||
v3 = stop + _right*thickness;
|
||||
v4 = start + _right*thickness;
|
||||
|
||||
tri(v1, color, LVector2f(u,v),
|
||||
v2, color, LVector2f(u+_frame_size,v),
|
||||
v3, color, LVector2f(u+_frame_size,v+_frame_size));
|
||||
tri(v3, color, LVector2f(u+_frame_size,v+_frame_size),
|
||||
v4, color, LVector2f(u,v+_frame_size),
|
||||
v1, color, LVector2f(u,v));
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::uneven_segment
|
||||
// Access: Published
|
||||
// Description: Draws a segment a line with different thickness
|
||||
// and color on both sides.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::uneven_segment(LVector3f start, LVector3f stop,
|
||||
int frame, int multi_frame,
|
||||
float thickness_start, LVector4f color_start,
|
||||
float thickness_stop, LVector4f color_stop) {
|
||||
|
||||
float u = float(int(frame%_plate_size))*_frame_size;
|
||||
float v = 1.0f-float(int(frame/_plate_size+1))*_frame_size;
|
||||
|
||||
LVector3f v1 = start - _up*thickness_start;
|
||||
LVector3f v2 = stop - _up*thickness_stop;
|
||||
LVector3f v3 = stop + _up*thickness_stop;
|
||||
LVector3f v4 = start + _up*thickness_start;
|
||||
|
||||
tri(v1, color_start, LVector2f(u,v),
|
||||
v2, color_stop, LVector2f(u+_frame_size*multi_frame,v),
|
||||
v3, color_stop, LVector2f(u+_frame_size*multi_frame,v+_frame_size));
|
||||
tri(v3, color_stop, LVector2f(u+_frame_size*multi_frame,v+_frame_size),
|
||||
v4, color_start, LVector2f(u,v+_frame_size),
|
||||
v1, color_start, LVector2f(u,v));
|
||||
|
||||
v1 = start - _right*thickness_start;
|
||||
v2 = stop - _right*thickness_stop;
|
||||
v3 = stop + _right*thickness_stop;
|
||||
v4 = start + _right*thickness_start;
|
||||
|
||||
tri(v1, color_start, LVector2f(u,v),
|
||||
v2, color_stop, LVector2f(u+_frame_size*multi_frame,v),
|
||||
v3, color_stop, LVector2f(u+_frame_size*multi_frame,v+_frame_size));
|
||||
tri(v3, color_stop, LVector2f(u+_frame_size*multi_frame,v+_frame_size),
|
||||
v4, color_start, LVector2f(u,v+_frame_size),
|
||||
v1, color_start, LVector2f(u,v));
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::explosion
|
||||
// Access: Published
|
||||
// Description: Draws number of particles in a sphere like emitter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::explosion(
|
||||
LVector3f pos, int frame, float size, LVector4f _color,
|
||||
int seed, int number, float distance) {
|
||||
srand(seed);
|
||||
LVector3f relative_pos;
|
||||
for(int i = 0; i < number; i++) {
|
||||
relative_pos = LVector3f(randFloat()-.5f,randFloat()-.5f,randFloat()-.5f);
|
||||
relative_pos.normalize();
|
||||
relative_pos *= randFloat()*distance;
|
||||
particle(relative_pos+pos,frame,size,_color,randFloat()*360.0f);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::stream
|
||||
// Access: Published
|
||||
// Description: Draws a number of particles in a big line with a
|
||||
// shift dictated by the offset.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::stream(LVector3f start, LVector3f stop, int frame, float size, LVector4f _color,
|
||||
int number, float offset) {
|
||||
|
||||
offset = offset-floor(offset);
|
||||
LVector3f relative_pos = stop;
|
||||
LVector3f vec = stop - start;
|
||||
float distance = vec.length();
|
||||
for(int i = 0; i < number; i++) {
|
||||
relative_pos = stop + vec * ((i-offset)*(distance/float(number)));
|
||||
billboard(relative_pos,frame,size,_color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::geometry
|
||||
// Access: Published
|
||||
// Description: Draws the geometry that is inside this node path into
|
||||
// the MeshDrawer object. This performs a similar
|
||||
// functions as RigidBodyCombiner but for very
|
||||
// dynamic situations that share the same texture
|
||||
// like physcal chunks of explosions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::geometry(NodePath draw_node) {
|
||||
assert(_render.get_error_type() == NodePath::ET_ok);
|
||||
|
||||
LVector4f color = LVector4f(1,1,1,1);
|
||||
LVector3f vec[3];
|
||||
LVector2f uv[3];
|
||||
|
||||
// process node
|
||||
NodePathCollection geom_collection = draw_node.find_all_matches("**/+GeomNode");
|
||||
for(int i=0; i < geom_collection.get_num_paths(); i++ ) {
|
||||
NodePath current_node_path = geom_collection.get_path(i);
|
||||
PT(GeomNode) geomNode = DCAST(GeomNode, current_node_path.node());
|
||||
|
||||
// process geom node
|
||||
for(int j=0; j<geomNode->get_num_geoms(); j++) {
|
||||
CPT(Geom) geom = geomNode->get_geom(j);
|
||||
CPT(GeomVertexData) v_data = geom->get_vertex_data();
|
||||
GeomVertexReader *prim_vertex_reader = new GeomVertexReader(v_data, "vertex");
|
||||
GeomVertexReader *prim_uv_reader = new GeomVertexReader(v_data, "texcoord");
|
||||
for(int k=0; k <geom->get_num_primitives(); k++) {
|
||||
CPT(GeomPrimitive) prim1 = geom->get_primitive(k);
|
||||
CPT(GeomPrimitive) _prim = prim1->decompose();
|
||||
|
||||
// process primitive
|
||||
for(int p=0; p < _prim->get_num_primitives();p++) {
|
||||
int s = _prim->get_primitive_start(p);
|
||||
int e = _prim->get_primitive_end(p);
|
||||
int indx_over = 0;
|
||||
|
||||
// process polygon
|
||||
for(int idx=s; idx<e; idx++) {
|
||||
int vidx = _prim->get_vertex(idx);
|
||||
prim_vertex_reader->set_row(vidx);
|
||||
prim_uv_reader->set_row(vidx);
|
||||
vec[indx_over] = _render.get_relative_point(
|
||||
current_node_path,prim_vertex_reader->get_data3f());
|
||||
uv[indx_over] = prim_uv_reader->get_data2f();
|
||||
indx_over++;
|
||||
if (indx_over > 2) break;
|
||||
}
|
||||
|
||||
// draw polygon
|
||||
tri(vec[0],color,uv[0],
|
||||
vec[1],color,uv[1],
|
||||
vec[2],color,uv[2]);
|
||||
}
|
||||
// if we are over budget just quit
|
||||
if( _clear_index > _end_clear_index) return;
|
||||
}
|
||||
// delete our reders
|
||||
delete prim_vertex_reader;
|
||||
delete prim_uv_reader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::link_segment
|
||||
// Access: Published
|
||||
// Description: Stars or continues linked segment.
|
||||
// Control position, frame, thickness and color with
|
||||
// parameters.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::link_segment(LVector3f pos, int frame,
|
||||
float thickness, LVector4f color) {
|
||||
assert(_render.get_error_type() == NodePath::ET_ok);
|
||||
assert(_camera.get_error_type() == NodePath::ET_ok);
|
||||
/*
|
||||
* X
|
||||
* ---X
|
||||
* ===0---X
|
||||
* ===0===0---X
|
||||
* ===0===0===O---X
|
||||
* ===0===0===0===End
|
||||
*
|
||||
* first call marks position X
|
||||
* second call moves position and promises to draw segment
|
||||
* it can't draw it yet because next segment might bend it
|
||||
* third call finally draws segment
|
||||
* and the chain continues till
|
||||
* link_segment_end to flush the linking segments is called.
|
||||
*/
|
||||
|
||||
// mark 1st position
|
||||
if(_at_start==0) {
|
||||
_last_pos = pos;
|
||||
_last_thickness = thickness;
|
||||
_last_color = color;
|
||||
_at_start=1;
|
||||
return;
|
||||
}
|
||||
|
||||
LVector3f start = _last_pos;
|
||||
LVector3f stop = pos;
|
||||
|
||||
LVector3f cam_start3d = _camera.get_relative_point(_render, start);
|
||||
LPoint2f cam_start2d = LVector2f();
|
||||
LVector3f cam_stop3d = _camera.get_relative_point(_render, stop);
|
||||
LPoint2f cam_stop2d = LVector2f();
|
||||
|
||||
PT(Camera) camera = DCAST(Camera, _camera.node());
|
||||
PT(Lens) lens = camera->get_lens();
|
||||
|
||||
bool start_good = lens->project(cam_start3d, cam_start2d);
|
||||
bool stop_good = lens->project(cam_stop3d, cam_stop2d);
|
||||
//if start_good and stop_good:
|
||||
|
||||
LVector2f dif = cam_stop2d - cam_start2d;
|
||||
float rotation = atan2(dif.get_x(),dif.get_y());
|
||||
|
||||
LVector3f now_v1 = start + _b1*(float)(thickness*sin(rotation)) + _b2*(float)(thickness*cos(rotation));
|
||||
LVector3f now_v4 = start + _b4*(float)(thickness*sin(rotation)) + _b1*(float)(thickness*cos(rotation));
|
||||
LVector3f now_v2 = stop + _b2*(float)(thickness*sin(rotation)) + _b3*(float)(thickness*cos(rotation));
|
||||
LVector3f now_v3 = stop + _b3*(float)(thickness*sin(rotation)) + _b4*(float)(thickness*cos(rotation));
|
||||
|
||||
// mark the segment we going to draw
|
||||
// we need to draw it when we know what the next segment looks like
|
||||
// because it can bend it a little
|
||||
if(_at_start==1) {
|
||||
_last_v1 = now_v1;
|
||||
_last_v2 = now_v2;
|
||||
_last_v3 = now_v3;
|
||||
_last_v4 = now_v4;
|
||||
_at_start = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
// draw the last segment a little bent
|
||||
LVector3f v1 = _last_v1;
|
||||
LVector3f v2 = (_last_v2+now_v1)/2.0f;
|
||||
LVector3f v3 = (_last_v3+now_v4)/2.0f;
|
||||
LVector3f v4 = _last_v4;
|
||||
|
||||
// compute this frame
|
||||
float u = float(int(frame%_plate_size))*_frame_size;
|
||||
float v = 1.0f-float(int(frame/_plate_size+1))*_frame_size;
|
||||
|
||||
tri(v1, _last_color, LVector2f(u,v),
|
||||
v2, color, LVector2f(u+_frame_size,v),
|
||||
v3, color, LVector2f(u+_frame_size,v+_frame_size));
|
||||
tri(v3, color, LVector2f(u+_frame_size,v+_frame_size),
|
||||
v4, _last_color, LVector2f(u,v+_frame_size),
|
||||
v1, _last_color, LVector2f(u,v));
|
||||
|
||||
// save this segment
|
||||
_last_v1 = v2;
|
||||
_last_v2 = now_v2;
|
||||
_last_v3 = now_v3;
|
||||
_last_v4 = v3;
|
||||
|
||||
// make this position
|
||||
_last_pos = pos;
|
||||
_last_thickness = thickness;
|
||||
_last_color = color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MeshDrawer::link_segment_end
|
||||
// Access: Published
|
||||
// Description: Finish drawing linked segments, needs at least
|
||||
// two calls to link_segment before it can end
|
||||
// the linked segment.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MeshDrawer::link_segment_end(LVector4f color, int frame)
|
||||
{
|
||||
float u = float(int(frame%_plate_size))*_frame_size;
|
||||
float v = 1.0f-float(int(frame/_plate_size+1))*_frame_size;
|
||||
|
||||
tri(_last_v1, _last_color, LVector2f(u,v),
|
||||
_last_v2, color, LVector2f(u+_frame_size,v),
|
||||
_last_v3, color, LVector2f(u+_frame_size,v+_frame_size));
|
||||
tri(_last_v3, color, LVector2f(u+_frame_size,v+_frame_size),
|
||||
_last_v4, _last_color, LVector2f(u,v+_frame_size),
|
||||
_last_v1, _last_color, LVector2f(u,v));
|
||||
|
||||
_at_start = 0;
|
||||
}
|
145
panda/src/grutil/meshDrawer.h
Normal file
145
panda/src/grutil/meshDrawer.h
Normal file
@ -0,0 +1,145 @@
|
||||
// Filename: meshDrawer.h
|
||||
// Created by: treeform (19dec08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef MESHDRAWER_H
|
||||
#define MESHDRAWER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "luse.h"
|
||||
#include "pandaNode.h"
|
||||
#include "pointerTo.h"
|
||||
#include "lpoint2.h"
|
||||
#include "lvecBase2.h"
|
||||
#include "pnmImage.h"
|
||||
#include "nodePath.h"
|
||||
#include "texture.h"
|
||||
#include "geomVertexFormat.h"
|
||||
#include "geomVertexArrayFormat.h"
|
||||
#include "geomVertexData.h"
|
||||
#include "geomVertexWriter.h"
|
||||
#include "geomVertexRewriter.h"
|
||||
#include "boundingVolume.h"
|
||||
|
||||
#include "nodePathCollection.h"
|
||||
|
||||
#include "geomTristrips.h"
|
||||
#include "geomTriangles.h"
|
||||
#include "geom.h"
|
||||
#include "geomNode.h"
|
||||
#include "nodePath.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : MeshDrawer
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_GRUTIL MeshDrawer : public TypedObject {
|
||||
PUBLISHED:
|
||||
INLINE MeshDrawer();
|
||||
INLINE ~MeshDrawer();
|
||||
|
||||
INLINE void set_plate_size(int plate_size);
|
||||
INLINE int get_plate_size();
|
||||
INLINE void set_budget(int budget);
|
||||
INLINE int get_budget();
|
||||
|
||||
INLINE NodePath get_root();
|
||||
|
||||
void begin(NodePath camera, NodePath render);
|
||||
INLINE void tri(LVector3f v1, LVector4f c1, LVector2f uv1,
|
||||
LVector3f v2, LVector4f c2, LVector2f uv2,
|
||||
LVector3f v3, LVector4f c3, LVector2f uv3);
|
||||
void particle(LVector3f pos, int frame, float size, LVector4f color, float rotation);
|
||||
void billboard(LVector3f pos, int frame, float size, LVector4f color);
|
||||
void segment(LVector3f start, LVector3f stop, int frame, float thickness, LVector4f color);
|
||||
void uneven_segment(LVector3f start, LVector3f stop,
|
||||
int frame, int multi_frame,
|
||||
float thickness_start, LVector4f color_start,
|
||||
float thickness_stop, LVector4f color_stop);
|
||||
|
||||
void link_segment(LVector3f pos, int frame, float thickness, LVector4f color);
|
||||
void link_segment_end(LVector4f color, int frame);
|
||||
|
||||
void explosion(LVector3f pos, int frame, float size, LVector4f color,
|
||||
int seed, int number, float distance);
|
||||
void stream(LVector3f start, LVector3f stop, int frame, float size, LVector4f color,
|
||||
int number, float offset);
|
||||
void geometry(NodePath node);
|
||||
void end();
|
||||
|
||||
private:
|
||||
|
||||
// use vars
|
||||
NodePath _root;
|
||||
NodePath _camera, _render;
|
||||
int _plate_size;
|
||||
float _frame_size;
|
||||
int _budget;
|
||||
|
||||
// store regeneration geoms & nodes
|
||||
PT(Geom) _geom;
|
||||
PT(GeomNode) _geomnode;
|
||||
PT(GeomVertexData) _vdata;
|
||||
PT(GeomTriangles) _prim;
|
||||
CPT(GeomPrimitive) _dprim;
|
||||
|
||||
// writers
|
||||
GeomVertexRewriter *_vertex;
|
||||
GeomVertexRewriter *_normal;
|
||||
GeomVertexRewriter *_uv;
|
||||
GeomVertexRewriter *_color;
|
||||
|
||||
// billboard vectors
|
||||
LVector4f _colorv;
|
||||
LVector3f _normalv;
|
||||
LVector3f _eyePos;
|
||||
LVector3f _b1, _b2, _b3, _b4;
|
||||
LVector3f _up, _right;
|
||||
|
||||
// clear indexes
|
||||
int _last_clear_index, _start_clear_index, _end_clear_index, _clear_index;
|
||||
|
||||
// used for curves
|
||||
int _at_start;
|
||||
LVector3f _last_v1,_last_v2,_last_v3,_last_v4,_last_pos;
|
||||
float _last_thickness;
|
||||
LVector4f _last_color;
|
||||
|
||||
// bounding volume
|
||||
PT(BoundingVolume) _bv;
|
||||
|
||||
// private create all the needed geoms
|
||||
void generator(int budget);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedObject::init_type();
|
||||
register_type(_type_handle, "MeshDrawer",
|
||||
TypedObject::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
};
|
||||
|
||||
#include "meshDrawer.I"
|
||||
|
||||
#endif /*MESHDRAWER_H*/
|
Loading…
x
Reference in New Issue
Block a user