void Body::Update(float dt, btTransform& Parent) { btVector3 parentPos; parentPos = Parent.getOrigin(); //Get Offset Rotation of a model(child) btQuaternion LocalRot; LocalRot = btQuaternion(m_yaw, m_pitch, m_roll); btQuaternion parentRotation; parentRotation = Parent.getRotation(); //Construct Directx Matricies out of give Quaternion rotations, sets up proper transformation of a model, Global + local XMMATRIX matrixChildRotation = XMMatrixRotationQuaternion(XMLoadFloat4(&XMFLOAT4(LocalRot.getX(), LocalRot.getY(), LocalRot.getZ(), LocalRot.getW()))); XMMATRIX matrixParentRotation = XMMatrixRotationQuaternion(XMLoadFloat4(&XMFLOAT4(parentRotation.getX(), parentRotation.getY(), parentRotation.getZ(), parentRotation.getW()))); //calcualte the final rotation by multiplying quaternions using dxmatrix XMMATRIX matrixFinalRotation = matrixChildRotation * matrixParentRotation; XMFLOAT3 m_offset = XMFLOAT3(0, 0, 0); XMMATRIX childOffset = XMMatrixTranslation(m_offset.x, m_offset.y, m_offset.z); XMMATRIX zeroWorld = XMMatrixTranslation(0, 0, 0); XMMATRIX translationMat = XMMatrixTranslation(parentPos.getX(), parentPos.getY(), parentPos.getZ()); XMMATRIX scaleMat = XMMatrixScaling(m_scale, m_scale, m_scale); XMMATRIX worldMat = childOffset * matrixFinalRotation * zeroWorld * scaleMat * translationMat; XMStoreFloat4x4(&m_worldMat, worldMat); }
void AnimModel::CreateFinalMatrices(UINT clipNumber1, UINT frameNumber1, UINT clipNumber2, UINT frameNumber2, float blendFactor, XMFLOAT4X4* finalMatrices) { // смешивание двух клипов XMFLOAT3 positionF3; XMVECTOR quatF4; std::vector<XMFLOAT4X4> toRoot(bonesAmount); for (UINT i(0); i < bonesAmount; i++) { // загрузка матриц XMVECTOR position1 = XMLoadFloat3(&clips[clipNumber1].bonesPositions[i + bonesAmount * frameNumber1]); XMVECTOR position2 = XMLoadFloat3(&clips[clipNumber2].bonesPositions[i + bonesAmount * frameNumber2]); XMStoreFloat3(&positionF3, XMVectorLerp(position1, position2, blendFactor)); XMVECTOR quaternion1 = XMLoadFloat4(&clips[clipNumber1].bonesQuaternions[i + bonesAmount * frameNumber1]); XMVECTOR quaternion2 = XMLoadFloat4(&clips[clipNumber2].bonesQuaternions[i + bonesAmount * frameNumber2]); quatF4 = XMQuaternionSlerp(quaternion1, quaternion2, blendFactor); // интерполяция матриц XMMATRIX T = XMMatrixTranslation(positionF3.x, positionF3.y, positionF3.z); XMMATRIX R = XMMatrixRotationQuaternion(quatF4); XMStoreFloat4x4(&toRoot[i], R * T); } // перемножение матриц для получения final for (UINT i(0); i < bonesAmount; i++) { UINT coef = order[i]; if (hierarchy[coef] == -1) continue; XMStoreFloat4x4(&toRoot[coef], XMLoadFloat4x4(&toRoot[coef]) * XMLoadFloat4x4(&toRoot[hierarchy[coef]])); } for (UINT i(0); i < bonesAmount; i++) { XMMATRIX offSet = XMLoadFloat4x4(&offsetMatrices[i]); XMStoreFloat4x4(&finalMatrices[i], offSet * XMLoadFloat4x4(&toRoot[i])); } }
// создать финальные матрицы для шейдера void AnimModel::CreateFinalMatricesOldStyle(UINT clipNumber, UINT frameNumber, XMFLOAT4X4* finalMatrices) { // без смешивания клипов по древнему алгоритму (для отладки) // загрузка матриц std::vector<XMFLOAT4X4> reserve(bonesAmount); std::vector<XMFLOAT4X4> reserve2(bonesAmount); for (UINT i(0); i < bonesAmount; i++) { XMFLOAT3 position = clips[clipNumber].bonesPositions[i + bonesAmount * frameNumber]; XMMATRIX T = XMMatrixTranslation(position.x, position.y, position.z); XMFLOAT4 quaternion = clips[clipNumber].bonesQuaternions[i + bonesAmount * frameNumber]; XMMATRIX R = XMMatrixRotationQuaternion(XMLoadFloat4(&quaternion)); XMStoreFloat4x4(&reserve[i], R * T); XMStoreFloat4x4(&reserve2[i], R * T); } // перемножение матриц для получения final for (UINT i(0); i < bonesAmount; i++) { XMMATRIX fin = XMMatrixIdentity(); UINT curMatrix = i; fin = fin * XMLoadFloat4x4(&reserve[curMatrix]); while (curMatrix != -1) { curMatrix = hierarchy[curMatrix]; if (curMatrix == -1) break; fin = fin * XMLoadFloat4x4(&reserve[curMatrix]); } XMMATRIX offSet = XMLoadFloat4x4(&offsetMatrices[i]); XMStoreFloat4x4(&finalMatrices[i], offSet * fin); } }
XMMATRIX Transform::GetTransformMatrix() { XMVECTOR scaleVector(m_Scale.AsXMVECTOR()); XMVECTOR rotationVector(m_Rotation.AsXMVECTOR()); XMVECTOR positionVector(m_Position.AsXMVECTOR()); return XMMatrixScalingFromVector(scaleVector) * XMMatrixRotationQuaternion(rotationVector) * XMMatrixTranslationFromVector(positionVector); }
void Transform::UpdateCBuffer() { //updatesubresource med den nya transformData XMMATRIX tempWorld = XMMatrixIdentity(); XMMATRIX tempScale = XMMatrixIdentity(); XMMATRIX tempRotation = XMMatrixIdentity(); XMMATRIX tempPosition = XMMatrixIdentity(); tempScale = XMMatrixScaling(transformData.scale.x, transformData.scale.y, transformData.scale.z); //XMMatrixRotationQuaternion använd en quaternion istället! cool stuff, sen bör det funka //transformData.pos.z = transformData.pos.z * -1.0f; //transformData.rot.x = transformData.rot.x * -1.0f; //transformData.rot.y = transformData.rot.y * -1.0f; XMVECTOR rotationQuat = XMVectorSet(transformData.rot.x, transformData.rot.y, transformData.rot.z, transformData.rot.w); tempRotation = XMMatrixRotationQuaternion(rotationQuat); tempPosition = XMMatrixTranslation(transformData.pos.x, transformData.pos.y, transformData.pos.z); tempWorld = tempRotation * tempScale * tempPosition; if (parent != nullptr) { parent->UpdateCBuffer(); XMMATRIX parentWorld = XMLoadFloat4x4(&parent->transformCBufferData.world); tempWorld = tempWorld /** parentWorld*/; } XMStoreFloat4x4(&transformCBufferData.world, XMMatrixTranspose(tempWorld)); //transformdata ligger på plats 0, material på 1, osv gDeviceContext->UpdateSubresource(transformCBuffer, 0, NULL, &transformCBufferData.world, 0, 0); //skapa en separat struct för transformdata som ska in i shadern, world osv gDeviceContext->VSSetConstantBuffers(0, 1, &transformCBuffer); }
// スケール、回転、移動行列 XMMATRIX SQTMatrix(const XMVECTOR& scale, const XMVECTOR& quat_rot, const XMVECTOR& trans) { return XMMatrixMultiply( XMMatrixMultiply( XMMatrixScalingFromVector(scale), XMMatrixRotationQuaternion(quat_rot)), XMMatrixTranslationFromVector(trans)); }
void BatchRenderer::DrawFrustum( const XNA::Frustum& frustum, const FColor& color ) { // compute corner points XMVECTOR Origin = XMVectorSet( frustum.Origin.x, frustum.Origin.y, frustum.Origin.z, 0 ); FLOAT Near = frustum.Near; FLOAT Far = frustum.Far; FLOAT RightSlope = frustum.RightSlope; FLOAT LeftSlope = frustum.LeftSlope; FLOAT TopSlope = frustum.TopSlope; FLOAT BottomSlope = frustum.BottomSlope; XMFLOAT3 CornerPoints[8]; CornerPoints[0] = XMFLOAT3( RightSlope * Near, TopSlope * Near, Near ); CornerPoints[1] = XMFLOAT3( LeftSlope * Near, TopSlope * Near, Near ); CornerPoints[2] = XMFLOAT3( LeftSlope * Near, BottomSlope * Near, Near ); CornerPoints[3] = XMFLOAT3( RightSlope * Near, BottomSlope * Near, Near ); CornerPoints[4] = XMFLOAT3( RightSlope * Far, TopSlope * Far, Far ); CornerPoints[5] = XMFLOAT3( LeftSlope * Far, TopSlope * Far, Far ); CornerPoints[6] = XMFLOAT3( LeftSlope * Far, BottomSlope * Far, Far ); CornerPoints[7] = XMFLOAT3( RightSlope * Far, BottomSlope * Far, Far ); XMVECTOR Orientation = XMLoadFloat4( &frustum.Orientation ); XMMATRIX Mat = XMMatrixRotationQuaternion( Orientation ); for( UINT i = 0; i < 8; i++ ) { XMVECTOR Result = XMVector3Transform( XMLoadFloat3( &CornerPoints[i] ), Mat ); Result = XMVectorAdd( Result, Origin ); XMStoreFloat3( &CornerPoints[i], Result ); } // copy to vertex buffer //Assert( (12 * 2) <= MAX_VERTS ); #define DBG_DRAW_LINE(pointA,pointB) \ DrawLine3D( pointA.x,pointA.y,pointA.z, pointB.x,pointB.y,pointB.z, \ color, color ); DBG_DRAW_LINE(CornerPoints[0],CornerPoints[1]); DBG_DRAW_LINE(CornerPoints[1],CornerPoints[2]); DBG_DRAW_LINE(CornerPoints[2],CornerPoints[3]); DBG_DRAW_LINE(CornerPoints[3],CornerPoints[0]); DBG_DRAW_LINE(CornerPoints[0],CornerPoints[4]); DBG_DRAW_LINE(CornerPoints[1],CornerPoints[5]); DBG_DRAW_LINE(CornerPoints[2],CornerPoints[6]); DBG_DRAW_LINE(CornerPoints[3],CornerPoints[7]); DBG_DRAW_LINE(CornerPoints[4],CornerPoints[5]); DBG_DRAW_LINE(CornerPoints[5],CornerPoints[6]); DBG_DRAW_LINE(CornerPoints[6],CornerPoints[7]); DBG_DRAW_LINE(CornerPoints[7],CornerPoints[4]); #undef DBG_DRAW_LINE }
XMMATRIX Transform::createWorldMatrix() const { XMMATRIX world = XMMatrixIdentity(); world *= XMMatrixScalingFromVector(XMLoadFloat3(&scale)); world *= XMMatrixRotationQuaternion(XMLoadFloat4(&rotation)); world *= XMMatrixTranslationFromVector(XMLoadFloat3(&position)); if (parent != nullptr) world *= parent->createWorldMatrix(); return world; }
void HydraRenderer::Render(D3DRenderer* renderer) { CBPerObject perObject; perObject.Material.HasDiffuseTex = false; perObject.Material.HasNormalTex = false; perObject.Material.HasSpecTex = false; perObject.Material.HasEmissiveTex = false; HydraManager* hydra = InputSystem::get()->getHydra(); for (int controller = 0; controller < sixenseGetMaxControllers(); controller++) { if (sixenseIsControllerEnabled(controller)) { XMVECTOR rotationQuat = hydra->getRotation(controller); XMVECTOR position = hydra->getPosition(controller); //XMVectorSetZ(position, -XMVectorGetZ(position));//Flip Z axis //position += XMVectorSet(0.0f, 0.9f, 0.0f, 0.0f);//Offset for table height perObject.World = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMLoadFloat3(&XMFLOAT3(1.0f, 0.0f, 0.0f)), XMConvertToRadians(90.0f))) * XMMatrixTranslation(0.0f, 0.0f, 0.07f) * //XMMatrixTranslation(0.0f, 0.0f, 0.25f) * XMMatrixRotationQuaternion(rotationQuat) * XMMatrixTranslationFromVector(position); perObject.WorldInvTranspose = XMMatrixInverse(NULL, XMMatrixTranspose(perObject.World)); perObject.WorldViewProj = perObject.World * renderer->getPerFrameBuffer()->ViewProj; renderer->setPerObjectBuffer(perObject); mpPointerRenderer->Render(renderer); //Render root trackers perObject.World = XMMatrixRotationQuaternion(XMQuaternionRotationAxis(XMLoadFloat3(&XMFLOAT3(1.0f, 0.0f, 0.0f)), XMConvertToRadians(90.0f))) * XMMatrixRotationQuaternion(rotationQuat) * XMMatrixTranslationFromVector(position); perObject.WorldInvTranspose = XMMatrixInverse(NULL, XMMatrixTranspose(perObject.World)); perObject.WorldViewProj = perObject.World * renderer->getPerFrameBuffer()->ViewProj; renderer->setPerObjectBuffer(perObject); mpRootRenderer->Render(renderer); } } }
VOID DebugDraw::DrawObb( const OrientedBox& obb, D3DCOLOR Color ) { XMMATRIX matWorld = XMMatrixRotationQuaternion( XMLoadFloat4( &obb.Orientation ) ); XMMATRIX matScale = XMMatrixScaling( obb.Extents.x, obb.Extents.y, obb.Extents.z ); matWorld = XMMatrixMultiply( matScale, matWorld ); XMVECTOR position = XMLoadFloat3( &obb.Center ); matWorld.r[3] = XMVectorSelect( matWorld.r[3], position, XMVectorSelectControl( 1, 1, 1, 0 ) ); DrawCubeWireframe( matWorld, Color ); }
XMVECTOR GetAngle(XMVECTOR quat) { XMMATRIX mtx = XMMatrixRotationQuaternion(quat); //ZYX Y=-90〜90°Y軸=ねじり方向 float rx = -atan2f(XMVectorGetY(mtx.r[2]), XMVectorGetZ(mtx.r[2])); float ry = asinf(XMVectorGetX(mtx.r[2])); float rz = -atan2f(XMVectorGetX(mtx.r[1]), XMVectorGetX(mtx.r[0])); return XMVectorSet(rx, ry, rz, 0); }
void BatchRenderer::DrawOBB( const rxOOBB& box, const FColor& color ) { XMMATRIX matWorld = XMMatrixRotationQuaternion( XMLoadFloat4( &box.Orientation ) ); XMMATRIX matScale = XMMatrixScaling( box.Extents.x, box.Extents.y, box.Extents.z ); matWorld = XMMatrixMultiply( matScale, matWorld ); XMVECTOR position = XMLoadFloat3( &box.Center ); matWorld.r[3] = XMVectorSelect( matWorld.r[3], position, XMVectorSelectControl( 1, 1, 1, 0 ) ); DrawCube( matWorld, color ); }
void Local_Light_Editor::SetOrientation_Impl( const Quat& newRot ) { //mxUNUSED(newRot); XMMATRIX rotationMatrix = XMMatrixRotationQuaternion( newRot.quad ); this->GetLight().m_spotDirection = XMVector3TransformNormal( this->GetLight().m_spotDirection, rotationMatrix ); this->GetLight().m_spotDirection = XMVector3Normalize( this->GetLight().m_spotDirection ); }
void JF::Component::ColisionBox::Render() { // Declear) float blendFactors[] = { 0.0f, 0.0f, 0.0f, 0.0f }; // Get) auto* pTransform = GetOwner()->GetComponent<JF::Component::Transform>(); // Check) RETURN_IF(pTransform == nullptr, ); // Set Layout And Topology gRENDERER->DeviceContext()->IASetInputLayout(InputLayouts::PosColor); gRENDERER->DeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); // Set VertexBuffer And IndexBuffer UINT stride = sizeof(JF::Vertex::PosColor); UINT offset = 0; gRENDERER->DeviceContext()->IASetVertexBuffers(0, 1, &m_VertBuff, &stride, &offset); gRENDERER->DeviceContext()->IASetIndexBuffer(m_IndexBuff, DXGI_FORMAT_R32_UINT, 0); // worldViewProj 행렬을 구한다. XMFLOAT3 rPosition = XMFLOAT3(pTransform->GetPosition().x + m_Center.x, pTransform->GetPosition().y + m_Center.y, pTransform->GetPosition().z + m_Center.z); XMFLOAT3 rScale = XMFLOAT3(pTransform->GetScale().x * m_Size.x, pTransform->GetScale().y * m_Size.y, pTransform->GetScale().z * m_Size.z); XMFLOAT4 rRotation = pTransform->GetRotation(); XMMATRIX scl, rot, tsl; scl = XMMatrixScalingFromVector(XMLoadFloat3(&rScale)); rot = XMMatrixRotationQuaternion(XMLoadFloat4(&rRotation)); tsl = XMMatrixTranslationFromVector(XMLoadFloat3(&rPosition)); XMMATRIX world = scl*rot*tsl; XMMATRIX view = Camera::g_pMainCamera->GetView(); XMMATRIX proj = Camera::g_pMainCamera->GetProj(); XMMATRIX worldViewProj = world * view * proj; Effects::SimpleFX->SetWorldViewProj(worldViewProj); // 노말맵이 있는지에따라 FX Tech 설정 변경. ID3DX11EffectTechnique* Tech; Tech = Effects::SimpleFX->ColorTech; D3DX11_TECHNIQUE_DESC techDesc; Tech->GetDesc(&techDesc); for (UINT p = 0; p < techDesc.Passes; ++p) { Tech->GetPassByIndex(p)->Apply(0, gRENDERER->DeviceContext()); gRENDERER->DeviceContext()->DrawIndexed(m_indexCnt, 0, 0); } // 기본 랜더상태로 복원한다. gRENDERER->DeviceContext()->RSSetState(0); gRENDERER->DeviceContext()->OMSetBlendState(0, blendFactors, 0xffffffff); }
inline XMFLOAT4X4 BuildTransform( XMFLOAT3& translation , XMFLOAT4& rotation ) { XMVECTOR stuff = XMLoadFloat4(&rotation); XMMATRIX matrix = XMMatrixRotationQuaternion(stuff); matrix._41 = translation.x; matrix._42 = translation.y; matrix._43 = translation.z; XMFLOAT4X4 mtx; XMStoreFloat4x4(&mtx, matrix); return mtx; }
void Wheel::Update(float dt,btTransform & parentTransform) { ///ROTATION //get the quaternion rotation from euler angles using bt //offset rotation(initial rotation) btQuaternion btLocalRot = btQuaternion(m_yaw, m_pitch, m_roll); XMMATRIX localRot = XMMatrixRotationQuaternion(XMLoadFloat4(&XMFLOAT4(btLocalRot.getX(), btLocalRot.getY(), btLocalRot.getZ(), btLocalRot.getW()))); //worldspace rotation btQuaternion btParentRot = parentTransform.getRotation(); XMMATRIX ParentRot = XMMatrixRotationQuaternion(XMLoadFloat4(&XMFLOAT4(btParentRot.getX(), btParentRot.getY(), btParentRot.getZ(), btParentRot.getW()))); //add rotations together XMMATRIX finalRot = localRot * ParentRot; btVector3 btparentPos = parentTransform.getOrigin(); XMMATRIX translationMat = XMMatrixTranslation(btparentPos.getX(), btparentPos.getY(), btparentPos.getZ()); //XMMATRIX scaleMat = XMMatrixScaling(m_scale, m_scale, m_scale); XMMATRIX scaleMat = XMMatrixScaling(m_scale, m_scale, m_scale); XMMATRIX worldMat = finalRot * scaleMat * translationMat; XMStoreFloat4x4(&m_worldMat, worldMat); }
XMFLOAT4X4 Transform::RecalculateWorldMatrix() { //TODO: figure out a better way to handle rotaions if (!GetIsDirty()) return worldMatrix;//Dont know if I want to keep it. XMMATRIX allignedWorldMatrix = XMLoadFloat4x4(&worldMatrix); if (parent == nullptr) { XMMATRIX calculatedWorldMatrix = XMMatrixScalingFromVector(XMLoadFloat3(&scale)) * //XMMatrixRotationRollPitchYawFromVector(XMLoadFloat3(&rotation)) * //XMMatrixRotationX(rotation.x) * XMMatrixRotationY(rotation.y) * XMMatrixRotationZ(rotation.z) * XMMatrixRotationQuaternion(XMQuaternionRotationRollPitchYawFromVector(XMLoadFloat3(&rotation))) * XMMatrixTranslationFromVector(XMLoadFloat3(&position)); XMStoreFloat4x4(&worldMatrix, XMMatrixTranspose(calculatedWorldMatrix)); } else { XMMATRIX calculatedWorldMatrix = XMMatrixScalingFromVector(XMLoadFloat3(&scale)) * //XMMatrixRotationRollPitchYawFromVector(XMLoadFloat3(&rotation)) * XMMatrixRotationQuaternion(XMQuaternionRotationRollPitchYawFromVector(XMLoadFloat3(&rotation))) * XMMatrixTranslationFromVector(XMLoadFloat3(&position)); XMStoreFloat4x4(&worldMatrix, XMMatrixTranspose( XMMatrixMultiply(XMMatrixTranspose(XMLoadFloat4x4(&parent->GetWorldMatrix())), calculatedWorldMatrix))); } return worldMatrix; }
void make_worldmatrix(QuaternionTransform const& qt, XMFLOAT4X4 &mat) { XMVECTOR trans_vec = XMLoadFloat3(&qt.pos); XMMATRIX trans_mat = XMMatrixTranslationFromVector(trans_vec); XMVECTOR scale_vec = XMLoadFloat3(&qt.scale); XMMATRIX scale_mat = XMMatrixScalingFromVector(scale_vec); XMVECTOR rotat_vec = XMLoadFloat4(&qt.quat); XMMATRIX rotat_mat = XMMatrixRotationQuaternion(rotat_vec); XMMATRIX world = scale_mat * rotat_mat * trans_mat; XMStoreFloat4x4(&mat, world); }
boneConstantBuffer* BonedMeshGroup::getBoneConstantBuffer(int* ids,int num){ boneConstantBuffer* result=new boneConstantBuffer; XMMATRIX* m=(XMMATRIX*)malloc(40*64);; result->boneTrans=m; XMMATRIX rmatrix=XMMatrixIdentity(); rmatrix=XMMatrixTranspose(rmatrix); for(int i=0;i<40;i++){ memcpy(&m[i],&rmatrix,64); } for(int i=0;i<num;i++) { boneSample sample=m_bgroup->getBoneSample(ids[i],(int)m_CurFrame); boneTM first=m_bgroup->getBone(ids[i])->getFirstTM(); XMMATRIX rmatrix=XMMatrixTranslation(-first.translate.x,-first.translate.y,-first.translate.z); rmatrix*=XMMatrixRotationQuaternion(XMVectorSet(first.rotate.x,first.rotate.y,first.rotate.z,first.rotate.w)); rmatrix*=XMMatrixRotationQuaternion(XMVectorSet(sample.tm.rotate.x,sample.tm.rotate.y,sample.tm.rotate.z,-sample.tm.rotate.w)); rmatrix=rmatrix*XMMatrixTranslation(sample.tm.translate.x,sample.tm.translate.y,sample.tm.translate.z); rmatrix=XMMatrixTranspose(rmatrix); memcpy(&m[i],&rmatrix,64); } return result; }
XMMATRIX AaEntity::getWorldMatrix() { if(dirtyWM) { XMMATRIX translationM = XMMatrixTranslation( position.x,position.y,position.z ); XMMATRIX rotationM; rotationM = XMMatrixRotationQuaternion( *quaternion ); XMMATRIX scaleM = XMMatrixScaling(scale.x,scale.y,scale.z); *wMatrix=XMMatrixMultiply(XMMatrixMultiply(scaleM,rotationM),translationM); dirtyWM=false; } return *wMatrix; }
void SphereWalker::move(float dt) { XMVECTOR perp = XMVectorSet(-cosf(angle), sinf(angle), 0,0); XMVECTOR incrementalRotation; incrementalRotation = XMQuaternionRotationAxis(perp, dt ); XMStoreFloat4(&qPos, XMQuaternionMultiply(incrementalRotation , XMLoadFloat4(&qPos))); orientationToPos(qPos, pos); //Rotate in space XMMATRIX globalRotation = XMMatrixRotationQuaternion( XMLoadFloat4(&qPos)); XMMATRIX localRotation; XMVECTOR up = XMVectorSet( 0,0,1,0); localRotation = XMMatrixRotationAxis(up, -angle); XMStoreFloat4x4(&orientation, localRotation * globalRotation); }
void IObject::Scale(float scaleX, float scaleY, float scaleZ) { XMVECTOR quat = XMQuaternionRotationMatrix(XMLoadFloat4x4(&m_mWorld)); XMFLOAT3 pos = *GetPosition(); XMMATRIX newScale = XMMatrixIdentity(); XMMATRIX newMat = XMMatrixIdentity(); newScale = XMMatrixScaling(scaleX, scaleY, scaleZ); newMat = newScale * XMMatrixRotationQuaternion(quat); XMStoreFloat4x4(&m_mWorld, newMat); m_mWorld._41 = pos.x; m_mWorld._42 = pos.y; m_mWorld._43 = pos.z; if (m_cpRenderMesh) m_cpRenderMesh->GetPositionMatrix() = m_mWorld; }
void D3DCamera::Render(XMVECTOR translate, XMVECTOR rotate, bool move, bool playback) { XMVECTOR upVector, lookAtVector, rightVector; XMMATRIX rotationMatrix; rightVector = XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f); upVector = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); lookAtVector = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); if (move) { XMVECTOR quaternion = XMQuaternionRotationRollPitchYawFromVector(rotate); quaternion = XMQuaternionNormalize(quaternion); m_rotation = XMQuaternionMultiply(quaternion, m_rotation); } if (playback) m_rotation = rotate; rotationMatrix = XMMatrixRotationQuaternion(m_rotation); // Transform the lookAt and up vector by the rotation matrix so the view is correctly rotated at the origin. lookAtVector = XMVector3TransformCoord(lookAtVector, rotationMatrix); upVector = XMVector3TransformCoord(upVector, rotationMatrix); rightVector = XMVector3TransformCoord(upVector, rotationMatrix); if (move) { translate = XMVector3TransformCoord(translate, rotationMatrix); translate = XMVectorSetW(translate, 0); m_position += translate; } if (playback) m_position = translate; // Translate the rotated camera position to the location of the viewer. lookAtVector = XMVectorAdd(m_position, lookAtVector); m_lookAtVector.x = lookAtVector.m128_f32[0]; m_lookAtVector.y = lookAtVector.m128_f32[1]; m_lookAtVector.z = lookAtVector.m128_f32[2]; // Finally create the view matrix from the three updated vectors. m_viewMatrix = XMMatrixLookAtLH(m_position, lookAtVector, upVector); return; }
void AnimModel::CreateFinalMatrices(UINT clipNumber, UINT frameNumber, XMFLOAT4X4* finalMatrices) { // без смешивания клипов // загрузка матриц std::vector<XMFLOAT4X4> toRoot(bonesAmount); for (UINT i(0); i < bonesAmount; i++) { XMFLOAT3 position = clips[clipNumber].bonesPositions[i + bonesAmount * frameNumber]; XMMATRIX T = XMMatrixTranslation(position.x, position.y, position.z); XMFLOAT4 quaternion = clips[clipNumber].bonesQuaternions[i + bonesAmount * frameNumber]; XMMATRIX R = XMMatrixRotationQuaternion(XMLoadFloat4(&quaternion)); XMStoreFloat4x4(&toRoot[i], R * T); } // перемножение матриц для получения final for (UINT i(0); i < bonesAmount; i++) { UINT coef = order[i]; if (hierarchy[coef] == -1) continue; XMStoreFloat4x4(&toRoot[coef], XMLoadFloat4x4(&toRoot[coef]) * XMLoadFloat4x4(&toRoot[hierarchy[coef]])); } for (UINT i(0); i < bonesAmount; i++) { XMMATRIX offSet = XMLoadFloat4x4(&offsetMatrices[i]); XMStoreFloat4x4(&finalMatrices[i], offSet * XMLoadFloat4x4(&toRoot[i])); } }
void AnimationController::Interpolate( float dt ) { timeSinceStart += dt; Anim anim = *anims[currentAnim]; float animCurrentTime = fmod( timeSinceStart, anim.totalTime ); for( Bone* bone:anim.boneSet ) { XMMATRIX rotMat, scaleMat, translateMat; // Interpolate Rotation auto rotSetIt = anim.rotChannels.find( bone ); if( rotSetIt==anim.rotChannels.end() ) { rotMat = XMMatrixIdentity(); } else { keySet_t rotKeySet = rotSetIt->second; auto itLow = rotKeySet.lower_bound( animCurrentTime ); if( itLow==rotKeySet.begin() ) { itLow = rotKeySet.end(); } --itLow; auto itHigh = rotKeySet.upper_bound( animCurrentTime ); if( itHigh==rotKeySet.end() ) { itHigh = rotKeySet.begin(); } float factor = (animCurrentTime-itLow->first)/(itHigh->first-itLow->first); XMVECTOR low = XMLoadFloat4( &itLow->second ); XMVECTOR high = XMLoadFloat4( &itHigh->second ); XMVECTOR interp = XMQuaternionSlerp( low, high, factor ); XMVECTOR normalized = XMQuaternionNormalize( interp ); rotMat = XMMatrixRotationQuaternion( interp ); } // Interpolate Scale auto scaleSetIt = anim.scaleChannels.find( bone ); if( scaleSetIt==anim.scaleChannels.end() ) { scaleMat = XMMatrixIdentity(); } else { keySet_t scaleKeySet = scaleSetIt->second; auto itLow = scaleKeySet.lower_bound( animCurrentTime ); if( itLow==scaleKeySet.begin() ) { itLow = scaleKeySet.end(); } --itLow; auto itHigh = scaleKeySet.upper_bound( animCurrentTime ); if( itHigh==scaleKeySet.end() ) { itHigh = scaleKeySet.begin(); } float factor = (animCurrentTime-itLow->first)/(itHigh->first-itLow->first); XMFLOAT4 lowVec = itLow->second; XMFLOAT4 highVec = itHigh->second; scaleMat = XMMatrixScaling( lowVec.x+factor*(highVec.x-lowVec.x), lowVec.y+factor*(highVec.y-lowVec.y), lowVec.z+factor*(highVec.z-lowVec.z) ); } // Interpolate Position auto posSetIt = anim.posChannels.find( bone ); if( posSetIt==anim.posChannels.end() ) { translateMat = XMMatrixIdentity(); } else { keySet_t posKeySet = posSetIt->second; auto itLow = posKeySet.lower_bound( animCurrentTime ); if( itLow==posKeySet.begin() ) { itLow = posKeySet.end(); } --itLow; auto itHigh = posKeySet.upper_bound( animCurrentTime ); if( itHigh==posKeySet.end() ) { itHigh = posKeySet.begin(); } float factor = (animCurrentTime-itLow->first)/(itHigh->first-itLow->first); XMFLOAT4 lowVec = itLow->second; XMFLOAT4 highVec = itHigh->second; translateMat = XMMatrixTranslation( lowVec.x+factor*(highVec.x-lowVec.x), lowVec.y+factor*(highVec.y-lowVec.y), lowVec.z+factor*(highVec.z-lowVec.z) ); } // Conversion Matrix - this converts imported coords to DirectX XMMATRIX reflectX = XMMatrixReflect( XMLoadFloat3( &XMFLOAT3( 1.f, 0.f, 0.f ) ) ); XMMATRIX reflectY = XMMatrixReflect( XMLoadFloat3( &XMFLOAT3( 0.f, 1.f, 0.f ) ) ); XMMATRIX reflectZ = XMMatrixReflect( XMLoadFloat3( &XMFLOAT3( 0.f, 0.f, 1.f ) ) ); XMMATRIX rotX = XMMatrixRotationX( XM_PIDIV2 ); XMMATRIX rotY = XMMatrixRotationY( XM_PIDIV2 ); XMMATRIX rotZ = XMMatrixRotationZ( XM_PIDIV2 ); int foo = 17; //DELETEME XMMATRIX flip = XMLoadFloat4x4( &XMFLOAT4X4( 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f ) ); XMMATRIX finalMat = scaleMat * rotMat * translateMat; XMFLOAT4X4 transform; XMStoreFloat4x4( &transform, finalMat ); finalTransform[bone] = transform; } }
//------------------------------------------- // とりあえずIK void BoneModel::VMDIkAnimation() { //XMStoreFloat4() //XMLoadFloat4() if (mBone.empty())return; if (mMotion.empty())return; DWORD mBoneNum = mBone.size(); DWORD mIkNum = mIk.size(); // IK計算 for (DWORD i = 0; i < mIkNum; i++){ //{ // int i = 0; Ik& ik = mIk[i]; UINT tg_idx = ik.target_bone_index; UINT ik_idx = ik.bone_index; for (UINT ite = 0; ite<ik.iterations; ++ite){ for (UINT chn = 0; chn<ik.chain_length; ++chn){ UINT link_idx = ik.child_bone_index[chn];// if (link_idx >= mBoneNum)continue; Bone& link_bone = mBone[link_idx]; //UINT link_pidx = link_bone.mIkBoneIdx; UINT link_pidx = link_bone.mHierarchy.mIdxParent; //if (link_bone.mIkBoneIdx != 0){ // continue; //} if (link_pidx >= mBoneNum)continue; Bone& link_parent = mBone[link_pidx]; Bone& tg_bone = mBone[tg_idx]; (void)tg_bone; Bone& ik_bone = mBone[ik_idx]; (void)ik_bone; XMVECTOR target_wpos = mBone[tg_idx].mMtxPose.r[3]; XMVECTOR ik_wpos = mBone[ik_idx].mMtxPose.r[3]; XMVECTOR lp_wpos = link_parent.mMtxPose.r[3]; //Linkボーンのローカル空間に変換 XMVECTOR Determinant; XMMATRIX inv_mtx = XMMatrixInverse(&Determinant, link_bone.mMtxPose); XMVECTOR tg_pos = XMVector4Transform(target_wpos, inv_mtx); XMVECTOR ik_pos = XMVector4Transform(ik_wpos, inv_mtx); XMVECTOR lp_pos = XMVector4Transform(lp_wpos, inv_mtx); // 回転軸と角度 XMVECTOR rot_axis = XMVectorSet(1, 0, 0, 0); float ang = 0.0f; bool same_dir = false; if (!RotDir(tg_pos, ik_pos, ik.control_weight, &rot_axis, &ang)){ same_dir = true; } if (!same_dir){ //tg_dirをik_dirに一致させるための回転 XMVECTOR rot = XMQuaternionRotationAxis(rot_axis, ang); XMVECTOR lrot = FloatToVector(link_bone.mRot); XMVECTOR bone_rot_before = lrot; link_bone.mRot = VectorToFloat(XMQuaternionMultiply(rot, lrot)); float dist_tg = XMVectorGetX(XMVector3Length(tg_pos)); float dist_ik = XMVectorGetX(XMVector3Length(ik_pos)); (void)dist_ik; float dist_lp = XMVectorGetX(XMVector3Length(lp_pos)); (void)dist_lp; float dist_pltg = XMVectorGetX(XMVector3Length(lp_pos - tg_pos)); float dist_plik = XMVectorGetX(XMVector3Length(lp_pos - ik_pos)); float dot_tgik = XMVectorGetX(XMVector3Dot(XMVector3Normalize(tg_pos), XMVector3Normalize(ik_pos))); (void)dot_tgik; // 回転制限 if (/*link.bLimit*/ 1){ XMVECTOR rotmax, rotmin; //114.5916 = 2 float a = 2;// XM_PI / 180.0f * 57.25f; rotmax = XMVectorSet(a, a, a, 0);//link.vMax; rotmin = XMVectorSet(-a, -a, -a, 0);//link.vMin; //名前に"ひざ"があったら回転制限 if (std::string::npos != link_bone.mStrName.find("ひざ")){ rotmax = XMVectorSet(-XM_PI / 180.0f*0.5f, 0, 0, 0); rotmin = XMVectorSet(-XM_PI, 0, 0, 0); } struct IkLink{ XMFLOAT4 mMax; XMFLOAT4 mMin; }; IkLink link = { VectorToFloat(rotmax), VectorToFloat(rotmin) }; //Bone& link = link_bone; link_bone.mRot = VectorToFloat(LimitAngle(FloatToVector(link_bone.mRot), rotmin, rotmax)); XMVECTOR angxyz = GetAngle(rot); //膝を曲げるための仮処理 かなりてきとう if (XMVectorGetX(angxyz) >= 0 && //0.9f < dot_tgik && //dist_tg > dist_ik && dist_pltg > dist_plik && link.mMax.x < 0 && link.mMax.y == link.mMin.y && link.mMax.z == link.mMin.z){ //親リンクの回転接平面(できるだけこの平面に近づけたほうがよりIK目標に近づける) XMVECTOR lp_nor = XMVector3Normalize(-lp_pos);//平面の法線 //lp_norとの内積が0になる位置を目標にする //2つあるので回転制限後の|内積|が小さいほう XMVECTOR tng = XMVector3Cross(XMVectorSet(1, 0, 0, 0), lp_nor); //+tngと-tngの2つ XMVECTOR rot_axis0, rot_axis1; float ang0 = 0, ang1 = 0; // 回転軸をXに限定 rot_axis1 = rot_axis0 = XMVectorSet(1, 0, 0, 0); XMVECTOR tdir = XMVector3Normalize(XMVectorSetX(tg_pos, 0)); tng = XMVector3Normalize(XMVectorSetX(tng, 0)); RotDir(tdir, tng, ik.control_weight, &rot_axis0, &ang0); RotDir(tdir, -tng, ik.control_weight, &rot_axis1, &ang1); if (XMVectorGetX(rot_axis0) < 0.0f)ang0 = -ang0; if (XMVectorGetX(rot_axis1) < 0.0f)ang1 = -ang1; //これは絶対違う ぴくぴく対策 float coef = (dist_pltg - dist_plik) / dist_tg; if (coef > 1)coef = 1; ang0 *= coef; ang1 *= coef; //ang0,1は現在の位置からの相対角度 // 回転制限を考慮した相対角度に float angx_b = XMVectorGetX(GetAngle(bone_rot_before)); float angx_a0 = angx_b + ang0; float angx_a1 = angx_b + ang1; if (angx_a0 < link.mMin.x) angx_a0 = link.mMin.x; if (angx_a0 > link.mMax.x) angx_a0 = link.mMax.x; if (angx_a1 < link.mMin.x) angx_a1 = link.mMin.x; if (angx_a1 > link.mMax.x) angx_a1 = link.mMax.x; ang0 = angx_a0 - angx_b; ang1 = angx_a1 - angx_b; XMVECTOR rot0 = XMQuaternionRotationRollPitchYaw(ang0, 0, 0); XMVECTOR rot1 = XMQuaternionRotationRollPitchYaw(ang1, 0, 0); XMVECTOR tdir0 = XMVector3TransformCoord(tdir, XMMatrixRotationQuaternion(rot0)); XMVECTOR tdir1 = XMVector3TransformCoord(tdir, XMMatrixRotationQuaternion(rot1)); float d0 = XMVectorGetX(XMVectorAbs(XMVector3Dot(tdir0, lp_nor))); float d1 = XMVectorGetX(XMVectorAbs(XMVector3Dot(tdir1, lp_nor))); if (d0 < d1){ link_bone.mRot = VectorToFloat(XMQuaternionMultiply(rot0, bone_rot_before)); } else{ link_bone.mRot = VectorToFloat(XMQuaternionMultiply(rot1, bone_rot_before)); } } } } //ワールド行列更新 link_bone.mMtxPose = SQTMatrix(FloatToVector(link_bone.mScale), FloatToVector(link_bone.mRot), FloatToVector(link_bone.mPos)); if (link_bone.mHierarchy.mIdxParent < mBoneNum){ link_bone.mMtxPose = XMMatrixMultiply(link_bone.mMtxPose, mBone[link_bone.mHierarchy.mIdxParent].mMtxPose); } // 子階層のリンク再計算 for (int lidown = chn - 1; lidown >= 0; --lidown){ UINT idx = ik.child_bone_index[lidown]; if (idx >= mBoneNum)continue; Bone& linkb = mBone[idx]; linkb.mMtxPose = SQTMatrix(FloatToVector(linkb.mScale), FloatToVector(linkb.mRot), FloatToVector(linkb.mPos)); if (linkb.mHierarchy.mIdxParent < mBoneNum){ linkb.mMtxPose = XMMatrixMultiply(linkb.mMtxPose, mBone[linkb.mHierarchy.mIdxParent].mMtxPose); } } mBone[tg_idx].mMtxPose = SQTMatrix(FloatToVector(mBone[tg_idx].mScale), FloatToVector(mBone[tg_idx].mRot), FloatToVector(mBone[tg_idx].mPos)); if (mBone[tg_idx].mHierarchy.mIdxParent < mBoneNum){ mBone[tg_idx].mMtxPose = XMMatrixMultiply(mBone[tg_idx].mMtxPose, mBone[mBone[tg_idx].mHierarchy.mIdxParent].mMtxPose); } } } //Bone& b = mBone[tg_idx]; //Bone& b2 = mBone[mBone[tg_idx].mHierarchy.mIdxParent]; //Bone& b3 = mBone[b2.mHierarchy.mIdxParent]; //int sa = 1; //IKの計算結果を子階層に反映 //UpdatePose(); } UpdatePose(); }
XMMATRIX ArcBall::GetRotationMatrixIncreament() { m_mRotation = XMMatrixRotationQuaternion(m_increament); return m_mRotation; }
XMMATRIX ArcBall::GetRotationMatrix() { m_mRotation = XMMatrixRotationQuaternion(m_qNow) ; return m_mRotation; }
static Matrix rotation_quaternion(const Quaternion& q) { return static_cast<Matrix>(XMMatrixRotationQuaternion(q)); }
VOID DebugDraw::DrawFrustum( const Frustum& frustum, D3DCOLOR Color ) { // compute corner points XMVECTOR Origin = XMVectorSet( frustum.Origin.x, frustum.Origin.y, frustum.Origin.z, 0 ); FLOAT Near = frustum.Near; FLOAT Far = frustum.Far; FLOAT RightSlope = frustum.RightSlope; FLOAT LeftSlope = frustum.LeftSlope; FLOAT TopSlope = frustum.TopSlope; FLOAT BottomSlope = frustum.BottomSlope; XMFLOAT3 CornerPoints[8]; CornerPoints[0] = XMFLOAT3( RightSlope * Near, TopSlope * Near, Near ); CornerPoints[1] = XMFLOAT3( LeftSlope * Near, TopSlope * Near, Near ); CornerPoints[2] = XMFLOAT3( LeftSlope * Near, BottomSlope * Near, Near ); CornerPoints[3] = XMFLOAT3( RightSlope * Near, BottomSlope * Near, Near ); CornerPoints[4] = XMFLOAT3( RightSlope * Far, TopSlope * Far, Far ); CornerPoints[5] = XMFLOAT3( LeftSlope * Far, TopSlope * Far, Far ); CornerPoints[6] = XMFLOAT3( LeftSlope * Far, BottomSlope * Far, Far ); CornerPoints[7] = XMFLOAT3( RightSlope * Far, BottomSlope * Far, Far ); XMVECTOR Orientation = XMLoadFloat4( &frustum.Orientation ); XMMATRIX Mat = XMMatrixRotationQuaternion( Orientation ); for( UINT i = 0; i < 8; i++ ) { XMVECTOR Result = XMVector3Transform( XMLoadFloat3( &CornerPoints[i] ), Mat ); Result = XMVectorAdd( Result, Origin ); XMStoreFloat3( &CornerPoints[i], Result ); } XMFLOAT3 Lines[12 * 2]; Lines[0] = CornerPoints[0]; Lines[1] = CornerPoints[1]; Lines[2] = CornerPoints[1]; Lines[3] = CornerPoints[2]; Lines[4] = CornerPoints[2]; Lines[5] = CornerPoints[3]; Lines[6] = CornerPoints[3]; Lines[7] = CornerPoints[0]; Lines[8] = CornerPoints[0]; Lines[9] = CornerPoints[4]; Lines[10] = CornerPoints[1]; Lines[11] = CornerPoints[5]; Lines[12] = CornerPoints[2]; Lines[13] = CornerPoints[6]; Lines[14] = CornerPoints[3]; Lines[15] = CornerPoints[7]; Lines[16] = CornerPoints[4]; Lines[17] = CornerPoints[5]; Lines[18] = CornerPoints[5]; Lines[19] = CornerPoints[6]; Lines[20] = CornerPoints[6]; Lines[21] = CornerPoints[7]; Lines[22] = CornerPoints[7]; Lines[23] = CornerPoints[4]; // draw frustum SimpleShaders::SetDeclPos(); SimpleShaders::BeginShader_Transformed_ConstantColor( g_matViewProjection, Color ); g_pd3dDevice->DrawPrimitiveUP( D3DPT_LINELIST, 12, Lines, sizeof( XMFLOAT3 ) ); SimpleShaders::EndShader(); }