#ifndef CLIPPER_H #define CLIPPER_H /*! ** ** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net ** ** Portions of this source has been released with the PhysXViewer application, as well as ** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. ** ** If you find this code useful or you are feeling particularily generous I would ** ask that you please go to http://www.amillionpixels.us and make a donation ** to Troy DeMolay. ** ** DeMolay is a youth group for young men between the ages of 12 and 21. ** It teaches strong moral principles, as well as leadership skills and ** public speaking. The donations page uses the 'pay for pixels' paradigm ** where, in this case, a pixel is only a single penny. Donations can be ** made for as small as $4 or as high as a $100 block. Each person who donates ** will get a link to their own site as well as acknowledgement on the ** donations blog located here http://www.amillionpixels.blogspot.com/ ** ** If you wish to contact me you can use the following methods: ** ** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) ** Skype ID: jratcliff63367 ** Yahoo: jratcliff63367 ** AOL: jratcliff1961 ** email: jratcliff@infiniplex.net ** ** ** The MIT license: ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and associated documentation files (the "Software"), to deal ** in the Software without restriction, including without limitation the rights ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is furnished ** to do so, subject to the following conditions: ** ** The above copyright notice and this permission notice shall be included in all ** copies or substantial portions of the Software. ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, ** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define MAX_CLIP 64 // This is a general purpose CohenSutherland polygon clipper written in // C++ and using STL. This clipper is not inherently slow, but then again // it is not necessarily blazingly fast. It uses STL vectors to build // the clipped polygon and return the result. // // This routine is presented to educate clearly the cohen sutherland // clipping algorithm. It clips against an arbitrary // 3d axis aligned bounding region which you specify. // // It is fairly straightforward to change the Vector3d class to some // other vertex format and easily use this routine to clip any kind // of vertex data with any number of interpolants. // // This was written by John W. Ratcliff (jratcliff@verant.com) on // August 10, 2000 and is relased into the public domain as part of // the Code Snippet library on FlipCode.com class Vec3d { public: Vec3d(void) { }; Vec3d(const float *p) { x = p[0]; y = p[1]; z = p[2]; }; Vec3d(float _x,float _y,float _z) { x = _x; y = _y; z = _z; }; void set(float _x,float _y,float _z) { x = _x; y = _y; z = _z; }; void set(const float *p) { x = p[0]; y = p[1]; z = p[2]; }; float x; float y; float z; }; // Enumeration defining the 6 planes of the view frustum. enum ClipPlane { CP_TOP = 0, CP_BOTTOM, CP_LEFT, CP_RIGHT, CP_NEAR, CP_FAR, CP_LAST }; enum ClipResult { CR_INSIDE, // completely inside the frustum. CR_OUTSIDE, //completely outside the frustum. CR_PARTIAL, // was clipped. CR_LAST }; // An intermediate vertex format which contains the cohen sutherland // clipping codes. class ClipVertex { public: ClipVertex(void) { }; ClipVertex(const Vec3d &pos,int code) { mPos = pos; mClipCode = code; }; // clip vertex between v1 and v2 on this plane.. ClipVertex(const ClipVertex &v1, const ClipVertex &v2, ClipPlane p, float edge); // the clipping boundary.. void Set(const Vec3d &pos,int code) { mPos = pos; mClipCode = code; }; const Vec3d& GetPos(void) const { return mPos; }; int GetClipCode(void) const { return mClipCode; }; void SetClipCode(int code) { mClipCode = code; }; float GetX(void) const { return mPos.x; }; float GetY(void) const { return mPos.y; }; float GetZ(void) const { return mPos.z; }; int mClipCode; Vec3d mPos; }; class FrustumClipper { public: FrustumClipper(const float *fmin,const float *fmax) { SetFrustum(fmin,fmax); }; FrustumClipper(void) { Vec3d minbound(-0.5f,-0.5f,-0.5f); Vec3d maxbound(+0.5f,+0.5f,+0.5f); SetFrustum(&minbound.x,&maxbound.x); }; void SetFrustum(const float *fmin,const float *fmax) { mEdges[CP_LEFT] = fmin[0]; mEdges[CP_RIGHT] = fmax[0]; mEdges[CP_TOP] = fmin[1]; mEdges[CP_BOTTOM] = fmax[1]; mEdges[CP_NEAR] = fmin[2]; mEdges[CP_FAR] = fmax[2]; }; // compute the cohen sutherland clipping bits for this 3d position // against the view frustum. int ClipCode(const Vec3d &pos) const; // compute the cohen sutherland clipping codes, and *also* accumulate // the or bits and the and bits for a series of point tests. int ClipCode(const Vec3d &pos,int &ocode,int &acode) const; // clips input polygon against the frustum. Places output polygon // in 'output'. ClipResult Clip(const Vec3d *input, // input vertices. unsigned int vcount, // input vertex count. Vec3d *output, unsigned int &ocount) const; ClipResult ClipRay(const Vec3d &r1a, const Vec3d &r2a, Vec3d &r1b, Vec3d &r2b); private: float mEdges[CP_LAST]; // define the clipping planes of the view frustum }; #endif