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