bool RayIntersectTriangle( XMVECTOR xmvOrigin , XMVECTOR xmvDirection , XMVECTOR xmvP0 , XMVECTOR xmvP1 , XMVECTOR xmvP2 , float *pfU , float *pfV , float *pfRayToTriangle ) { XMVECTOR xmvEdge1 = xmvP1 - xmvP0; XMVECTOR xmvEdge2 = xmvP2 - xmvP0; XMVECTOR xmvP, xmvQ; xmvP = XMVector3Cross(xmvDirection, xmvEdge2); XMVECTOR xmvA = XMVector3Dot(xmvEdge1, xmvP); if (XMVector3Equal(xmvA, XMVectorZero())) return(false); float f = 1.0f / XMVectorGetX(xmvA); XMVECTOR d3dxvP0ToOrigin = xmvOrigin - xmvP0; *pfU = f * XMVectorGetX(XMVector3Dot(d3dxvP0ToOrigin, xmvP)); if ((*pfU < 0.0f) || (*pfU > 1.0f)) return(false); xmvQ = XMVector3Cross(d3dxvP0ToOrigin, xmvEdge1); *pfV = f * XMVectorGetX(XMVector3Dot(xmvDirection, xmvQ)); if ((*pfV < 0.0f) || ((*pfU + *pfV) > 1.0f)) return(false); *pfRayToTriangle = f * XMVectorGetX(XMVector3Dot(xmvEdge2, xmvQ)); return(*pfRayToTriangle >= 0.0f); }
_Use_decl_annotations_ __forceinline void __vectorcall FindBarycentricCoordinates(FXMVECTOR a, FXMVECTOR b, FXMVECTOR c, FXMVECTOR p, float* s, float* r, float* t) { XMVECTOR u = b - a; XMVECTOR v = c - a; XMVECTOR w = p - a; XMVECTOR vCrossW = XMVector3Cross(v, w); XMVECTOR vCrossU = XMVector3Cross(v, u); // Validate r is positive (should be if p is in triangle) assert(XMVector2GreaterOrEqual(XMVector3Dot(vCrossW, vCrossU), XMVectorZero())); XMVECTOR uCrossW = XMVector3Cross(u, w); XMVECTOR uCrossV = XMVector3Cross(u, v); // Validate t is positive (should be if p is in triangle) assert(XMVector2GreaterOrEqual(XMVector3Dot(uCrossW, uCrossV), XMVectorZero())); XMVECTOR denom = XMVector3Length(uCrossV); XMVECTOR R = XMVector3Length(vCrossW) / denom; XMVECTOR T = XMVector3Length(uCrossW) / denom; assert(XMVector2LessOrEqual(R + T, XMVectorSet(1, 1, 1, 1))); *r = XMVectorGetX(R); *t = XMVectorGetX(T); *s = 1 - (*r) - (*t); }
bool CPUTModel_CPRT::IntersectFace( const XMVECTOR &rayOrigin, const XMVECTOR &rayDirection, const XMVECTOR &vertexOne, const XMVECTOR &vertexTwo, const XMVECTOR &vertexThree, const XMVECTOR &vertexFour) { for(int i = 0; i < 2; ++i) { XMVECTOR edge1 = (i==0) ? vertexOne-vertexTwo : vertexOne-vertexFour; XMVECTOR edge2 = (i==0) ? vertexThree-vertexTwo : vertexThree-vertexFour; XMVECTOR crossWithPickRay = XMVector3Cross(rayDirection, edge2); float otherEdgeProjection = XMVectorGetX( XMVector3Dot(edge1, crossWithPickRay) ); XMVECTOR tvec = (otherEdgeProjection > 0) ? (i==0 ? rayOrigin - vertexTwo : rayOrigin - vertexFour) : (i==0 ? vertexTwo - rayOrigin : vertexFour - rayOrigin); otherEdgeProjection = (otherEdgeProjection > 0) ? otherEdgeProjection : - otherEdgeProjection; if(otherEdgeProjection < 0.0001f) continue; float u = XMVectorGetX( XMVector3Dot( tvec, crossWithPickRay ) ); if( u < 0.0f || u > otherEdgeProjection ) continue; XMVECTOR qvec = XMVector3Cross( tvec, edge1 ); float v = XMVectorGetX( XMVector3Dot( rayDirection, qvec ) ); if ( v < 0.0f || u + v > otherEdgeProjection ) continue; return true; } return false; }
bool D3DPicking::PointInTriangle(XMVECTOR& triV1, XMVECTOR& triV2, XMVECTOR& triV3, XMVECTOR& point ) { //To find out if the point is inside the triangle, we will check to see if the point //is on the correct side of each of the triangles edges. XMVECTOR cp1 = XMVector3Cross((triV3 - triV2), (point - triV2)); XMVECTOR cp2 = XMVector3Cross((triV3 - triV2), (triV1 - triV2)); if(XMVectorGetX(XMVector3Dot(cp1, cp2)) >= 0) { cp1 = XMVector3Cross((triV3 - triV1), (point - triV1)); cp2 = XMVector3Cross((triV3 - triV1), (triV2 - triV1)); if(XMVectorGetX(XMVector3Dot(cp1, cp2)) >= 0) { cp1 = XMVector3Cross((triV2 - triV1), (point - triV1)); cp2 = XMVector3Cross((triV2 - triV1), (triV3 - triV1)); if(XMVectorGetX(XMVector3Dot(cp1, cp2)) >= 0) { return true; } else return false; } else return false; } return false; }
void TrackingCamera::Update(float deltaTime, float totalTime) { XMVECTOR vPosition = XMLoadFloat3(&position); XMVECTOR vForward = XMLoadFloat3(&forward); XMVECTOR vTarget = XMLoadFloat3(&(target->GetTranslation())); XMVECTOR vUp = XMLoadFloat3(&up); //get vector to object from camera XMVECTOR vToObject = vTarget - vPosition; //get vector projection and rejection of toObject onto forward XMVECTOR vProjection = (XMVector3Dot(vToObject, vForward) / XMVector3Dot(vForward, vForward)) * vForward; XMVECTOR vRejection = vToObject - vProjection; //multiply rejection by trackStrength vRejection = vRejection * trackStrength; //add projection and multiplied rejection XMVECTOR vDirection = vProjection + vRejection; //use new vector as look to XMMATRIX mViewMat = XMMatrixLookToLH(vPosition, vDirection, vUp); XMStoreFloat4x4(&viewMat, XMMatrixTranspose(mViewMat)); }
float Terrain::computeTriangleIntersection(const Ray& ray, const XMVECTOR triangle[3]) { XMVECTOR e1 = triangle[1] - triangle[0]; XMVECTOR e2 = triangle[2] - triangle[0]; XMVECTOR q = XMVector3Cross(ray.direction, e2); const float a = XMVectorGetX(XMVector3Dot(e1, q)); if (a > -std::numeric_limits<float>::epsilon() && a < std::numeric_limits<float>::epsilon()) return -1.f; const float f = 1.f / a; XMVECTOR s = ray.origin - triangle[0]; const float u = f * XMVectorGetX(XMVector3Dot(s, q)); if (u < 0.f) return -1.f; XMVECTOR r = XMVector3Cross(s, e1); const float v = f * XMVectorGetX(XMVector3Dot(ray.direction, r)); if (v < 0.f || u + v > 1.f) return -1.f; return f * XMVectorGetX(XMVector3Dot(e2, r)); }
void Camera::UpdateViewMatrix() { XMVECTOR R = XMLoadFloat3(&mRight); XMVECTOR U = XMLoadFloat3(&mUp); XMVECTOR L = XMLoadFloat3(&mLook); XMVECTOR P = XMLoadFloat3(&mPosition); // Keep camera's axes orthogonal to each other and of unit length. L = XMVector3Normalize(L); U = XMVector3Normalize(XMVector3Cross(L, R)); // U, L already ortho-normal, so no need to normalize cross product. R = XMVector3Cross(U, L); // Fill in the view matrix entries. float x = -XMVectorGetX(XMVector3Dot(P, R)); float y = -XMVectorGetX(XMVector3Dot(P, U)); float z = -XMVectorGetX(XMVector3Dot(P, L)); XMStoreFloat3(&mRight, R); XMStoreFloat3(&mUp, U); XMStoreFloat3(&mLook, L); /* mView(0,0) = mRight.x; mView(1,0) = mRight.y; mView(2,0) = mRight.z; mView(3,0) = x; mView(0,1) = mUp.x; mView(1,1) = mUp.y; mView(2,1) = mUp.z; mView(3,1) = y; mView(0,2) = mLook.x; mView(1,2) = mLook.y; mView(2,2) = mLook.z; mView(3,2) = z; mView(0,3) = 0.0f; mView(1,3) = 0.0f; mView(2,3) = 0.0f; mView(3,3) = 1.0f; */ }
_Use_decl_annotations_ bool __vectorcall ShapeCast(const XMFLOAT3& posA, const XMFLOAT3& moveA, SupportMapping* supA, const XMFLOAT3& posB, const XMFLOAT3& moveB, SupportMapping* supB, XMFLOAT3* normal, float* distance) { XMVECTOR s = XMLoadFloat3(&posA); XMVECTOR r = XMVectorSubtract(XMLoadFloat3(&moveA), XMLoadFloat3(&moveB)); XMVECTOR lambda = XMVectorZero(); XMVECTOR x = s; XMVECTOR v = x - XMLoadFloat3(&posB); XMVECTOR vDotR; XMVECTOR p; XMVECTOR w; XMVECTOR simplexP[5] = {}; uint32_t bits = 0; *distance = 0.0f; *normal = XMFLOAT3(0, 0, 0); XMVECTOR e2 = g_XMEpsilon * g_XMEpsilon; uint32_t iterations = 0; while (XMVector2Greater(XMVector3LengthSq(v), e2) && iterations++ < 1000) { v = XMVector3Normalize(v); p = supA->GetSupportPoint(v) + supB->GetSupportPoint(v); w = x - p; if (XMVector2Greater(XMVector3Dot(v, w), XMVectorZero())) { vDotR = XMVector3Dot(v, r); if (XMVector2GreaterOrEqual(vDotR, XMVectorZero())) { return false; } lambda = lambda - XMVector3Dot(v, w) / vDotR; if (XMVector2Greater(lambda, XMVectorSet(1, 1, 1, 1))) { return false; } x = s + lambda * r; XMStoreFloat3(normal, v); } AddPoint(simplexP, p, &bits); v = FindSupportVectorAndReduce(simplexP, x, &bits); } *distance = XMVectorGetX(lambda); return true; }
void Camera::Update() { if (m_HasMoved) { XMVECTOR t_Right = XMLoadFloat3(&m_Right); XMVECTOR t_Up = XMLoadFloat3(&m_Up); XMVECTOR t_Look = XMLoadFloat3(&m_Look); XMVECTOR t_Pos = XMLoadFloat3(&m_Position); // // Orthonormalize the right, up and look vectors. // // Make look vector unit length. t_Look = XMVector3Normalize(t_Look); // Compute a new corrected "up" vector and normalize it. t_Up = XMVector3Normalize(XMVector3Cross(t_Look, t_Right)); // Compute a new corrected "right" vector. t_Right = XMVector3Cross(t_Up, t_Look); // // Fill in the view matrix entries. // float t_X = -XMVectorGetX(XMVector3Dot(t_Pos, t_Right)); float t_Y = -XMVectorGetX(XMVector3Dot(t_Pos, t_Up)); float t_Z = -XMVectorGetX(XMVector3Dot(t_Pos, t_Look)); XMStoreFloat3(&m_Right, t_Right); XMStoreFloat3(&m_Up, t_Up); XMStoreFloat3(&m_Look, t_Look); m_View(0, 0) = m_Right.x; m_View(1, 0) = m_Right.y; m_View(2, 0) = m_Right.z; m_View(3, 0) = t_X; m_View(0, 1) = m_Up.x; m_View(1, 1) = m_Up.y; m_View(2, 1) = m_Up.z; m_View(3, 1) = t_Y; m_View(0, 2) = m_Look.x; m_View(1, 2) = m_Look.y; m_View(2, 2) = m_Look.z; m_View(3, 2) = t_Z; m_View(0, 3) = 0.0f; m_View(1, 3) = 0.0f; m_View(2, 3) = 0.0f; m_View(3, 3) = 1.0f; m_HasMoved = false; } }
void Camera:: UpdateViewMatrix() { XMVECTOR R = XMLoadFloat3(&mRight); XMVECTOR U = XMLoadFloat3(&mUp); XMVECTOR L = XMLoadFloat3(&mLook); XMVECTOR P = XMLoadFloat3(&mPosition); // // Orthonormalize the right, up and look vectors. // // Make look vector unit length. L = XMVector3Normalize(L); // Compute a new corrected "up" vector and normalize it. U = XMVector3Normalize(XMVector3Cross(L, R)); // Compute a new corrected "right" vector. U and L are // already ortho-normal, so no need to normalize cross product. // ||up × look|| = ||up|| ||look|| sin90° = 1 R = XMVector3Cross(U, L); // // Fill in the view matrix entries. // float x = -XMVectorGetX(XMVector3Dot(P, R)); float y = -XMVectorGetX(XMVector3Dot(P, U)); float z = -XMVectorGetX(XMVector3Dot(P, L)); XMStoreFloat3(&mRight, R); XMStoreFloat3(&mUp, U); XMStoreFloat3(&mLook, L); mView(0,0) = mRight.x; mView(1,0) = mRight.y; mView(2,0) = mRight.z; mView(3,0) = x; mView(0,1) = mUp.x; mView(1,1) = mUp.y; mView(2,1) = mUp.z; mView(3,1) = y; mView(0,2) = mLook.x; mView(1,2) = mLook.y; mView(2,2) = mLook.z; mView(3,2) = z; mView(0,3) = 0.0f; mView(1,3) = 0.0f; mView(2,3) = 0.0f; mView(3,3) = 1.0f; }
XMVECTOR MathHelper::RandHemisphereUnitVec3(XMVECTOR n) { XMVECTOR One = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f); XMVECTOR Zero = XMVectorZero(); // Keep trying until we get a point on/in the hemisphere. while(true) { // Generate random point in the cube [-1,1]^3. XMVECTOR v = XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f); // Ignore points outside the unit sphere in order to get an even distribution // over the unit sphere. Otherwise points will clump more on the sphere near // the corners of the cube. if( XMVector3Greater( XMVector3LengthSq(v), One) ) continue; // Ignore points in the bottom hemisphere. if( XMVector3Less( XMVector3Dot(n, v), Zero ) ) continue; return XMVector3Normalize(v); } }
_Use_decl_annotations_ void BspCompiler::SplitEdge(const Vertex& v0, const Vertex& v1, const XMFLOAT4& plane, Vertex* v) { XMFLOAT3 vv0 = v0.Position; XMFLOAT3 vv1 = v1.Position; float d0 = DistToPlane(plane, vv0); XMVECTOR sub = XMVectorSubtract(XMLoadFloat3(&vv1), XMLoadFloat3(&vv0)); XMVECTOR dir = XMVector3Normalize(sub); XMVECTOR n = XMLoadFloat4(&plane); float d = d0; if (d > 0) { n = XMVectorNegate(n); } else if (d < 0) { d = -d; } else { assert(false); } float x = d / XMVectorGetX(XMVector3Dot(n, dir)); XMStoreFloat3(&v->Position, XMVectorAdd(XMLoadFloat3(&vv0), XMVectorScale(dir, x))); }
f32 Vector::dot(const Vector& vec) const { XMVECTOR vecDot = XMVector3Dot(m_vector, vec.getXMVector()); XMFLOAT4 fDot; XMStoreFloat4(&fDot, vecDot); return fDot.x; }
bool bounding_sphere::contains(const point & point) const { xvector dist(origin - point); float squared = math::point(XMVector3Dot(dist, dist))[axis::x]; return squared < std::pow(get_radius(), 2); }
_Use_decl_annotations_ void KdTreeCompiler2::SplitEdge(_In_ const StaticGeometryVertex& v0, _In_ const StaticGeometryVertex& v1, uint32_t axis, float value, _Out_ StaticGeometryVertex* v) { XMFLOAT3 vv0 = v0.Position; XMFLOAT3 vv1 = v1.Position; float d0 = *(&vv0.x + axis) - value; XMVECTOR sub = XMVectorSubtract(XMLoadFloat3(&vv1), XMLoadFloat3(&vv0)); XMVECTOR dir = XMVector3Normalize(sub); XMVECTOR n = XMLoadFloat3(&_normals[axis]); float d = d0; if (d > 0) { n = XMVectorNegate(n); } else if (d < 0) { d = -d; } else { assert(false); } float x = d / XMVectorGetX(XMVector3Dot(n, dir)); XMStoreFloat3(&v->Position, XMVectorAdd(XMLoadFloat3(&vv0), XMVectorScale(dir, x))); }
void Camera::updateViewMatrix() { //TODO: use XMatrixLookAt built in? // A partir de la view matrix on peut aller chercher les elements (position, up, look) si je me souviens bien XMVECTOR R = XMLoadFloat3(&m_right); XMVECTOR U = XMLoadFloat3(&m_up); XMVECTOR L = XMLoadFloat3(&m_look); XMVECTOR P = XMLoadFloat3(&m_position); // Keep camera's axes orthogonal to each other and of unit length. // Necessary because after several rotations numerical errors can accumulate L = XMVector3Normalize(L); U = XMVector3Normalize(XMVector3Cross(L, R)); // U, L already ortho-normal, so no need to normalize cross product. R = XMVector3Cross(U, L); // Fill in the view matrix entries. float x = -XMVectorGetX(XMVector3Dot(P, R)); float y = -XMVectorGetX(XMVector3Dot(P, U)); float z = -XMVectorGetX(XMVector3Dot(P, L)); XMStoreFloat3(&m_right, R); XMStoreFloat3(&m_up, U); XMStoreFloat3(&m_look, L); //Build the matrix m_view(0,0) = m_right.x; m_view(1,0) = m_right.y; m_view(2,0) = m_right.z; m_view(3,0) = x; m_view(0,1) = m_up.x; m_view(1,1) = m_up.y; m_view(2,1) = m_up.z; m_view(3,1) = y; m_view(0,2) = m_look.x; m_view(1,2) = m_look.y; m_view(2,2) = m_look.z; m_view(3,2) = z; m_view(0,3) = 0.0f; m_view(1,3) = 0.0f; m_view(2,3) = 0.0f; m_view(3,3) = 1.0f; }
bool bounding_sphere::intersects(const sphere & sphere) const { xvector dist(origin - sphere.origin); float squared = math::point(XMVector3Dot(dist, dist))[axis::x]; float radius_sum = get_radius() + sphere.radius; return squared <= std::pow(radius_sum, 2); }
bool bounding_sphere::intersects(const ray & ray) const { point m = ray.get_origin() - origin; point c = point(XMVector3Dot(m, m)) - std::pow(get_radius(), 2); if (c <= 0.f) return true; point b = XMVector3Dot(m, ray.get_direction()); if (b > 0.f) return false; float disc = std::pow(b[axis::x], 2) - c[axis::x]; return disc >= 0.f; }
XMMATRIX Camera::getViewMatrix() const { XMMATRIX m_view = XMMatrixIdentity(); XMVECTOR x = -XMVector3Dot(XMLoadFloat4(&v_Right), XMLoadFloat4(&v_Pos)); XMVECTOR y = -XMVector3Dot(XMLoadFloat4(&v_Up), XMLoadFloat4(&v_Pos)); XMVECTOR z = -XMVector3Dot(XMLoadFloat4(&v_Look), XMLoadFloat4(&v_Pos)); m_view(0,0) = v_Right.x; m_view(0,1) = v_Up.x; m_view(0,2) = v_Look.x; m_view(1,0) = v_Right.y; m_view(1,1) = v_Up.y; m_view(1,2) = v_Look.y; m_view(2,0) = v_Right.z; m_view(2,1) = v_Up.z; m_view(2,2) = v_Look.z; m_view(3,0) = XMVectorGetX(x); m_view(3,1) = XMVectorGetY(y); m_view(3,2) = XMVectorGetZ(z); return m_view; }
//This is the sphere test from the DX SDK "Touch" sample. Pretty elegant imo. bool CPUTModel_CPRT::IntersectionTest(const XMVECTOR &rayOrigin, const XMVECTOR &rayDirection, XMVECTOR &modelPosition, BoundingBox &box) { modelPosition = XMVectorSet ( m_pTransform.m_pData[0][3] , m_pTransform.m_pData[1][3] , m_pTransform.m_pData[2][3] , m_pTransform.m_pData[3][3] ); //TODO: may have to change this for(unsigned int i = 0; i < boxes.size(); ++i) { box = boxes.at(i); XMVECTOR rayToSphere = modelPosition - rayOrigin; //Basic idea is to compare the projection of the casted ray on the ray from the camera position to the sphere position. //If the the casted ray is sufficiently close to the rayToSphere then box.GetSphereRadiusSquared() - lengthOfDisplacementSquared will be > 0 float pointingTheRightWayMeasure = XMVectorGetW( XMVector3Dot( rayToSphere , rayDirection ) ); float lengthOfDisplacementSquared = XMVectorGetW( XMVector3Dot( rayToSphere , rayToSphere ) ); float magic = pointingTheRightWayMeasure*pointingTheRightWayMeasure - lengthOfDisplacementSquared + box.GetSphereRadiusSquared(); selected = ( magic > 0 ) ? true : false ; if(selected) return selected; } return selected; }
void D3DCamera::RebuildView() { // Keep camera's axes orthogonal to each other and of unit length. m_LookAt = XMVector3Normalize(m_LookAt); m_Up = XMVector3Cross(m_LookAt, m_Right); m_Up = XMVector3Normalize(m_Up); m_Right = XMVector3Cross(m_Up, m_LookAt); m_Right = XMVector3Normalize(m_Right); // Fill in the view matrix entries. float x = -XMVectorGetX(XMVector3Dot(m_Position, m_Right)); float y = -XMVectorGetX(XMVector3Dot(m_Position, m_Up)); float z = -XMVectorGetX(XMVector3Dot(m_Position, m_LookAt)); XMFLOAT4X4 tempView; tempView(0, 0) = XMVectorGetX(m_Right); tempView(1, 0) = XMVectorGetY(m_Right); tempView(2, 0) = XMVectorGetZ(m_Right); tempView(3, 0) = x; tempView(0, 1) = XMVectorGetX(m_Up); tempView(1, 1) = XMVectorGetY(m_Up); tempView(2, 1) = XMVectorGetZ(m_Up); tempView(3, 1) = y; tempView(0, 2) = XMVectorGetX(m_LookAt); tempView(1, 2) = XMVectorGetX(m_LookAt); tempView(2, 2) = XMVectorGetX(m_LookAt); tempView(3, 2) = z; tempView(0, 3) = 0.0f; tempView(1, 3) = 0.0f; tempView(2, 3) = 0.0f; tempView(3, 3) = 1.0f; m_ViewMatrix = XMLoadFloat4x4(&tempView); // Reconstuct the viewing frustum. //m_Frustum->ConstructFrustrum( m_zFar, m_ProjMatrix, m_ViewMatrix ); }
XMVECTOR ArcBall::QuatFromBallPoints(XMVECTOR startPoint, XMVECTOR endPoint ) { XMVECTOR dotVector = XMVector3Dot(startPoint, endPoint); float fDot = XMVectorGetX(dotVector); XMVECTOR vPart; vPart = XMVector3Cross(startPoint, endPoint); XMVECTOR result = XMVectorSet(XMVectorGetX(vPart), XMVectorGetY(vPart), XMVectorGetZ(vPart), fDot); return result; }
void GCamera::buildViewMatrix() { XMVECTOR vecLookW = XMVector3Normalize(GMathFV(mLook)); XMVECTOR vecRightW = XMVector3Normalize(XMVector3Cross(GMathFV(mUp), vecLookW)); XMVECTOR vecUpW = XMVector3Normalize(XMVector3Cross(vecLookW, vecRightW)); XMVECTOR vecPosW = GMathFV(mPosition); float x = -GMathVF(XMVector3Dot(vecPosW, vecRightW)).x; float y = -GMathVF(XMVector3Dot(vecPosW, vecUpW)).x; float z = -GMathVF(XMVector3Dot(vecPosW, vecLookW)).x; mRight = GMathVF(vecRightW); mUp = GMathVF(vecUpW); mLook = GMathVF(vecLookW); mView(0, 0) = mRight.x; mView(1, 0) = mRight.y; mView(2, 0) = mRight.z; mView(3, 0) = x; mView(0, 1) = mUp.x; mView(1, 1) = mUp.y; mView(2, 1) = mUp.z; mView(3, 1) = y; mView(0, 2) = mLook.x; mView(1, 2) = mLook.y; mView(2, 2) = mLook.z; mView(3, 2) = z; mView(0, 3) = 0.0f; mView(1, 3) = 0.0f; mView(2, 3) = 0.0f; mView(3, 3) = 1.0f; }
inline BOOL checkOctreeInCamFrus(const Engine::Octree *octree, const Engine::PerspCamera *cam) { const XMVECTOR camera_position = cam->getCameraPosition(); const XMVECTOR view_vector = cam->getViewVector(); const FLOAT fov_2 = cam->getFOV() / 2; XMVECTOR position = XMLoadFloat3(&octree->position); XMVECTOR direction = XMVector3Normalize(position - camera_position); FLOAT dot = XMVectorGetX(XMVector3Dot(view_vector, direction)); if (acosf(dot) < fov_2) return TRUE; for (INT i = 0; i < 8; i++) { position = XMLoadFloat3(&octree->vertex[i]); direction = XMVector3Normalize(position - camera_position); dot = XMVectorGetX(XMVector3Dot(view_vector, direction)); if (acosf(dot) < fov_2) return TRUE; } return FALSE; }
void Camera::UpdateViewMat(){ XMVECTOR r = XMLoadFloat3(&m_right); XMVECTOR u = XMLoadFloat3(&m_up); XMVECTOR l = XMLoadFloat3(&m_look); XMVECTOR p = XMLoadFloat3(&m_position); l = XMVector3Normalize(l); u = XMVector3Normalize(XMVector3Cross(l, r)); r = XMVector3Cross(u, l); float x = -XMVectorGetX(XMVector3Dot(p, r)); float y = -XMVectorGetX(XMVector3Dot(p, u)); float z = -XMVectorGetX(XMVector3Dot(p, l)); XMStoreFloat3(&m_right, r); XMStoreFloat3(&m_up, u); XMStoreFloat3(&m_look, l); XMStoreFloat3(&m_position, p); m_viewMat(0,0) = m_right.x; m_viewMat(0,1) = m_up.x; m_viewMat(0,2) = m_look.x; m_viewMat(0,3) = 0; m_viewMat(1,0) = m_right.y; m_viewMat(1,1) = m_up.y; m_viewMat(1,2) = m_look.y; m_viewMat(1,3) = 0; m_viewMat(2,0) = m_right.z; m_viewMat(2,1) = m_up.z; m_viewMat(2,2) = m_look.z; m_viewMat(2,3) = 0; m_viewMat(3,0) = x; m_viewMat(3,1) = y; m_viewMat(3,2) = z; m_viewMat(3,3) = 1; }
float Physics::comp_ray_tri(XMVECTOR const& _pocz, XMVECTOR const& _kier, CXMVECTOR const& _w0, CXMVECTOR const& _w1, CXMVECTOR const& _w2) const { //------------------WZORY------------------------- // pkt promienia r(t) = pocz + t*kier // wekt1 = w1 - w0, wekt2 = w2 - w0 // pkt trojkata T(u,v) = w0 + u*wekt1 + v*wekt2, dla u >= 0, v >= 0, u+v <= 1 // m = pocz - w0 // t = wekt2 * (m x wekt1) / wekt1 * (kier x wekt2) // u = m * (kier x wekt2) / wekt1 * (kier x wekt2) // v = kier * (m x wekt1) / wekt1 * (kier x wekt2) //------------------------------------------------ XMVECTOR _wekt1 = _w1 - _w0; XMVECTOR _wekt2 = _w2 - _w0; XMVECTOR _m = _pocz - _w0; XMVECTOR _kxwekt2 = XMVector3Cross(_kier, _wekt2); XMVECTOR _mxwekt1 = XMVector3Cross(_m, _wekt1); XMVECTOR _U = XMVector3Dot(_m, _kxwekt2) / XMVector3Dot(_wekt1, _kxwekt2); XMVECTOR _V = XMVector3Dot(_kier, _mxwekt1) / XMVector3Dot(_wekt1, _kxwekt2); float _u = XMVectorGetX(_U); float _v = XMVectorGetX(_V); // jeśli kolizja if(_u >= 0 && _v >= 0 && _u + _v <= 1) { XMVECTOR _T = XMVector3Dot(_wekt2, _mxwekt1) / XMVector3Dot(_wekt1, _kxwekt2); return XMVectorGetX(_T); } else { return 1000.0f; } }
bool bounding_sphere::intersects(const ray & ray, intersection_data & out) const { point m = ray.get_origin() - origin; point b = point(XMVector3Dot(m, ray.get_direction())); point c = point(XMVector3Dot(m, m)) - std::pow(get_radius(), 2); if (c > 0.f && b > 0.f) return false; float disc = std::pow(b[axis::x], 2) - c[axis::x]; if (disc < 0.f) return false; out.distance = -b[axis::x] - std::sqrt(disc); if (out.distance < 0.f) out.distance = 0.f; out.coordinates = ray.get_origin() + point(out.distance) * float3(ray.get_direction()); return true; }
bool SnapToGravity(_Inout_ Plane* plane, _Inout_opt_ XMFLOAT3* tangent, _In_ const XMFLOAT3& center, float snapToGravityThreshold, _In_ const XMVECTOR& vUp) { XMVECTOR vNormal = XMLoadFloat3(&plane->normal); XMVECTOR vCenter = XMLoadFloat3(¢er); float dotGravity = XMVectorGetX(XMVector3Dot(vNormal, vUp)); float dotProductThreshold = cosf(XMConvertToRadians(snapToGravityThreshold)); bool isGravityAligned = false; // check for nearly horizontal planes if (dotGravity > dotProductThreshold) { vNormal = vUp; } else if (dotGravity < -dotProductThreshold) { vNormal = -vUp; } else { // check for nearly vertical planes XMVECTOR vNormalProjectedPerpendicularToGravity = vNormal - (vUp * dotGravity); float dotPerpendicularToGravity = XMVectorGetX(XMVector3Length(vNormalProjectedPerpendicularToGravity)); if (fabs(dotPerpendicularToGravity) > dotProductThreshold) { vNormal = XMVector3Normalize(vNormalProjectedPerpendicularToGravity); isGravityAligned = true; } else { // plane should not be snapped, so exit without modifying plane/tangent return false; } } // update the plane equation plane->StoreVector(XMPlaneFromPointNormal(vCenter, vNormal)); // update the tangent vector if (tangent != nullptr) { XMVECTOR vTangent = (isGravityAligned) ? XMVector3Cross(vNormal, vUp) : XMVector3Cross(XMVector3Cross(vNormal, XMLoadFloat3(tangent)), vNormal); XMStoreFloat3(tangent, XMVector3Normalize(vTangent)); } return isGravityAligned; }
E_INTERSECT_STATE IntersectOrientedBoxPlane(const SOrientedBox& obb, const XMFLOAT4& plane) { /* e = hx*|(n*bu)| + hy*|(n*bv)| + hz*|dot(n*bw)| note: (hx,hy,hz) is the half size of the obb n is the normal of the plane bu,bv,bw is the coordinate system axes of the obb s = dot(c * n) + d; note: c is the center of the obb n is the normal of the plane d is the constant term of the plane if s - e > 0 then INSIDE if s + e < 0 then OUTSIDE else INTERSECTING */ XMVECTOR n = XMLoadFloat4(&plane); XMVECTOR bu = XMLoadFloat3(&obb.Axis[0]); XMVECTOR bv = XMLoadFloat3(&obb.Axis[1]); XMVECTOR bw = XMLoadFloat3(&obb.Axis[2]); XMVECTOR c = XMLoadFloat3(&obb.Center); f32 e = obb.Extents.x * fabs(XMVectorGetX(XMVector3Dot(n, bu))) + obb.Extents.y * fabs(XMVectorGetX(XMVector3Dot(n, bv))) + obb.Extents.z * fabs(XMVectorGetX(XMVector3Dot(n, bw))); f32 s = XMVectorGetX(XMVector3Dot(c, n)) + plane.w; if (s - e > 0) return EIS_INSIDE; if (s + e < 0) return EIS_OUTSIDE; return EIS_INTERSECTING; }
void XM_CALLCONV Camera::UpdateViewMatrix() { XMVECTOR R = XMLoadFloat3( &right ); XMVECTOR U = XMLoadFloat3( &up ); XMVECTOR L = XMLoadFloat3( &look ); XMVECTOR P = XMLoadFloat3( &pos ); L = XMVector3Normalize( L ); U = XMVector3Normalize( XMVector3Cross( L, R ) ); R = XMVector3Cross( U, L ); float x = -XMVectorGetX( XMVector3Dot( P, R ) ); float y = -XMVectorGetX( XMVector3Dot( P, U ) ); float z = -XMVectorGetX( XMVector3Dot( P, L ) ); XMStoreFloat3( &right, R ); XMStoreFloat3( &up, U ); XMStoreFloat3( &look, L ); view( 0, 0 ) = right.x; view( 1, 0 ) = right.y; view( 2, 0 ) = right.z; view( 3, 0 ) = x; view( 0, 1 ) = up.x; view( 1, 1 ) = up.y; view( 2, 1 ) = up.z; view( 3, 1 ) = y; view( 0, 2 ) = look.x; view( 1, 2 ) = look.y; view( 2, 2 ) = look.z; view( 3, 2 ) = z; view( 0, 3 ) = 0.0f; view( 1, 3 ) = 0.0f; view( 2, 3 ) = 0.0f; view( 3, 3 ) = 1.0f; }