#ifndef gra_WatchBall_H__ #define gra_WatchBall_H__ #include "Camera.h" #include "../Self.h" #include "../geo/Vectors.h" #include "../math/LinearTransformations.h" #include "../oo/ObjBase.h" #include #include namespace meow { /*! * @brief \b 多個camera, 一個offset, 一個rotation * * @author cat_leopard */ template class WatchBall: public ObjBase { public: typedef std::vector > Cameras; private: struct Myself { Cameras cameras_; Vector3D offset_; Myself() { } ~Myself() { } Myself& copyFrom(Myself const& b) { cameras_ = b.cameras_; offset_ = b. offset_; return *this; } }; Self const self; public: /*! * @brief constructor */ WatchBall(): self() { } /*! * @brief copy constructor */ WatchBall(WatchBall const& b): self(b.self, Self::COPY_FROM) { } /*! * @brief destructor */ ~WatchBall() { } /*! * @brief copy data */ WatchBall& copyFrom(WatchBall const& b) { self().copyFrom(b.self); return *this; } /*! * @brief reference */ WatchBall& referenceFrom(WatchBall const& b) { self().referenceFrom(b.self); return *this; } /*! * @brief 取得有幾個camera */ size_t cameraSize() const { return self->cameras_.size(); } /*! * @brief 取得 cameras */ Cameras const& cameras() const { return self->cameras_; } /*! * @brief 取得 cameras (non-constant) */ Cameras& camerasGet() { return self()->cameras_; } /*! * @brief 設定 camera */ Cameras const& cameras(Cameras const& c) { self()->cameras_ = c; return cameras(); } /*! * @brief 取得第i個camera */ Camera const& camera(size_t i) const { return cameras()[i]; } /*! * @brief 取得第i個camera (non-constant reference) */ Camera& camera(size_t i) { return cameras()[i]; } /*! * @brief 設定第i個camera */ Camera const& camera(size_t i, Camera const& c) { cameras()[i] = c; return camera(i); } /*! * @brief 取得offset */ Vector3D const& offset() const { return self->offset_; } /*! * @brief 取得offset (non-constant reference) */ Vector3D& offset() { return self()->offset_; } /*! * @brief 設定offset */ Vector3D const& offset(Vector3D const& ofs) { self()->offset_ = ofs; return offset(); } /*! * @brief 取得底片color */ Pixel color(Vector3D p) const { Vector3D p2(p - offset()); Pixel sum(0); double ct = 0; for (size_t i = 0, I = cameraSize(); i < I; ++i) { if (camera(i).inside(p2)) { sum = sum + camera(i).color(p2); ++ct; } } return (ct > 0 ? sum / ct : sum); } /*! * @brief 輸出展開圖 * * @param [in] radius 半徑 */ Bitmap expand(double radius) const { radius = std::max(radius, 0.5); size_t height = std::max(1, 2.0 * radius); size_t width = 2.0* PI * radius; Bitmap ret(height, width, Pixel(0)); for (size_t i = 0; i < height; ++i) { for (size_t j = 0; j < width; ++j) { double theta = (1.0 * j / width - 0.5) * 2 * PI; double phi = asin(-(1.0 * i / height - 0.5) * 2.0); ret.pixel(i, j, color(Vector3D( sin(theta) * cos(phi), sin(phi), -cos(theta) * cos(phi) ))); } } return ret; } /*! * @brief same as \c copyFrom(b) */ WatchBall& operator=(WatchBall const& b) { return copyFrom(b); } /*! @brief 將資料寫入檔案 * * @note 未完成 */ bool write(FILE* f, bool bin, unsigned int fg) const { return false; } /*! @brief 將資料讀入 * * @note 未完成 */ bool read(FILE* f, bool bin, unsigned int fg) { return false; } /*! @brief new一個自己 * * @return 一個new出來的pointer */ ObjBase* create() const { return new WatchBall(); } /*! * @brief 複製資料 * * 輸入型別是 \c ObjBase \c const* * 事實上這個method就只是幫忙轉型然後呼叫原本的\c copyFrom * * @param [in] b 資料來源 * @return this */ ObjBase* copyFrom(ObjBase const* b) { return &(copyFrom(*(WatchBall*)b)); } /*! @brief 回傳class的type * * @return \c char \c const\c * 形式的typename */ char const* ctype() const{ static char const* ptr = typeid(*this).name(); return ptr; } /*! @brief 回傳class的type * * @return \c std::string 形式的typename */ std::string type() const { return std::string(ctype()); } }; } #endif // gra_WatchBall_H__