Panda3D
collisionCone.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 collisionCone.cxx
10  * @author rdb
11  * @date 2021-01-29
12  */
13 
14 #include "collisionCone.h"
15 #include "collisionEntry.h"
16 #include "collisionSphere.h"
17 #include "collisionPolygon.h"
18 #include "config_collide.h"
19 #include "cmath.h"
20 #include "geom.h"
21 #include "geomTrifans.h"
22 #include "geomLinestrips.h"
23 #include "mathNumbers.h"
24 #include "billboardEffect.h"
25 
26 PStatCollector CollisionCone::_volume_pcollector("Collision Volumes:CollisionCone");
27 PStatCollector CollisionCone::_test_pcollector("Collision Tests:CollisionCone");
28 TypeHandle CollisionCone::_type_handle;
29 
30 /**
31  *
32  */
33 CollisionSolid *CollisionCone::
34 make_copy() {
35  return new CollisionCone(*this);
36 }
37 
38 /**
39  * Transforms the solid by the indicated matrix.
40  */
42 xform(const LMatrix4 &mat) {
43  CollisionSolid::xform(mat);
44 }
45 
46 /**
47  * Returns the point in space deemed to be the "origin" of the solid for
48  * collision purposes. The closest intersection point to this origin point is
49  * considered to be the most significant.
50  */
52 get_collision_origin() const {
53  return LPoint3::origin();
54 }
55 
56 /**
57  * Returns a PStatCollector that is used to count the number of bounding
58  * volume tests made against a solid of this type in a given frame.
59  */
62  return _volume_pcollector;
63 }
64 
65 /**
66  * Returns a PStatCollector that is used to count the number of intersection
67  * tests made against a solid of this type in a given frame.
68  */
71  return _test_pcollector;
72 }
73 
74 /**
75  *
76  */
77 void CollisionCone::
78 output(std::ostream &out) const {
79  out << "ccone, (" << _radius << ")";
80 }
81 
82 /**
83  *
84  */
85 PT(BoundingVolume) CollisionCone::
86 compute_internal_bounds() const {
87  return new BoundingSphere(LPoint3(0, 0, 0), std::max(_radius, _apex[2]) * 2);
88 }
89 
90 /**
91  *
92  */
93 PT(CollisionEntry) CollisionCone::
94 test_intersection_from_sphere(const CollisionEntry &entry) const {
95  const CollisionSphere *sphere;
96  DCAST_INTO_R(sphere, entry.get_from(), nullptr);
97 
98  const LMatrix4 &wrt_mat = entry.get_wrt_mat();
99 
100  LPoint3 from_center = sphere->get_center() * wrt_mat;
101  LVector3 from_radius_v =
102  LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
103  PN_stdfloat from_radius = length(from_radius_v);
104 
105  // Distance to center line
106  PN_stdfloat dist_to_line = from_center.get_xy().length();
107  if (dist_to_line > _radius + from_radius) {
108  return nullptr;
109  }
110 
111  if (from_center.get_z() > _apex.get_z() + from_radius) {
112  return nullptr;
113  }
114 
115  LPlane side(LPoint3(_radius, 1, 0), LPoint3(_radius, 0, 0), _apex);
116 
117  PN_stdfloat dist_bottom = from_center.get_z() + from_radius;
118  PN_stdfloat dist_side = side.dist_to_plane(LPoint3(dist_to_line, 0, from_center.get_z())) + from_radius;
119 
120  std::cerr << dist_side << " " << dist_to_line << "\n";
121 
122 
123  if (dist_bottom < 0 || dist_side < 0) {
124  return nullptr;
125  }
126 
127  if (collide_cat.is_debug()) {
128  collide_cat.debug()
129  << "intersection detected from " << entry.get_from_node_path()
130  << " into " << entry.get_into_node_path() << "\n";
131  }
132  PT(CollisionEntry) new_entry = new CollisionEntry(entry);
133 
134  LPoint3 surface_point;
135  LVector3 surface_normal;
136 
137  if (dist_bottom < dist_side) {
138  surface_normal = LVector3(0, 0, -1);
139  surface_point = LPoint3(from_center[0], from_center[1], 0);
140  if (dist_to_line > _radius) {
141  surface_point = surface_point * (_radius / dist_to_line);
142  }
143  }
144  else {
145  surface_normal = side.get_normal();
146  surface_point = get_apex();
147  }
148 
149  LVector3 normal = (
151  ? get_effective_normal() : surface_normal;
152 //
153  new_entry->set_surface_normal(normal);
154  new_entry->set_surface_point(surface_point);
155  //new_entry->set_interior_point(from_center - get_normal() * from_radius);
156 
157  return new_entry;
158 }
159 
160 /**
161  * Fills the _viz_geom GeomNode up with Geoms suitable for rendering this
162  * solid.
163  */
164 void CollisionCone::
165 fill_viz_geom() {
166  if (collide_cat.is_debug()) {
167  collide_cat.debug()
168  << "Recomputing viz for " << *this << "\n";
169  }
170 
171  static int num_base_vertices = 8;
172 
173  PT(GeomVertexData) vdata = new GeomVertexData
174  ("collision", GeomVertexFormat::get_v3(),
175  Geom::UH_static);
176  vdata->unclean_set_num_rows(num_base_vertices + 2);
177 
178  {
179  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
180  double factor = MathNumbers::pi * 2.0 / (double)num_base_vertices;
181  for (int i = 0; i < num_base_vertices; ++i) {
182  double angle = i * factor;
183  vertex.set_data3(ccos(angle) * _radius, csin(angle) * _radius, 0);
184  }
185  vertex.set_data3(0, 0, 0);
186  vertex.set_data3(get_apex());
187  }
188 
189  PT(GeomTrifans) body = new GeomTrifans(Geom::UH_static);
190  body->add_vertex(num_base_vertices);
191  body->add_vertex(0);
192  for (int i = num_base_vertices - 1; i >= 0; --i) {
193  body->add_vertex(i);
194  }
195  body->close_primitive();
196 
197  body->add_vertex(num_base_vertices + 1);
198  body->add_consecutive_vertices(0, num_base_vertices);
199  body->add_vertex(0);
200  body->close_primitive();
201 
202  PT(GeomLinestrips) border = new GeomLinestrips(Geom::UH_static);
203  border->add_consecutive_vertices(0, num_base_vertices);
204  border->add_vertex(0);
205  border->add_vertex(num_base_vertices + 1);
206  border->add_vertex(num_base_vertices / 2);
207  border->close_primitive();
208 
209  PT(Geom) geom1 = new Geom(vdata);
210  geom1->add_primitive(body);
211 
212  PT(Geom) geom2 = new Geom(vdata);
213  geom2->add_primitive(border);
214 
215  _viz_geom->add_geom(geom1, get_solid_viz_state());
216  _viz_geom->add_geom(geom2, get_wireframe_viz_state());
217  _viz_geom->set_effect(BillboardEffect::make_axis());
218 
219  _bounds_viz_geom->add_geom(geom1, get_solid_bounds_viz_state());
220  _bounds_viz_geom->add_geom(geom2, get_wireframe_bounds_viz_state());
221  _bounds_viz_geom->set_effect(BillboardEffect::make_axis());
222 }
223 
224 /**
225  * Function to write the important information in the particular object to a
226  * Datagram
227  */
229 write_datagram(BamWriter *manager, Datagram &me) {
230  CollisionSolid::write_datagram(manager, me);
231  //_plane.write_datagram(me);
232 }
233 
234 /**
235  * Function that reads out of the datagram (or asks manager to read) all of
236  * the data that is needed to re-create this object and stores it in the
237  * appropiate place
238  */
239 void CollisionCone::
240 fillin(DatagramIterator& scan, BamReader* manager)
241 {
242  CollisionSolid::fillin(scan, manager);
243  //_plane.read_datagram(scan);
244 }
245 
246 /**
247  * Factory method to generate a CollisionCone object
248  */
249 TypedWritable *CollisionCone::
250 make_from_bam(const FactoryParams &params) {
251  CollisionCone *me = new CollisionCone;
252  DatagramIterator scan;
253  BamReader *manager;
254 
255  parse_params(params, scan, manager);
256  me->fillin(scan, manager);
257  return me;
258 }
259 
260 /**
261  * Factory method to generate a CollisionCone object
262  */
265  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
266 }
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.
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
This defines a bounding sphere, consisting of a center and a radius.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
This implements a conical solid consisting a circular base with a pointy tip.
Definition: collisionCone.h:23
virtual LPoint3 get_collision_origin() const
Returns the point in space deemed to be the "origin" of the solid for collision purposes.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Function to write the important information in the particular object to a Datagram.
virtual PStatCollector & get_volume_pcollector()
Returns a PStatCollector that is used to count the number of bounding volume tests made against a sol...
static void register_with_read_factory()
Factory method to generate a CollisionCone object.
virtual PStatCollector & get_test_pcollector()
Returns a PStatCollector that is used to count the number of intersection tests made against a solid ...
virtual void xform(const LMatrix4 &mat)
Transforms the solid by the indicated matrix.
Defines a single collision event.
get_from_node_path
Returns the NodePath that represents the CollisionNode that contains the CollisionSolid that triggere...
get_into_node_path
Returns the NodePath that represents the specific CollisionNode or GeomNode instance that was collide...
get_from
Returns the CollisionSolid pointer for the particular solid that triggered this collision.
The abstract base class for all things that can collide with other things in the world,...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
bool has_effective_normal() const
Returns true if a special normal was set by set_effective_normal(), false otherwise.
const LVector3 & get_effective_normal() const
Returns the normal that was set by set_effective_normal().
get_respect_effective_normal
See set_respect_effective_normal().
A spherical collision volume or object.
A class to retrieve the individual data elements previously stored in a Datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
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
Defines a series of line strips.
Defines a series of triangle fans.
Definition: geomTrifans.h:23
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
static const GeomVertexFormat * get_v3()
Returns a standard vertex format with just a 3-component vertex position.
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
A lightweight class that represents a single element that may be timed and/or counted via stats.
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.
Definition: typedWritable.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(BoundingVolume) CollisionCone
Fills the _viz_geom GeomNode up with Geoms suitable for rendering this solid.
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.
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.