// Given an actor and desired velocity, calculate a corresponding torque vec3 Behavior::CalculateTorque(Actor &actor, const vec3& dvel) { // 1. Get current rotation matrix mat3 currentRotation(actor.globalOrientation); // 2. Construct desired rotation matrix // (This corresponds to facing in the direction of our desired velocity) // Note: Z points forwards; Y Points UP; and X points left vec3 y(0,1,0), z(dvel); z.Normalize(); vec3 x = y.Cross(z); mat3 desiredRotatioon = mat3(x, y, z).Transpose(); // 3. Compute the change in rotation matrix that will // rotate the actor towards our desired rotation mat3 deltaMatrixRot = desiredRotatioon * currentRotation.Transpose(); // 4. Construct quaternion to get axis and angle from dr Quaternion deltaQuadRot = deltaMatrixRot.ToQuaternion(); vec3 axis; //Dont need rad angle? float radAngle; deltaQuadRot.ToAxisAngle(axis, radAngle); // find torque vec3 w = actor.angularVelocity; mat3 I = actor.globalInertialTensor; return w.Cross(I * w) + (I * ( g_fOriKp * (radAngle * axis) - g_fOriKv * w)); }
void DefaultsWidget::applySettings( KuickData& data ) { data.isModsEnabled = cbEnableMods->isChecked(); data.downScale = cbDownScale->isChecked(); data.upScale = cbUpScale->isChecked(); data.maxUpScale = sbMaxUpScaleFactor->value(); data.flipVertically = cbFlipVertically->isChecked(); data.flipHorizontally = cbFlipHorizontally->isChecked(); data.rotation = currentRotation(); ImData *id = data.idata; id->brightness = sbBrightness->value(); id->contrast = sbContrast->value(); id->gamma = sbGamma->value(); }
void DefaultsWidget::updatePreview() { if ( !imFiltered ) return; imFiltered->setAutoRender( false ); int flipMode = cbFlipHorizontally->isChecked() ? FlipHorizontal : FlipNone; flipMode |= cbFlipVertically->isChecked() ? FlipVertical : FlipNone; imFiltered->setFlipMode( flipMode ); Rotation rotation = cbEnableMods->isChecked() ? currentRotation() : ROT_0; imFiltered->setRotation( rotation ); imFiltered->setBrightness( sbBrightness->value() ); imFiltered->setContrast( sbContrast->value() ); imFiltered->setGamma( sbGamma->value() ); imFiltered->updateImage(); imFiltered->setAutoRender( true ); }
// calculates the node transformations for the scene // returns false of the animation is completed or if there is no animation bool Animator::UpdateAnimation(float time, bool loop) { if (currentAnimation && currentAnimation->mDuration > 0.0 && CurAnimation != NULL) { // map into animation's duration double timeInTicks = 0.0f; float dur = (CurAnimation->endFrame - CurAnimation->startFrame)/FPS; if(time == 0) { timeInTicks = 0; } else if (dur > 0.0) { timeInTicks = (CurAnimation->startFrame/FPS) + fmod(time-(1/FPS), dur); } else { timeInTicks = CurAnimation->startFrame/FPS; } if (boneTransforms.size() != currentAnimation->mNumChannels) { boneTransforms.resize(currentAnimation->mNumChannels); } //calculate the transformations for each animation channel for (unsigned int i = 0; i < currentAnimation->mNumChannels; i++) { const aiNodeAnim* channel = currentAnimation->mChannels[i]; //******** Position ***** aiVector3D currentPosition(0, 0, 0); if (channel->mNumPositionKeys > 0) { // Look for present frame number. Search from last position if time is after the last time, else from beginning unsigned int frame = (timeInTicks >= lastTime) ? lastFramePosition[i].x : 0; while (frame < channel->mNumPositionKeys - 1) { if (timeInTicks < channel->mPositionKeys[frame + 1].mTime) { break; } frame++; } // interpolate between this frame's value and next frame's value unsigned int nextFrame = (frame + 1) % channel->mNumPositionKeys; const aiVectorKey& key = channel->mPositionKeys[frame]; const aiVectorKey& nextKey = channel->mPositionKeys[nextFrame]; double dt = nextKey.mTime - key.mTime; if (dt < 0.0) { dt += dur; } if (dt > 0) { float interpolationFactor = (float) ((timeInTicks - key.mTime) / dt); currentPosition = key.mValue + (nextKey.mValue - key.mValue) * interpolationFactor; } else { currentPosition = key.mValue; } lastFramePosition[i].x = frame; } //******** Rotation ********* aiQuaternion currentRotation(1, 0, 0, 0); if (channel->mNumRotationKeys > 0) { unsigned int frame = (timeInTicks >= lastTime) ? lastFramePosition[i].y : 0; while (frame < channel->mNumRotationKeys - 1) { if (timeInTicks < channel->mRotationKeys[frame + 1].mTime) { break; } frame++; } // interpolate between this frame's value and next frame's value unsigned int nextFrame = (frame + 1) % channel->mNumRotationKeys; const aiQuatKey& key = channel->mRotationKeys[frame]; const aiQuatKey& nextKey = channel->mRotationKeys[nextFrame]; double dt = nextKey.mTime - key.mTime; if (dt < 0.0) { dt += dur; } if (dt > 0) { float interpolationFactor = (float) ((timeInTicks - key.mTime) / dt); aiQuaternion::Interpolate(currentRotation, key.mValue, nextKey.mValue, interpolationFactor); } else { currentRotation = key.mValue; } lastFramePosition[i].y = frame; } //******** Scaling ********** aiVector3D currentScaling(1, 1, 1); if (channel->mNumScalingKeys > 0) { unsigned int frame = (timeInTicks >= lastTime) ? lastFramePosition[i].z : 0; while (frame < channel->mNumScalingKeys - 1) { if (timeInTicks < channel->mScalingKeys[frame + 1].mTime) { break; } frame++; } currentScaling = channel->mScalingKeys[frame].mValue; lastFramePosition[i].z = frame; } // build a transformation matrix from the current position, rotation, and scale aiMatrix4x4& transformation = boneTransforms[i]; transformation = aiMatrix4x4(currentRotation.GetMatrix()); transformation.a1 *= currentScaling.x; transformation.b1 *= currentScaling.x; transformation.c1 *= currentScaling.x; transformation.a2 *= currentScaling.y; transformation.b2 *= currentScaling.y; transformation.c2 *= currentScaling.y; transformation.a3 *= currentScaling.z; transformation.b3 *= currentScaling.z; transformation.c3 *= currentScaling.z; transformation.a4 = currentPosition.x; transformation.b4 = currentPosition.y; transformation.c4 = currentPosition.z; } lastTime = timeInTicks; // update all node transformations with the results UpdateTransforms(rootNode, boneTransforms); if(time <= dur || loop) { if(CurAnimation != NULL) CurAnimation->isPlaying = true; return true; } } if(CurAnimation != NULL) CurAnimation->isPlaying = false; return false; }