www.pudn.com > raytracer3.zip > scene.cpp
// -----------------------------------------------------------
// scene.cpp
// 2004 - Jacco Bikker - jacco@bik5.com - www.bik5.com - <><
// -----------------------------------------------------------
#include "common.h"
#include "string.h"
#include "scene.h"
#include "raytracer.h"
namespace Raytracer {
// -----------------------------------------------------------
// Primitive class implementation
// -----------------------------------------------------------
void Primitive::SetName( char* a_Name )
{
delete m_Name;
m_Name = new char[strlen( a_Name ) + 1];
strcpy( m_Name, a_Name );
}
// -----------------------------------------------------------
// Material class implementation
// -----------------------------------------------------------
Material::Material() :
m_Color( Color( 0.2f, 0.2f, 0.2f ) ),
m_Refl( 0 ), m_Diff( 0.2f ), m_Spec( 0.8f ), m_RIndex( 1.5f )
{
}
// -----------------------------------------------------------
// Sphere primitive methods
// -----------------------------------------------------------
int Sphere::Intersect( Ray& a_Ray, float& a_Dist )
{
vector3 v = a_Ray.GetOrigin() - m_Centre;
float b = -DOT( v, a_Ray.GetDirection() );
float det = (b * b) - DOT( v, v ) + m_SqRadius;
int retval = MISS;
if (det > 0)
{
det = sqrtf( det );
float i1 = b - det;
float i2 = b + det;
if (i2 > 0)
{
if (i1 < 0)
{
if (i2 < a_Dist)
{
a_Dist = i2;
retval = INPRIM;
}
}
else
{
if (i1 < a_Dist)
{
a_Dist = i1;
retval = HIT;
}
}
}
}
return retval;
}
// -----------------------------------------------------------
// Plane primitive class implementation
// -----------------------------------------------------------
int PlanePrim::Intersect( Ray& a_Ray, float& a_Dist )
{
float d = DOT( m_Plane.N, a_Ray.GetDirection() );
if (d != 0)
{
float dist = -(DOT( m_Plane.N, a_Ray.GetOrigin() ) + m_Plane.D) / d;
if (dist > 0)
{
if (dist < a_Dist)
{
a_Dist = dist;
return HIT;
}
}
}
return MISS;
}
vector3 PlanePrim::GetNormal( vector3& a_Pos )
{
return m_Plane.N;
}
// -----------------------------------------------------------
// Scene class implementation
// -----------------------------------------------------------
Scene::~Scene()
{
delete m_Primitive;
}
void Scene::InitScene()
{
m_Primitive = new Primitive*[500];
// ground plane
m_Primitive[0] = new PlanePrim( vector3( 0, 1, 0 ), 4.4f );
m_Primitive[0]->SetName( "plane" );
m_Primitive[0]->GetMaterial()->SetReflection( 0.0f );
m_Primitive[0]->GetMaterial()->SetRefraction( 0.0f );
m_Primitive[0]->GetMaterial()->SetDiffuse( 1.0f );
m_Primitive[0]->GetMaterial()->SetColor( Color( 0.4f, 0.3f, 0.3f ) );
// big sphere
m_Primitive[1] = new Sphere( vector3( 2, 0.8f, 3 ), 2.5f );
m_Primitive[1]->SetName( "big sphere" );
m_Primitive[1]->GetMaterial()->SetReflection( 0.2f );
m_Primitive[1]->GetMaterial()->SetRefraction( 0.8f );
m_Primitive[1]->GetMaterial()->SetRefrIndex( 1.3f );
m_Primitive[1]->GetMaterial()->SetColor( Color( 0.7f, 0.7f, 1.0f ) );
// small sphere
m_Primitive[2] = new Sphere( vector3( -5.5f, -0.5, 7 ), 2 );
m_Primitive[2]->SetName( "small sphere" );
m_Primitive[2]->GetMaterial()->SetReflection( 0.5f );
m_Primitive[2]->GetMaterial()->SetRefraction( 0.0f );
m_Primitive[2]->GetMaterial()->SetRefrIndex( 1.3f );
m_Primitive[2]->GetMaterial()->SetDiffuse( 0.1f );
m_Primitive[2]->GetMaterial()->SetColor( Color( 0.7f, 0.7f, 1.0f ) );
// light source 1
m_Primitive[3] = new Sphere( vector3( 0, 5, 5 ), 0.1f );
m_Primitive[3]->Light( true );
m_Primitive[3]->GetMaterial()->SetColor( Color( 0.4f, 0.4f, 0.4f ) );
// light source 2
m_Primitive[4] = new Sphere( vector3( -3, 5, 1 ), 0.1f );
m_Primitive[4]->Light( true );
m_Primitive[4]->GetMaterial()->SetColor( Color( 0.6f, 0.6f, 0.8f ) );
// extra sphere
m_Primitive[5] = new Sphere( vector3( -1.5f, -3.8f, 1 ), 1.5f );
m_Primitive[5]->SetName( "extra sphere" );
m_Primitive[5]->GetMaterial()->SetReflection( 0.0f );
m_Primitive[5]->GetMaterial()->SetRefraction( 0.8f );
m_Primitive[5]->GetMaterial()->SetColor( Color( 1.0f, 0.4f, 0.4f ) );
// back plane
m_Primitive[6] = new PlanePrim( vector3( 0.4f, 0, -1 ), 12 );
m_Primitive[6]->SetName( "back plane" );
m_Primitive[6]->GetMaterial()->SetReflection( 0.0f );
m_Primitive[6]->GetMaterial()->SetRefraction( 0.0f );
m_Primitive[6]->GetMaterial()->SetSpecular( 0 );
m_Primitive[6]->GetMaterial()->SetDiffuse( 0.6f );
m_Primitive[6]->GetMaterial()->SetColor( Color( 0.5f, 0.3f, 0.5f ) );
// ceiling plane
m_Primitive[7] = new PlanePrim( vector3( 0, -1, 0 ), 7.4f );
m_Primitive[7]->SetName( "back plane" );
m_Primitive[7]->GetMaterial()->SetReflection( 0.0f );
m_Primitive[7]->GetMaterial()->SetRefraction( 0.0f );
m_Primitive[7]->GetMaterial()->SetSpecular( 0 );
m_Primitive[7]->GetMaterial()->SetDiffuse( 0.5f );
m_Primitive[7]->GetMaterial()->SetColor( Color( 0.4f, 0.7f, 0.7f ) );
// grid
int prim = 8;
for ( int x = 0; x < 8; x++ ) for ( int y = 0; y < 7; y++ )
{
m_Primitive[prim] = new Sphere( vector3( -4.5f + x * 1.5f, -4.3f + y * 1.5f, 10 ), 0.3f );
m_Primitive[prim]->SetName( "grid sphere" );
m_Primitive[prim]->GetMaterial()->SetReflection( 0 );
m_Primitive[prim]->GetMaterial()->SetRefraction( 0 );
m_Primitive[prim]->GetMaterial()->SetSpecular( 0.6f );
m_Primitive[prim]->GetMaterial()->SetDiffuse( 0.6f );
m_Primitive[prim]->GetMaterial()->SetColor( Color( 0.3f, 1.0f, 0.4f ) );
prim++;
}
// set number of primitives
m_Primitives = prim;
}
}; // namespace Raytracer