Panda3D

bulletHelper.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file bulletHelper.cxx
10 * @author enn0x
11 * @date 2011-01-19
12 */
13
14 #include "bulletHelper.h"
15
16 #include "bulletRigidBodyNode.h"
17 #include "bulletSoftBodyNode.h"
18 #include "bulletGhostNode.h"
19
20 #include "geomLines.h"
21 #include "geomTriangles.h"
22 #include "geomVertexRewriter.h"
23
24 #include "bullet_utils.h"
25
26 PT(InternalName) BulletHelper::_sb_index;
27 PT(InternalName) BulletHelper::_sb_flip;
28
29 /**
30 *
31 */
32 NodePathCollection BulletHelper::
33 from_collision_solids(NodePath &np, bool clear) {
34
35 NodePathCollection result;
36
37 // Iterate over all CollisionNodes below the given node
38 NodePathCollection npc = np.find_all_matches( "**/+CollisionNode" );
39
40 for (int i=0; i<npc.get_num_paths(); i++) {
41 NodePath cnp = npc.get_path(i);
42 CollisionNode *cnode = DCAST(CollisionNode, cnp.node());
43
44 PT(PandaNode) bnode = nullptr;
45
46 // Create a either a new rigid body or a new ghost for each CollisionNode,
47 // and add one shape per CollisionSolid contained in the CollisionNode
48 if (is_tangible(cnode)) {
49 PT(BulletRigidBodyNode) body;
50
51 body = new BulletRigidBodyNode();
52 body->add_shapes_from_collision_solids(cnode);
53 body->set_transform(cnp.get_transform(np));
54 body->set_into_collide_mask(cnode->get_into_collide_mask());
55 body->set_mass(0.0f);
56 body->set_name(cnode->get_name());
57
58 bnode = body;
59 }
60 else {
61 PT(BulletGhostNode) ghost;
62
63 ghost = new BulletGhostNode();
64 ghost->add_shapes_from_collision_solids(cnode);
65 ghost->set_transform(cnp.get_transform(np));
66 ghost->set_into_collide_mask(cnode->get_into_collide_mask());
67 ghost->set_name(cnode->get_name());
68
69 bnode = ghost;
70 }
71
72 // Remove collision node if requested
73 if (clear) {
74 cnp.remove_node();
75 }
76
77 result.add_path(NodePath::any_path(bnode));
78 }
79
80 return result;
81 }
82
83 /**
84 * Returns TRUE if at least one CollisionSolid of the given CollisionNode is
85 * tangible. Returns FALSE if all CollisionSolids are intangible.
86 */
87 bool BulletHelper::
88 is_tangible(CollisionNode *cnode) {
89
90 for (size_t j = 0; j < cnode->get_num_solids(); ++j) {
91 CPT(CollisionSolid) solid = cnode->get_solid(j);
92 if (solid->is_tangible()) {
93 return true;
94 }
95 }
96
97 return false;
98 }
99
100 /**
101 *
102 */
103 CPT(GeomVertexFormat) BulletHelper::
104 add_sb_index_column(const GeomVertexFormat *format) {
105
106 PT(InternalName) name = BulletHelper::get_sb_index();
107
108 if (format->has_column(name)) return format;
109
110 PT(GeomVertexArrayFormat) array;
111 PT(GeomVertexFormat) unregistered_format;
112 CPT(GeomVertexFormat) registered_format;
113
114 array = new GeomVertexArrayFormat();
115 array->add_column(name, 1, Geom::NT_uint16, Geom::C_index);
116
117 unregistered_format = new GeomVertexFormat(*format);
118 unregistered_format->add_array(array);
119
120 registered_format = GeomVertexFormat::register_format(unregistered_format);
121
122 return registered_format;
123 }
124
125 /**
126 *
127 */
128 CPT(GeomVertexFormat) BulletHelper::
129 add_sb_flip_column(const GeomVertexFormat *format) {
130
131 PT(InternalName) name = BulletHelper::get_sb_flip();
132
133 if (format->has_column(name)) return format;
134
135 PT(GeomVertexArrayFormat) array;
136 PT(GeomVertexFormat) unregistered_format;
137 CPT(GeomVertexFormat) registered_format;
138
139 array = new GeomVertexArrayFormat();
140 array->add_column(name, 1, Geom::NT_uint8, Geom::C_other);
141
142 unregistered_format = new GeomVertexFormat(*format);
143 unregistered_format->add_array(array);
144
145 registered_format = GeomVertexFormat::register_format(unregistered_format);
146
147 return registered_format;
148 }
149
150 /**
151 *
152 */
153 PT(Geom) BulletHelper::
154 make_geom_from_faces(BulletSoftBodyNode *node, const GeomVertexFormat *format, bool two_sided) {
155
156 return make_geom(node, format, two_sided, true);
157 }
158
159 /**
160 *
161 */
162 PT(Geom) BulletHelper::
163 make_geom_from_links(BulletSoftBodyNode *node, const GeomVertexFormat *format) {
164
165 return make_geom(node, format, false, false);
166 }
167
168 /**
169 *
170 */
171 PT(Geom) BulletHelper::
172 make_geom(BulletSoftBodyNode *node, const GeomVertexFormat *format, bool two_sided, bool use_faces) {
173
174 btTransform trans = btTransform::getIdentity();
175 get_node_transform(trans, node);
176
177 btSoftBody *body = (btSoftBody *)node->get_object();
178
179 PT(Geom) geom;
180 PT(GeomPrimitive) prim;
181 PT(GeomVertexData) vdata;
182
183 CPT(GeomVertexFormat) fmt = (format) ? format : GeomVertexFormat::get_v3n3t2();
184 fmt = BulletHelper::add_sb_flip_column(fmt);
185
186 nassertr(fmt->has_column(InternalName::get_vertex()), nullptr);
187 nassertr(fmt->has_column(InternalName::get_normal()), nullptr);
188
189 btSoftBody::tNodeArray &nodes(body->m_nodes);
190
191 // Vertex data
192 vdata = new GeomVertexData("", fmt, Geom::UH_stream);
193
194 GeomVertexWriter vwriter(vdata, InternalName::get_vertex());
195 GeomVertexWriter nwriter(vdata, InternalName::get_normal());
196 GeomVertexWriter fwriter(vdata, BulletHelper::get_sb_flip());
197
198 for (int j=0; j<nodes.size(); ++j) {
199 btVector3 v = nodes[j].m_x;
200 btVector3 &n = nodes[j].m_n;
201
202 v = trans.invXform(v);
203
204 vwriter.add_data3((PN_stdfloat)v.getX(), (PN_stdfloat)v.getY(), (PN_stdfloat)v.getZ());
205 nwriter.add_data3((PN_stdfloat)n.getX(), (PN_stdfloat)n.getY(), (PN_stdfloat)n.getZ());
206 fwriter.add_data1i(0);
207 }
208
209 if (two_sided) {
210 for (int j=0; j<nodes.size(); ++j) {
211 btVector3 v = nodes[j].m_x;
212 btVector3 &n = nodes[j].m_n;
213
214 v = trans.invXform(v);
215
216 vwriter.add_data3((PN_stdfloat)v.getX(), (PN_stdfloat)v.getY(), (PN_stdfloat)v.getZ());
217 nwriter.add_data3((PN_stdfloat)n.getX(), (PN_stdfloat)n.getY(), (PN_stdfloat)n.getZ());
218 fwriter.add_data1i(1);
219 }
220 }
221
222 // Indices
223 btSoftBody::Node *node0 = &nodes[0];
224 int i0, i1, i2;
225
226 if (use_faces) {
227
228 btSoftBody::tFaceArray &faces(body->m_faces);
229
230 prim = new GeomTriangles(Geom::UH_stream);
231 prim->set_shade_model(Geom::SM_uniform);
232
233 for (int j=0; j<faces.size(); ++j) {
234 i0 = int(faces[j].m_n[0] - node0);
235 i1 = int(faces[j].m_n[1] - node0);
236 i2 = int(faces[j].m_n[2] - node0);
237
238 prim->add_vertices(i0, i1, i2);
239 prim->close_primitive();
240
241 if (two_sided) {
242 i0 = nodes.size() + int(faces[j].m_n[0] - node0);
243 i1 = nodes.size() + int(faces[j].m_n[2] - node0);
244 i2 = nodes.size() + int(faces[j].m_n[1] - node0);
245
246 prim->add_vertices(i0, i1, i2);
247 prim->close_primitive();
248 }
249 }
250 }
251 else {
252 btSoftBody::tLinkArray &links(body->m_links);
253
254 prim = new GeomLines(Geom::UH_stream);
255 prim->set_shade_model(Geom::SM_uniform);
256
257 for (int j=0; j<links.size(); ++j) {
258 i0 = int(links[j].m_n[0] - node0);
259 i1 = int(links[j].m_n[1] - node0);
260
261 prim->add_vertices(i0, i1);
262 prim->close_primitive();
263 }
264 }
265
266 // Geom
267 geom = new Geom(vdata);
268 geom->add_primitive(prim);
269
270 return geom;
271 }
272
273 /**
274 *
275 */
276 void BulletHelper::
277 make_texcoords_for_patch(Geom *geom, int resx, int resy) {
278
279 PT(GeomVertexData) vdata = geom->modify_vertex_data();
280
281 nassertv(vdata->has_column(InternalName::get_texcoord()));
282
283 GeomVertexRewriter texcoords(vdata, InternalName::get_texcoord());
284
285 int n = resx * resy;
286 int i = 0;
287 int ix;
288 int iy;
289 float u;
290 float v;
291
292 while (!texcoords.is_at_end()) {
293 ix = i / resx;
294 iy = i % resy;
295
296 if (i > n) ix -= 1;
297
298 u = (float)ix/(float)(resx - 1);
299 v = (float)iy/(float)(resy - 1);
300
301 texcoords.set_data2f(u, v);
302 i++;
303 }
304 }
bulletGhostNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CPT
CPT(GeomVertexFormat) BulletHelper
Given a source GeomVertexFormat, converts it if necessary to the appropriate format for rendering.
Definition: bulletHelper.cxx:103
PT
PT(Geom) BulletHelper
Returns a bounding-box visualization of the indicated node's "tight" bounding volume.
Definition: bulletHelper.cxx:153
bulletHelper.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bulletRigidBodyNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bulletSoftBodyNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bullet_utils.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BulletGhostNode
Definition: bulletGhostNode.h:31
BulletRigidBodyNode
Definition: bulletRigidBodyNode.h:31
BulletSoftBodyNode
Definition: bulletSoftBodyNode.h:71
CollisionNode
A node in the scene graph that can hold any number of CollisionSolids.
Definition: collisionNode.h:30
CollisionNode::get_into_collide_mask
get_into_collide_mask
Returns the current "into" CollideMask.
Definition: collisionNode.h:61
CollisionSolid
The abstract base class for all things that can collide with other things in the world,...
Definition: collisionSolid.h:45
GeomLines
Defines a series of disconnected line segments.
Definition: geomLines.h:23
GeomPrimitive
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56
GeomTriangles
Defines a series of disconnected triangles.
Definition: geomTriangles.h:23
GeomVertexArrayFormat
This describes the structure of a single array within a Geom data.
Definition: geomVertexArrayFormat.h:47
GeomVertexData
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
Definition: geomVertexData.h:68
GeomVertexFormat
This class defines the physical layout of the vertex data stored within a Geom.
Definition: geomVertexFormat.h:55
GeomVertexFormat::get_v3n3t2
static const GeomVertexFormat * get_v3n3t2()
Returns a standard vertex format with a 2-component texture coordinate pair, a 3-component normal,...
Definition: geomVertexFormat.I:278
GeomVertexFormat::has_column
has_column
Returns true if the format has the named column, false otherwise.
Definition: geomVertexFormat.h:129
GeomVertexRewriter
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter,...
Definition: geomVertexRewriter.h:33
GeomVertexWriter
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
Definition: geomVertexWriter.h:55
Geom
A container for geometry primitives.
Definition: geom.h:54
InternalName
Encodes a string name in a hash table, mapping it to a pointer.
Definition: internalName.h:38
NodePathCollection
This is a set of zero or more NodePaths.
Definition: nodePathCollection.h:26
NodePathCollection::add_path
void add_path(const NodePath &node_path)
Adds a new NodePath to the collection.
Definition: nodePathCollection.cxx:29
NodePathCollection::get_num_paths
get_num_paths
Returns the number of NodePaths in the collection.
Definition: nodePathCollection.h:47
NodePathCollection::get_path
get_path
Returns the nth NodePath in the collection.
Definition: nodePathCollection.h:47
NodePath
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
NodePath::any_path
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node.
Definition: nodePath.I:62
NodePath::remove_node
void remove_node(Thread *current_thread=Thread::get_current_thread())
Disconnects the referenced node from the scene graph.
Definition: nodePath.cxx:624
NodePath::find_all_matches
NodePathCollection find_all_matches(const std::string &path) const
Returns the complete set of all NodePaths that begin with this NodePath and can be extended by path.
Definition: nodePath.cxx:354
NodePath::node
PandaNode * node() const
Returns the referenced node of the path.
Definition: nodePath.I:227
NodePath::get_transform
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition: nodePath.cxx:791
PandaNode
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
geomLines.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomTriangles.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
geomVertexRewriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.