diff --git a/panda/src/collide/collisionFloorMesh.cxx b/panda/src/collide/collisionFloorMesh.cxx new file mode 100755 index 0000000000..fb89939c99 --- /dev/null +++ b/panda/src/collide/collisionFloorMesh.cxx @@ -0,0 +1,285 @@ +// Filename: collisionPlane.cxx +// Created by: drose (25Apr00) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +#include "collisionFloorMesh.h" +#include "collisionHandler.h" +#include "collisionEntry.h" +#include "collisionSphere.h" +#include "collisionLine.h" +#include "collisionRay.h" +#include "collisionSegment.h" +#include "config_collide.h" +#include "pointerToArray.h" +#include "geomNode.h" +#include "geom.h" +#include "datagram.h" +#include "datagramIterator.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "boundingPlane.h" +#include "geom.h" +#include "geomTrifans.h" +#include "geomLinestrips.h" +#include "geomVertexWriter.h" +#include +PStatCollector CollisionFloorMesh::_volume_pcollector("Collision Volumes:CollisionFloorMesh"); +PStatCollector CollisionFloorMesh::_test_pcollector("Collision Tests:CollisionFloorMesh"); +TypeHandle CollisionFloorMesh::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: CollisionPlane::make_copy +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CollisionSolid *CollisionFloorMesh:: +make_copy() { + return new CollisionFloorMesh(*this); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionPlane::xform +// Access: Public, Virtual +// Description: Transforms the solid by the indicated matrix. +//////////////////////////////////////////////////////////////////// +void CollisionFloorMesh:: +xform(const LMatrix4f &mat) { + CollisionSolid::xform(mat); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionPlane::get_collision_origin +// Access: Public, Virtual +// Description: Returns the point in space deemed to be the "origin" +// of the solid for collision purposes. The closest +// intersection point to this origin point is considered +// to be the most significant. +//////////////////////////////////////////////////////////////////// +LPoint3f CollisionFloorMesh:: +get_collision_origin() const { + // No real sensible origin exists for a plane. We return 0, 0, 0, + // without even bothering to ensure that that point exists on the + // plane. + return LPoint3f::origin(); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionPlane::output +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void CollisionFloorMesh:: +output(ostream &out) const { + out << "cfloor"; +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::compute_internal_bounds +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +PT(BoundingVolume) CollisionFloorMesh:: +compute_internal_bounds() const { + return new BoundingBox(LPoint3f(0,0,0), LPoint3f(1,1,1)); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::test_intersection_from_ray +// Access: Public, Virtual +// Description: must be a vertical Ray!!! +//////////////////////////////////////////////////////////////////// +PT(CollisionEntry) CollisionFloorMesh:: +test_intersection_from_ray(const CollisionEntry &entry) const { + const CollisionRay *ray; + DCAST_INTO_R(ray, entry.get_from(), 0); + const LMatrix4f &wrt_mat = entry.get_wrt_mat(); + LPoint3f from_origin = ray->get_origin() * wrt_mat; + LVector3f from_direction = ray->get_direction() * wrt_mat; + + double fx=from_origin[0]; + double fy=from_origin[1]; + + CollisionFloorMesh::Triangles::const_iterator ti; + bool collided = false; + for (ti=_triangles.begin();ti< _triangles.end();++ti) { + TriangleIndices tri = *ti; + LPoint3d p0=_vertices[tri.p1]; + LPoint3d p1=_vertices[tri.p2]; + LPoint3d p2=_vertices[tri.p3]; + double p0x = p0[0]; + double p1x = p1[0]; + double p2x = p2[0]; + + double p0y = p0[1]; + double p1y = p1[1]; + double p2y = p2[1]; + + double e0x,e0y,e1x,e1y,e2x,e2y; + double u,v; + + e0x = fx - p0x; e0y = fy - p0y; + e1x = p1x - p0x; e1y = p1y - p0y; + e2x = p2x - p0x; e2y = p2y - p0y; + if (e1x==0) { + if (e2x == 0) continue; + u = e0x/e2x; + if (u<0 || u>1) continue; + if (e1y == 0) continue; + v = ( e0y - (e2y*u))/e1y; + if (v<0) continue; + } else { + double d = (e2y * e1x)-(e2x * e1y); + if (d==0) continue; + u = ((e0y * e1x) - (e0x * e1y))/d; + if (u<0 || u>1) continue; + v = (e0x - (e2x * u)) / e1x; + if (v<0) continue; + if (u + v > 1) continue; + } + //we collided!! + double mag = u + v; + double p0z = p0[2]; + double p1z = p1[2]; + double p2z = p2[2]; + + + double uz = (p2z - p0z) * mag; + double vz = (p1z - p0z) * mag; + double ratio = u/(u+v); + double finalz = vz+((uz - vz) * ratio); + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + + new_entry->set_surface_normal(LPoint3f(0,0,1)); + new_entry->set_surface_point(LPoint3f(fx,fy,finalz)); + return new_entry; + } + return NULL; +} + + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::fill_viz_geom +// Access: Protected, Virtual +// Description: Fills the _viz_geom GeomNode up with Geoms suitable +// for rendering this solid. +//////////////////////////////////////////////////////////////////// +void CollisionFloorMesh:: +fill_viz_geom() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::get_volume_pcollector +// Access: Public, Virtual +// Description: Returns a PStatCollector that is used to count the +// number of bounding volume tests made against a solid +// of this type in a given frame. +//////////////////////////////////////////////////////////////////// +PStatCollector &CollisionFloorMesh:: +get_volume_pcollector() { + return _volume_pcollector; +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::get_test_pcollector +// Access: Public, Virtual +// Description: Returns a PStatCollector that is used to count the +// number of intersection tests made against a solid +// of this type in a given frame. +//////////////////////////////////////////////////////////////////// +PStatCollector &CollisionFloorMesh:: +get_test_pcollector() { + return _test_pcollector; +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::write_datagram +// Access: Public +// Description: Function to write the important information in +// the particular object to a Datagram +//////////////////////////////////////////////////////////////////// +void CollisionFloorMesh:: +write_datagram(BamWriter *manager, Datagram &me) +{ + CollisionSolid::write_datagram(manager, me); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::fillin +// Access: Protected +// Description: Function that reads out of the datagram (or asks +// manager to read) all of the data that is needed to +// re-create this object and stores it in the appropiate +// place +//////////////////////////////////////////////////////////////////// +void CollisionFloorMesh:: +fillin(DatagramIterator& scan, BamReader* manager) +{ + CollisionSolid::fillin(scan, manager); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionPolygon::make_CollisionPolygon +// Access: Protected +// Description: Factory method to generate a CollisionPolygon object +//////////////////////////////////////////////////////////////////// +TypedWritable* CollisionFloorMesh:: +make_CollisionFloorMesh(const FactoryParams ¶ms) { + CollisionFloorMesh *me = new CollisionFloorMesh; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + me->fillin(scan, manager); + return me; +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionPolygon::register_with_factory +// Access: Public, Static +// Description: Factory method to generate a CollisionPolygon object +//////////////////////////////////////////////////////////////////// +void CollisionFloorMesh:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_CollisionFloorMesh); +} + + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::write +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void CollisionFloorMesh:: +write(ostream &out, int indent_level) const { + indent(out, indent_level) << (*this) << "\n"; +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::add_triangle +// Access: Published +// Description: store a triangle for processing +//////////////////////////////////////////////////////////////////// +void CollisionFloorMesh:: +add_triangle(unsigned int pointA, unsigned int pointB, unsigned int pointC) { + CollisionFloorMesh::TriangleIndices tri; + tri.p1 = pointA; + tri.p2 = pointB; + tri.p3 = pointC; + _triangles.push_back(tri); +} diff --git a/panda/src/collide/collisionFloorMesh.h b/panda/src/collide/collisionFloorMesh.h new file mode 100755 index 0000000000..9892e9069a --- /dev/null +++ b/panda/src/collide/collisionFloorMesh.h @@ -0,0 +1,124 @@ +// Filename: collisionFloorMesh.h +// Created by: zpavlov (28Jun07) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef COLLISIONFLOORMESH_H +#define COLLISIONFLOORMESH_H + +#include "pandabase.h" + +#include "collisionPlane.h" +#include "clipPlaneAttrib.h" +#include "look_at.h" + +#include "vector_LPoint2f.h" + +class GeomNode; + +//////////////////////////////////////////////////////////////////// +// Class : CollisionFloorMesh +// Description : This object represents a solid made entirely of triangles, which +// will only be tested again z axis aligned rays +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA CollisionFloorMesh : public CollisionSolid { +public: + typedef struct { + unsigned int p1; + unsigned int p2; + unsigned int p3; + } TriangleIndices; + + +PUBLISHED: + + INLINE CollisionFloorMesh(); + + INLINE void add_vertex(const LPoint3d &vert); + void add_triangle(unsigned int pointA, unsigned int pointB, unsigned int pointC); + + INLINE const unsigned int get_num_vertices() const; + INLINE const unsigned int get_num_triangles() const; + INLINE const LPoint3d get_triangle(unsigned int index) const; + INLINE const LPoint3d get_vertex(unsigned int index) const; + + virtual LPoint3f get_collision_origin() const; + +public: + CollisionFloorMesh(const CollisionFloorMesh ©); + virtual CollisionSolid *make_copy(); + +public: + + virtual void xform(const LMatrix4f &mat); + + virtual PStatCollector &get_volume_pcollector(); + virtual PStatCollector &get_test_pcollector(); + + virtual void output(ostream &out) const; + virtual void write(ostream &out, int indent_level = 0) const; + + INLINE static void flush_level(); + +protected: + virtual PT(BoundingVolume) compute_internal_bounds() const; + + virtual PT(CollisionEntry) + test_intersection_from_ray(const CollisionEntry &entry) const; + virtual void fill_viz_geom(); + +private: + typedef pvector< LPoint3d > Vertices; + + typedef pvector< TriangleIndices > Triangles; + + Vertices _vertices; + Triangles _triangles; + + + static PStatCollector _volume_pcollector; + static PStatCollector _test_pcollector; + +protected: + void fillin(DatagramIterator& scan, BamReader* manager); + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter* manager, Datagram &me); + + static TypedWritable *make_CollisionFloorMesh(const FactoryParams ¶ms); + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + CollisionSolid::init_type(); + register_type(_type_handle, "CollisionFloorMesh", + CollisionSolid::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 "collisionFloorMesh.I" + +#endif + + diff --git a/panda/src/collide/collisionFloorMesh.i b/panda/src/collide/collisionFloorMesh.i new file mode 100755 index 0000000000..d8e491405a --- /dev/null +++ b/panda/src/collide/collisionFloorMesh.i @@ -0,0 +1,83 @@ +//: collisionPlane.I +// Created by: drose (25Apr00) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: CollisionPlane::Default Constructor +// Access: Protected +// Description: This is only for the convenience of CollisionPolygon. +// Normally, you should not attempt to create an +// uninitialized CollisionPlane. +//////////////////////////////////////////////////////////////////// +INLINE CollisionFloorMesh:: +CollisionFloorMesh() { +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE CollisionFloorMesh:: +CollisionFloorMesh(const CollisionFloorMesh ©) : + CollisionSolid(copy) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::flush_level +// Access: Public, Static +// Description: Flushes the PStatCollectors used during traversal. +//////////////////////////////////////////////////////////////////// +INLINE void CollisionFloorMesh:: +flush_level() { + _volume_pcollector.flush_level(); + _test_pcollector.flush_level(); +} + +//////////////////////////////////////////////////////////////////// +// Function: CollisionFloorMesh::add_vertex +// Access: Published +// Description: store away a vertex to index against +//////////////////////////////////////////////////////////////////// +INLINE void CollisionFloorMesh:: +add_vertex(const LPoint3d &vert) { + _vertices.push_back(vert); +} + +INLINE const unsigned int CollisionFloorMesh:: +get_num_vertices() const { + return _vertices.size(); +} + +INLINE const unsigned int CollisionFloorMesh:: +get_num_triangles() const { + return _triangles.size(); +} + +INLINE const LPoint3d CollisionFloorMesh:: +get_triangle(unsigned int index) const { + CollisionFloorMesh::TriangleIndices tri = _triangles[index]; + return LPoint3d(tri.p1, tri.p2, tri.p3); +} + + +INLINE const LPoint3d CollisionFloorMesh:: +get_vertex(unsigned int index) const { + return _vertices[index]; +}