| 1 |
/////////////////////////////////////////////////////////////////////////////
|
| 2 |
// //
|
| 3 |
// Copyright (C) 1992-1995 by Alex Keller ([email protected]) //
|
| 4 |
// All rights reserved //
|
| 5 |
// //
|
| 6 |
// This software may be freely copied, modified, and redistributed //
|
| 7 |
// provided that this copyright notice is preserved on all copies. //
|
| 8 |
// //
|
| 9 |
// You may not distribute this software, in whole or in part, as part of //
|
| 10 |
// any commercial product without the express consent of the authors. //
|
| 11 |
// //
|
| 12 |
// There is no warranty or other guarantee of fitness of this software //
|
| 13 |
// for any purpose. It is provided solely "as is". //
|
| 14 |
// //
|
| 15 |
/////////////////////////////////////////////////////////////////////////////
|
| 16 |
|
| 17 |
int Face(int ac, char ** av)
|
| 18 |
{
|
| 19 |
Point Center;
|
| 20 |
Vector E1, E2, E3, nn, ConvexNormal;
|
| 21 |
int i, max, Corners, p0, p1, p2, n, Start;
|
| 22 |
double maxd, d, x, y;
|
| 23 |
Boolean * Out, Empty;
|
| 24 |
C_VERTEX * Pnt;
|
| 25 |
FVECT P;
|
| 26 |
Vertex * Points;
|
| 27 |
Surface * CurrentSurface;
|
| 28 |
Texture * Luminaire;
|
| 29 |
Color Tone;
|
| 30 |
|
| 31 |
if(ac--)
|
| 32 |
av++;
|
| 33 |
|
| 34 |
if(Zero(c_cmaterial->ed))
|
| 35 |
Luminaire = NULL;
|
| 36 |
else
|
| 37 |
{
|
| 38 |
x = c_cmaterial->ed_c.cx;
|
| 39 |
y = c_cmaterial->ed_c.cy;
|
| 40 |
Tone.fromCIE(x, y, 1.0 - x - y);
|
| 41 |
Tone *= c_cmaterial->ed / (2 * M_PI);
|
| 42 |
Luminaire = new Monoton(Tone);
|
| 43 |
}
|
| 44 |
|
| 45 |
x = c_cmaterial->rd_c.cx;
|
| 46 |
y = c_cmaterial->rd_c.cy;
|
| 47 |
Tone.fromCIE(x, y, 1.0 - x - y);
|
| 48 |
Tone *= c_cmaterial->rd;
|
| 49 |
CurrentSurface = new Ward(new Monoton(Tone), c_cmaterial->rd,
|
| 50 |
NULL, c_cmaterial->rs, c_cmaterial->rs_a, c_cmaterial->rs_a,
|
| 51 |
NULL, c_cmaterial->td,
|
| 52 |
NULL, c_cmaterial->ts, c_cmaterial->ts_a, c_cmaterial->ts_a,
|
| 53 |
Luminaire);
|
| 54 |
|
| 55 |
Points = new Vertex[ac];
|
| 56 |
n = 0;
|
| 57 |
|
| 58 |
while(ac-- > 0)
|
| 59 |
{
|
| 60 |
Pnt = c_getvert(*av++);
|
| 61 |
|
| 62 |
//if(Pnt == NULL)
|
| 63 |
// cout << "Error" << endl;
|
| 64 |
|
| 65 |
xf_xfmpoint(P, Pnt->p);
|
| 66 |
|
| 67 |
Points[n].Origin.x = P[0];
|
| 68 |
Points[n].Origin.y = P[1];
|
| 69 |
Points[n].Origin.z = P[2];
|
| 70 |
|
| 71 |
n++;
|
| 72 |
}
|
| 73 |
|
| 74 |
if(n == 3)
|
| 75 |
*World << new Triangle(*World, &Points[0], &Points[1], &Points[2], CurrentSurface);
|
| 76 |
else if(n > 3)
|
| 77 |
{
|
| 78 |
Center = Points[0].Origin;
|
| 79 |
|
| 80 |
for(i = 1; i < n; i++)
|
| 81 |
{
|
| 82 |
Center.x += Points[i].Origin.x;
|
| 83 |
Center.y += Points[i].Origin.y;
|
| 84 |
Center.z += Points[i].Origin.z;
|
| 85 |
}
|
| 86 |
|
| 87 |
Center.x /= (double) n;
|
| 88 |
Center.y /= (double) n;
|
| 89 |
Center.z /= (double) n;
|
| 90 |
|
| 91 |
maxd = Length(Center - Points[0].Origin);
|
| 92 |
max = 0;
|
| 93 |
|
| 94 |
for(i = 1; i < n; i++)
|
| 95 |
{
|
| 96 |
d = Length(Center - Points[i].Origin);
|
| 97 |
|
| 98 |
if(d > maxd)
|
| 99 |
{
|
| 100 |
max = i;
|
| 101 |
maxd = d;
|
| 102 |
}
|
| 103 |
}
|
| 104 |
|
| 105 |
Out = new Boolean[n];
|
| 106 |
|
| 107 |
for(i = 0; i < n; i++)
|
| 108 |
Out[i] = False;
|
| 109 |
|
| 110 |
p1 = max;
|
| 111 |
p0 = p1 - 1;
|
| 112 |
|
| 113 |
if(p0 < 0)
|
| 114 |
p0 = n - 1;
|
| 115 |
|
| 116 |
p2 = p1 + 1;
|
| 117 |
|
| 118 |
if(p2 == n)
|
| 119 |
p2 = 0;
|
| 120 |
|
| 121 |
ConvexNormal = (Points[p2].Origin - Points[p0].Origin) | (Points[p1].Origin - Points[p0].Origin);
|
| 122 |
Normalize(ConvexNormal);
|
| 123 |
|
| 124 |
Corners = n;
|
| 125 |
p0 = - 1;
|
| 126 |
|
| 127 |
while(Corners >= 3)
|
| 128 |
{
|
| 129 |
Start = p0;
|
| 130 |
|
| 131 |
do
|
| 132 |
{
|
| 133 |
p0 = (p0 + 1) % n;
|
| 134 |
|
| 135 |
while(Out[p0])
|
| 136 |
p0 = (p0 + 1) % n;
|
| 137 |
|
| 138 |
p1 = (p0 + 1) % n;
|
| 139 |
|
| 140 |
while(Out[p1])
|
| 141 |
p1 = (p1 + 1) % n;
|
| 142 |
|
| 143 |
p2 = (p1 + 1) % n;
|
| 144 |
|
| 145 |
while(Out[p2])
|
| 146 |
p2 = (p2 + 1) % n;
|
| 147 |
|
| 148 |
if(p0 == Start)
|
| 149 |
break;
|
| 150 |
|
| 151 |
nn = (Points[p2].Origin - Points[p0].Origin) | (Points[p1].Origin - Points[p0].Origin);
|
| 152 |
Normalize(nn);
|
| 153 |
d = Length(nn - ConvexNormal);
|
| 154 |
|
| 155 |
E1 = nn | (Points[p1].Origin - Points[p0].Origin);
|
| 156 |
E2 = nn | (Points[p2].Origin - Points[p1].Origin);
|
| 157 |
E3 = nn | (Points[p0].Origin - Points[p2].Origin);
|
| 158 |
|
| 159 |
Empty = True;
|
| 160 |
|
| 161 |
for(i = 0; i < n; i++)
|
| 162 |
if(! Out[i])
|
| 163 |
if((i != p0) && (i != p1) && (i != p2))
|
| 164 |
{
|
| 165 |
Empty = Empty && ! ((E1 * (Points[i].Origin - Points[p0].Origin) <= - Epsilon)
|
| 166 |
&& (E2 * (Points[i].Origin - Points[p1].Origin) <= - Epsilon)
|
| 167 |
&& (E3 * (Points[i].Origin - Points[p2].Origin) <= - Epsilon));
|
| 168 |
}
|
| 169 |
}
|
| 170 |
while((d > 1.0) || (! Empty));
|
| 171 |
|
| 172 |
if(p0 == Start)
|
| 173 |
{
|
| 174 |
cout << "misbuilt polygonal face..." << endl;
|
| 175 |
break;
|
| 176 |
}
|
| 177 |
|
| 178 |
*World << new Triangle(*World, &Points[p0], &Points[p1], &Points[p2], CurrentSurface);
|
| 179 |
|
| 180 |
Out[p1] = True;
|
| 181 |
Corners--;
|
| 182 |
}
|
| 183 |
|
| 184 |
delete [] Out;
|
| 185 |
}
|
| 186 |
|
| 187 |
return(MG_OK);
|
| 188 |
}
|
| 189 |
|
| 190 |
/////////////////////////////////////////////////////////////////////////////
|