I want you to implement the code for the class 'SimpleRayTracer' while making use of the 'Vector', 'Camera', 'Material', 'Triangle', 'PointLight', 'Scene', 'Color', and 'RGBImage' classes.


class SimpleRayTracer
{
public:
    SimpleRayTracer(unsigned int MaxDepth);
    void traceScene( const Scene& SceneModel, RGBImage& Image);
protected:
    Color trace( const Scene& SceneModel, const Vector& o, const Vector& d, int depth);
    Color localIllumination( const Vector& SurfacePoint, const Vector& Eye, const Vector& Normal, const PointLight& Light, const Material& Material );    
};


Remarks:

- To simplify the task a bit, you don't need to consider transmissions for ray tracing.

- The traceScene method is called from outside the class as follows:

int main(int argc, const char * argv[]) {
    Scene scene(0);
    RGBImage image(640,480);
    SimpleRayTracer tracer(2);
    tracer.traceScene(scene, image);
    image.saveToDisk("C:\\Users\\moazh\\Desktop\\test\\raytracing_image.bmp");
    return 0;
}

- In this task, it is not yet necessary to correctly implement the localIllumination(..) method. Instead, you can simply return the diffuse component of the material in this method.

- When constructing the class, a maximum recursion depth MaxDepth should be passed.

- The initial camera rays are generated in the traceScene method and traced by recursively calling trace(..).

- Initialize the camera with the following values:

zvalue=-8, planedist=1, width=1, height=0.75, widthInPixel=640, heightInPixel=480.

- You can determine the internal structure of the class yourself, so add additional helper methods etc. if necessary.

- Make sure that the collision test only ever finds the closest triangle.

- Make sure the collision test excludes the origin triangle (origin of the ray). Otherwise, the triangle will find a collision with itself since it is the closest.



class RGBImage;

class Camera
{
public:
    Camera(float zvalue, float planedist, float width, float height, unsigned int widthInPixel, unsigned int heightInPixel);
    Vector generateRay(unsigned int x, unsigned int y) const;
    Vector Position() const;
private:
    float m_zvalue;
    float m_planedist;
    float m_width;
    float m_height;
    unsigned int m_widthInPixel;
    unsigned int m_heightInPixel;
    Vector m_position;
};


class Material
{
public:
    Material();
    Material( const Color& Diffuse, const Color& Specular, const Color& Ambient, float SpecularExp,  float Reflectivity);
    virtual Color getDiffuseCoeff(const Vector& Pos) const;
    virtual Color getSpecularCoeff(const Vector& Pos) const;
    virtual Color getAmbientCoeff(const Vector& Pos) const;
    virtual float getSpecularExp(const Vector& Pos) const;
    virtual float getReflectivity(const Vector& Pos) const;
    

    static Material DefaultMaterial;
    static Material RedMtrl;
    static Material GreenMtrl;
    static Material BlueMtrl;
    static Material YellowMtrl;
    static Material CyanMtrl;
protected:
    Color m_DiffuseCoeff;
    Color m_SpecularCoeff;
    Color m_AmbientCoeff;
    float m_SpecularExp;

    float m_Reflectivity;
};


class Triangle
{
public:
    Triangle();
    Triangle(const Vector& a, const Vector& b, const Vector& c, const Material* mtrl);
    Vector A,B,C; // vertex-positions
    const Material* pMtrl; // pointer to triangle material
    Vector calcNormal( const Vector& PointOnTriangle) const;

    Material getMaterial() const;

protected:
    friend class Scene;
    Vector NA, NB, NC; // vertex-normals

};

class PointLight
{
public:
    PointLight();
    PointLight( const Vector& pos, const Color& intensity);
    Vector Position;
    Color Intensity;
};

class Scene
{
public:
    Scene( unsigned int SceneComplexity ); // Set SceneComplexity to zero for a scene with only 10 triangles, for a more complex scene set Scenecompleyity to 20.
    virtual ~Scene();
    const Triangle& getTriangle(unsigned int Index) const;
    unsigned int getTriangleCount() const;
    const PointLight& getLight(unsigned int Index) const;
    unsigned int getLightCount() const;
    
protected:
    Triangle* m_Triangles;
    unsigned int m_TriangleCount;
    PointLight* m_Lights;
    unsigned int m_LightCount;
    void createInnerModel( std::vector<Triangle>& Triangles, float Radius, int Slices, int Stacks) const;

};



class Vector
{
public:
    float X;
    float Y;
    float Z;
    
    Vector( float x, float y, float z);
    Vector();
    
    float dot(const Vector& v) const;
    Vector cross(const Vector& v) const;
    Vector operator+(const Vector& v) const;
    Vector operator-(const Vector& v) const;
    Vector& operator+=(const Vector& v);
    Vector operator*(float c) const;
    Vector operator-() const;
    bool operator==(const Vector& v) const;
    Vector& normalize();
    float length() const;
    float lengthSquared() const;
    Vector reflection( const Vector& normal) const;
    bool triangleIntersection( const Vector& d, const Vector& a, const Vector& b,
                              const Vector& c, float& s) const;
 };



class Color
{
public:
    float R;
    float G;
    float B;
    
    Color();
    Color( float r, float g, float b);
    Color operator*(const Color& c) const;
    Color operator*(const float Factor) const;
    Color operator+(const Color& c) const;
    Color& operator+=(const Color& c);
    
};



class Color;

class RGBImage
{
public:
    RGBImage( unsigned int Width, unsigned Height);
    ~RGBImage();
    void setPixelColor( unsigned int x, unsigned int y, const Color& c);
    const Color& getPixelColor( unsigned int x, unsigned int y) const;
    bool saveToDisk( const char* Filename);
    unsigned int width() const;
    unsigned int height() const;
    
    static unsigned char convertColorChannel( float f);
protected:
    Color* m_Image;
    unsigned int m_Height;
    unsigned int m_Width;
};