//---------------------------------------------------------------------------- // William Baxter III's Ray Tracer // // Project for Comp 238, Raster Graphics // University of North Carolina at Chapel Hill // // $Id:$ //---------------------------------------------------------------------------- #ifndef WB3ARTIFACT_H #define WB3ARTIFACT_H #include "ray3f.hpp" #include "wb3Shader.hpp" #include "wb3Material.hpp" #include "wb3TextureSet.hpp" class wb3Artifact { public: wb3Artifact(); ~wb3Artifact(); virtual const wb3Artifact* Intersect(const Ray3f& r, float *idist, const wb3Artifact* ignore =0) const = 0; virtual void GetNormal(const Ray3f& r, const Vec3f &isect, Vec3f& normal) const = 0; virtual void Shade(const wb3Scene* scene, const wb3Artifact* from, const wb3Artifact* hit, const Ray3f& r, const Vec3f &isect, Vec3f& color, Vec3f& attenuation, int hits) const; wb3Shader* GetShader() const; void SetShader(wb3Shader *pShader); wb3Material* GetMaterial() const; void SetMaterial(wb3Material *pMaterial); void AddTexture(wb3Texture *tex, wb3Component::ComponentType typ); const wb3TextureList* GetTextureList(wb3Component::ComponentType typ) const; Vec3f& GetAmbient(Vec3f& color, const Vec3f& worldCoords) const; Vec3f& GetDiffuse(Vec3f& color, const Vec3f& worldCoords) const; Vec3f& GetSpecular(Vec3f& color, const Vec3f& worldCoords) const; Vec3f& GetReflect(Vec3f& color, const Vec3f& worldCoords) const; Vec3f& GetRefract(Vec3f& color, const Vec3f& worldCoords) const; float GetSpecularity(const Vec3f& worldCoords) const; float GetBump(const Vec3f& worldCoords) const; // Gloss is an oddball because that's the way rayshade has it // It would make sense for it to be part of a surface material. But no. // It would make sense for it to be a standard image modulated // surface property. But no. // They have it as a built-in texture class that operates per object. // Odd. void SetGloss(float gloss); float GetGloss() const; protected: virtual Vec3f& GetColorComponent( Vec3f& color, wb3Component::ComponentType type, const Vec3f& worldCoords) const; virtual float GetScalarComponent( wb3Component::ComponentType type, const Vec3f& worldCoords) const; wb3Shader *m_pShader; wb3Material *m_pMaterial; wb3TextureSet *m_pTexset; float m_fGloss; static const float ms_fEps; }; //---------------------------------------------------------------------------- inline void wb3Artifact::Shade( const wb3Scene *scene, const wb3Artifact *from, const wb3Artifact *hit, const Ray3f& r, const Vec3f &isect, Vec3f& color, Vec3f& attenuation, int hits) const { if (m_pShader) m_pShader->Shade(scene, from, hit, r, isect, color, attenuation, hits); } //---------------------------------------------------------------------------- inline wb3Shader* wb3Artifact::GetShader() const { return m_pShader; } //---------------------------------------------------------------------------- inline void wb3Artifact::SetShader(wb3Shader *pShader) { m_pShader = pShader; } //---------------------------------------------------------------------------- inline wb3Material* wb3Artifact::GetMaterial() const { return m_pMaterial; } //---------------------------------------------------------------------------- inline void wb3Artifact::SetMaterial(wb3Material *pMaterial) { m_pMaterial = pMaterial; } //---------------------------------------------------------------------------- inline void wb3Artifact::AddTexture( wb3Texture *tex, wb3Component::ComponentType type) { if (!m_pTexset) m_pTexset = new wb3TextureSet(); m_pTexset->AddTexture(tex, type); } //---------------------------------------------------------------------------- inline const wb3TextureList* wb3Artifact::GetTextureList( wb3Component::ComponentType type) const { if (!m_pTexset) return 0; else return m_pTexset->GetTextureList(type); } //---------------------------------------------------------------------------- inline Vec3f& wb3Artifact::GetAmbient( Vec3f& color, const Vec3f& worldCoords) const { return GetColorComponent(color, wb3Component::AMBIENT, worldCoords); } //---------------------------------------------------------------------------- inline Vec3f& wb3Artifact::GetDiffuse( Vec3f& color, const Vec3f& worldCoords) const { return GetColorComponent(color, wb3Component::DIFFUSE, worldCoords); } //---------------------------------------------------------------------------- inline Vec3f& wb3Artifact::GetSpecular( Vec3f& color, const Vec3f& worldCoords) const { return GetColorComponent(color, wb3Component::SPECULAR, worldCoords); } //---------------------------------------------------------------------------- inline Vec3f& wb3Artifact::GetReflect( Vec3f& color, const Vec3f& worldCoords) const { return GetColorComponent(color, wb3Component::REFLECT, worldCoords); } //---------------------------------------------------------------------------- inline Vec3f& wb3Artifact::GetRefract( Vec3f& color, const Vec3f& worldCoords) const { return GetColorComponent(color, wb3Component::REFRACT, worldCoords); } //---------------------------------------------------------------------------- inline float wb3Artifact::GetSpecularity(const Vec3f& worldCoords) const { return GetScalarComponent(wb3Component::SPECPOW, worldCoords); } //---------------------------------------------------------------------------- inline float wb3Artifact::GetBump(const Vec3f& worldCoords) const { return GetScalarComponent(wb3Component::BUMP, worldCoords); } //---------------------------------------------------------------------------- inline void wb3Artifact::SetGloss(float gloss) { // Should be no bigger than 1.0 // 1.0 == perfect mirror, 0.0 = lotsa blur. m_fGloss = gloss; } //---------------------------------------------------------------------------- inline float wb3Artifact::GetGloss() const { return m_fGloss; } //---------------------------------------------------------------------------- #endif