mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 19:34:23 +02:00
handle registration point in rendering of box, sphere, and model entities
This commit is contained in:
parent
a3e3a1dc2b
commit
f00947ada7
8 changed files with 91 additions and 49 deletions
examples
interface/src
entities
renderer
libraries/entities/src
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue