EntityItem::SimulationState EntityItem::computeSimulationState() const { if (hasVelocity() || (hasGravity() && !isRestingOnSurface()) || hasAngularVelocity()) { return EntityItem::Moving; } if (isMortal()) { return EntityItem::Mortal; } return EntityItem::Static; }
void EntityItem::update(const quint64& updateTime) { bool wantDebug = false; if (_lastUpdated == 0) { _lastUpdated = updateTime; } float timeElapsed = (float)(updateTime - _lastUpdated) / (float)(USECS_PER_SECOND); if (wantDebug) { qDebug() << "********** EntityItem::update()"; qDebug() << " entity ID=" << getEntityItemID(); qDebug() << " updateTime=" << updateTime; qDebug() << " _lastUpdated=" << _lastUpdated; qDebug() << " timeElapsed=" << timeElapsed; qDebug() << " hasVelocity=" << hasVelocity(); qDebug() << " hasGravity=" << hasGravity(); qDebug() << " isRestingOnSurface=" << isRestingOnSurface(); qDebug() << " hasAngularVelocity=" << hasAngularVelocity(); qDebug() << " getAngularVelocity=" << getAngularVelocity(); qDebug() << " isMortal=" << isMortal(); qDebug() << " getAge()=" << getAge(); qDebug() << " getLifetime()=" << getLifetime(); if (hasVelocity() || (hasGravity() && !isRestingOnSurface())) { qDebug() << " MOVING...="; qDebug() << " hasVelocity=" << hasVelocity(); qDebug() << " hasGravity=" << hasGravity(); qDebug() << " isRestingOnSurface=" << isRestingOnSurface(); qDebug() << " hasAngularVelocity=" << hasAngularVelocity(); qDebug() << " getAngularVelocity=" << getAngularVelocity(); } if (hasAngularVelocity()) { qDebug() << " CHANGING...="; qDebug() << " hasAngularVelocity=" << hasAngularVelocity(); qDebug() << " getAngularVelocity=" << getAngularVelocity(); } if (isMortal()) { qDebug() << " MORTAL...="; qDebug() << " isMortal=" << isMortal(); qDebug() << " getAge()=" << getAge(); qDebug() << " getLifetime()=" << getLifetime(); } } _lastUpdated = updateTime; if (wantDebug) { qDebug() << " ********** EntityItem::update() .... SETTING _lastUpdated=" << _lastUpdated; } if (hasAngularVelocity()) { glm::quat rotation = getRotation(); glm::vec3 angularVelocity = glm::radians(getAngularVelocity()); float angularSpeed = glm::length(angularVelocity); if (angularSpeed < EPSILON_VELOCITY_LENGTH) { setAngularVelocity(NO_ANGULAR_VELOCITY); } else { float angle = timeElapsed * angularSpeed; glm::quat dQ = glm::angleAxis(angle, glm::normalize(angularVelocity)); rotation = dQ * rotation; setRotation(rotation); // handle damping for angular velocity if (getAngularDamping() > 0.0f) { glm::vec3 dampingResistance = getAngularVelocity() * getAngularDamping(); glm::vec3 newAngularVelocity = getAngularVelocity() - (dampingResistance * timeElapsed); setAngularVelocity(newAngularVelocity); if (wantDebug) { qDebug() << " getDamping():" << getDamping(); qDebug() << " dampingResistance:" << dampingResistance; qDebug() << " newAngularVelocity:" << newAngularVelocity; } } } } if (hasVelocity() || hasGravity()) { glm::vec3 position = getPosition(); glm::vec3 velocity = getVelocity(); glm::vec3 newPosition = position + (velocity * timeElapsed); if (wantDebug) { qDebug() << " EntityItem::update()...."; qDebug() << " timeElapsed:" << timeElapsed; qDebug() << " old AACube:" << getMaximumAACube(); qDebug() << " old position:" << position; qDebug() << " old velocity:" << velocity; qDebug() << " old getAABox:" << getAABox(); qDebug() << " getDistanceToBottomOfEntity():" << getDistanceToBottomOfEntity() * (float)TREE_SCALE << " in meters"; qDebug() << " newPosition:" << newPosition; qDebug() << " glm::distance(newPosition, position):" << glm::distance(newPosition, position); } position = newPosition; // handle bounces off the ground... We bounce at the distance to the bottom of our entity if (position.y <= getDistanceToBottomOfEntity()) { velocity = velocity * glm::vec3(1,-1,1); // if we've slowed considerably, then just stop moving if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) { velocity = NO_VELOCITY; } position.y = getDistanceToBottomOfEntity(); } // handle gravity.... if (hasGravity() && !isRestingOnSurface()) { velocity += getGravity() * timeElapsed; } // 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 = getDistanceToBottomOfEntity(); } // handle damping for velocity glm::vec3 dampingResistance = velocity * getDamping(); if (wantDebug) { qDebug() << " getDamping():" << getDamping(); qDebug() << " dampingResistance:" << dampingResistance; qDebug() << " dampingResistance * timeElapsed:" << dampingResistance * timeElapsed; } velocity -= dampingResistance * timeElapsed; if (wantDebug) { qDebug() << " velocity AFTER dampingResistance:" << velocity; qDebug() << " glm::length(velocity):" << glm::length(velocity); qDebug() << " EPSILON_VELOCITY_LENGTH:" << EPSILON_VELOCITY_LENGTH; } // round velocity to zero if it's close enough... if (glm::length(velocity) <= EPSILON_VELOCITY_LENGTH) { velocity = NO_VELOCITY; } setPosition(position); // this will automatically recalculate our collision shape setVelocity(velocity); if (wantDebug) { qDebug() << " new position:" << position; qDebug() << " new velocity:" << velocity; qDebug() << " new AACube:" << getMaximumAACube(); qDebug() << " old getAABox:" << getAABox(); } } }