add some basic support for coming to a rest on the ground plane in case of downward gravity

This commit is contained in:
ZappoMan 2014-08-11 14:52:19 -07:00
parent 779d846f1e
commit 466b4c5e40
4 changed files with 82 additions and 33 deletions

View file

@ -320,12 +320,15 @@ void EntityTreeRenderer::renderEntityTypeModel(EntityItem* entity, RenderArgs* a
// handle animations..
if (entityItem->hasAnimation()) {
//qDebug() << "entityItem->hasAnimation()...";
if (!entityItem->jointsMapped()) {
QStringList modelJointNames = model->getJointNames();
entityItem->mapJoints(modelJointNames);
//qDebug() << "entityItem->mapJoints()...";
}
if (entityItem->jointsMapped()) {
//qDebug() << "model->setJointState()...";
QVector<glm::quat> frameData = entityItem->getAnimationFrame();
for (int i = 0; i < frameData.size(); i++) {
model->setJointState(i, true, frameData[i]);

View file

@ -661,11 +661,21 @@ void EntityItem::adjustEditPacketForClockSkew(unsigned char* editPacketBuffer, s
}
}
bool EntityItem::isRestingOnSurface() const {
return _position.y <= _radius
&& _velocity.y >= -EPSILON && _velocity.y <= EPSILON
&& _gravity.y < 0.0f;
}
void EntityItem::update(const quint64& updateTime) {
bool wantDebug = false;
float timeElapsed = (float)(updateTime - _lastUpdated) / (float)(USECS_PER_SECOND);
_lastUpdated = updateTime;
qDebug() << "********** EntityItem::update() .... SETTING _lastUpdated=" << _lastUpdated;
if (wantDebug) {
qDebug() << "********** EntityItem::update() .... SETTING _lastUpdated=" << _lastUpdated;
}
if (isMortal()) {
if (getAge() > getLifetime()) {
@ -677,66 +687,97 @@ qDebug() << "********** EntityItem::update() .... SETTING _lastUpdated=" << _las
if (hasVelocity() || hasGravity()) {
glm::vec3 position = getPosition();
glm::vec3 velocity = getVelocity();
qDebug() << "EntityItem::update()....";
qDebug() << " timeElapsed:" << timeElapsed;
qDebug() << " old AACube:" << getAACube();
qDebug() << " old position:" << position;
qDebug() << " old velocity:" << velocity;
if (wantDebug) {
qDebug() << "EntityItem::update()....";
qDebug() << " timeElapsed:" << timeElapsed;
qDebug() << " old AACube:" << getAACube();
qDebug() << " old position:" << position;
qDebug() << " old velocity:" << velocity;
}
position += velocity * timeElapsed;
// handle bounces off the ground...
if (position.y <= 0) {
// handle bounces off the ground... We bounce at the height of our radius...
if (position.y <= _radius) {
velocity = velocity * glm::vec3(1,-1,1);
position.y = 0;
qDebug() << "################### handle bounces off the ground...... velocity=" << velocity;
// if we've slowed considerably, then just stop moving
if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) {
velocity = NO_VELOCITY;
}
position.y = _radius;
}
// handle gravity....
if (hasGravity()) {
if (hasGravity() && !isRestingOnSurface()) {
velocity += getGravity() * timeElapsed;
qDebug() << "################### apply gravity......";
qDebug() << " getGravity()=" << getGravity();
qDebug() << " velocity=" << velocity;
}
// handle resting on surface case, this is definitely a bit of a hack, and it only works on the
// "ground" plane of the domain, but for now it
if (hasGravity() && isRestingOnSurface()) {
velocity.y = 0.0f;
position.y = _radius;
}
// handle damping
glm::vec3 dampingResistance = velocity * getDamping();
qDebug() << " getDamping():" << getDamping();
qDebug() << " dampingResistance:" << dampingResistance;
qDebug() << " dampingResistance * timeElapsed:" << dampingResistance * timeElapsed;
if (wantDebug) {
qDebug() << " getDamping():" << getDamping();
qDebug() << " dampingResistance:" << dampingResistance;
qDebug() << " dampingResistance * timeElapsed:" << dampingResistance * timeElapsed;
}
velocity -= dampingResistance * timeElapsed;
qDebug() << " velocity AFTER dampingResistance:" << velocity;
if (wantDebug) {
qDebug() << " velocity AFTER dampingResistance:" << velocity;
}
// round velocity to zero if it's close enough...
if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) {
velocity = NO_VELOCITY;
}
qDebug() << " new position:" << position;
qDebug() << " new velocity:" << velocity;
if (wantDebug) {
qDebug() << " new position:" << position;
qDebug() << " new velocity:" << velocity;
}
setPosition(position);
setVelocity(velocity);
qDebug() << " new AACube:" << getAACube();
if (wantDebug) {
qDebug() << " new AACube:" << getAACube();
}
}
}
EntityItem::SimuationState EntityItem::getSimulationState() const {
qDebug() << "EntityItem::getSimulationState()... ";
qDebug() << " hasVelocity()=" << hasVelocity();
qDebug() << " getVelocity()=" << getVelocity();
qDebug() << " hasGravity()=" << hasGravity();
qDebug() << " isMortal()=" << isMortal();
if (hasVelocity() || hasGravity()) {
qDebug() << " return EntityItem::Moving;";
bool wantDebug = false;
if (wantDebug) {
qDebug() << "EntityItem::getSimulationState()... ";
qDebug() << " hasVelocity()=" << hasVelocity();
qDebug() << " getVelocity()=" << getVelocity();
qDebug() << " hasGravity()=" << hasGravity();
qDebug() << " isRestingOnSurface()=" << isRestingOnSurface();
qDebug() << " isMortal()=" << isMortal();
}
if (hasVelocity() || (hasGravity() && !isRestingOnSurface())) {
if (wantDebug) {
qDebug() << " return EntityItem::Moving;";
}
return EntityItem::Moving;
}
if (isMortal()) {
qDebug() << " return EntityItem::Changing;";
if (wantDebug) {
qDebug() << " return EntityItem::Changing;";
}
return EntityItem::Changing;
}
qDebug() << " return EntityItem::Static;";
if (wantDebug) {
qDebug() << " return EntityItem::Static;";
}
return EntityItem::Static;
}

View file

@ -135,6 +135,9 @@ public:
const glm::vec3& getGravity() const { return _gravity; } /// gravity in domain scale units (0.0-1.0) per second squared
void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in domain scale units (0.0-1.0) per second squared
bool hasGravity() const { return _gravity != NO_GRAVITY; }
// TODO: this should eventually be updated to support resting on collisions with other surfaces
bool isRestingOnSurface() const;
static const float DEFAULT_DAMPING;
float getDamping() const { return _damping; }

View file

@ -539,7 +539,7 @@ QVector<glm::quat> ModelEntityItem::getAnimationFrame() {
animationFrameIndex = 0;
}
//qDebug() << "ModelEntityItem::getAnimationFrame().... _animationFrameIndex=" << _animationFrameIndex << "frameCount=" << frameCount << "animationFrameIndex=" << animationFrameIndex;
//qDebug() << "ModelEntityItem::getAnimationFrame().... _animationFrameIndex=" << _animationFrameIndex << "frameCount=" << frameCount << "animationFrameIndex=" << animationFrameIndex;
QVector<glm::quat> rotations = frames[animationFrameIndex].rotations;
frameData.resize(_jointMapping.size());
@ -581,13 +581,15 @@ void ModelEntityItem::update(const quint64& updateTime) {
EntityItem::update(updateTime); // let our base class handle it's updates...
quint64 now = updateTime; //usecTimestampNow();
qDebug() << "ModelEntityItem::update() getAnimationIsPlaying()="<< getAnimationIsPlaying();
// only advance the frame index if we're playing
if (getAnimationIsPlaying()) {
float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND;
const bool wantDebugging = false;
const bool wantDebugging = true;
if (wantDebugging) {
qDebug() << "EntityItem::update() now=" << now;
qDebug() << " updateTime=" << updateTime;