diff options
Diffstat (limited to 'libdimensionxx')
-rw-r--r-- | libdimensionxx/Makefile.am | 6 | ||||
-rw-r--r-- | libdimensionxx/dimensionxx.hpp | 1 | ||||
-rw-r--r-- | libdimensionxx/dimensionxx/object.hpp | 43 | ||||
-rw-r--r-- | libdimensionxx/dimensionxx/texture.hpp | 115 | ||||
-rw-r--r-- | libdimensionxx/object.cpp | 94 | ||||
-rw-r--r-- | libdimensionxx/texture.cpp | 106 |
6 files changed, 342 insertions, 23 deletions
diff --git a/libdimensionxx/Makefile.am b/libdimensionxx/Makefile.am index c31a643..0f8d3a4 100644 --- a/libdimensionxx/Makefile.am +++ b/libdimensionxx/Makefile.am @@ -31,7 +31,8 @@ nobase_include_HEADERS = dimensionxx.hpp \ dimensionxx/png.hpp \ dimensionxx/progress.hpp \ dimensionxx/raytrace.hpp \ - dimensionxx/scene.hpp + dimensionxx/scene.hpp \ + dimensionxx/texture.hpp INCLUDES = -I../libdimension @@ -49,7 +50,8 @@ libdimensionxx_la_SOURCES = $(nobase_include_HEADERS) \ png.cpp \ progress.cpp \ raytrace.cpp \ - scene.cpp + scene.cpp \ + texture.cpp if FOPENCOOKIE libdimensionxx_la_SOURCES += cookie-fopencookie.cpp diff --git a/libdimensionxx/dimensionxx.hpp b/libdimensionxx/dimensionxx.hpp index f063760..99b9a97 100644 --- a/libdimensionxx/dimensionxx.hpp +++ b/libdimensionxx/dimensionxx.hpp @@ -33,6 +33,7 @@ #include <dimensionxx/canvas.hpp> #include <dimensionxx/gl.hpp> #include <dimensionxx/png.hpp> +#include <dimensionxx/texture.hpp> #include <dimensionxx/object.hpp> #include <dimensionxx/objects.hpp> #include <dimensionxx/camera.hpp> diff --git a/libdimensionxx/dimensionxx/object.hpp b/libdimensionxx/dimensionxx/object.hpp index c661fa8..4c9dbff 100644 --- a/libdimensionxx/dimensionxx/object.hpp +++ b/libdimensionxx/dimensionxx/object.hpp @@ -25,10 +25,43 @@ namespace Dimension { - // Abstract base object class. Wraps a dmnsn_object*. + // Type to represent a ray-object intersection + class Intersection + { + public: + Intersection(const Line& ray, double t, const Texture& texture); + explicit Intersection(dmnsn_intersection *intersection); + // Intersection(const Intersection& intersection); + ~Intersection(); + + Line& ray() { return m_ray; } + const Line& ray() const { return m_ray; } + + double t() const { return dmnsn()->t; } + void t(double t) { dmnsn()->t = t; } + + const Texture& texture() const { return m_texture; } + + dmnsn_intersection* dmnsn(); + const dmnsn_intersection* dmnsn() const; + + dmnsn_intersection* release(); + + private: + // Copy-assignment prohibited + Intersection& operator=(const Intersection& intersection); + + std::tr1::shared_ptr<dmnsn_intersection*> m_intersection; + Line m_ray; + const Texture m_texture; + }; + + // Base object class. Wraps a dmnsn_object*. class Object { public: + // Wrap an existing object. + explicit Object(dmnsn_object* object); // Delete the object virtual ~Object(); @@ -37,11 +70,11 @@ namespace Dimension void trans(const Matrix& trans); // Object callbacks - virtual Array<double> intersections(const Line& l); + virtual Intersection intersection(const Line& l); virtual bool inside(const Vector& point); // Shallow-copy a derived object - virtual Object* copy() const = 0; + virtual Object* copy() const; // Access the wrapped C object dmnsn_object* dmnsn(); @@ -52,8 +85,6 @@ namespace Dimension Object(); // Shallow copy Object(const Object& object); - // Wrap an existing object. - explicit Object(dmnsn_object* object); // Is m_object unique? bool unique() const; @@ -75,7 +106,7 @@ namespace Dimension Custom_Object(); virtual ~Custom_Object(); - virtual Array<double> intersections(const Line& l) = 0; + virtual Intersection intersection(const Line& l) = 0; virtual bool inside(const Vector& point) = 0; }; diff --git a/libdimensionxx/dimensionxx/texture.hpp b/libdimensionxx/dimensionxx/texture.hpp new file mode 100644 index 0000000..7f42206 --- /dev/null +++ b/libdimensionxx/dimensionxx/texture.hpp @@ -0,0 +1,115 @@ +/************************************************************************* + * Copyright (C) 2009 Tavian Barnes <tavianator@gmail.com> * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * <http://www.gnu.org/licenses/>. * + *************************************************************************/ + +// dmnsn_texture* wrapper. + +#ifndef DIMENSIONXX_TEXTURE_HPP +#define DIMENSIONXX_TEXTURE_HPP + +namespace Dimension +{ + // Pigment base class. Wraps a dmnsn_pigment*. + class Pigment + { + public: + explicit Pigment(dmnsn_pigment* pigment); + ~Pigment(); + + Pigment* copy() const; + + dmnsn_pigment* dmnsn(); + const dmnsn_pigment* dmnsn() const; + + protected: + // No-op + Pigment(); + // Shallow copy + Pigment(const Pigment& pigment); + + // Is m_pigment unique? + bool unique() const; + + private: + // Copy-assignment prohibited + Pigment& operator=(const Pigment&); + + std::tr1::shared_ptr<dmnsn_pigment*> m_pigment; + }; + + // Texture class. Wraps a dmnsn_texture*. + class Texture + { + public: + Texture(const Pigment& pigment); + explicit Texture(dmnsn_texture* texture); + // Texture(const Texture& texture); + ~Texture(); + + dmnsn_texture* dmnsn(); + const dmnsn_texture* dmnsn() const; + + private: + // Copy-assignment prohibited + Texture& operator=(const Texture&); + + std::tr1::shared_ptr<dmnsn_texture*> m_texture; + std::tr1::shared_ptr<Pigment> m_pigment; + }; + + // Array_Element specializations + + template <> + class Array_Element<Pigment> + : public Polymorphic_Array_Element<Pigment, dmnsn_pigment*> + { + public: + typedef dmnsn_pigment* C_Type; + + Array_Element() { } + Array_Element(Pigment& pigment) + : Polymorphic_Array_Element<Pigment, dmnsn_pigment*>(pigment) { } + Array_Element(C_Type c) + : Polymorphic_Array_Element<Pigment, dmnsn_pigment*>(c) { } + // Array_Element(const Array_Element& ae); + // ~Array_Element(); + + // Array_Element& operator=(const Array_Element& ae); + }; + + template <> + class Array_Element<Texture> + : public DMNSN_Array_Element<Texture, dmnsn_texture*> + { + public: + typedef dmnsn_texture* C_Type; + + Array_Element() { } + Array_Element(Texture& texture) + : DMNSN_Array_Element<Texture, dmnsn_texture*>(texture) { } + Array_Element(C_Type c) + : DMNSN_Array_Element<Texture, dmnsn_texture*>(c) { } + // Array_Element(const Array_Element& ae); + // ~Array_Element(); + + // Array_Element& operator=(const Array_Element& ae); + }; +} + +#endif /* DIMENSIONXX_TEXTURE_HPP */ diff --git a/libdimensionxx/object.cpp b/libdimensionxx/object.cpp index 407935a..c36a37f 100644 --- a/libdimensionxx/object.cpp +++ b/libdimensionxx/object.cpp @@ -22,7 +22,69 @@ namespace Dimension { - // Virtual destructor + // Construct an intersection object + Intersection::Intersection(const Line& ray, double t, const Texture& texture) + : m_intersection(new dmnsn_intersection*(dmnsn_new_intersection())), + m_ray(ray), m_texture(texture) + { + dmnsn()->t = t; + } + + // Wrap an existing intersection - don't release() one of these + Intersection::Intersection(dmnsn_intersection *intersection) + : m_intersection(new dmnsn_intersection*(intersection)), + m_ray(intersection->ray), + m_texture(const_cast<dmnsn_texture*>(intersection->texture)) + { } + + // Delete an intersection + Intersection::~Intersection() { + if (m_intersection && m_intersection.unique()) { + dmnsn_delete_intersection(dmnsn()); + } + } + + dmnsn_intersection* + Intersection::dmnsn() + { + if (!m_intersection) { + throw Dimension_Error("Attempt to access released intersection."); + } + return *m_intersection; + } + + const dmnsn_intersection* + Intersection::dmnsn() const + { + if (!m_intersection) { + throw Dimension_Error("Attempt to access released intersection."); + } + return *m_intersection; + } + + dmnsn_intersection* + Intersection::release() + { + if (!m_intersection) { + throw Dimension_Error("Attempt to release previously released" + " intersection."); + } + + if (!m_intersection.unique()) { + throw Dimension_Error("Attempt to release non-unique intersection."); + } + + dmnsn_intersection* intersection = dmnsn(); + m_intersection.reset(); + return intersection; + } + + // Manual constructor + Object::Object(dmnsn_object* object) + : m_object(new dmnsn_object*(object)) + { } + + // Virtual Object destructor Object::~Object() { if (unique()) { @@ -45,10 +107,10 @@ namespace Dimension } // Intersection list for the line l - Array<double> - Object::intersections(const Line& l) + Intersection + Object::intersection(const Line& l) { - return Array<double>((*dmnsn()->intersections_fn)(dmnsn(), l.dmnsn())); + return Intersection((*dmnsn()->intersection_fn)(dmnsn(), l.dmnsn())); } // Whether the point `point' is inside the object @@ -69,6 +131,12 @@ namespace Dimension return *m_object; } + Object* + Object::copy() const + { + return new Object(*this); + } + // Return a const version of the wrapped canvas const dmnsn_object* Object::dmnsn() const @@ -90,11 +158,6 @@ namespace Dimension : m_object(object.m_object) { } - // Protected manual constructor - Object::Object(dmnsn_object* object) - : m_object(new dmnsn_object*(object)) - { } - // Is m_object unique? bool Object::unique() const @@ -110,12 +173,13 @@ namespace Dimension } // Custom object callbacks - namespace { - dmnsn_array * - intersections_fn(const dmnsn_object *object, dmnsn_line line) + namespace + { + dmnsn_intersection * + intersection_fn(const dmnsn_object *object, dmnsn_line line) { Custom_Object* cobject = reinterpret_cast<Custom_Object*>(object->ptr); - return cobject->intersections(Line(line)).release(); + return cobject->intersection(Line(line)).release(); } int @@ -131,8 +195,8 @@ namespace Dimension : Object(dmnsn_new_object()) { dmnsn()->ptr = this; - dmnsn()->intersections_fn = &intersections_fn; - dmnsn()->inside_fn = &inside_fn; + dmnsn()->intersection_fn = &intersection_fn; + dmnsn()->inside_fn = &inside_fn; } // Delete the object diff --git a/libdimensionxx/texture.cpp b/libdimensionxx/texture.cpp new file mode 100644 index 0000000..cd9c2a8 --- /dev/null +++ b/libdimensionxx/texture.cpp @@ -0,0 +1,106 @@ +/************************************************************************* + * Copyright (C) 2009 Tavian Barnes <tavianator@gmail.com> * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * <http://www.gnu.org/licenses/>. * + *************************************************************************/ + +#include "dimensionxx.hpp" + +namespace Dimension +{ + Pigment::Pigment(dmnsn_pigment* pigment) + : m_pigment(new dmnsn_pigment*(pigment)) + { } + + Pigment::~Pigment() + { + if (unique()) { + dmnsn_delete_pigment(dmnsn()); + } + } + + Pigment* + Pigment::copy() const + { + return new Pigment(*this); + } + + dmnsn_pigment* + Pigment::dmnsn() + { + if (!m_pigment) { + throw Dimension_Error("Attempt to access NULL pigment."); + } + return *m_pigment; + } + + const dmnsn_pigment* + Pigment::dmnsn() const + { + if (!m_pigment) { + throw Dimension_Error("Attempt to access NULL pigment."); + } + return *m_pigment; + } + + // Protected no-op constructor + Pigment::Pigment() { } + + // Shallow copy + Pigment::Pigment(const Pigment& pigment) + : m_pigment(pigment.m_pigment) + { + } + + bool + Pigment::unique() const + { + return m_pigment && m_pigment.unique(); + } + + Texture::Texture(const Pigment& pigment) + : m_texture(new dmnsn_texture*(dmnsn_new_texture())), + m_pigment(pigment.copy()) + { + dmnsn()->pigment = m_pigment->dmnsn(); + } + + Texture::Texture(dmnsn_texture* texture) + : m_texture(new dmnsn_texture*(texture)), + m_pigment(new Pigment(texture->pigment)) + { + } + + Texture::~Texture() + { + if (m_texture.unique()) { + dmnsn_delete_texture(dmnsn()); + } + } + + dmnsn_texture* + Texture::dmnsn() + { + return *m_texture; + } + + const dmnsn_texture* + Texture::dmnsn() const + { + return *m_texture; + } +} |