OQuaternion OQuaternion::operator*(const OQuaternion& q) const { OQuaternion qr; qr.w_ = w_ * q.w_ - V3().Dot(q.V3()); qr.V3() = w_ * q.V3() + q.w_ * V3() + V3() * q.V3(); return qr; }
aabb Canopy::setAABB(){ m_AABB.xMin = FLT_MAX; m_AABB.yMin = FLT_MAX; m_AABB.zMin = FLT_MAX; m_AABB.xMax = -FLT_MAX; m_AABB.yMax = -FLT_MAX; m_AABB.zMax = -FLT_MAX; m_AABB.max = V3(m_AABB.xMax, m_AABB.yMax, m_AABB.zMax); m_AABB.min = V3(m_AABB.xMin, m_AABB.yMin, m_AABB.zMin); std::vector<V3*>::iterator it,itend; it = m_Canopy.begin(); itend = m_Canopy.end(); for(it;it!=itend;it++){ V3 vertex = *(*it); if (m_AABB.xMin > vertex.x) m_AABB.xMin = vertex.x; if (m_AABB.xMax < vertex.x) m_AABB.xMax = vertex.x; if (m_AABB.yMin > vertex.y) m_AABB.yMin = vertex.y; if (m_AABB.yMax < vertex.y) m_AABB.yMax = vertex.y; if (m_AABB.zMin > vertex.z) m_AABB.zMin = vertex.z; if (m_AABB.zMax < vertex.z) m_AABB.zMax = vertex.z; m_AABB.min = V3(m_AABB.xMin,m_AABB.yMin,m_AABB.zMin); m_AABB.max = V3(m_AABB.xMax,m_AABB.yMax,m_AABB.zMax); } return m_AABB; }
void update_and_render(Pixel_Buffer *buffer) { // for (int y = 0; y < buffer->height / 2; y++) { // for (int x = 0; x < buffer->width / 2; x++) { // draw_pixel(buffer, x, y, 0x00326799); // } // } v3 eye = V3(0, 0, -50); r32 screen_width = 200; r32 pixel_size = (r32)buffer->width / screen_width; r32 screen_height = (r32)buffer->height / pixel_size; // Sphere v3 c = V3(0, 0, -100); r32 r = 40; for (int y = 0; y < buffer->height; y++) { for (int x = 0; x < buffer->width; x++) { // get ray through pixel v3 pixel; pixel.x = (-screen_width / 2.0f) + (0.5f + x) * pixel_size; pixel.y = (-screen_height / 2.0f) + (0.5f + y) * pixel_size; pixel.z = 0; v3 d = pixel - eye; } } }
PPC::PPC(float hfov, int w, int h) : w(w), h(h) { a = V3(1.0f, 0.0f, 0.0f); b = V3(0.0f, -1.0f, 0.0f); C = V3(0.0f, 0.0f, 0.0f); float f = (float)w/2.0f/tanf(DEG2RAD(hfov/2.0f)); c = V3(-(float)w/2.0f, (float)h/2.0f, -f); SetPMat(); }
void OrbitCamera::reset() { center = V3(0.0, 0.0, 0.0); up = V3(0.0, 1.0, 0.0); zoom = 3.5; angle_x = PI * 1.5f; angle_y = 0.2f; fovy = 60.0; far_clip = 1000.0; near_clip = 0.1; }
PPC::PPC() { a = V3(1.0f, 0.0f, 0.0f); b = V3(0.0f, -1.0f, 0.0f); c = V3(0.0f, 0.0f, 0.0f); C = V3(0.0f, 0.0f, 0.0f); w = 0; h = 0; SetPMat(); }
void DrawingExample::addControlPointWithUXEvent(shared_ptr<UXEvent> event){ if (!event->referenceNode) { auto store = View::viewWithSize(size.get().xy); canvas->addChild(store); event->referenceNode = store; auto layer = MeshBatcher::nodeWithPrimitive(NKPrimitiveRect, Texture::textureWithImageFile("soft64.png"), BLACK, 1); layer->setIs2d(true); //auto layer = SpriteEmitter::nodeWithTexture(Texture::textureWithImageFile("soft64.png"), Color(0)); store->addChild(layer); layer->position.set(event->screenLocation - (scene()->size.get().xy / 2.0)); // DO FIRST POINT auto cp = Node::node(Color(0,0),1); layer->addChild(cp); auto point = Node::node(BLACK,V3(3)); cp->addChild(point); } else { auto& lastCP = event->referenceNode->child()->children().back(); auto& lastPoint = lastCP->children().back(); auto delta = event->screenLocation - event->previousScreenLocation; F1t velocity = sqrtf(event->avgVelocity().length()); F1t brushScale = 10.0; if (event->scale.x < 1.0) event->scale.x = 1.0; F1t targetSize = (velocity+.2) * brushScale * event->scale.x; F1t density = .6 / Platform::Screen::scale(); auto cp = Node::node(Color(0), V3(1)); cp->position.set(lastCP->position.get() + lastPoint->position.get()); event->referenceNode->child()->addChild(cp); int numSteps = (delta.length() * density) + 1; for (int i = 0; i < numSteps; i++){ F1t mu = (i+1) / (F1t)numSteps; auto point = Node::node(BLACK,V3(getTween(lastPoint->size.get().x, targetSize , mu))); cp->addChild(point); point->position.set(delta * mu); point->scale.set(1.0 - mu); // nkLog("pos: %f, %f, scale %f",point->position.get().x,point->position.get().y, 1.0 - mu); } } }
void Box::create(Vector3 origin, float length, float depth, float width) { this->center = origin; this->sizeX = length; this->sizeY = depth; this->sizeZ = width; Vector3 V0(origin.x()-(length/2), origin.y()-(depth/2), origin.z()-(width/2)); Vector3 V1(origin.x()+(length/2), origin.y()-(depth/2), origin.z()-(width/2)); Vector3 V2(origin.x()+(length/2), origin.y()+(depth/2), origin.z()-(width/2)); Vector3 V3(origin.x()-(length/2), origin.y()+(depth/2), origin.z()-(width/2)); Vector3 V4(origin.x()-(length/2), origin.y()-(depth/2), origin.z()+(width/2)); Vector3 V5(origin.x()+(length/2), origin.y()-(depth/2), origin.z()+(width/2)); Vector3 V6(origin.x()+(length/2), origin.y()+(depth/2), origin.z()+(width/2)); Vector3 V7(origin.x()-(length/2), origin.y()+(depth/2), origin.z()+(width/2)); vector<Quadrilateral> Q; Q.push_back(Quadrilateral(V0,V1,V5,V4)); Q.push_back(Quadrilateral(V2,V3,V7,V6)); Q.push_back(Quadrilateral(V0,V4,V7,V3)); Q.push_back(Quadrilateral(V5,V1,V2,V6)); Q.push_back(Quadrilateral(V1,V0,V3,V2)); Q.push_back(Quadrilateral(V4,V5,V6,V7)); setFaces(Q); calculateMinMax(); }
V3 intersectMandelbox(V3 ray, V3 start_point) { float t = 0.0; V3 curPoint; //printV3(start_point); curPoint.x = start_point.x; curPoint.y = start_point.y; curPoint.z = start_point.z; float dist = 0.0; float curDist = 0.0; for (int i = 0; i < int(ITR); i++) { dist += t; if (isInMandelbox(curPoint, &curDist)) { return curPoint; } t = max(curDist, float(EPS)); curPoint.x += float(t) * ray.x; curPoint.y += float(t) * ray.y; curPoint.z += float(t) * ray.z; } //didn't intersect, total hack return V3(-1001, -1001, -1001); }
void ImageWidget::getFrame(int z) { unsigned char *p2, *p3; // int width, height, depth; int xysize, x, y; // width = itkImage3->GetLargestPossibleRegion().GetSize()[0]; // height = itkImage3->GetLargestPossibleRegion().GetSize()[1]; // depth = itkImage3->GetLargestPossibleRegion().GetSize()[2]; xysize = imageWidth*imageHeight; printf("Image dimensions: width, height, depth: %ld %ld %ld\n",imageWidth,imageHeight,imageDepth); p3 = (unsigned char *)(itkImage3->GetBufferPointer()); // create image itkImage2 that is the selected frame of itkImage3 if (!itkImage2) itkImage2 = ImageType2::New(); ImageType2::SizeType imsize; imsize[0] = imageWidth; imsize[1] = imageHeight; ImageType2::IndexType imstart; imstart[0] = 0; imstart[1] = 0; ImageType2::RegionType imregion; imregion.SetSize(imsize); imregion.SetIndex(imstart); itkImage2->SetRegions(imregion); itkImage2->Allocate(); p2 = (unsigned char *)(itkImage2->GetBufferPointer()); for (x=0; x<imageWidth; x++) { for (y=0; y<imageHeight; y++) { V2(x,y) = V3(x,y,z); } } // imageDepth = depth; }
void SetSearchDirection(V3 direction) { searchDirection = direction; if (Equals(searchDirection, V3(0.0f))) { LogError("GJK Set searchDirection to [0, 0, 0]"); GetEngine()->isPaused = true; } }
void DebugRectangle2D::setCorners(Real left, Real top, Real right, Real bottom) { VertexDeclaration * const decl = mRenderOp.vertexData->vertexDeclaration; const VertexElement* poselem = decl->findElementBySemantic(VES_POSITION); const VertexElement* colorelem = decl->findElementBySemantic(VES_DIFFUSE); HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); const size_t vertexSize = vbuf->getVertexSize (); float *pPos; RGBA *pColor; Root * const root = Root::getSingletonPtr(); uchar* pMain = static_cast<uchar *>( vbuf->lock(HardwareBuffer::HBL_DISCARD)); // #define V3(AX, AY, AZ, ACOLOR) poselem->baseVertexPointerToElement(pMain, &pPos); \ // *pPos++ = AX; *pPos++ = AY; *pPos++ = AZ; \ // pMain += vertexSize; #define V3(A_X, A_Y, A_Z, ACOLOR) poselem->baseVertexPointerToElement(pMain, &pPos); \ *pPos++ = static_cast <float> (A_X); \ *pPos++ = static_cast <float> (A_Y); \ *pPos++ = static_cast <float> (A_Z); \ colorelem->baseVertexPointerToElement(pMain, &pColor); \ root->convertColourValue (ACOLOR, pColor); \ pMain += vertexSize; V3(left, top, -1.0f, ColourValue::White) V3(left, bottom, -1.0f, ColourValue::White) V3(right, bottom, -1.0f, ColourValue::White) V3(right, top, -1.0f, ColourValue::White) vbuf->unlock(); HardwareIndexBufferSharedPtr iBuf = mRenderOp.indexData->indexBuffer; ushort* pIdx = static_cast<ushort*>( iBuf->lock(0, iBuf->getSizeInBytes(),HardwareBuffer::HBL_DISCARD)); *pIdx++ = static_cast<ushort> (0); *pIdx++ = static_cast<ushort> (1); // line 1 *pIdx++ = static_cast<ushort> (1); *pIdx++ = static_cast<ushort> (2);// line 2 *pIdx++ = static_cast<ushort> (2); *pIdx++ = static_cast<ushort> (3);// line 3 *pIdx++ = static_cast<ushort> (3); *pIdx++ = static_cast<ushort> (0);// line 4 iBuf->unlock(); }
static void DrawBone(S32 jointIndex, Animation_Joint *jointList, M4 *globalTransforms, M4 modelMatrix) { static const V4 LINE_COLOR = COLOR_YELLOW; Animation_Joint *joint = &jointList[jointIndex]; if (joint->child_index != -1) { V4 start = globalTransforms[jointIndex] * V4(0.0f, 0.0f, 0.0f, 1.0f); V4 end = globalTransforms[joint->child_index] * V4(0.0f, 0.0f, 0.0f, 1.0f); start = modelMatrix * start; end = modelMatrix * end; draw_debug_line(V3(start), V3(end), LINE_COLOR); } else { V4 start = globalTransforms[jointIndex] * V4(0.0f, 0.0f, 0.0f, 1.0f); V4 end = globalTransforms[jointIndex] * V4(0.0f, 1.0f, 0.0f, 1.0f); start = modelMatrix * start; end = modelMatrix * end; draw_debug_line(V3(start), V3(end), LINE_COLOR); } }
std::vector<V3> computePointCloud(float step) { // std::vector<V3> points_on_sphere = getPointsOnSphere(V3(0, 0, 0), // 11, // 100, // 100); std::vector<V3> pc; // int len = points_on_sphere.size(); // printf("%d\n", len); // for (int i = 0; i < len; i++) { // //cast ray from point on sphere to origin // //printV3(points_on_sphere[i]); // V3 ray = - points_on_sphere[i]; // V3 intersection = intersectMandelbox(ray, points_on_sphere[i]); // if (intersection.x < -1000) { // continue; // } // pc.push_back(intersection); // } for (float x = -8.0; x < 8.0; x += step) { for (float y = -8.0; y < 8.0; y += step) { for (float z = -8.0; z < 8.0; z += step) { if (isInMandelbox2(V3(x, y, z))) { pc.push_back(V3(x, y, z)); } } } } // for (float x = 0; x < 8.0; x += step) { // for (float y = -8.0; y < 0; y += step) { // for (float z = 0; z < 8.0; z += step) { // if (isInMandelbox2(V3(x, y, z))) { // pc.push_back(V3(x, y, z)); // } // } // } // } return pc; }
CSoundItem::CSoundItem():SceItem() { _euler = V3(0,0,0); // spheric no spot _specAngle = 0; // no angle _volume = 100.0; _radius = 1000; // in cm _item = ITM_SNDSOURCE; strcpy(_catname , "ITM_SNDSOURCE") ; _stprintf(_name,"Sound%d",_id); }
void TMesh::ScaleToNewDiagonal(float newDiagonal) { float oldDiagonal = (aabb->corners[1] - aabb->corners[0]).length(); float sf = newDiagonal / oldDiagonal; V3 oldCenter = GetCenter(); Position(V3(0.0f, 0.0f, 0.0f)); Scale(sf); Position(oldCenter); SetAABB(); }
/** * Rotate this vector about the specified direction by the specified angle. * * @param axis the specified direction * @param angle the specified angle * @return the rotated point */ V3 V3::RotateAbout(const V3& dir, float angle) { return RotateAbout(dir, angle, V3(0, 0, 0)); /* M33 m = M33::generateAxes(dir); V3 pt2 = m * (*this); V3 pt3 = M33::createRotationMatrixAboutX(angle) * pt2; return m.Inverted() * pt3; */ }
void CatmullRomCurveEvaluator::convertPoints(std::vector<Point>& pts, Point P0, Point P1, Point P2, Point P3) const { Point V0(P1); Point V1(Point(P1.x + cat / 3 * (P2.x - P0.x), P1.y + cat / 3 * (P2.y - P0.y))); Point V2(Point(P2.x - cat / 3 * (P3.x - P1.x), P2.y - cat / 3 * (P3.y - P1.y))); Point V3(P2); pts.push_back(V0); pts.push_back(V1); pts.push_back(V2); pts.push_back(V3); }
std::vector<V3> getPointsOnSphere(V3 center, double radius, int n_sides, int n_vertical_divisions) { V3 top = V3(center.x, center.y + radius, center.z); V3 bottom = V3(center.x, center.y - radius, center.z); printV3(top); printV3(bottom); std::vector<V3> points; points.push_back(top); points.push_back(bottom); std::vector<double> radii; std::vector<V3> heights; double theta = PI / n_vertical_divisions; for (int i = 1; i < n_vertical_divisions; i++) { radii.push_back(sin(theta*i)*radius); heights.push_back(V3(center.x, center.y + cos(theta*i)*radius, center.z)); //same radius but negative height radii.push_back(sin(theta*i)*radius); heights.push_back(V3(center.x, center.y - cos(theta*i)*radius, center.z)); } int len = heights.size(); for (int i = 1; i < len; i++) { //printV3(heights[i]); //printf("%.3f\n", radii[i]); std::vector<V3> points_around = getPointsOnCircle(heights[i], radii[i], n_sides); int size = points_around.size(); for (int i = 0; i < size; i++) { //printV3(points_around[i]); points.push_back(points_around[i]); } } return points; }
//given a center, a radius, and a number n, return n evenly spaced points //in the X-Z plane at height Y. std::vector<V3> getPointsOnCircle(V3 center, double radius, int n) { std::vector<V3> points; for (int i = 0; i < n; i++) { double theta = 2 * i * PI / n; //printf("theta = %.2f\n", theta); points.push_back(V3(center.x + radius * cos(theta), center.y, center.z + radius * sin(theta))); } return points; }
/*-------------------------------------------------------------------------* * New_Alpha * * * * Returns a new spherical triangle derived from the original one by * * moving the "C" vertex along the edge "BC" until the new "alpha" angle * * equals the given argument. * * * *-------------------------------------------------------------------------*/ SphericalTriangle SphericalTriangle::New_Alpha( float alpha ) const { Vec3 V1( A() ), V2( B() ), V3( C() ); Vec3 E1 = Unit( V2 ^ V1 ); Vec3 E2 = E1 ^ V1; Vec3 G = ( cos(alpha) * E1 ) + ( sin(alpha) * E2 ); Vec3 D = Unit( V3 / V2 ); Vec3 C2 = ((G * D) * V2) - ((G * V2) * D); if( Triple( V1, V2, C2 ) > 0.0 ) C2 *= -1.0; return SphericalTriangle( V1, V2, C2 ); }
/*-------------------------------------------------------------------------* * New_Alpha * * * * Returns a new spherical triangle derived from the original one by * * moving the "C" vertex along the edge "BC" until the new "alpha" angle * * equals the given argument. * * * *-------------------------------------------------------------------------*/ SphericalTriangle SphericalTriangle::New_Alpha( double alpha ) const { Vector3d V1( A() ), V2( B() ), V3( C() ); Vector3d E1 = Unit( V2 ^ V1 ); Vector3d E2 = E1 ^ V1; Vector3d G = ( cos(alpha) * E1 ) + ( sin(alpha) * E2 ); Vector3d D = Unit( V3 / V2 ); Vector3d C2 = ((G * D) * V2) - ((G * V2) * D); if( Triple( V1, V2, C2 ) > 0.0 ) C2 = -1.0 * C2 ; return SphericalTriangle( V1, V2, C2 ); }
/*! Build a vpMbtDistanceLine thanks to two points corresponding to the extremities. \param _p1 : The first extremity. \param _p2 : The second extremity. */ void vpMbtDistanceLine::buildFrom(vpPoint &_p1, vpPoint &_p2) { line = new vpLine ; poly.setNbPoint(2); poly.addPoint(0, _p1); poly.addPoint(1, _p2); p1 = &poly.p[0]; p2 = &poly.p[1]; vpColVector V1(3); vpColVector V2(3); vpColVector V3(3); vpColVector V4(3); V1[0] = p1->get_oX(); V1[1] = p1->get_oY(); V1[2] = p1->get_oZ(); V2[0] = p2->get_oX(); V2[1] = p2->get_oY(); V2[2] = p2->get_oZ(); //if((V1-V2).sumSquare()!=0) if(std::fabs((V1-V2).sumSquare()) > std::numeric_limits<double>::epsilon()) { { V3[0]=double(rand()%1000)/100; V3[1]=double(rand()%1000)/100; V3[2]=double(rand()%1000)/100; vpColVector v_tmp1,v_tmp2; v_tmp1 = V2-V1; v_tmp2 = V3-V1; V4=vpColVector::cross(v_tmp1,v_tmp2); } vpPoint P3; P3.setWorldCoordinates(V3[0],V3[1],V3[2]); vpPoint P4; P4.setWorldCoordinates(V4[0],V4[1],V4[2]); buildLine(*p1,*p2, P3,P4, *line) ; } else { vpPoint P3; P3.setWorldCoordinates(V1[0],V1[1],V1[2]); vpPoint P4; P4.setWorldCoordinates(V2[0],V2[1],V2[2]); buildLine(*p1,*p2,P3,P4,*line) ; } }
void TMesh::SetRectangle(V3 center, float a, float b) { vertsN = 4; verts = new V3[vertsN]; cols = new V3[vertsN]; normals = new V3[vertsN]; int i = 0; verts[i++] = center + V3(-a/2.0f, +b/2.0f, 0.0f); verts[i++] = center + V3(-a/2.0f, -b/2.0f, 0.0f); verts[i++] = center + V3(+a/2.0f, -b/2.0f, 0.0f); verts[i++] = center + V3(+a/2.0f, +b/2.0f, 0.0f); for (int i = 0; i < 4; i++) { cols[i] = V3(0, 1, 0); normals[i] = V3(0, 0, 1); } trisN = 2; tris = new unsigned int[3*trisN]; i = 0; tris[i++] = 0; tris[i++] = 1; tris[i++] = 2; tris[i++] = 0; tris[i++] = 2; tris[i++] = 3; }
void Sub(int *u, int m) { int temp1 = V1(u[0],u[1],u[2],u[3], m); int temp2 = V2(u[0],u[1],u[2],u[3], m); int temp3 = V3(u[0],u[1],u[2],u[3], m); int temp4 = V4(u[0],u[1],u[2],u[3], m); u[0] = temp1; u[1] = temp2; u[2] = temp3; u[3] = temp4; }
void Sub(double *u) { double temp1 = V1(u[0],u[1],u[2],u[3]); double temp2 = V2(u[0],u[1],u[2],u[3]); double temp3 = V3(u[0],u[1],u[2],u[3]); double temp4 = V4(u[0],u[1],u[2],u[3]); u[0] = temp1; u[1] = temp2; u[2] = temp3; u[3] = temp4; }
int get_block_size() { char buf[255]; int len,lba=0,bsize=0; read_capacity(&lba,&bsize); len=255; if (mode_sense(buf,&len)==0 && buf[3]>=8) { return V3(&buf[4+5]); } if (mode_sense10(buf,&len)==0 && V2(&buf[6])>=8) { return V3(&buf[8+5]); } if (read_capacity(&lba,&bsize)==0) { return bsize; } return -1; }
rgba InfiniteAreaLight::eval(Point const& p) const { auto q = normalize(V3(p)); auto phi = std::atan2(q.x, q.y); if (phi < 0) phi = phi + 2 * M_PI; auto theta = std::acos(std::max(std::min(q.z, 1.0f), -1.0f)); int u = (phi / (2 * M_PI)) * width; int v = (theta / M_PI) * height; int index = (v * width + u) * 4; return rgba(data[index + 0], data[index + 1], data[index + 2], 1); }
internal rectangle2 DEBUGTextOp(debug_state *DebugState, debug_text_op Op, v2 P, char *String, v4 Color = V4(1, 1, 1, 1)) { rectangle2 Result = InvertedInfinityRectangle2(); if (DebugState && DebugState->DebugFont) { render_group *RenderGroup = DebugState->RenderGroup; loaded_font *Font = DebugState->DebugFont; hha_font *Info = DebugState->DebugFontInfo; u32 PrevCodePoint = 0; for (char *At = String; *At; ++At) { u32 CodePoint = *At; if (At[0] == '\\' && IsHex(At[1]) && IsHex(At[2]) && IsHex(At[3]) && IsHex(At[4])) { CodePoint = (GetHex(At[1]) << 12 | GetHex(At[2]) << 8 | GetHex(At[3]) << 4 | GetHex(At[4]) << 0); At += 4; } r32 AdvanceX = DebugState->FontScale * GetHorizontalAdvanceForPair(Info, Font, PrevCodePoint, CodePoint); P.x += AdvanceX; if (CodePoint != ' ') { bitmap_id BitmapID = GetBitmapForGlyph(RenderGroup->Assets, Info, Font, CodePoint); hha_bitmap *BitmapInfo = GetBitmapInfo(RenderGroup->Assets, BitmapID); r32 BitmapScale = DebugState->FontScale * (r32)BitmapInfo->Dim[1]; v3 BitmapOffset = V3(P.x, P.y, 0); if (Op == DEBUGTextOp_DrawText) { PushBitmap(RenderGroup, BitmapID, BitmapScale, BitmapOffset, Color); } else { Assert(Op == DEBUGTextOp_SizeText); loaded_bitmap *Bitmap = GetBitmap(RenderGroup->Assets, BitmapID, RenderGroup->GenerationID); if (Bitmap) { used_bitmap_dim Dim = GetBitmapDim(RenderGroup, Bitmap, BitmapScale, BitmapOffset, 1.0f); rectangle2 GlyphDim = RectMinDim(Dim.P.xy, Dim.Size); Result = Union(Result, GlyphDim); } } } PrevCodePoint = CodePoint; } } return Result; }
V3 CubeMap::getColor(const V3 & direction) { // use direction to create a 3D point at the focal plane. V3 lookAt3DPoint = cubeMapCenter + (direction * cubeMapFocalLength); V3 projectedPoint; unsigned int returnColor; bool isProjValid = false; int timesTried = 0; // find the face that sees this point but start by the one used last time // to leverage locality principle. while(timesTried < 6) { isProjValid = cubeMapFacesCams[currentLookAtFace % 6]->project(lookAt3DPoint, projectedPoint); // be very strict with the projection: no projection if: // - point is left of view frustrum or is right of view frustrum // - or is above view frustrum or is below of view frustrum if (isProjValid && (projectedPoint[0] > 0.0f) && (projectedPoint[0] < envMapResWidth) && (projectedPoint[1] > 0.0f) && (projectedPoint[1] < envMapResHeight)) { // go from x,y to s,t which ranges from [0,1] float s = projectedPoint[0] / (envMapResWidth - 1.0f); float t = projectedPoint[1] / (envMapResHeight - 1.0f); // bilinear interpolation assumes t ranges [0,1] starting from the bottom of texture // and since y screen goes from top to bottom we need to flip t here as well t = (envMapResHeight - 1.0f) - t; returnColor = cubeMapFaces[currentLookAtFace % 6]->sampleTexBilinearTile(s, t); return V3(returnColor); } else { currentLookAtFace++; // try with a different face of the cube timesTried++; } } // This should not ever happen. Any ray direction should be contained by a cubemap return V3(255.0f/255.0f, 0.0f/255.0f, 128.0f/255.0f); // bright pink so its easy to spot if it ever happens (debug) }