Move the eyeball meshes according to the lookat direction (not really visible

yet since the eyeballs have no textures).
This commit is contained in:
Andrzej Kapolka 2013-09-24 18:57:37 -07:00
parent 452eb9be47
commit 71ec6f75e5
5 changed files with 43 additions and 9 deletions

View file

@ -37,10 +37,12 @@ bool BlendFace::render(float alpha) {
glm::quat orientation = _owningHead->getOrientation();
glm::vec3 axis = glm::axis(orientation);
glRotatef(glm::angle(orientation), axis.x, axis.y, axis.z);
glTranslatef(0.0f, -0.025f, -0.025f); // temporary fudge factor until we have a better method of per-model positioning
const glm::vec3 MODEL_TRANSLATION(0.0f, -0.025f, -0.025f); // temporary fudge factor
glTranslatef(MODEL_TRANSLATION.x, MODEL_TRANSLATION.y, MODEL_TRANSLATION.z);
const float MODEL_SCALE = 0.0006f;
glScalef(_owningHead->getScale() * MODEL_SCALE, _owningHead->getScale() * MODEL_SCALE,
glm::vec3 scale(_owningHead->getScale() * MODEL_SCALE, _owningHead->getScale() * MODEL_SCALE,
-_owningHead->getScale() * MODEL_SCALE);
glScalef(scale.x, scale.y, scale.z);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
@ -58,6 +60,17 @@ bool BlendFace::render(float alpha) {
const FBXMesh& mesh = _geometry.meshes.at(i);
int vertexCount = mesh.vertices.size();
// apply eye rotation if appropriate
if (mesh.isEye) {
glPushMatrix();
glTranslatef(mesh.pivot.x, mesh.pivot.y, mesh.pivot.z);
glm::quat rotation = glm::inverse(orientation) * _owningHead->getEyeRotation(orientation *
(mesh.pivot * scale + MODEL_TRANSLATION) + _owningHead->getPosition());
glm::vec3 rotationAxis = glm::axis(rotation);
glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glTranslatef(-mesh.pivot.x, -mesh.pivot.y, -mesh.pivot.z);
}
// all meshes after the first are white
if (i == 1) {
glColor4f(1.0f, 1.0f, 1.0f, alpha);
@ -97,6 +110,10 @@ bool BlendFace::render(float alpha) {
glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, mesh.quadIndices.size(), GL_UNSIGNED_INT, 0);
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertexCount - 1, mesh.triangleIndices.size(),
GL_UNSIGNED_INT, (void*)(mesh.quadIndices.size() * sizeof(int)));
if (mesh.isEye) {
glPopMatrix();
}
}
glDisable(GL_NORMALIZE);

View file

@ -459,6 +459,11 @@ glm::quat Head::getCameraOrientation () const {
* glm::quat(glm::radians(glm::vec3(_cameraPitch + _mousePitch, _cameraYaw, 0.0f)));
}
glm::quat Head::getEyeRotation(const glm::vec3& eyePosition) const {
glm::quat orientation = getOrientation();
return rotationBetween(orientation * IDENTITY_FRONT, _lookAtPosition + _saccade - eyePosition) * orientation;
}
void Head::renderHeadSphere() {
glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z); //translate to head position
@ -663,17 +668,13 @@ void Head::renderEyeBalls() {
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
glEnable(GL_TEXTURE_2D);
glm::quat orientation = getOrientation();
glm::vec3 front = orientation * IDENTITY_FRONT;
// render left iris
glm::quat leftIrisRotation;
glPushMatrix(); {
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _leftEyePosition;
leftIrisRotation = rotationBetween(front, targetLookatVector) * orientation;
leftIrisRotation = getEyeRotation(_leftEyePosition);
glm::vec3 rotationAxis = glm::axis(leftIrisRotation);
glRotatef(glm::angle(leftIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION);
@ -697,8 +698,7 @@ void Head::renderEyeBalls() {
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _rightEyePosition;
rightIrisRotation = rotationBetween(front, targetLookatVector) * orientation;
rightIrisRotation = getEyeRotation(_rightEyePosition);
glm::vec3 rotationAxis = glm::axis(rightIrisRotation);
glRotatef(glm::angle(rightIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION);

View file

@ -72,6 +72,8 @@ public:
glm::vec3 getUpDirection() const { return getOrientation() * IDENTITY_UP; }
glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
glm::quat getEyeRotation(const glm::vec3& eyePosition) const;
Face& getFace() { return _face; }
BlendFace& getBlendFace() { return _blendFace; }

View file

@ -275,6 +275,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
QHash<qint64, qint64> parentMap;
QMultiHash<qint64, qint64> childMap;
QHash<qint64, glm::vec3> pivots;
qint64 jointEyeLeftID = 0;
qint64 jointEyeRightID = 0;
foreach (const FBXNode& child, node.children) {
if (child.name == "Objects") {
@ -360,6 +362,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
blendshapes.append(extracted);
}
} else if (object.name == "Model" && object.properties.at(2) == "LimbNode") {
if (object.properties.at(1).toByteArray().startsWith("jointEyeLeft")) {
jointEyeLeftID = object.properties.at(0).value<qint64>();
} else if (object.properties.at(1).toByteArray().startsWith("jointEyeRight")) {
jointEyeRightID = object.properties.at(0).value<qint64>();
}
} else if (object.name == "Deformer" && object.properties.at(2) == "Cluster") {
foreach (const FBXNode& subobject, object.children) {
if (subobject.name == "TransformLink") {
@ -401,6 +410,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node) {
qint64 clusterID = childMap.value(childID);
if (pivots.contains(clusterID)) {
mesh.pivot = pivots.value(clusterID);
qint64 jointID = childMap.value(clusterID);
if (jointID == jointEyeLeftID || jointID == jointEyeRightID) {
mesh.isEye = true;
}
}
}

View file

@ -49,6 +49,8 @@ public:
glm::vec3 pivot;
bool isEye;
QVector<FBXBlendshape> blendshapes;
};