Panda3D
Loading...
Searching...
No Matches
bulletHeightfieldShape.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 bulletHeightfieldShape.cxx
10 * @author enn0x
11 * @date 2010-02-05
12 */
13
15
16#include "config_bullet.h"
17
18#include "bulletWorld.h"
19
20TypeHandle BulletHeightfieldShape::_type_handle;
21
22/**
23 * @brief Creates a collision shape suited for terrains from a rectangular image.
24 * @details Stores the image's brightness values in a vector Bullet can use,
25 * while rotating it 90 degrees to the right.
26 */
27BulletHeightfieldShape::
28BulletHeightfieldShape(const PNMImage &image, PN_stdfloat max_height, BulletUpAxis up) :
29 _max_height(max_height), _up(up) {
30
31 _num_rows = image.get_x_size();
32 _num_cols = image.get_y_size();
33
34 _data = new btScalar[_num_rows * _num_cols];
35
36 for (int row=0; row < _num_rows; row++) {
37 for (int column=0; column < _num_cols; column++) {
38 // Transpose
39 _data[_num_rows * column + row] =
40 // Flip y
41 max_height * image.get_bright(row, _num_cols - column - 1);
42 }
43 }
44
45 _shape = new btHeightfieldTerrainShape(_num_rows,
46 _num_cols,
47 (const void *)_data,
48 max_height,
49 up,
50 true, false);
51 _shape->setUserPointer(this);
52}
53
54/**
55 *
56 */
57btCollisionShape *BulletHeightfieldShape::
58ptr() const {
59
60 return _shape;
61}
62
63/**
64 *
65 */
66void BulletHeightfieldShape::
67set_use_diamond_subdivision(bool flag) {
68 LightMutexHolder holder(BulletWorld::get_global_lock());
69
70 return _shape->setUseDiamondSubdivision(flag);
71}
72
73/**
74 * @brief Creates a collision shape suited for terrains from a rectangular texture.
75 * @details Alternative constructor intended for use with ShaderTerrainMesh. This will
76 * do bilinear sampling at the corners of all texels. Also works with textures
77 * that are non-power-of-two and/or rectangular.
78 */
79BulletHeightfieldShape::
80BulletHeightfieldShape(Texture *tex, PN_stdfloat max_height, BulletUpAxis up) :
81 _max_height(max_height), _up(up) {
82
83 _num_rows = tex->get_x_size() + 1;
84 _num_cols = tex->get_y_size() + 1;
85 _data = new btScalar[_num_rows * _num_cols];
86
87 btScalar step_x = 1.0 / (btScalar)tex->get_x_size();
88 btScalar step_y = 1.0 / (btScalar)tex->get_y_size();
89
90 PT(TexturePeeker) peeker = tex->peek();
91 LColor sample;
92
93 for (int row=0; row < _num_rows; row++) {
94 for (int column=0; column < _num_cols; column++) {
95 if (!peeker->lookup_bilinear(sample, row * step_x, column * step_y)) {
96 bullet_cat.error() << "Could not sample texture." << std::endl;
97 }
98 // Transpose
99 _data[_num_rows * column + row] = max_height * sample.get_x();
100 }
101 }
102
103 _shape = new btHeightfieldTerrainShape(_num_rows,
104 _num_cols,
105 (const void *)_data,
106 max_height,
107 up,
108 true, false);
109 _shape->setUserPointer(this);
110}
111
112/**
113 *
114 */
115BulletHeightfieldShape::
116BulletHeightfieldShape(const BulletHeightfieldShape &copy) {
117 LightMutexHolder holder(BulletWorld::get_global_lock());
118
119 _num_rows = copy._num_rows;
120 _num_cols = copy._num_cols;
121 _max_height = copy._max_height;
122 _up = copy._up;
123
124 size_t size = (size_t)_num_rows * (size_t)_num_cols;
125 _data = new btScalar[size];
126 memcpy(_data, copy._data, size * sizeof(btScalar));
127
128 _shape = new btHeightfieldTerrainShape(_num_rows,
129 _num_cols,
130 (const void *)_data,
131 _max_height,
132 _up,
133 true, false);
134 _shape->setUserPointer(this);
135}
136
137/**
138 * Tells the BamReader how to create objects of type BulletShape.
139 */
142 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
143}
144
145/**
146 * Writes the contents of this object to the datagram for shipping out to a
147 * Bam file.
148 */
150write_datagram(BamWriter *manager, Datagram &dg) {
151 BulletShape::write_datagram(manager, dg);
152 dg.add_stdfloat(get_margin());
153
154 // parameters to serialize:_num_rows,_num_cols,_data,max_height,up,
155 dg.add_int8((int8_t)_up);
156 dg.add_stdfloat(_max_height);
157 dg.add_int32(_num_rows);
158 dg.add_int32(_num_cols);
159
160 size_t size = (size_t)_num_rows * (size_t)_num_cols;
161 for (size_t i = 0; i < size; ++i) {
162 dg.add_stdfloat(_data[i]);
163 }
164}
165
166/**
167 * This function is called by the BamReader's factory when a new object of
168 * type BulletShape is encountered in the Bam file. It should create the
169 * BulletShape and extract its information from the file.
170 */
171TypedWritable *BulletHeightfieldShape::
172make_from_bam(const FactoryParams &params) {
173 // create a default BulletHeightfieldShape
175 DatagramIterator scan;
176 BamReader *manager;
177
178 parse_params(params, scan, manager);
179 param->fillin(scan, manager);
180
181 return param;
182}
183
184/**
185 * This internal function is called by make_from_bam to read in all of the
186 * relevant data from the BamFile for the new BulletShape.
187 */
188void BulletHeightfieldShape::
189fillin(DatagramIterator &scan, BamReader *manager) {
190 BulletShape::fillin(scan, manager);
191 nassertv(_shape == nullptr);
192
193 PN_stdfloat margin = scan.get_stdfloat();
194
195 // parameters to serialize: radius, height, up
196 _up = (BulletUpAxis) scan.get_int8();
197 _max_height = scan.get_stdfloat();
198 _num_rows = scan.get_int32();
199 _num_cols = scan.get_int32();
200
201 size_t size = (size_t)_num_rows * (size_t)_num_cols;
202 delete [] _data;
203 _data = new btScalar[size];
204
205 for (size_t i = 0; i < size; ++i) {
206 _data[i] = scan.get_stdfloat();
207 }
208
209 _shape = new btHeightfieldTerrainShape(_num_rows,
210 _num_cols,
211 (const void *)_data,
212 _max_height,
213 _up,
214 true, false);
215 _shape->setUserPointer(this);
216 _shape->setMargin(margin);
217}
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition bamReader.I:275
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition bamReader.I:177
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition bamWriter.h:63
static void register_with_read_factory()
Tells the BamReader how to create objects of type BulletShape.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
A class to retrieve the individual data elements previously stored in a Datagram.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
int8_t get_int8()
Extracts a signed 8-bit integer.
int32_t get_int32()
Extracts a signed 32-bit integer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
Definition datagram.I:67
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition datagram.I:133
void add_int8(int8_t value)
Adds a signed 8-bit integer to the datagram.
Definition datagram.I:42
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition factory.I:73
Similar to MutexHolder, but for a light mutex.
int get_x_size() const
Returns the number of pixels in the X direction.
int get_y_size() const
Returns the number of pixels in the Y direction.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
Definition pnmImage.h:58
float get_bright(int x, int y) const
Returns the linear brightness of the given xel, as a linearized float in the range 0....
Definition pnmImage.I:869
An instance of this object is returned by Texture::peek().
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition texture.h:72
get_y_size
Returns the height of the texture image in texels.
Definition texture.h:347
get_x_size
Returns the width of the texture image in texels.
Definition texture.h:343
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.