handle registration point in rendering of box, sphere, and model entities

This commit is contained in:
ZappoMan 2014-09-11 08:33:41 -07:00
parent a3e3a1dc2b
commit f00947ada7
8 changed files with 91 additions and 49 deletions

View file

@ -2865,6 +2865,13 @@ function handeMenuEvent(menuItem) {
array.push({ label: "Z:", value: properties.position.z.toFixed(decimals) });
index++;
array.push({ label: "Registration X:", value: properties.registrationPoint.x.toFixed(decimals) });
index++;
array.push({ label: "Registration Y:", value: properties.registrationPoint.y.toFixed(decimals) });
index++;
array.push({ label: "Registration Z:", value: properties.registrationPoint.z.toFixed(decimals) });
index++;
array.push({ label: "Rotation:", type: "header" });
index++;
var angles = Quat.safeEulerAngles(properties.rotation);
@ -3023,6 +3030,9 @@ Window.nonBlockingFormClosed.connect(function() {
properties.position.x = array[index++].value;
properties.position.y = array[index++].value;
properties.position.z = array[index++].value;
properties.registrationPoint.x = array[index++].value;
properties.registrationPoint.y = array[index++].value;
properties.registrationPoint.z = array[index++].value;
index++; // skip header
var angles = Quat.safeEulerAngles(properties.rotation);

View file

@ -32,7 +32,8 @@ EntityItem* RenderableBoxEntityItem::factory(const EntityItemID& entityID, const
void RenderableBoxEntityItem::render(RenderArgs* args) {
PerformanceTimer perfTimer("RenderableBoxEntityItem::render");
assert(getType() == EntityTypes::Box);
glm::vec3 position = getPosition() * (float)TREE_SCALE;
glm::vec3 position = getPositionInMeters();
glm::vec3 center = getCenter() * (float)TREE_SCALE;
glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
glm::vec3 halfDimensions = dimensions / 2.0f;
glm::quat rotation = getRotation();
@ -43,7 +44,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
if (useGlutCube) {
glColor3ub(getColor()[RED_INDEX], getColor()[GREEN_INDEX], getColor()[BLUE_INDEX]);
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
glTranslatef(center.x, center.y, center.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
@ -87,10 +88,15 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
// we need to do half the size because the geometry in the VBOs are from -1,-1,-1 to 1,1,1
glScalef(halfDimensions.x, halfDimensions.y, halfDimensions.z);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
// we need to do half the size because the geometry in the VBOs are from -1,-1,-1 to 1,1,1
glScalef(halfDimensions.x, halfDimensions.y, halfDimensions.z);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);
glPopMatrix();
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays

View file

@ -99,7 +99,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
glm::quat rotation = getRotation();
if (needsSimulation() && _model->isActive()) {
_model->setScaleToFit(true, dimensions);
_model->setSnapModelToCenter(true);
_model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
_model->setRotation(rotation);
_model->setTranslation(position);

View file

@ -31,7 +31,8 @@ EntityItem* RenderableSphereEntityItem::factory(const EntityItemID& entityID, co
void RenderableSphereEntityItem::render(RenderArgs* args) {
PerformanceTimer perfTimer("RenderableSphereEntityItem::render");
assert(getType() == EntityTypes::Sphere);
glm::vec3 position = getPosition() * (float)TREE_SCALE;
glm::vec3 position = getPositionInMeters();
glm::vec3 center = getCenterInMeters();
glm::vec3 dimensions = getDimensions() * (float)TREE_SCALE;
glm::quat rotation = getRotation();
@ -40,7 +41,14 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
glTranslatef(position.x, position.y, position.z);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
glutSolidSphere(0.5f, 15, 15);
glPushMatrix();
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
glutSolidSphere(0.5f, 15, 15);
glPopMatrix();
glPopMatrix();
};

View file

@ -56,8 +56,8 @@ Model::Model(QObject* parent) :
_scaleToFit(false),
_scaleToFitDimensions(0.0f),
_scaledToFit(false),
_snapModelToCenter(false),
_snappedToCenter(false),
_snapModelToRegistrationPoint(false),
_snappedToRegistrationPoint(false),
_showTrueJointTransforms(true),
_lodDistance(0.0f),
_pupilDilation(0.0f),
@ -157,8 +157,8 @@ void Model::setOffset(const glm::vec3& offset) {
_offset = offset;
// if someone manually sets our offset, then we are no longer snapped to center
_snapModelToCenter = false;
_snappedToCenter = false;
_snapModelToRegistrationPoint = false;
_snappedToRegistrationPoint = false;
}
void Model::initProgram(ProgramObject& program, Model::Locations& locations,
@ -905,30 +905,34 @@ void Model::scaleToFit() {
_scaledToFit = true;
}
void Model::setSnapModelToCenter(bool snapModelToCenter) {
if (_snapModelToCenter != snapModelToCenter) {
_snapModelToCenter = snapModelToCenter;
_snappedToCenter = false; // force re-centering
void Model::setSnapModelToRegistrationPoint(bool snapModelToRegistrationPoint, const glm::vec3& registrationPoint) {
glm::vec3 clampedRegistrationPoint = glm::clamp(registrationPoint, 0.0f, 1.0f);
if (_snapModelToRegistrationPoint != snapModelToRegistrationPoint || _registrationPoint != clampedRegistrationPoint) {
_snapModelToRegistrationPoint = snapModelToRegistrationPoint;
_registrationPoint = clampedRegistrationPoint;
_snappedToRegistrationPoint = false; // force re-centering
}
}
void Model::snapToCenter() {
void Model::snapToRegistrationPoint() {
Extents modelMeshExtents = getUnscaledMeshExtents();
glm::vec3 halfDimensions = (modelMeshExtents.maximum - modelMeshExtents.minimum) * 0.5f;
glm::vec3 offset = -modelMeshExtents.minimum - halfDimensions;
glm::vec3 dimensions = (modelMeshExtents.maximum - modelMeshExtents.minimum);
glm::vec3 offset = -modelMeshExtents.minimum - (dimensions * _registrationPoint);
_offset = offset;
_snappedToCenter = true;
_snappedToRegistrationPoint = true;
}
void Model::simulate(float deltaTime, bool fullUpdate) {
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit) || (_snapModelToCenter && !_snappedToCenter);
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);
if (isActive() && fullUpdate) {
// check for scale to fit
if (_scaleToFit && !_scaledToFit) {
scaleToFit();
}
if (_snapModelToCenter && !_snappedToCenter) {
snapToCenter();
if (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint) {
snapToRegistrationPoint();
}
simulateInternal(deltaTime);
}

View file

@ -55,8 +55,15 @@ public:
const glm::vec3& getScaleToFitDimensions() const { return _scaleToFitDimensions; } /// the dimensions model is scaled to
void setScaleToFit(bool scaleToFit, const glm::vec3& dimensions);
void setSnapModelToCenter(bool snapModelToCenter);
bool getSnapModelToCenter() { return _snapModelToCenter; }
void setSnapModelToCenter(bool snapModelToCenter) {
setSnapModelToRegistrationPoint(snapModelToCenter, glm::vec3(0.5f,0.5f,0.5f));
};
bool getSnapModelToCenter() {
return _snapModelToRegistrationPoint && _registrationPoint == glm::vec3(0.5f,0.5f,0.5f);
}
void setSnapModelToRegistrationPoint(bool snapModelToRegistrationPoint, const glm::vec3& registrationPoint);
bool getSnapModelToRegistrationPoint() { return _snapModelToRegistrationPoint; }
void setScale(const glm::vec3& scale);
const glm::vec3& getScale() const { return _scale; }
@ -185,8 +192,10 @@ protected:
glm::vec3 _scaleToFitDimensions; /// this is the dimensions that scale to fit will use
bool _scaledToFit; /// have we scaled to fit
bool _snapModelToCenter; /// is the model's offset automatically adjusted to center around 0,0,0 in model space
bool _snappedToCenter; /// are we currently snapped to center
bool _snapModelToRegistrationPoint; /// is the model's offset automatically adjusted to a registration point in model space
bool _snappedToRegistrationPoint; /// are we currently snapped to a registration point
glm::vec3 _registrationPoint; /// the point in model space our center is snapped to
bool _showTrueJointTransforms;
QVector<LocalLight> _localLights;
@ -207,7 +216,7 @@ protected:
void setScaleInternal(const glm::vec3& scale);
void scaleToFit();
void snapToCenter();
void snapToRegistrationPoint();
void simulateInternal(float deltaTime);

View file

@ -499,14 +499,6 @@ void EntityItem::adjustEditPacketForClockSkew(unsigned char* editPacketBuffer, s
}
}
float EntityItem::getDistanceToBottomOfEntity() const {
// TODO: change this to support registration point
// TODO: fix this to correctly handle rotation... since _dimensions is in entity space,
// if the entity has been rotated, then the distance to world.y=0 is not the same
// as the dimensions.y
return _dimensions.y / 2.0f;
}
bool EntityItem::isRestingOnSurface() const {
// TODO: change this to support registration point
return _position.y <= getDistanceToBottomOfEntity()
@ -727,20 +719,30 @@ float EntityItem::getSize() const {
return glm::length(_dimensions);
}
// TODO: Add support for registration point
glm::vec3 EntityItem::getMinimumPoint() const {
// This assumes the registration point is in the center, we need to update this when we really support
// registration point
return _position - (_dimensions / 2.0f);
// TODO: fix this to correctly handle rotation... since _dimensions is in entity space,
// if the entity has been rotated, then the distance to world.y=0 is not the same
// as the dimensions.y
float EntityItem::getDistanceToBottomOfEntity() const {
glm::vec3 minimumPoint = getMinimumPoint();
return minimumPoint.y;
}
// TODO: Add support for registration point
glm::vec3 EntityItem::getMaximumPoint() const {
// This assumes the registration point is in the center, we need to update this when we really support
// registration point
return _position + (_dimensions / 2.0f);
// TODO: doesn't this need to handle rotation?
glm::vec3 EntityItem::getMinimumPoint() const {
return _position - (_dimensions * _registrationPoint);
}
// TODO: doesn't this need to handle rotation?
glm::vec3 EntityItem::getMaximumPoint() const {
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
return _position + (_dimensions * registrationRemainder);
}
glm::vec3 EntityItem::getCenter() const {
return _position + (_dimensions * (glm::vec3(0.5f,0.5f,0.5f) - _registrationPoint));
}
// NOTE: This should only be used in cases of old bitstreams which only contain radius data
// 0,0,0 --> maxDimension,maxDimension,maxDimension
// ... has a corner to corner distance of glm::length(maxDimension,maxDimension,maxDimension)

View file

@ -126,6 +126,9 @@ public:
void setPositionInMeters(const glm::vec3& value) /// set position in meter units (0.0 - TREE_SCALE)
{ setPosition(glm::clamp(value / (float) TREE_SCALE, 0.0f, 1.0f)); }
glm::vec3 getCenter() const; /// calculates center of the entity in domain scale units (0.0 - 1.0)
glm::vec3 getCenterInMeters() const { return getCenter() * (float) TREE_SCALE; }
static const glm::vec3 DEFAULT_DIMENSIONS;
const glm::vec3& getDimensions() const { return _dimensions; } /// get dimensions in domain scale units (0.0 - 1.0)
glm::vec3 getDimensionsInMeters() const { return _dimensions * (float) TREE_SCALE; } /// get dimensions in meters
@ -203,7 +206,7 @@ public:
static const glm::vec3 DEFAULT_REGISTRATION_POINT;
const glm::vec3& getRegistrationPoint() const { return _registrationPoint; } /// registration point as ratio of entity
void setRegistrationPoint(const glm::vec3& value) { _registrationPoint = value; } /// registration point as ratio of entity
void setRegistrationPoint(const glm::vec3& value) { _registrationPoint = glm::clamp(value, 0.0f, 1.0f); } /// registration point as ratio of entity
static const glm::vec3 NO_ANGULAR_VELOCITY;
static const glm::vec3 DEFAULT_ANGULAR_VELOCITY;