Panda3D
Loading...
Searching...
No Matches
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
26PT(InternalName) BulletHelper::_sb_index;
27PT(InternalName) BulletHelper::_sb_flip;
28
29/**
30 *
31 */
32NodePathCollection BulletHelper::
33from_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 */
87bool BulletHelper::
88is_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 */
103CPT(GeomVertexFormat) BulletHelper::
104add_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 */
128CPT(GeomVertexFormat) BulletHelper::
129add_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 */
153PT(Geom) BulletHelper::
154make_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 */
162PT(Geom) BulletHelper::
163make_geom_from_links(BulletSoftBodyNode *node, const GeomVertexFormat *format) {
164
165 return make_geom(node, format, false, false);
166}
167
168/**
169 *
170 */
171PT(Geom) BulletHelper::
172make_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 */
276void BulletHelper::
277make_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}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node in the scene graph that can hold any number of CollisionSolids.
get_into_collide_mask
Returns the current "into" CollideMask.
The abstract base class for all things that can collide with other things in the world,...
Defines a series of disconnected line segments.
Definition geomLines.h:23
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Defines a series of disconnected triangles.
This describes the structure of a single array within a Geom data.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This class defines the physical layout of the vertex data stored within a Geom.
has_column
Returns true if the format has the named column, false otherwise.
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter,...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
A container for geometry primitives.
Definition geom.h:54
Encodes a string name in a hash table, mapping it to a pointer.
This is a set of zero or more NodePaths.
void add_path(const NodePath &node_path)
Adds a new NodePath to the collection.
get_num_paths
Returns the number of NodePaths in the collection.
get_path
Returns the nth NodePath in the collection.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition nodePath.h:159
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
void remove_node(Thread *current_thread=Thread::get_current_thread())
Disconnects the referenced node from the scene graph.
Definition nodePath.cxx:627
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:357
PandaNode * node() const
Returns the referenced node of the path.
Definition nodePath.I:227
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition nodePath.cxx:794
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.