/******************************************************************************** Initialise the camera ********************************************************************************/ void TPCamera::Init(const Vector3& pos, const Vector3& target, const Vector3& up) { this->position = defaultPosition = pos; this->target = defaultTarget = target; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); this->up = defaultUp = right.Cross(view).Normalized(); // Initialise the camera movement flags for (int i = 0; i<255; i++){ myKeys[i] = false; } // Initialise the camera type sCameraType = LAND_CAM; // For Jump use m_bJumping = false; JumpVel = 0.0f; JUMPMAXSPEED = 10.0f; JUMPACCEL = 10.0f; GRAVITY = -30.0f; // Maximum movement speed CAMERA_ACCEL = 10.0f; }
void Camera3::Init(const Vector3& pos, const Vector3& target, const Vector3& up) { this->position = defaultPosition = pos; this->target = defaultTarget = target; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); this->up = defaultUp = right.Cross(view).Normalized(); sCameraType = LAND_CAM; pitchMovingUp = pitchMovingDown = yawMovingLeft = yawMovingRight = false; walkMovingForward = false; //is position still changing walkMovingBackward = false; straftMovingLeft = false; straftMovingRight = false; pitchVelocity = yawVelocity = 0.f; //used for x and z (or y if flying) movingVelocity = false; //changing of pos straftVelocity = 0.f; movingVelocity = 0.f; moveAcceleration = 600.f; camAcceleration = 10.f; camBrakeOffset = 2.5f; cameraSpeed = 3.f; yawAngle = 0.f; //facing X croutching = false; }
void World::DoImpulse(std::vector<float>& impulseMag) { for(uint i = 0; i < contacts_.size(); i++) { Contact& rkContact = contacts_[i]; RigidBody& rkBodyA = *rkContact.A; RigidBody& rkBodyB = *rkContact.B; Vector3 kPA = rkBodyA.GetLinearMomentum(); Vector3 kPB = rkBodyB.GetLinearMomentum(); Vector3 kLA = rkBodyA.GetAngularMomentum(); Vector3 kLB = rkBodyB.GetAngularMomentum(); // update linear/angular momentum/velocity Vector3 kImpulse = impulseMag[i]*rkContact.N; kPA += kImpulse; kPB -= kImpulse; Vector3 kRelA = rkContact.PA - rkBodyA.GetPosition(); kLA += kRelA.Cross(kImpulse); Vector3 kRelB = rkContact.PB - rkBodyB.GetPosition(); kLB -= kRelB.Cross(kImpulse); rkBodyA.SetLinearMomentum(kPA); rkBodyB.SetLinearMomentum(kPB); rkBodyA.SetAngularMomentum(kLA); rkBodyB.SetAngularMomentum(kLB); } }
void tyrFreeFormDef::reParamVertices(vector<RectCoord> ¶m, Vector3 &S,Vector3 &T, Vector3 &U){ printf(" - Reparameterizing vertices\n"); int nVtx = _ply.GetNumVertices(); point3D_t *vtx = _ply.GetVertices(); Vector3 min = _ply.GetMin(); Vector3 p0 = min; Vector3 max = _ply.GetMax(); S = Vector3(max.x - min.x,0.0,0.0); T = Vector3(0.0,max.y - min.y,0.0); U = Vector3(0.0,0.0,max.z - min.z); Vector3 TcU = T.Cross(U); Vector3 ScU = S.Cross(U); Vector3 ScT = S.Cross(T); double TcUdS = TcU.Dot(S); double ScUdT = ScU.Dot(T); double ScTdU = ScT.Dot(U); for(int v = 0; v < nVtx; v++){ Vector3 diff = vtx[v].ToVector3() - p0; RectCoord tmp; tmp.s = TcU.Dot(diff/TcUdS); tmp.t = ScU.Dot(diff/ScUdT); tmp.u = ScT.Dot(diff/ScTdU); tmp.p = p0 + (tmp.s * S) + (tmp.t * T) + (tmp.u * U); tmp.p0 = p0; { ///Pre-calculate bernstein polynomial expansion. It only needs to be done once per parameterization for(int i = 0; i <= 5; i++){ for(int j = 0; j <= 5; j++){ for(int k = 0; k <= 5; k++){ tmp.bernPolyPack[n][k][2] = bern_poly(n,k,tmp.u); } tmp.bernPolyPack[m][j][1] = bern_poly(m,j,tmp.t); } tmp.bernPolyPack[l][i][0] = bern_poly(l,i,tmp.s); } } param.push_back(tmp); if(tmp.p.Dist(vtx[v].ToVector3()) > Math::EPSILON){ printf(" - Warning, vtx[%d] does not match it's parameterization.\n",v); } } for(int i = 0; i <= 5; i++){ for(int j = 0; j <= 5; j++){ Vector3 tK(0.0f,0.0f,0.0f); for(int k = 0; k <= 5; k++){ controlPoints[i][j][k] = createControlPoint(min,i,j,k,S,T,U); } } } }
void Triangle::computeForces(Vector3 &airVelocity) { this->airVelocity = airVelocity; Vector3 velocity = (p1->velocity + p2->velocity + p3->velocity) / 3; Vector3 realVelocity = velocity - airVelocity; if (realVelocity.Mag() > 0) { Vector3 *one = new Vector3(); Vector3 *two = new Vector3(); one->Cross(p2->position - p1->position, p3->position - p1->position); two->Cross(p2->position - p1->position, p3->position - p1->position); one->Normalize(); normal = *one; float a0 = 0.5 * two->Mag(); float a = a0 * (realVelocity.Dot(normal) / realVelocity.Mag()); Vector3 fAero = -0.5 * density * realVelocity.Mag2() *a *normal; Vector3 fAeroParticle = fAero / 3; if (!p1->pinned) p1->applyForce(fAeroParticle); if (!p2->pinned) p2->applyForce(fAeroParticle); if (!p3->pinned) p3->applyForce(fAeroParticle); delete one; delete two; } }
void CustomCam1::rotateCamVertical(float degrees) { if (degrees + f_currentPitch > f_pitchLimit && degrees > 0) { degrees = f_pitchLimit - f_currentPitch; if (f_currentPitch >= f_pitchLimit) { degrees = 0.f; } } else if (degrees + f_currentPitch < -f_pitchLimit && degrees < 0) { degrees = -f_pitchLimit - f_currentPitch; if (f_currentPitch <= -f_pitchLimit) { degrees = 0.f; } } Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); up = right.Cross(view).Normalized(); Mtx44 rotation; target -= position; f_currentPitch += degrees; rotation.SetToRotation(static_cast<float>(degrees), right.x, right.y, right.z); target = rotation * target; target += position; }
void Camera2::Init(const Vector3& pos, const Vector3& target, const Vector3& up) { this->position = defaultPosition = pos; this->target = defaultTarget = target; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); this->up = defaultUp = right.Cross(view).Normalized(); }
bool Collision::Capsule_Capsule(const Capsule& capsule1, const Capsule& capsule2, HitInfo& hitInfo) { Vector3 a = capsule1.vector; Vector3 b = capsule2.vector; Vector3 c = capsule2.p1 - capsule1.p1; float distance = capsule1.radius + capsule2.radius; Vector3 n = a.Cross(b).GetNormal(); float L = c.Dot(n); Vector3 n1 = a.Cross(n).GetNormal(); Vector3 n2 = b.Cross(n).GetNormal(); Vector3 p3Dash = capsule2.p1 - n * L; Vector3 p4Dash = capsule2.p2 - n * L; Vector3 v1 = capsule1.p1 - p3Dash; Vector3 v2 = capsule1.p2 - p3Dash; Vector3 v3 = p3Dash - capsule1.p1; Vector3 v4 = p4Dash - capsule1.p1; float L1 = v1.Dot(n2); float L2 = v2.Dot(n2); float L3 = v3.Dot(n1); float L4 = v4.Dot(n1); float t1 = L3 / (L3 - L4); float t2 = L1 / (L1 - L2); if ((Math::Abs(L) < distance) && (0 < t1 && t1 < 1) && (0 < t2 && t2 < 1)) { return true; } BoundingSphere s = BoundingSphere(capsule1.p1, capsule1.radius); if ((t1 < 0) && BoundingSphere_Capsule(s, capsule2, hitInfo)) { return true; } s = BoundingSphere(capsule2.p1, capsule2.radius); if ((t1 > 1) && BoundingSphere_Capsule(s, capsule1, hitInfo)) { return true; } s = BoundingSphere(capsule2.p1, capsule2.radius); if ((t2 < 0) && BoundingSphere_Capsule(s, capsule1, hitInfo)) { return true; } s = BoundingSphere(capsule2.p2, capsule2.radius); if ((t2 > 1) && BoundingSphere_Capsule(s, capsule1, hitInfo)) { return true; } return false; }
void Camera3::Init(const Vector3& pos, const Vector3& target, const Vector3& up) { maxCameraX = 49.99f; cameraSpeed = 2.5f; this->position = defaultPosition = pos; this->target = defaultTarget = target; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); this->up = defaultUp = right.Cross(view).Normalized(); directionRotation = Vector3(0, -180, 0); gunRecoil = Vector3(0,0,0); camerarotation = Vector3(0,0,0); speed = 100; location = (0,0,0); location2 = (0, 0, 0); //direction2 = (0, 0, 0); //mouseControl = true; //delay = 0; delay2 = 0; //cd = 10; cameraStore = 0; cRecoilCd = 0; stamina = 300; staminaDelay = 0; glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //for hitboxes minVectors.push_back(minPos(Vector3(-338, 0, 38), 20, 120, 90)); minVectors.push_back(minPos(Vector3(-460, 0, 38), 20, 120, 90)); minVectors.push_back(minPos(Vector3(-400, 0, 73), 120, 120, 20)); minVectors.push_back(minPos(Vector3(-360, 0, 0), 70, 100, 30)); minVectors.push_back(minPos(Vector3(-435, 0, 0), 58, 120, 20)); maxVectors.push_back(maxPos(Vector3(-338, 0, 38), 20, 120, 90)); maxVectors.push_back(maxPos(Vector3(-460, 0, 38), 20, 120, 90)); maxVectors.push_back(maxPos(Vector3(-400, 0, 73), 120, 120, 20)); maxVectors.push_back(maxPos(Vector3(-360, 0, 0), 70, 100, 30)); maxVectors.push_back(maxPos(Vector3(-435, 0, 0), 52, 120, 20)); //Minerals hitbox MineralVectors.push_back(Vector3(-113, 5, -66)); MineralVectors.push_back(Vector3(-126, 5, -394)); MineralVectors.push_back(Vector3(590, 5, -395)); MineralVectors.push_back(Vector3(270, 5, 201)); MineralVectors.push_back(Vector3(223, 5, 934)); MineralVectors.push_back(Vector3(84, 5, 522)); MineralVectors.push_back(Vector3(-516, 5, 809)); MineralVectors.push_back(Vector3(361, 5, 772)); MineralVectors.push_back(Vector3(-643, 5, 825)); MineralVectors.push_back(Vector3(-415, 5, 174)); }
void FirstPersonCamera::Init(const Vector3& pos, const Vector3& target, const Vector3& up) { this->position = defaultPosition = pos; this->target = defaultTarget = target; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); this->up = defaultUp = right.Cross(view).Normalized(); canMoveBuilding = true; canMoveInteractable = true; }
void Matrix::SetLookAtRH(const Vector3 &eye, const Vector3 &up, const Vector3 &at) { Vector3 zaxis; Vector3 xaxis; Vector3 yaxis; zaxis = (eye - at).Normalize(); xaxis = (up.Cross(zaxis)).Normalize(); yaxis = zaxis.Cross(xaxis); *this = Matrix( xaxis, yaxis, zaxis ); TranslatePreRotation( -eye.x, -eye.y, -eye.z ); }
void Camera::RenderPath(Scene &scn, int n) { RayTrace rayTrace(scn); for (int y = 0; y < _img.YRes; y++) { for (int x = 0; x < _img.XRes; x++) { // compute the primary ray Vector3 cy; cy.Cross(_worldMatrix.c, _worldMatrix.b); Vector3 cx = cy / pow(cy.Magnitude(), 2); cy.Cross(cx, _worldMatrix.c); float hfov = 2.f * atanf(_aspect * tanf(_verticalFOV / 2.f)); float cw = 2.f * tanf(hfov/2.f); float ch = cw / _aspect; Ray ray; ray.Origin = _worldMatrix.d; ray.Direction = _worldMatrix.c + ((float)(x + 0.5f) / (float)_img.XRes - 0.5f) * cw * cx + ((float)(y + 0.5f)/(float)_img.YRes - 0.5f) * ch * cy; ray.type = Ray::PRIMARY; // shoot the primary ray Intersection hit; if (x > 124 && x <= 140 && y == _img.YRes - 495 ) { // Color white = Color::WHITE; // std::cout << "debug pixel" << std::endl; // _img.SetPixel(x, y, white.ToInt()); // continue; } rayTrace.TraceRay(ray, hit); if (n != -1) { Color c; c.FromInt(_img.GetPixel(x, y)); Color avg = Color::BLACK; avg.AddScaled(c, n - 1); avg.Add(hit.Shade); avg.Scale(1.0f / n); _img.SetPixel(x, y, avg.ToInt()); } else _img.SetPixel(x, y, hit.Shade.ToInt()); } } }
bool IntersectTriangle(Vector3& orig, Vector3& dir, Vector3& v0, Vector3& v1, Vector3& v2) { double t, u, v; // E1 Vector3 E1 = v1 - v0; // E2 Vector3 E2 = v2 - v0; // P Vector3 P = dir.Cross(E2); // determinant double det = E1.Dot(P); // keep det > 0, modify T accordingly Vector3 T; if( det >0 ) { T = orig - v0; } else { T = v0 - orig; det = -det; } // If determinant is near zero, ray lies in plane of triangle if( det < 0.0001f ) return false; // Calculate u and make sure u <= 1 u = T.Dot(P); if( u < 0.0f || u > det ) return false; // Q Vector3 Q = T.Cross(E1); // Calculate v and make sure u + v <= 1 v = dir.Dot(Q); if( v < 0.0f || u + v > det ) return false; // Calculate t, scale parameters, ray intersects triangle t = E2.Dot(Q); if (t < 0.0f) return false; return true; }
/******************************************************************************** Turn right ********************************************************************************/ void TPCamera::TurnRight(const double dt) { Vector3 view = (target - position).Normalized(); // float yaw = (float)(-CAMERA_SPEED * Application::camera_yaw * (float)dt); float yaw = (float)(-CAMERA_SPEED * (float)dt); Mtx44 rotation; rotation.SetToRotation(yaw, 0, 1, 0); view = rotation * view; target = position + view; Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); up = right.Cross(view).Normalized(); }
/******************************************************************************** LookDown ********************************************************************************/ void TPCamera::LookDown(const double dt) { //float pitch = (float)(-CAMERA_SPEED * Application::camera_pitch * (float)dt); float pitch = (float)(CAMERA_SPEED * (float)dt); Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); up = right.Cross(view).Normalized(); Mtx44 rotation; rotation.SetToRotation(pitch, right.x, right.y, right.z); view = rotation * view; target = position + view; }
void Camera3::Init(const Vector3& pos, const Vector3& target, const Vector3& up) { this->position = defaultPosition = pos; this->target = defaultTarget = target; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); this->up = defaultUp = right.Cross(view).Normalized(); // Initialise the camera movement flags for (int i = 0; i < 255; i++) myKeys[i] = false; }
void Camera3::Init(const Vector3& pos, const Vector3& target, const Vector3& up, vector<Rock> *Rocks, Flag *flag, vector<CollisionObject> *Pillars) { this->position = defaultPosition = pos; this->target = defaultTarget = target; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); MouseSensitivity = 0.2; this->up = defaultUp = right.Cross(view).Normalized(); this->Rocks = Rocks; this->flag = flag; this->Pillars = Pillars; }
/******************************************************************************** LookRight ********************************************************************************/ void Camera3::LookRight(const double dt) { float yaw = yawVelocity; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); up = right.Cross(view).Normalized(); Mtx44 rotation; rotation.SetToRotation(yaw, 0, 1, 0); view = rotation * view; target = position + view; up = rotation * up; }
const Matrix4& Camera::GetViewMatrix( void ) { if (!m_viewMatrixDirty) { return m_viewMatrix; } Vector3 viewDir = m_lookAt - m_position; viewDir.Normalize(); Vector3 right = m_up.Cross(viewDir); right.Normalize(); Vector3 yAxis = viewDir.Cross(right); float tx = -m_position.Dot(right); float ty = -m_position.Dot(yAxis); float tz = -m_position.Dot(viewDir); m_viewMatrix.m11 = right.x; m_viewMatrix.m12 = yAxis.x; m_viewMatrix.m13 = viewDir.x; m_viewMatrix.m14 = 0.0f; m_viewMatrix.m21 = right.y; m_viewMatrix.m22 = yAxis.y; m_viewMatrix.m23 = viewDir.y; m_viewMatrix.m24 = 0.0f; m_viewMatrix.m31 = right.z; m_viewMatrix.m32 = yAxis.z; m_viewMatrix.m33 = viewDir.z; m_viewMatrix.m34 = 0.0f; m_viewMatrix.m41 = tx; m_viewMatrix.m42 = ty; m_viewMatrix.m43 = tz; m_viewMatrix.m44 = 1.0f; m_viewMatrixDirty = false; return m_viewMatrix; }
void Vector3<Real>::GenerateOrthonormalBasis (Vector3& rkU, Vector3& rkV, Vector3& rkW, bool bUnitLengthW) { if ( !bUnitLengthW ) rkW.Normalize(); Real fInvLength; if ( Math<Real>::FAbs(rkW.m_afTuple[0]) >= Math<Real>::FAbs(rkW.m_afTuple[1]) ) { // W.x or W.z is the largest magnitude component, swap them fInvLength = Math<Real>::InvSqrt(rkW.m_afTuple[0]*rkW.m_afTuple[0] + rkW.m_afTuple[2]*rkW.m_afTuple[2]); rkU.m_afTuple[0] = -rkW.m_afTuple[2]*fInvLength; rkU.m_afTuple[1] = (Real)0.0; rkU.m_afTuple[2] = +rkW.m_afTuple[0]*fInvLength; } else { // W.y or W.z is the largest magnitude component, swap them fInvLength = Math<Real>::InvSqrt(rkW.m_afTuple[1]*rkW.m_afTuple[1] + rkW.m_afTuple[2]*rkW.m_afTuple[2]); rkU.m_afTuple[0] = (Real)0.0; rkU.m_afTuple[1] = +rkW.m_afTuple[2]*fInvLength; rkU.m_afTuple[2] = -rkW.m_afTuple[1]*fInvLength; } rkV = rkW.Cross(rkU); }
Vector3 RigidBodyContact::CalculateFrictionlessImpulse(Matrix3x3* inverseInertiaTensor) { Vector3 impulseContact; float deltaVelocity = 0; for (int i = 0; i < 2; i ++) { if (Body[i] != NULL) { // Calculate a vector that shows the change in velocity in world space for a unit impulse // in the direction of the contact normal Vector3 deltaVelocityWorldspace = m_relativeContactPosition[i].Cross(ContactNormal); deltaVelocityWorldspace = inverseInertiaTensor[i] * deltaVelocityWorldspace; deltaVelocityWorldspace = deltaVelocityWorldspace.Cross(m_relativeContactPosition[i]); // Calculate the change in velocity in contact coordinates deltaVelocity += deltaVelocityWorldspace.Dot(ContactNormal); // Add the linear component of velocity change deltaVelocity += Body[i]->GetInverseMass(); } } impulseContact.SetX(m_desiredDeltaVelocity / deltaVelocity); impulseContact.SetY(0.0f); impulseContact.SetZ(0.0f); return impulseContact; }
void CustomCam1::Init(const Vector3& pos, const Vector3& target, const Vector3& up, const float mouseSensitivity) { this->position = defaultPosition = pos; this->target = defaultTarget = target; Vector3 view = (target - position).Normalized(); Vector3 right = view.Cross(up); right.y = 0; right.Normalize(); this->up = defaultUp = right.Cross(view).Normalized(); this->mouseSensitivity = mouseSensitivity; mouseX = 0.0; mouseY = 0.0; f_currentPitch = CalAnglefromPosition(target, position, false); f_pitchLimit = 80.f; }
Object::Object(Vector3 pos, Vector3 view, Vector3 up) { Pos = pos; View = view; Up = up; Right = view.Cross(up); }
void FPcamera::Init(const Vector3& pos, const Vector3& target, const Vector3& up) { this->position = defaultPosition = pos; this->target = defaultTarget = target; view = (target - position).Normalized(); Vector3 right = view.Cross(up).Normalized(); right.y = 0; right.Normalize(); this->up = defaultUp = right.Cross(view).Normalized(); this->sensitivity = defaultSensitivity = 1.0f; sCameraType = LAND_CAM; for (int i = 0; i < 255; ++i) { myKeys[i] = false; } m_bCrouching = false; m_bCollideGround = true; m_bJumping = false; m_bRecoil = false; JumpVel = 0.0f; JUMPMAXSPEED = 200.f; JUMPACCEL = 100.f; GRAVITY = -200.f; rotationX = 0.f; rotationY = 0.f; recoil = 0.f; }
Color Raytracer::CalnReflection( Collider* collider , Vector3 ray_V , int dep , bool refracted , int* hash, int rc, Color weight) { Primitive* pri = collider->GetPrimitive(); ray_V = ray_V.Reflect( collider->N ); if ( pri->GetMaterial()->drefl < EPS || dep > MAX_DREFL_DEP ) { Color alpha = pri->GetMaterial()->color * pri->GetMaterial()->refl; return RayTracing( collider->C , ray_V , dep + 1 , refracted , hash, rc, weight * alpha) * alpha; } Vector3 Dx = ray_V.GetAnVerticalVector(); Vector3 Dy = ray_V.Cross(Dx); Dx = Dx.GetUnitVector() * pri->GetMaterial()->drefl; Dy = Dy.GetUnitVector() * pri->GetMaterial()->drefl; int totalSample = camera->GetDreflQuality(); Color rcol, alpha = pri->GetMaterial()->color * pri->GetMaterial()->refl / totalSample; for ( int k = 0 ; k < totalSample ; k++ ) { double x , y; do { x = ran() * 2 - 1; y = ran() * 2 - 1; } while ( x * x + y * y > 1 ); x *= pri->GetMaterial()->drefl; y *= pri->GetMaterial()->drefl; rcol += RayTracing( collider->C , ray_V + Dx * x + Dy * y , dep + MAX_DREFL_DEP , refracted , NULL, rc, weight * alpha); } return rcol * alpha; }
void pTriangle::ComputeForce(Vector3 vair) { //find the tirangle velocity velocity = (p1->getVelocity() + p2->getVelocity() + p3->getVelocity()) / 3 ; //assume no air velocity for now Vector3 v = velocity - vair; Vector3 r1 = p1->getPosition(); Vector3 r2 = p2->getPosition(); Vector3 r3 = p3->getPosition(); //find triangle unnormalized normal, n* Vector3 ra = (r2 - r1); Vector3 rb = (r3 - r1); Vector3 ncross; ncross.Cross(ra, rb); //constants float p = 1.225f; float cd = 1.225f; //force = -1/2 * p * |v|^2 * cd * a * n Vector3 v2an = ( (v.Mag()*v.Dot(ncross))/(2.0f*ncross.Mag()) ) * ncross; Vector3 aeroForce = (-1.0f/2.0f) * p * cd * v2an; aeroForce = aeroForce / 3; p1->ApplyForce(aeroForce); p2->ApplyForce(aeroForce); p3->ApplyForce(aeroForce); normal = ncross.Normalize(); }
bool IntrSegment3Triangle3<Real>::Test () { // Compute the offset origin, edges, and normal. Vector3<Real> diff = mSegment->Center - mTriangle->V[0]; Vector3<Real> edge1 = mTriangle->V[1] - mTriangle->V[0]; Vector3<Real> edge2 = mTriangle->V[2] - mTriangle->V[0]; Vector3<Real> normal = edge1.Cross(edge2); // Solve Q + t*D = b1*E1 + b2*E2 (Q = diff, D = segment direction, // E1 = edge1, E2 = edge2, N = Cross(E1,E2)) by // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) Real DdN = mSegment->Direction.Dot(normal); Real sign; if (DdN > Math<Real>::ZERO_TOLERANCE) { sign = (Real)1; } else if (DdN < -Math<Real>::ZERO_TOLERANCE) { sign = (Real)-1; DdN = -DdN; } else { // Segment and triangle are parallel, call it a "no intersection" // even if the segment does intersect. mIntersectionType = IT_EMPTY; return false; } Real DdQxE2 = sign*mSegment->Direction.Dot(diff.Cross(edge2)); if (DdQxE2 >= (Real)0) { Real DdE1xQ = sign*mSegment->Direction.Dot(edge1.Cross(diff)); if (DdE1xQ >= (Real)0) { if (DdQxE2 + DdE1xQ <= DdN) { // Line intersects triangle, check if segment does. Real QdN = -sign*diff.Dot(normal); Real extDdN = mSegment->Extent*DdN; if (-extDdN <= QdN && QdN <= extDdN) { // Segment intersects triangle. mIntersectionType = IT_POINT; return true; } // else: |t| > extent, no intersection } // else: b1+b2 > 1, no intersection } // else: b2 < 0, no intersection } // else: b1 < 0, no intersection mIntersectionType = IT_EMPTY; return false; }
void rms::ComputeAlignAxisMatrix( const Vector3<Real> & vInitial, const Vector3<Real> & vAlignWith, Matrix3<Real> & matrix ) { // compute cosine of angle between vectors Real axisDot = vAlignWith.Dot( vInitial ); // compute rotation axis Vector3<Real> axisCross( vInitial.Cross( vAlignWith ) ); // apply rotation if necessary if (axisCross.SquaredLength() > Wml::Math<Real>::EPSILON) { // compute normalized axis and angle, then create rotation around axis axisCross.Normalize(); Real fAngle = Math<Real>::ACos( axisDot / vAlignWith.Length() ); matrix.FromAxisAngle( axisCross, fAngle ); } else if (axisDot < (Real)0) { // find some perpendicular vectors Wml::Vector3<Real> vPerp1, vPerp2; ComputePerpVectors( vInitial, vPerp1, vPerp2 ); matrix.FromAxisAngle( vPerp1, (Real)180 * Math<Real>::DEG_TO_RAD ); } else { matrix = Matrix3<Real>::IDENTITY; } }
Color Shade(const Ray ray, const int depth, const vector<BVHNode>& nodes, const vector<Sphere>& spheres) { // id of intersected object unsigned int sphereId = 0; // cout << "Shade: " << ray.ToString() << endl; const float t = ItrIntersect(ray, nodes, spheres, sphereId); // cout << endl; if (sphereId == -1) return Color(0,0,0); // Background color const Sphere& sphere = spheres[sphereId]; const Vector3 hitPos = ray.origin + ray.dir * t; const Vector3 norm = (hitPos - sphere.position).Normalize(); const Vector3 nl = Dot(norm, ray.dir) < 0 ? norm : norm * -1; Color f = sphere.color; const float maxRefl = f.x>f.y && f.x>f.z ? f.x : f.y>f.z ? f.y : f.z; if (depth > 1) // if depth above 5, then terminate return sphere.emission; // All objects are diffuse const float r1 = 2 * M_PI * Rand01(); const float r2 = Rand01(); const float r2s = sqrtf(r2); // Normal space const Vector3 w = nl; const Vector3 u = ((fabsf(w.x) > 0.1f ? Vector3(0,1,0) : Vector3(1,0,0)).Cross(w)).Normalize(); const Vector3 v = w.Cross(u); const Vector3 newRayDir = (u * cos(r1) * r2s + v * sin(r1) * r2s + w * sqrtf(1-r2)).Normalize(); const Vector3 newPos = hitPos + nl * 0.02f; return sphere.emission + f * Shade(Ray(newPos, newRayDir), depth+1, nodes, spheres); }
vector<Ray> CreateRays() { Ray cam(Vector3(50,52,295.6), Vector3(0,-0.042612,-1).Normalize()); // cam pos, dir Vector3 cx = Vector3(WIDTH * 0.5135 / HEIGHT, 0, 0); Vector3 cy = (cx.Cross(cam.dir)).Normalize() * 0.5135; vector<Ray> rays = vector<Ray>(WIDTH * HEIGHT * samples); for (int y = 0; y < HEIGHT; y++){ unsigned short Xi[3] = {0, 0, y*y*y}; for (unsigned short x = 0; x < WIDTH; x++) { // subpixel grid for (int subY = 0; subY < sqrtSamples; ++subY) for (int subX = 0; subX < sqrtSamples; ++subX) { // Samples double r1 = 2 * erand48(Xi); float dx = r1 < 1 ? sqrt(r1) - 1 : 1 - sqrt(2 - r1); double r2 = 2 * erand48(Xi); float dy = r2 < 1 ? sqrt(r2) - 1: 1 - sqrt(2 - r2); Vector3 rayDir = cx * (((subX + 0.5 + dx) / sqrtSamples + x) / WIDTH - 0.5) + cy * (((subY + 0.5 + dy) / sqrtSamples + y) / HEIGHT - 0.5) + cam.dir; rays[Index(x,y,subX,subY)] = Ray(cam.origin + rayDir * 140, rayDir.Normalize()); } } } return rays; }