open_toontown_panda3d/panda/src/physics/physicsObject.cxx

210 lines
7.4 KiB
C++

// Filename: physicsObject.cxx
// Created by: charles (13Jun00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "physicsObject.h"
ConfigVariableDouble PhysicsObject::_default_terminal_velocity
("default_terminal_velocity", 400.0f);
TypeHandle PhysicsObject::_type_handle;
////////////////////////////////////////////////////////////////////
// Function : PhysicsObject
// Access : Public
// Description : Default Constructor
////////////////////////////////////////////////////////////////////
PhysicsObject::
PhysicsObject() :
_terminal_velocity(_default_terminal_velocity),
_mass(1.0f),
_process_me(false),
_oriented(true)
{
_position.set(0.0f, 0.0f, 0.0f);
_last_position = _position;
_velocity.set(0.0f, 0.0f, 0.0f);
_orientation.set(1.0 ,0.0f, 0.0f, 0.0f);
_rotation = LRotationf::ident_quat();
}
////////////////////////////////////////////////////////////////////
// Function : PhysicsObject
// Access : Public
// Description : copy constructor
////////////////////////////////////////////////////////////////////
PhysicsObject::
PhysicsObject(const PhysicsObject& copy) {
operator=(copy);
}
////////////////////////////////////////////////////////////////////
// Function : ~PhysicsObject
// Access : Public
// Description : Destructor
////////////////////////////////////////////////////////////////////
PhysicsObject::
~PhysicsObject() {
}
////////////////////////////////////////////////////////////////////
// Function : Assignment operator
// Access : Public
// Description :
////////////////////////////////////////////////////////////////////
const PhysicsObject &PhysicsObject::
operator =(const PhysicsObject &other) {
_process_me = other._process_me;
_mass = other._mass;
_position = other._position;
_last_position = other._last_position;
_velocity = other._velocity;
_orientation = other._orientation;
_rotation = other._rotation;
_terminal_velocity = other._terminal_velocity;
_oriented = other._oriented;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function : make_copy
// Access : Public, virtual
// Description : dynamic copy.
////////////////////////////////////////////////////////////////////
PhysicsObject *PhysicsObject::
make_copy() const {
return new PhysicsObject(*this);
}
////////////////////////////////////////////////////////////////////
// Function : add_local_impact
// Access : Public
// Description : Adds an impulse and/or torque (i.e. an instantanious
// change in velocity) based on how well the offset and
// impulse align with the center of mass (aka position).
// If you wanted to immitate this function you could
// work out the impulse and torque and call add_impulse
// and add_torque respectively.
// offset and force are in local coordinates.
////////////////////////////////////////////////////////////////////
void PhysicsObject::
add_local_impact(const LPoint3f &offset_from_center_of_mass,
const LVector3f &force) {
nassertv(!offset_from_center_of_mass.is_nan());
nassertv(!force.is_nan());
add_impact(
_orientation.xform(offset_from_center_of_mass),
_orientation.xform(force));
}
////////////////////////////////////////////////////////////////////
// Function : add_impact
// Access : Public
// Description : Adds an impulse and/or torque (i.e. an instantanious
// change in velocity) based on how well the offset and
// impulse align with the center of mass (aka position).
// If you wanted to immitate this function you could
// work out the impulse and torque and call add_impulse
// and add_torque respectively.
// offset and force are in global (or parent) coordinates.
////////////////////////////////////////////////////////////////////
void PhysicsObject::
add_impact(const LPoint3f &offset,
const LVector3f &force) {
nassertv(!offset.is_nan());
nassertv(!force.is_nan());
LVector3f a = offset;
LVector3f b = force;
a.normalize();
b.normalize();
a = a.cross(b);
float angle = a.length();
if (angle) {
LRotationf torque;
float spin = force.length()*0.1f; // todo: this should account for
// impact distance and mass.
a.normalize();
assert(IS_THRESHOLD_EQUAL(a.length(), 1.0f, 0.001f));
torque.set_from_axis_angle(spin, a);
add_torque(torque);
}
LVector3f impulse = (1.0f - angle) * force;
add_impulse(impulse);
}
////////////////////////////////////////////////////////////////////
// Function : get_lcs
// Access : Public
// Description : returns a transform matrix to this object's
// local coordinate system.
////////////////////////////////////////////////////////////////////
LMatrix4f PhysicsObject::
get_lcs() const {
LMatrix4f m = LMatrix4f::translate_mat(_position);
if (_oriented) {
m=m*_orientation;
}
nassertr(!m.is_nan(), m);
return m;
}
////////////////////////////////////////////////////////////////////
// Function : get_inertial_tensor
// Access : Public
// Description : returns a transform matrix that represents the
// object's willingness to be forced.
////////////////////////////////////////////////////////////////////
LMatrix4f PhysicsObject::
get_inertial_tensor() const {
return LMatrix4f::ident_mat();
}
////////////////////////////////////////////////////////////////////
// Function : output
// Access : Public
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
void PhysicsObject::
output(ostream &out) const {
#ifndef NDEBUG //[
out<<"PhysicsObject";
#endif //] NDEBUG
}
////////////////////////////////////////////////////////////////////
// Function : write
// Access : Public
// Description : Write a string representation of this instance to
// <out>.
////////////////////////////////////////////////////////////////////
void PhysicsObject::
write(ostream &out, unsigned int indent) const {
#ifndef NDEBUG //[
out.width(indent);
out<<""<<"PhysicsObject "<<_name<<"\n";
out.width(indent+2); out<<""; out<<"_position "<<_position<<"\n";
out.width(indent+2); out<<""; out<<"_last_position "<<_last_position<<"\n";
out.width(indent+2); out<<""; out<<"_velocity "<<_velocity<<"\n";
out.width(indent+2); out<<""; out<<"(implicit velocity "<<get_implicit_velocity()<<")\n";
out.width(indent+2); out<<""; out<<"_orientation "<<_orientation<<"\n";
out.width(indent+2); out<<""; out<<"(hpr "<<_orientation.get_hpr()<<")\n";
out.width(indent+2); out<<""; out<<"_rotation "<<_rotation<<"\n";
out.width(indent+2); out<<""; out<<"_terminal_velocity "<<_terminal_velocity<<"\n";
out.width(indent+2); out<<""; out<<"_mass "<<_mass<<"\n";
out.width(indent+2); out<<""; out<<"_process_me "<<_process_me<<"\n";
out.width(indent+2); out<<""; out<<"_oriented "<<_oriented<<"\n";
#endif //] NDEBUG
}