Merge pull request #569 from ey6es/opencv

Added explicit third person mode, option to cycle through different methods of voxeltar rendering.
This commit is contained in:
Philip Rosedale 2013-06-21 14:23:36 -07:00
commit accafd0418
4 changed files with 98 additions and 36 deletions

View file

@ -982,15 +982,10 @@ void Application::pair() {
PairingHandler::sendPairRequest();
}
void Application::setHead(bool head) {
if (head) {
_myCamera.setMode(CAMERA_MODE_MIRROR);
_myCamera.setModeShiftRate(100.0f);
void Application::setRenderMirrored(bool mirrored) {
if (mirrored) {
_manualFirstPerson->setChecked(false);
} else {
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
_myCamera.setModeShiftRate(1.0f);
_manualThirdPerson->setChecked(false);
}
}
@ -1005,8 +1000,16 @@ void Application::setFullscreen(bool fullscreen) {
}
void Application::setRenderFirstPerson(bool firstPerson) {
if (firstPerson && _lookingInMirror->isChecked()) {
_lookingInMirror->trigger();
if (firstPerson) {
_lookingInMirror->setChecked(false);
_manualThirdPerson->setChecked(false);
}
}
void Application::setRenderThirdPerson(bool thirdPerson) {
if (thirdPerson) {
_lookingInMirror->setChecked(false);
_manualFirstPerson->setChecked(false);
}
}
@ -1307,7 +1310,7 @@ void Application::initMenu() {
pairMenu->addAction("Pair", this, SLOT(pair()));
QMenu* optionsMenu = menuBar->addMenu("Options");
(_lookingInMirror = optionsMenu->addAction("Mirror", this, SLOT(setHead(bool)), Qt::Key_H))->setCheckable(true);
(_lookingInMirror = optionsMenu->addAction("Mirror", this, SLOT(setRenderMirrored(bool)), Qt::Key_H))->setCheckable(true);
(_echoAudioMode = optionsMenu->addAction("Echo Audio"))->setCheckable(true);
optionsMenu->addAction("Noise", this, SLOT(setNoise(bool)), Qt::Key_N)->setCheckable(true);
@ -1344,12 +1347,15 @@ void Application::initMenu() {
_renderAvatarsOn->setChecked(true);
(_renderAvatarBalls = renderMenu->addAction("Avatar as Balls"))->setCheckable(true);
_renderAvatarBalls->setChecked(false);
renderMenu->addAction("Cycle Voxeltar Mode", _myAvatar.getVoxels(), SLOT(cycleMode()));
(_renderFrameTimerOn = renderMenu->addAction("Show Timer"))->setCheckable(true);
_renderFrameTimerOn->setChecked(false);
(_renderLookatOn = renderMenu->addAction("Lookat Vectors"))->setCheckable(true);
_renderLookatOn->setChecked(false);
(_manualFirstPerson = renderMenu->addAction(
"First Person", this, SLOT(setRenderFirstPerson(bool)), Qt::Key_P))->setCheckable(true);
(_manualThirdPerson = renderMenu->addAction(
"Third Person", this, SLOT(setRenderThirdPerson(bool))))->setCheckable(true);
QMenu* toolsMenu = menuBar->addMenu("Tools");
(_renderStatsOn = toolsMenu->addAction("Stats"))->setCheckable(true);
@ -1487,7 +1493,7 @@ void Application::init() {
_myAvatar.init();
_myAvatar.setPosition(START_LOCATION);
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON );
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
_myCamera.setModeShiftRate(1.0f);
_myAvatar.setDisplayingLookatVectors(false);
@ -1692,25 +1698,35 @@ void Application::update(float deltaTime) {
_myAvatar.simulate(deltaTime, NULL);
}
if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) {
if (_manualFirstPerson->isChecked()) {
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
if (!OculusManager::isConnected()) {
if (_lookingInMirror->isChecked()) {
if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
_myCamera.setMode(CAMERA_MODE_MIRROR);
_myCamera.setModeShiftRate(100.0f);
}
} else if (_manualFirstPerson->isChecked()) {
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
} else if (_manualThirdPerson->isChecked()) {
if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
} else {
const float THIRD_PERSON_SHIFT_VELOCITY = 2.0f;
const float TIME_BEFORE_SHIFT_INTO_FIRST_PERSON = 0.75f;
const float TIME_BEFORE_SHIFT_INTO_THIRD_PERSON = 0.1f;
if ((_myAvatar.getElapsedTimeStopped() > TIME_BEFORE_SHIFT_INTO_FIRST_PERSON)
&& (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON)) {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
&& (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON)) {
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
_myCamera.setModeShiftRate(1.0f);
}
if ((_myAvatar.getSpeed() > THIRD_PERSON_SHIFT_VELOCITY)
&& (_myAvatar.getElapsedTimeMoving() > TIME_BEFORE_SHIFT_INTO_THIRD_PERSON)
&& (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON)) {
&& (_myAvatar.getElapsedTimeMoving() > TIME_BEFORE_SHIFT_INTO_THIRD_PERSON)
&& (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON)) {
_myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
_myCamera.setModeShiftRate(1000.0f);
}

View file

@ -97,11 +97,12 @@ private slots:
void pair();
void setHead(bool head);
void setRenderMirrored(bool mirrored);
void setNoise(bool noise);
void setFullscreen(bool fullscreen);
void setRenderFirstPerson(bool firstPerson);
void setRenderThirdPerson(bool thirdPerson);
void renderThrustAtVoxel(const glm::vec3& thrust);
void renderLineToTouchedVoxel();
@ -202,6 +203,7 @@ private:
QAction* _renderFrameTimerOn; // Whether to show onscreen text overlay with stats
QAction* _renderLookatOn; // Whether to show lookat vectors from avatar eyes if looking at something
QAction* _manualFirstPerson; // Whether to force first-person mode
QAction* _manualThirdPerson; // Whether to force third-person mode
QAction* _logOn; // Whether to show on-screen log
QActionGroup* _voxelModeActions; // The group of voxel edit mode actions
QAction* _addVoxelMode; // Whether add voxel mode is enabled

View file

@ -22,7 +22,7 @@ const int BONE_ELEMENTS_PER_VOXEL = BONE_ELEMENTS_PER_VERTEX * VERTICES_PER_VOXE
AvatarVoxelSystem::AvatarVoxelSystem(Avatar* avatar) :
VoxelSystem(AVATAR_TREE_SCALE, MAX_VOXELS_PER_AVATAR),
_avatar(avatar), _voxelReply(0) {
_mode(0), _avatar(avatar), _voxelReply(0) {
// we may have been created in the network thread, but we live in the main thread
moveToThread(Application::getInstance()->thread());
@ -77,6 +77,30 @@ void AvatarVoxelSystem::removeOutOfView() {
// no-op for now
}
class Mode {
public:
bool bindVoxelsTogether;
int maxBonesPerBind;
bool includeBonesOutsideBindRadius;
};
const Mode MODES[] = {
{ false, BONE_ELEMENTS_PER_VERTEX, false }, // original
{ false, 1, true }, // one bone per vertex
{ true, 1, true }, // one bone per voxel
{ true, BONE_ELEMENTS_PER_VERTEX, false } }; // four bones per voxel
void AvatarVoxelSystem::cycleMode() {
_mode = (_mode + 1) % (sizeof(MODES) / sizeof(MODES[0]));
printLog("Voxeltar bind mode %d.\n", _mode);
// rebind
QUrl url = _voxelURL;
setVoxelURL(QUrl());
setVoxelURL(url);
}
void AvatarVoxelSystem::setVoxelURL(const QUrl& url) {
// don't restart the download if it's the same URL
if (_voxelURL == url) {
@ -117,14 +141,28 @@ void AvatarVoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::v
VoxelSystem::updateNodeInArrays(nodeIndex, startVertex, voxelScale, color);
GLubyte* writeBoneIndicesAt = _writeBoneIndicesArray + (nodeIndex * BONE_ELEMENTS_PER_VOXEL);
GLfloat* writeBoneWeightsAt = _writeBoneWeightsArray + (nodeIndex * BONE_ELEMENTS_PER_VOXEL);
for (int i = 0; i < VERTICES_PER_VOXEL; i++) {
GLfloat* writeBoneWeightsAt = _writeBoneWeightsArray + (nodeIndex * BONE_ELEMENTS_PER_VOXEL);
if (MODES[_mode].bindVoxelsTogether) {
BoneIndices boneIndices;
glm::vec4 boneWeights;
computeBoneIndicesAndWeights(computeVoxelVertex(startVertex, voxelScale, i), boneIndices, boneWeights);
for (int j = 0; j < BONE_ELEMENTS_PER_VERTEX; j++) {
*(writeBoneIndicesAt + i * BONE_ELEMENTS_PER_VERTEX + j) = boneIndices[j];
*(writeBoneWeightsAt + i * BONE_ELEMENTS_PER_VERTEX + j) = boneWeights[j];
computeBoneIndicesAndWeights(startVertex + glm::vec3(voxelScale, voxelScale, voxelScale) * 0.5f,
boneIndices, boneWeights);
for (int i = 0; i < VERTICES_PER_VOXEL; i++) {
for (int j = 0; j < BONE_ELEMENTS_PER_VERTEX; j++) {
*(writeBoneIndicesAt + i * BONE_ELEMENTS_PER_VERTEX + j) = boneIndices[j];
*(writeBoneWeightsAt + i * BONE_ELEMENTS_PER_VERTEX + j) = boneWeights[j];
}
}
} else {
for (int i = 0; i < VERTICES_PER_VOXEL; i++) {
BoneIndices boneIndices;
glm::vec4 boneWeights;
computeBoneIndicesAndWeights(computeVoxelVertex(startVertex, voxelScale, i), boneIndices, boneWeights);
for (int j = 0; j < BONE_ELEMENTS_PER_VERTEX; j++) {
*(writeBoneIndicesAt + i * BONE_ELEMENTS_PER_VERTEX + j) = boneIndices[j];
*(writeBoneWeightsAt + i * BONE_ELEMENTS_PER_VERTEX + j) = boneWeights[j];
}
}
}
}
@ -177,7 +215,7 @@ void AvatarVoxelSystem::applyScaleAndBindProgram(bool texture) {
glm::vec3 position;
glm::quat orientation;
_avatar->getBodyBallTransform((AvatarJointID)i, position, orientation);
boneMatrices[i].translate(position.x, position.y, position.z);
boneMatrices[i].translate(position.x, position.y, position.z);
orientation = orientation * glm::inverse(_avatar->getSkeleton().joint[i].absoluteBindPoseRotation);
boneMatrices[i].rotate(QQuaternion(orientation.w, orientation.x, orientation.y, orientation.z));
const glm::vec3& bindPosition = _avatar->getSkeleton().joint[i].absoluteBindPosePosition;
@ -244,7 +282,7 @@ void AvatarVoxelSystem::computeBoneIndicesAndWeights(const glm::vec3& vertex, Bo
float distance = glm::length(computeVectorFromPointToSegment(jointVertex,
skeleton.joint[parent == AVATAR_JOINT_NULL ? i : parent].absoluteBindPosePosition,
skeleton.joint[i].absoluteBindPosePosition));
if (distance > skeleton.joint[i].bindRadius) {
if (!MODES[_mode].includeBonesOutsideBindRadius && distance > skeleton.joint[i].bindRadius) {
continue;
}
for (int j = 0; j < BONE_ELEMENTS_PER_VERTEX; j++) {
@ -261,7 +299,7 @@ void AvatarVoxelSystem::computeBoneIndicesAndWeights(const glm::vec3& vertex, Bo
// compute the weights based on inverse distance
float totalWeight = 0.0f;
for (int i = 0; i < BONE_ELEMENTS_PER_VERTEX; i++) {
for (int i = 0; i < MODES[_mode].maxBonesPerBind; i++) {
indices[i] = nearest[i].index;
if (nearest[i].distance != FLT_MAX) {
weights[i] = 1.0f / glm::max(nearest[i].distance, EPSILON);

View file

@ -25,7 +25,7 @@ class AvatarVoxelSystem : public QObject, public VoxelSystem {
Q_OBJECT
public:
AvatarVoxelSystem(Avatar* avatar);
virtual ~AvatarVoxelSystem();
@ -35,6 +35,10 @@ public:
Q_INVOKABLE void setVoxelURL(const QUrl& url);
const QUrl& getVoxelURL() const { return _voxelURL; }
public slots:
void cycleMode();
protected:
@ -54,6 +58,8 @@ private:
void computeBoneIndicesAndWeights(const glm::vec3& vertex, BoneIndices& indices, glm::vec4& weights) const;
int _mode;
Avatar* _avatar;
QUrl _voxelURL;