void Vec3TransformNormal(KVec3& res, const KVec3& v, const KMatrix4& mat) { KVec3 orig, dst; Vec3TransformCoord(orig, KVec3(0,0,0), mat); Vec3TransformCoord(dst, v, mat); res = dst - orig; res.normalize(); }
void LocalTRSFrame::TransformRay(KRay& out_ray, const KRay& in_ray, const LocalTRSFrame::LclTRS& trs) { KMatrix4 inv_trs = trs.trs.getInverse(); KVec3d newOrig; Vec3TransformCoord(newOrig, in_ray.GetOrg(), inv_trs); KVec3d oldDst = in_ray.GetOrg() + in_ray.GetDir(); KVec3d newDst; Vec3TransformCoord(newDst, oldDst, inv_trs); KVec3d newDir = newDst - newOrig; out_ray.Init(newOrig, newDir, NULL); }
float3 operator*(const float3& v, const _float4x4& m) { _float4 t; Vec3TransformCoord(&t, &v, &m); const float fInverseW = 1.0f / t.w; return float3(t.x * fInverseW, t.y * fInverseW, t.z * fInverseW); }
void TracingInstance::CalcuHitInfo(const IntersectContext& hit_ctx, IntersectInfo& out_info) const { const KSceneSet* pPlainScene = mpScene->GetSource(); const KScene* pKDScene = pPlainScene->GetNodeKDScene(hit_ctx.bbox_node_idx); KAnimation::LocalTRSFrame::LclTRS nodeTRS; pPlainScene->GetNodeTransform(nodeTRS, hit_ctx.bbox_node_idx, mCameraContext.inMotionTime); const nvmath::Mat33f scene_rot = nodeTRS.trs.getRotation(); const nvmath::Mat44f scene_trans = nodeTRS.trs.getMatrix(); const KTriDesc* pTri = mpScene->GetAccelTriData(hit_ctx.bbox_node_idx, hit_ctx.tri_id); UINT32 mesh_idx = pTri->GetMeshIdx(); UINT32 node_idx = pTri->GetNodeIdx(); UINT32 tri_idx = pTri->mTriIdx; const KTriMesh* pMesh = pKDScene->GetMesh(mesh_idx); const KNode* pNode = pKDScene->GetNode(node_idx); const nvmath::Mat33f world_rot = nvmath::Mat33f(pNode->GetObjectRot()) * scene_rot; KTriMesh::PN_Data pn_vert[3]; pMesh->ComputePN_Data(pn_vert[0], pMesh->mFaces[tri_idx].pn_idx[0], mCameraContext.inMotionTime); pMesh->ComputePN_Data(pn_vert[1], pMesh->mFaces[tri_idx].pn_idx[1], mCameraContext.inMotionTime); pMesh->ComputePN_Data(pn_vert[2], pMesh->mFaces[tri_idx].pn_idx[2], mCameraContext.inMotionTime); out_info.pos = pn_vert[0].pos * hit_ctx.w + pn_vert[1].pos * hit_ctx.u + pn_vert[2].pos * hit_ctx.v; KVec3 temp_vec; Vec3TransformCoord(temp_vec, out_info.pos, pNode->GetObjectTM()); Vec3TransformCoord(out_info.pos, temp_vec, scene_trans); // interpolate the normal temp_vec = pn_vert[0].nor * hit_ctx.w + pn_vert[1].nor * hit_ctx.u + pn_vert[2].nor * hit_ctx.v; KVec3 normal = temp_vec * pNode->GetObjectRot(); out_info.nor = normal * scene_rot; out_info.nor.normalize(); KVec3 edge[3]; edge[0] = (pn_vert[1].pos - pn_vert[0].pos); edge[1] = (pn_vert[2].pos - pn_vert[1].pos); KVec3 nor; nor = edge[0] ^ edge[1]; nor.normalize(); out_info.face_nor = nor * world_rot; out_info.bbox_node_idx = hit_ctx.bbox_node_idx; out_info.tri_id = hit_ctx.tri_id; }
float3& float3::operator*=(const _float4x4& m) { _float4 t; Vec3TransformCoord(&t, (const float3*)this, (const _float4x4*)&m); const float fInverseW = 1.0f / t.w; x = t.x * fInverseW; y = t.y * fInverseW; z = t.z * fInverseW; return *this; }
void RectLightBase::SetSize(float w, float h) { mParams.mSizeX = w; mParams.mSizeY = h; KVec3 pos; pos[2] = 0.0f; pos[0] = w * 0.5f; pos[1] = h * 0.5f; Vec3TransformCoord(mParams.mCornerPos[0], pos, mParams.mLightMat); pos[0] = w * 0.5f; pos[1] = h * -0.5f; Vec3TransformCoord(mParams.mCornerPos[1], pos, mParams.mLightMat); pos[0] = w * -0.5f; pos[1] = h * 0.5f; Vec3TransformCoord(mParams.mCornerPos[2], pos, mParams.mLightMat); pos[0] = w * -0.5f; pos[1] = h * -0.5f; Vec3TransformCoord(mParams.mCornerPos[3], pos, mParams.mLightMat); mParams.mEdgeDir[0] = mParams.mCornerPos[0] - mParams.mCornerPos[2]; mParams.mEdgeDir[1] = mParams.mCornerPos[0] - mParams.mCornerPos[1]; }
void KBBox::TransformByMatrix(const KMatrix4d& mat) { KBBox newBBox; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 2; ++j) { KVec3d v = ToVec3d((*this)[j]); v[i] = (*this)[j == 1 ? 0 : 1][i]; KVec3d out_v; Vec3TransformCoord(out_v, v, mat); newBBox.ContainVert(ToVec3f(out_v)); } } (*this) = newBBox; }
bool RectLightBase::EvaluateLighting( const KVec2& samplePos, const KVec3& shading_point, KVec3& outLightPos, LightIterator& outLightIter) const { KVec3 tempPos; tempPos[0] = mParams.mSizeX * (samplePos[0] - 0.5f); tempPos[1] = mParams.mSizeY * (samplePos[1] - 0.5f); tempPos[2] = 0; Vec3TransformCoord(outLightPos, tempPos, mParams.mLightMat); // evaluate the lighting KVec3 temp_vec = outLightPos - shading_point; float rcpLenSqr = 1.0f / (temp_vec[0]*temp_vec[0] + temp_vec[1]*temp_vec[1] + temp_vec[2]*temp_vec[2]); outLightIter.direction = temp_vec * sqrtf(rcpLenSqr); outLightIter.intensity.r = mParams.mIntensity.r; outLightIter.intensity.g = mParams.mIntensity.g; outLightIter.intensity.b = mParams.mIntensity.b; return false; }
//-------------------------------------------------------------------------------------- // Update the view matrix based on user input & elapsed time //-------------------------------------------------------------------------------------- void CFirstPersonCamera::FrameMove( double fElapsedTime ) { if( IsKeyDown( mKeys[CAM_RESET] ) ) { Reset(); } if (IsKeyDown(mKeys[CAM_ACCELERATE])) { if (mKeyboardMoveScaler < 10000.0) { mKeyboardMoveScaler *= 1.2; } if (mMouseMoveScaler < 10000.0) { mMouseMoveScaler *= 1.2; } //since accelerating shouldn't be done continously, force key up here HandleKeys(CAM_ACCELERATE, false); } if (IsKeyDown(mKeys[CAM_THROTTLE])) { if (mKeyboardMoveScaler > 0.1) { mKeyboardMoveScaler /= 1.2; } if (mMouseMoveScaler > 0.1) { mMouseMoveScaler /= 1.2; } HandleKeys(CAM_THROTTLE, false); } // Get keyboard/mouse/gamepad input GetInput( mEnablePositionMovement, ( mActiveButtonMask & mCurrentButtonMask ) || mRotateWithoutButtonDown, true, mResetCursorAfterMove ); // Get amount of velocity based on the keyboard input and drag (if any) UpdateVelocity( fElapsedTime ); // Simple euler method to calculate position delta dvec3 vPosDelta = mVelocity * fElapsedTime; // If rotating the camera if (mMouseRotates) { if( ( mActiveButtonMask & mCurrentButtonMask ) || mRotateWithoutButtonDown) { // Update the pitch & yaw angle based on mouse movement double fYawDelta = mRotVelocity.x; double fPitchDelta = mRotVelocity.y; // Invert pitch if requested if( mInvertPitch ) fPitchDelta = -fPitchDelta; mCameraPitchAngle -= fPitchDelta; mCameraYawAngle -= fYawDelta; // Limit pitch to straight up or straight down mCameraPitchAngle = std::max( -pi<double>() * 0.499, mCameraPitchAngle ); mCameraPitchAngle = std::min( +pi<double>() * 0.499, mCameraPitchAngle ); } } // Make a rotation matrix based on the camera's yaw & pitch dmat4 mCameraRot = yawPitchRoll(mCameraYawAngle, mCameraPitchAngle, 0.0); // Transform vectors based on camera's rotation matrix dvec3 vWorldUp, vWorldAhead; const dvec3 vLocalUp = dvec3( 0, 1, 0 ); const dvec3 vLocalAhead = dvec3( 0, 0, -1 ); vWorldUp = Vec3TransformCoord(vLocalUp, mCameraRot); vWorldAhead = Vec3TransformCoord(vLocalAhead, mCameraRot); // Transform the position delta by the camera's rotation dvec3 vPosDeltaWorld; if( !mEnableYAxisMovement ) { // If restricting Y movement, do not include pitch // when transforming position delta vector. mCameraRot = yawPitchRoll(mCameraYawAngle, 0.0, 0.0 ); } vPosDeltaWorld = Vec3TransformCoord(vPosDelta, mCameraRot ); // Move the eye position mEye += vPosDeltaWorld; if( mClipToBoundary ) ConstrainToBoundary( &mEye ); // Update the lookAt position based on the eye position mLookAt = mEye + vWorldAhead; // Update the view matrix mViewMatrix = lookAt(mEye, mLookAt, vWorldUp ); mCameraWorld = inverse(mViewMatrix ); }
void TracingInstance::CalcuShadingContext(const KRay& hitRay, const IntersectContext& hit_ctx, ShadingContext& out_shading_ctx) const { const KSceneSet* pPlainScene = mpScene->GetSource(); const KScene* pKDScene = pPlainScene->GetNodeKDScene(hit_ctx.bbox_node_idx); KAnimation::LocalTRSFrame::LclTRS nodeTRS; pPlainScene->GetNodeTransform(nodeTRS, hit_ctx.bbox_node_idx, mCameraContext.inMotionTime); const nvmath::Mat33f scene_rot = nodeTRS.trs.getRotation(); const nvmath::Mat44f scene_trans = nodeTRS.trs.getMatrix(); const KTriDesc* pTri = mpScene->GetAccelTriData(hit_ctx.bbox_node_idx, hit_ctx.tri_id); UINT32 mesh_idx = pTri->GetMeshIdx(); UINT32 node_idx = pTri->GetNodeIdx(); UINT32 tri_idx = pTri->mTriIdx; const KTriMesh* pMesh = pKDScene->GetMesh(mesh_idx); const KNode* pNode = pKDScene->GetNode(node_idx); const UINT32* pn_idx = pMesh->mFaces[tri_idx].pn_idx; out_shading_ctx.tracing_instance = this; out_shading_ctx.excluding_bbox = hit_ctx.bbox_node_idx; out_shading_ctx.excluding_tri = hit_ctx.tri_id; assert(out_shading_ctx.excluding_bbox < NOT_HIT_INDEX); assert(out_shading_ctx.excluding_tri < NOT_HIT_INDEX); KTriMesh::PN_Data pn_vert[3]; pMesh->ComputePN_Data(pn_vert[0], pMesh->mFaces[tri_idx].pn_idx[0], mCameraContext.inMotionTime); pMesh->ComputePN_Data(pn_vert[1], pMesh->mFaces[tri_idx].pn_idx[1], mCameraContext.inMotionTime); pMesh->ComputePN_Data(pn_vert[2], pMesh->mFaces[tri_idx].pn_idx[2], mCameraContext.inMotionTime); if (!pMesh->mTexFaces.empty()) { KTriMesh::TT_Data tt_data; pMesh->InterpolateTT(tri_idx, hit_ctx, tt_data, mCameraContext.inMotionTime); out_shading_ctx.uv.uv = tt_data.texcoord; out_shading_ctx.tangent.tangent = tt_data.tangent; out_shading_ctx.tangent.binormal = tt_data.binormal; out_shading_ctx.hasUV = 1; } else out_shading_ctx.hasUV = 0; KVec3 temp_vec; // interpolate the normal temp_vec = pn_vert[0].nor * hit_ctx.w + pn_vert[1].nor * hit_ctx.u + pn_vert[2].nor * hit_ctx.v; out_shading_ctx.normal = temp_vec * pNode->GetObjectRot(); temp_vec = out_shading_ctx.normal * scene_rot; out_shading_ctx.normal = temp_vec; float rcp_len_nor = 1.0f / nvmath::length(temp_vec); out_shading_ctx.normal *= rcp_len_nor; // interpolate the position out_shading_ctx.position = pn_vert[0].pos * hit_ctx.w + pn_vert[1].pos * hit_ctx.u + pn_vert[2].pos * hit_ctx.v; Vec3TransformCoord(temp_vec, out_shading_ctx.position, pNode->GetObjectTM()); Vec3TransformCoord(out_shading_ctx.position, temp_vec, scene_trans); const nvmath::Mat33f world_rot = nvmath::Mat33f(pNode->GetObjectRot()) * scene_rot; KVec3 edge[3]; edge[0] = (pn_vert[1].pos - pn_vert[0].pos) * world_rot; edge[1] = (pn_vert[2].pos - pn_vert[1].pos) * world_rot; edge[2] = (pn_vert[0].pos - pn_vert[2].pos) * world_rot; float edge_len_sqr[3]; edge_len_sqr[0] = nvmath::lengthSquared(edge[0]); edge_len_sqr[1] = nvmath::lengthSquared(edge[1]); edge_len_sqr[2] = nvmath::lengthSquared(edge[2]); float edge_len[3]; edge_len[0] = sqrt(edge_len_sqr[0]); edge_len[1] = sqrt(edge_len_sqr[1]); edge_len[2] = sqrt(edge_len_sqr[2]); // Calculate the face normal and triangle size out_shading_ctx.face_size = edge_len[0] + edge_len[1] + edge_len[2]; out_shading_ctx.face_size *= 0.05f; // Move the shading position along it normal for a epsilon distance. out_shading_ctx.position += (out_shading_ctx.normal * out_shading_ctx.face_size * 0.0001f); KVec3 face_nor; face_nor = edge[0] ^ edge[1]; out_shading_ctx.face_normal = face_nor; out_shading_ctx.face_normal.normalize(); KVec3d rayDir = hitRay.GetDir(); rayDir.normalize(); // Normalize the ray direction because it's not normalized // Get the surface shader ISurfaceShader* pSurfShader = pNode->mpSurfShader; out_shading_ctx.surface_shader = pSurfShader; out_shading_ctx.out_vec = ToVec3f(-rayDir); }
float4 float3::transform(const _float4x4& m) const { float4 t; return *Vec3TransformCoord(&t, this, &m); }