10bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 30bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Licensed under the Apache License, Version 2.0 (the "License"); 40bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// you may not use this file except in compliance with the License. 50bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// You may obtain a copy of the License at 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 70bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// http://www.apache.org/licenses/LICENSE-2.0 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 90bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Unless required by applicable law or agreed to in writing, software 100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// distributed under the License is distributed on an "AS IS" BASIS, 110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// See the License for the specific language governing permissions and 130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// limitations under the License. 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Clipper.hpp" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Polygon.hpp" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Renderer.hpp" 19708c24b3cd03b68aa98b29a9099d6a9ce96eca16Nicolas Capens#include "Common/Debug.hpp" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace sw 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 2300bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens Clipper::Clipper(bool symmetricNormalizedDepth) 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 2500bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens n = symmetricNormalizedDepth ? -1.0f : 0.0f; 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Clipper::~Clipper() 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3253bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens unsigned int Clipper::computeClipFlags(const float4 &v) 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 3400bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens return ((v.x > v.w) ? CLIP_RIGHT : 0) | 3500bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens ((v.y > v.w) ? CLIP_TOP : 0) | 3600bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens ((v.z > v.w) ? CLIP_FAR : 0) | 3700bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens ((v.x < -v.w) ? CLIP_LEFT : 0) | 3800bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens ((v.y < -v.w) ? CLIP_BOTTOM : 0) | 3900bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens ((v.z < n * v.w) ? CLIP_NEAR : 0) | 4053bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens Clipper::CLIP_FINITE; // FIXME: xyz finite 4153bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens } 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 4353bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens bool Clipper::clip(Polygon &polygon, int clipFlagsOr, const DrawCall &draw) 4453bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens { 4553bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens if(clipFlagsOr & CLIP_FRUSTUM) 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(clipFlagsOr & CLIP_NEAR) clipNear(polygon); 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(clipFlagsOr & CLIP_FAR) clipFar(polygon); 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 5153bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens if(clipFlagsOr & CLIP_LEFT) clipLeft(polygon); 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 5353bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens if(clipFlagsOr & CLIP_RIGHT) clipRight(polygon); 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 5553bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens if(clipFlagsOr & CLIP_TOP) clipTop(polygon); 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 5753bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens if(clipFlagsOr & CLIP_BOTTOM) clipBottom(polygon); 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }}}}} 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 6153bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens if(clipFlagsOr & CLIP_USER) 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 636b164c337c647c0898a0e54cdb260f0ee91ae4a6Alexis Hetu int clipFlags = draw.clipFlags; 6453bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens DrawData &data = *draw.data; 6553bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 676b164c337c647c0898a0e54cdb260f0ee91ae4a6Alexis Hetu if(clipFlags & CLIP_PLANE0) clipPlane(polygon, data.clipPlane[0]); 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 696b164c337c647c0898a0e54cdb260f0ee91ae4a6Alexis Hetu if(clipFlags & CLIP_PLANE1) clipPlane(polygon, data.clipPlane[1]); 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 716b164c337c647c0898a0e54cdb260f0ee91ae4a6Alexis Hetu if(clipFlags & CLIP_PLANE2) clipPlane(polygon, data.clipPlane[2]); 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 736b164c337c647c0898a0e54cdb260f0ee91ae4a6Alexis Hetu if(clipFlags & CLIP_PLANE3) clipPlane(polygon, data.clipPlane[3]); 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 756b164c337c647c0898a0e54cdb260f0ee91ae4a6Alexis Hetu if(clipFlags & CLIP_PLANE4) clipPlane(polygon, data.clipPlane[4]); 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(polygon.n >= 3) { 776b164c337c647c0898a0e54cdb260f0ee91ae4a6Alexis Hetu if(clipFlags & CLIP_PLANE5) clipPlane(polygon, data.clipPlane[5]); 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }}}}}} 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return polygon.n >= 3; 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void Clipper::clipNear(Polygon &polygon) 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **V = polygon.P[polygon.i]; 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **T = polygon.P[polygon.i + 1]; 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int t = 0; 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < polygon.n; i++) 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int j = i == polygon.n - 1 ? 0 : i + 1; 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 9500bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens float di = V[i]->z - n * V[i]->w; 9600bfa189ce055ff6cf1197b8ce9af503dcf0e65cNicolas Capens float dj = V[j]->z - n * V[j]->w; 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(di >= 0) 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = V[i]; 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj < 0) 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj); 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj > 0) 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di); 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.n = t; 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.i += 1; 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void Clipper::clipFar(Polygon &polygon) 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **V = polygon.P[polygon.i]; 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **T = polygon.P[polygon.i + 1]; 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int t = 0; 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < polygon.n; i++) 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int j = i == polygon.n - 1 ? 0 : i + 1; 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman float di = V[i]->w - V[i]->z; 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman float dj = V[j]->w - V[j]->z; 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(di >= 0) 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = V[i]; 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj < 0) 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj); 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj > 0) 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di); 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.n = t; 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.i += 1; 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 16053bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens void Clipper::clipLeft(Polygon &polygon) 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **V = polygon.P[polygon.i]; 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **T = polygon.P[polygon.i + 1]; 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int t = 0; 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < polygon.n; i++) 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int j = i == polygon.n - 1 ? 0 : i + 1; 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1715491cb48df1edf37f75b36214f0e8aa3a7d6dbc1Nicolas Capens float di = V[i]->w + V[i]->x; 1725491cb48df1edf37f75b36214f0e8aa3a7d6dbc1Nicolas Capens float dj = V[j]->w + V[j]->x; 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(di >= 0) 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = V[i]; 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj < 0) 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj); 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj > 0) 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di); 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.n = t; 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.i += 1; 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 19853bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens void Clipper::clipRight(Polygon &polygon) 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **V = polygon.P[polygon.i]; 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **T = polygon.P[polygon.i + 1]; 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int t = 0; 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < polygon.n; i++) 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int j = i == polygon.n - 1 ? 0 : i + 1; 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2095491cb48df1edf37f75b36214f0e8aa3a7d6dbc1Nicolas Capens float di = V[i]->w - V[i]->x; 2105491cb48df1edf37f75b36214f0e8aa3a7d6dbc1Nicolas Capens float dj = V[j]->w - V[j]->x; 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(di >= 0) 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = V[i]; 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj < 0) 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj); 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj > 0) 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di); 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.n = t; 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.i += 1; 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 23653bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens void Clipper::clipTop(Polygon &polygon) 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **V = polygon.P[polygon.i]; 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **T = polygon.P[polygon.i + 1]; 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int t = 0; 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < polygon.n; i++) 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int j = i == polygon.n - 1 ? 0 : i + 1; 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2475491cb48df1edf37f75b36214f0e8aa3a7d6dbc1Nicolas Capens float di = V[i]->w - V[i]->y; 2485491cb48df1edf37f75b36214f0e8aa3a7d6dbc1Nicolas Capens float dj = V[j]->w - V[j]->y; 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(di >= 0) 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = V[i]; 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj < 0) 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj); 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj > 0) 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di); 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.n = t; 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.i += 1; 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 27453bf0a113e42d70eb681abd88816960574af55f1Nicolas Capens void Clipper::clipBottom(Polygon &polygon) 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **V = polygon.P[polygon.i]; 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **T = polygon.P[polygon.i + 1]; 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int t = 0; 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < polygon.n; i++) 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int j = i == polygon.n - 1 ? 0 : i + 1; 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2855491cb48df1edf37f75b36214f0e8aa3a7d6dbc1Nicolas Capens float di = V[i]->w + V[i]->y; 2865491cb48df1edf37f75b36214f0e8aa3a7d6dbc1Nicolas Capens float dj = V[j]->w + V[j]->y; 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(di >= 0) 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = V[i]; 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj < 0) 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj); 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj > 0) 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di); 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.n = t; 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.i += 1; 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void Clipper::clipPlane(Polygon &polygon, const Plane &p) 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **V = polygon.P[polygon.i]; 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const float4 **T = polygon.P[polygon.i + 1]; 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int t = 0; 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for(int i = 0; i < polygon.n; i++) 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int j = i == polygon.n - 1 ? 0 : i + 1; 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman float di = p.A * V[i]->x + p.B * V[i]->y + p.C * V[i]->z + p.D * V[i]->w; 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman float dj = p.A * V[j]->x + p.B * V[j]->y + p.C * V[j]->z + p.D * V[j]->w; 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(di >= 0) 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = V[i]; 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj < 0) 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[i], *V[j], di, dj); 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if(dj > 0) 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman clipEdge(polygon.B[polygon.b], *V[j], *V[i], dj, di); 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman T[t++] = &polygon.B[polygon.b++]; 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.n = t; 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman polygon.i += 1; 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman inline void Clipper::clipEdge(float4 &Vo, const float4 &Vi, const float4 &Vj, float di, float dj) const 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman float D = 1.0f / (dj - di); 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Vo.x = (dj * Vi.x - di * Vj.x) * D; 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Vo.y = (dj * Vi.y - di * Vj.y) * D; 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Vo.z = (dj * Vi.z - di * Vj.z) * D; 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Vo.w = (dj * Vi.w - di * Vj.w) * D; 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 360