29 void Print(
const char* fmt, ...);
33 static bool use_collision_detection =
true;
49 using namespace Opcode;
56 locs =
new(__FILE__,__LINE__) IcePoint[
nverts];
57 tris =
new(__FILE__,__LINE__) IndexedTriangle[
ntris];
62 for (i = 0; i <
nverts; i++) {
63 IcePoint* p =
locs + i;
66 p->Set(v->
x, v->
y, v->
z);
69 for (i = 0; i <
npolys; i++) {
73 IndexedTriangle& t =
tris[n++];
75 t.mVRef[0] = p->
verts[0];
76 t.mVRef[1] = p->
verts[2];
77 t.mVRef[2] = p->
verts[1];
80 IndexedTriangle& t1 =
tris[n++];
81 IndexedTriangle& t2 =
tris[n++];
83 t1.mVRef[0] = p->
verts[0];
84 t1.mVRef[1] = p->
verts[2];
85 t1.mVRef[2] = p->
verts[1];
87 t2.mVRef[0] = p->
verts[0];
88 t2.mVRef[1] = p->
verts[3];
89 t2.mVRef[2] = p->
verts[2];
93 mesh.SetNbVertices(nverts);
98 creator.mIMesh = &
mesh;
99 status =
model.Build(creator);
130 :
model(0), own_model(1),
131 roll(0.0f), pitch(0.0f), yaw(0.0f), intersection_poly(0)
134 sprintf_s(
name,
"Solid %d",
id);
189 for (
int i = 0; i < vset->
nverts; i++) {
249 for (
int i = 0; i < 6; i++) {
253 extent.
x =
model->extents[i];
256 extent.
y =
model->extents[i];
259 extent.
z =
model->extents[i];
266 if (extent.
x < l) l = (int) extent.
x;
267 if (extent.
x > r) r = (int) extent.
x;
268 if (extent.
y < t) t = (int) extent.
y;
269 if (extent.
y > b) b = (int) extent.
y;
306 using namespace Opcode;
308 bool contact =
false;
317 world0.m[0][0] = (float) m1.
elem[0][0];
318 world0.m[0][1] = (
float) m1.elem[0][1];
319 world0.m[0][2] = (float) m1.elem[0][2];
320 world0.m[0][3] = 0.0f;
322 world0.m[1][0] = (
float) m1.elem[1][0];
323 world0.m[1][1] = (float) m1.elem[1][1];
324 world0.m[1][2] = (
float) m1.elem[1][2];
325 world0.m[1][3] = 0.0f;
327 world0.m[2][0] = (float) m1.elem[2][0];
328 world0.m[2][1] = (
float) m1.elem[2][1];
329 world0.m[2][2] = (float) m1.elem[2][2];
330 world0.m[2][3] = 0.0f;
335 world0.m[3][3] = 1.0f;
337 world1.m[0][0] = (float) m2.elem[0][0];
338 world1.m[0][1] = (
float) m2.elem[1][0];
339 world1.m[0][2] = (float) m2.elem[2][0];
340 world1.m[0][3] = 0.0f;
342 world1.m[1][0] = (
float) m2.elem[0][1];
343 world1.m[1][1] = (float) m2.elem[1][1];
344 world1.m[1][2] = (
float) m2.elem[2][1];
345 world1.m[1][3] = 0.0f;
347 world1.m[2][0] = (float) m2.elem[0][2];
348 world1.m[2][1] = (
float) m2.elem[1][2];
349 world1.m[2][2] = (float) m2.elem[2][2];
350 world1.m[2][3] = 0.0f;
355 world1.m[3][3] = 1.0f;
358 while (++s1_iter && !contact) {
362 while (++s2_iter && !contact) {
391 bool treat_translucent_polys_as_solid)
401 double dlen = d1.
length();
425 Point closest = Q + w * (d0 * w);
428 Point leading_edge = Q + w*len;
429 Point leading_delta = leading_edge -
loc;
430 double leading_dist = leading_delta.
length();
433 if (leading_dist >
radius) {
436 Point delta1 = closest - Q;
437 Point delta2 = leading_edge - Q;
441 if (delta1 * delta2 < 0 || delta1.
length() > len) {
459 w.
x = tmp *
Vec3(xform(0,0), xform(0,1), xform(0,2));
460 w.
y = tmp * Vec3(xform(1,0), xform(1,1), xform(1,2));
461 w.
z = tmp * Vec3(xform(2,0), xform(2,1), xform(2,2));
465 Q.
x = tmp * Vec3(xform(0,0), xform(0,1), xform(0,2));
466 Q.y = tmp * Vec3(xform(1,0), xform(1,1), xform(1,2));
467 Q.z = tmp * Vec3(xform(2,0), xform(2,1), xform(2,2));
478 for (
int i = 0; i < s->
NumPolys(); i++) {
489 if (denom < -1.0e-5) {
491 double ilen = ((P-Q)*v)/denom;
493 if (ilen > 0 && ilen < min) {
494 Point intersect = Q + w * ilen;
602 for (
int v = 0; v < s->
NumVerts(); v++) {
603 s->vertex_set->
loc[v] *= (float) scale;
604 s->vloc[v] *= (float) scale;
606 float lvi = s->vloc[v].
length();
641 if (intensity / distance > 1)
642 active_lights.
append(light);
646 if (intensity > 0.65)
647 active_lights.
insert(light);
652 iter.
attach(active_lights);
656 int index = iter.
index();
786 : nverts(0), npolys(0),
radius(0),
luminous(false), dynamic(false)
788 ZeroMemory(name,
sizeof(name));
792 : nverts(0), npolys(0), radius(0), luminous(false), dynamic(false)
817 luminous = m.luminous;
827 CopyMemory(matl2, matl1,
sizeof(
Material));
838 surf2->
Copy(*surf1,
this);
853 for (
int i = 0; i < surfaces.
size(); i++) {
854 const Surface* s = surfaces[i];
863 inline bool Collinear(
const double* a,
const double* b,
const double* c)
865 Point ab(b[0]-a[0], b[1]-a[1], b[2]-a[2]);
866 Point ac(c[0]-a[0], c[1]-a[1], c[2]-a[2]);
868 return (cross.
length() == 0);
886 static void LoadFlags(LPDWORD flags,
DataLoader* l, BYTE*& fp)
889 l->
fread(&magic_flags,
sizeof(DWORD), 1, fp);
902 const DWORD magic_mask = 0x0fc3;
904 *flags = magic_flags & magic_mask;
925 Print(
"MAG Open Failed: no data loader for file '%s'\n", mag_file);
929 int size = loader->
LoadBuffer(mag_file, block);
934 Print(
"MAG Open Failed: could not open file '%s'\n", mag_file);
938 strncpy_s(name, mag_file, 31);
942 CopyMemory(file_id, block, 4);
946 if (!strcmp(file_id,
"MAG6")) {
949 else if (!strcmp(file_id,
"MAG5")) {
952 else if (!strcmp(file_id,
"MAG4")) {
956 Print(
"MAG Open Failed: File '%s' Invalid file type '%s'\n", mag_file, file_id);
971 result = LoadMag5(block, size, scale);
975 result = LoadMag6(block, size, scale);
992 return mod_file->
Load(
this, scale);
1000 static int mcomp(
const void* a,
const void* b)
1015 Model::LoadMag5(BYTE* block,
int len,
double scale)
1017 bool result =
false;
1020 BYTE* fp = block + 4;
1024 loader->
fread(&ntex,
sizeof(ntex), 1, fp);
1025 loader->
fread(&nsurfs,
sizeof(nsurfs), 1, fp);
1042 strcpy_s(mtl->
name,
"(default)");
1048 for (
int i = 0; i < ntex; i++) {
1049 mtl =
new(__FILE__,__LINE__)
Material;
1065 loader->
fread(tname, 32, 1, fp);
1067 strcpy_s(mtl->
name, tname);
1069 char* dot = strrchr(mtl->
name,
'.');
1073 char* plus = strrchr(mtl->
name,
'+');
1082 loader->
fread(&nverts, 4, 1, fp);
1083 loader->
fread(&npolys, 4, 1, fp);
1086 int mag_nverts = nverts;
1087 int next_vert = nverts;
1089 nverts = npolys * 4;
1095 strcpy_s(s->name,
"default");
1098 s->vertex_set =
new(__FILE__,__LINE__)
VertexSet(nverts);
1099 s->vloc =
new(__FILE__,__LINE__)
Vec3[nverts];
1101 ZeroMemory(s->vertex_set->
loc, nverts *
sizeof(
Vec3));
1102 ZeroMemory(s->vertex_set->
diffuse, nverts *
sizeof(DWORD));
1103 ZeroMemory(s->vertex_set->
specular, nverts *
sizeof(DWORD));
1104 ZeroMemory(s->vertex_set->
tu, nverts *
sizeof(
float));
1105 ZeroMemory(s->vertex_set->
tv, nverts *
sizeof(
float));
1106 ZeroMemory(s->vertex_set->
rw, nverts *
sizeof(
float));
1107 ZeroMemory(s->vloc, nverts *
sizeof(
Vec3));
1110 s->polys =
new(__FILE__,__LINE__)
Poly[npolys];
1112 ZeroMemory(s->polys,
sizeof(
Poly) * npolys);
1115 vset = s->vertex_set;
1119 for (v = 0; v < mag_nverts; v++) {
1123 loader->
fread(&vert,
sizeof(
Vec3), 1, fp);
1124 loader->
fread(&norm,
sizeof(
Vec3), 1, fp);
1125 loader->
fread(&vstate,
sizeof(DWORD), 1, fp);
1128 vert *= (float) scale;
1130 vset->
loc[v] = vert;
1131 vset->
nrm[v] = norm;
1133 double d = vert.
length();
1137 if (vert.
x > extents[0]) extents[0] = vert.
x;
1138 if (vert.
x < extents[1]) extents[1] = vert.
x;
1139 if (vert.
y > extents[2]) extents[2] = vert.
y;
1140 if (vert.
y < extents[3]) extents[3] = vert.
y;
1141 if (vert.
z > extents[4]) extents[4] = vert.
z;
1142 if (vert.
z < extents[5]) extents[5] = vert.
z;
1155 int vert_index_buffer[32];
1156 float texture_index_buffer[32];
1158 for (
int n = 0; n < npolys; n++) {
1159 Poly& poly = s->polys[n];
1162 loader->
fread(&dummy_flags,
sizeof(DWORD), 1, fp);
1163 loader->
fread(&dummy_center,
sizeof(
Vec3), 1, fp);
1165 LoadPlane(dummy_plane, loader, fp);
1167 loader->
fread(&dummy_color,
sizeof(DWORD), 1, fp);
1168 loader->
fread(&texture_num,
sizeof(
int), 1, fp);
1170 if (texture_num >= 0 && texture_num < ntex) {
1171 int mtl_num = texture_num + 1;
1172 poly.
material = materials[mtl_num];
1175 bool flag_translucent = (dummy_flags & 0x04) ?
true :
false;
1176 bool flag_transparent = (dummy_flags & 0x08) ?
true :
false;
1179 if (dummy_flags & 2) {
1180 mtl = materials[mtl_num];
1191 if (flag_translucent && flag_transparent)
1195 else if (flag_translucent)
1199 else if (flag_transparent)
1208 poly.
visible = (BYTE) (dummy_flags & 1);
1210 loader->
fread(&poly_nverts,
sizeof(
int), 1, fp);
1211 loader->
fread(vert_index_buffer,
sizeof(
int), poly_nverts, fp);
1213 if (poly_nverts == 3)
1216 else if (poly_nverts == 4)
1219 poly.
nverts = poly_nverts;
1220 for (
int vi = 0; vi < poly_nverts; vi++) {
1221 v = vert_index_buffer[vi];
1223 if (vset->
rw[v] > 0) {
1232 loader->
fread(texture_index_buffer,
sizeof(
float), poly_nverts, fp);
1233 for (
int vi = 0; vi < poly_nverts; vi++) {
1235 vset->
tu[v] = texture_index_buffer[vi];
1238 loader->
fread(texture_index_buffer,
sizeof(
float), poly_nverts, fp);
1239 for (
int vi = 0; vi < poly_nverts; vi++) {
1241 vset->
tv[v] = texture_index_buffer[vi];
1248 for (
int n = 0; n < npolys; n++) {
1249 Poly& poly = s->polys[n];
1256 poly_nverts = poly.
nverts;
1258 for (
int vi = 0; vi < poly_nverts; vi++) {
1266 qsort((
void*) s->polys, s->npolys,
sizeof(
Poly), mcomp);
1271 for (
int n = 0; n < npolys; n++) {
1280 segment =
new(__FILE__,__LINE__)
Segment;
1283 segment->
polys = &s->polys[n];
1285 segment->
model =
this;
1287 s->segments.
append(segment);
1293 result = nverts && npolys;
1330 Model::LoadMag6(BYTE* block,
int len,
double scale)
1332 bool result =
false;
1335 BYTE* fp = block + 4;
1341 loader->
fread(&ntex,
sizeof(ntex), 1, fp);
1342 loader->
fread(&nmtls,
sizeof(nmtls), 1, fp);
1343 loader->
fread(&nsurfs,
sizeof(nsurfs), 1, fp);
1347 char* buffer =
new(__FILE__,__LINE__)
char[ntex];
1351 loader->
fread(buffer, ntex, 1, fp);
1353 while (p < buffer + ntex) {
1363 for (
int i = 0; i < nmtls; i++) {
1367 loader->
fread(&m6,
sizeof(m6), 1, fp);
1410 for (
int i = 0; i < nsurfs; i++) {
1416 loader->
fread(&nverts, 4, 1, fp);
1417 loader->
fread(&npolys, 4, 1, fp);
1418 loader->
fread(&namelen, 1, 1, fp);
1419 loader->
fread(name, 1, namelen, fp);
1422 surface->model =
this;
1430 ZeroMemory(polys,
sizeof(
Poly) * npolys);
1433 for (
int v = 0; v < nverts; v++) {
1434 loader->
fread(&vset->
loc[v],
sizeof(
float), 3, fp);
1435 loader->
fread(&vset->
nrm[v],
sizeof(
float), 3, fp);
1436 loader->
fread(&vset->
tu[v],
sizeof(
float), 1, fp);
1437 loader->
fread(&vset->
tv[v],
sizeof(
float), 1, fp);
1439 vset->
loc[v] *= (float) scale;
1443 double d = vert.
length();
1447 if (vert.
x > extents[0]) extents[0] = vert.
x;
1448 if (vert.
x < extents[1]) extents[1] = vert.
x;
1449 if (vert.
y > extents[2]) extents[2] = vert.
y;
1450 if (vert.
y < extents[3]) extents[3] = vert.
y;
1451 if (vert.
z > extents[4]) extents[4] = vert.
z;
1452 if (vert.
z < extents[5]) extents[5] = vert.
z;
1456 for (
int n = 0; n < npolys; n++) {
1457 Poly& poly = polys[n];
1458 BYTE poly_nverts = 0;
1459 BYTE material_index = 0;
1462 loader->
fread(&poly_nverts,
sizeof(BYTE), 1, fp);
1463 loader->
fread(&material_index,
sizeof(BYTE), 1, fp);
1464 loader->
fread(&poly_verts[0],
sizeof(WORD), poly_nverts, fp);
1466 if (poly_nverts >= 3) {
1467 poly.
nverts = poly_nverts;
1469 for (
int i = 0; i < poly_nverts; i++) {
1470 poly.
verts[i] = poly_verts[i];
1477 if (material_index > 0) {
1478 poly.
material = materials[material_index-1];
1479 poly.
sortval = material_index;
1481 else if (materials.
size()) {
1492 else if (poly.
nverts == 4)
1502 qsort((
void*) polys, npolys,
sizeof(
Poly), mcomp);
1507 for (
int n = 0; n < npolys; n++) {
1516 segment =
new(__FILE__,__LINE__)
Segment;
1519 segment->
polys = &polys[n];
1521 segment->
model =
this;
1528 surfaces.
append(surface);
1530 this->nverts += nverts;
1531 this->npolys += npolys;
1535 result = nverts && npolys;
1543 surface->model =
this;
1548 segment->
model =
this;
1552 surfaces.
append(surface);
1565 if (mtl_name && *mtl_name) {
1572 if (!strcmp(mtl->
name, mtl_name))
1589 int n = materials.
index(mtl_orig);
1593 while (++surf_iter) {
1597 while (++seg_iter) {
1615 if (nsurf >= 0 && nsurf < surfaces.
size())
1616 return surfaces[nsurf]->
AddPolys(np, nv);
1618 ::Print(
"WARNING: AddPolys(%d,%d,%d) invalid surface\n", nsurf, np, nv);
1671 for (
int i = 0; i < materials.
size(); i++) {
1674 for (
int n = i; n < materials.
size(); n++) {
1769 while (++seg_iter) {
1786 : model(0), vertex_set(0), vloc(0), nhull(0), npolys(0), nindices(0),
1787 polys(0), state(0), video_data(0), opcode(0)
1789 ZeroMemory(name,
sizeof(name));
1824 nindices = s.nindices;
1827 orientation = s.orientation;
1831 vertex_set = s.vertex_set->
Clone();
1834 vloc =
new(__FILE__,__LINE__)
Vec3[nhull];
1835 CopyMemory(vloc, s.vloc, nhull *
sizeof(
Vec3));
1841 polys =
new(__FILE__,__LINE__)
Poly[npolys];
1842 CopyMemory(polys, s.polys, npolys *
sizeof(
Poly));
1844 for (
int i = 0; i < npolys; i++) {
1857 seg2->
polys = polys + (seg1->
polys - s.polys);
1862 seg2->
model = model;
1874 int len =
sizeof(name);
1876 ZeroMemory(name, len);
1877 strncpy_s(name, n, len-1);
1913 if (!vertex_set && !vloc) {
1914 vertex_set =
new(__FILE__,__LINE__)
VertexSet(nverts);
1915 vloc =
new(__FILE__,__LINE__)
Vec3[nverts];
1922 if (!polys && !npolys) {
1924 polys =
new(__FILE__,__LINE__)
Poly[npolys];
1926 ZeroMemory(polys, npolys *
sizeof(
Poly));
1935 if ( polys && vertex_set &&
1939 int newverts = nv + vertex_set->
nverts;
1940 int newpolys = np + npolys;
1942 vertex_set->
Resize(newverts,
true);
1944 Poly* pset =
new(__FILE__,__LINE__)
Poly[newpolys];
1945 Poly* pnew = pset + npolys;
1947 CopyMemory(pset, polys, npolys *
sizeof(
Poly));
1948 ZeroMemory(pnew, np *
sizeof(
Poly));
1950 if (segments.
size() > 0) {
1954 for (
int i = 0; i < np; i++) {
1971 if (!vertex_set || vertex_set->
nverts < 3)
1978 for (i = 0; i < npolys; i++) {
1979 Poly* p = polys + i;
1988 for (i = 0; i < npolys; i++) {
1989 Poly* p = polys + i;
1992 for (j = 0; j < p->
nverts; j++) {
1993 int vsrc = p->
verts[j];
1995 vset->
loc[v] = vertex_set->
loc[vsrc];
1996 vset->
nrm[v] = vertex_set->
nrm[vsrc];
1997 vset->
tu[v] = vertex_set->
tu[vsrc];
1998 vset->
tv[v] = vertex_set->
tv[vsrc];
1999 vset->
rw[v] = vertex_set->
rw[vsrc];
2016 vloc =
new(__FILE__,__LINE__)
Vec3[nverts];
2027 static bool MatchVerts(
VertexSet* vset,
int i,
int j)
2030 const Vec3& vl1 = vset->
loc[i];
2031 const Vec3& vn1 = vset->
nrm[i];
2032 float tu1 = vset->
tu[i];
2033 float tv1 = vset->
tv[i];
2034 const Vec3& vl2 = vset->
loc[j];
2035 const Vec3& vn2 = vset->
nrm[j];
2036 float tu2 = vset->
tu[j];
2037 float tv2 = vset->
tv[j];
2039 d = fabs(vl1.
x - vl2.
x);
2040 if (d > SELECT_EPSILON)
2043 d = fabs(vl1.
y - vl2.
y);
2044 if (d > SELECT_EPSILON)
2047 d = fabs(vl1.
z - vl2.
z);
2048 if (d > SELECT_EPSILON)
2051 d = fabs(vn1.
x - vn2.
x);
2052 if (d > SELECT_EPSILON)
2055 d = fabs(vn1.
y - vn2.
y);
2056 if (d > SELECT_EPSILON)
2059 d = fabs(vn1.
z - vn2.
z);
2060 if (d > SELECT_EPSILON)
2063 d = fabs(tu1 - tu2);
2064 if (d > SELECT_TEXTURE)
2067 d = fabs(tv1 - tv2);
2068 if (d > SELECT_TEXTURE)
2077 if (!vertex_set || vertex_set->
nverts < 3)
2080 int nverts = vertex_set->
nverts;
2086 BYTE* vert_map =
new BYTE[nverts];
2087 WORD* vert_dst =
new WORD[nverts];
2088 ZeroMemory(vert_map, nverts *
sizeof(BYTE));
2089 ZeroMemory(vert_dst, nverts *
sizeof(WORD));
2092 for (
int i = 0; i < npolys; i++) {
2093 Poly* p = polys + i;
2095 for (
int j = 0; j < p->
nverts; j++) {
2096 WORD vert = p->
verts[j];
2098 if (vert < nverts) {
2110 for (
int i = 0; i < nverts; i++) {
2111 if (vert_map[i] == 0)
continue;
2114 vset->
loc[v] = vertex_set->
loc[i];
2115 vset->
nrm[v] = vertex_set->
nrm[i];
2116 vset->
tu[v] = vertex_set->
tu[i];
2117 vset->
tv[v] = vertex_set->
tv[i];
2118 vset->
rw[v] = vertex_set->
rw[i];
2122 for (
int j = i+1; j < nverts; j++) {
2123 if (vert_map[j] == 0)
continue;
2125 if (MatchVerts(vertex_set, i, j)) {
2138 for (
int n = 0; n < npolys; n++) {
2139 Poly* p = polys + n;
2141 for (
int v = 0; v < p->
nverts; v++) {
2147 if (vset &&
final < nverts) {
2150 vset->
Resize(
final,
true);
2160 vloc =
new(__FILE__,__LINE__)
Vec3[nverts];
2173 if (vertex_set && vertex_set->
nverts) {
2174 for (
int i = 0; i < vertex_set->
nverts; i++) {
2175 vertex_set->
loc[i] *= (float) factor;
2185 if (npolys < 1 || !vertex_set || vertex_set->nverts < 1)
2190 for (
int i = 0; i < npolys; i++) {
2191 Poly* p = polys + i;
2193 for (
int n = 0; n < p->
nverts; n++) {
2194 WORD v = p->
verts[n];
2197 for (h = 0; h < nhull; h++) {
2198 Vec3& vl = vertex_set->
loc[v];
2199 Vec3& loc = vloc[h];
2201 double d = vl.
x - loc.
x;
2203 if (d < -SELECT_EPSILON || d > SELECT_EPSILON)
2208 if (d < -SELECT_EPSILON || d > SELECT_EPSILON)
2213 if (d < -SELECT_EPSILON || d > SELECT_EPSILON)
2222 vloc[h] = vertex_set->
loc[v];
2230 if (use_collision_detection)
2239 if (npolys < 1 || !vertex_set || vertex_set->nverts < 1)
2244 for (
int i = 0; i < npolys; i++) {
2245 Poly* p = polys + i;
2255 for (
int v = 0; v < vertex_set->
nverts; v++) {
2260 vertex_set->
nrm[v] =
Vec3(0.0f, 0.0f, 0.0f);
2262 for (
int i = 0; i < faces.
size(); i++) {
2263 vertex_set->
nrm[v] += faces[i]->plane.normal;
2269 else if (vertex_set->
loc[v].
length() > 0) {
2270 vertex_set->
nrm[v] = vertex_set->
loc[v];
2275 vertex_set->
nrm[v] =
Vec3(0.0f, 1.0f, 0.0f);
2281 for (
int i = 0; i < npolys; i++) {
2282 Poly* p = polys + i;
2284 for (
int n = 0; n < p->
nverts; n++) {
2285 int v = p->
verts[n];
2296 const double SELECT_EPSILON = 0.05;
2298 for (
int i = 0; i < npolys; i++) {
2299 Poly* p = polys + i;
2301 for (
int n = 0; n < p->
nverts; n++) {
2302 int v = p->
verts[n];
2303 Vec3& vl = vertex_set->
loc[v];
2304 double d = vl.
x - loc.
x;
2306 if (d < -SELECT_EPSILON || d > SELECT_EPSILON)
2311 if (d < -SELECT_EPSILON || d > SELECT_EPSILON)
2316 if (d < -SELECT_EPSILON || d > SELECT_EPSILON)
2328 for (
int i = 0; i < npolys; i++) {
2329 Poly* p = polys + i;
2344 if (!vertex_set || !vertex_set->
nverts)
2352 for (
int i = 0; i < npolys; i++) {
2353 Poly* p = polys + i;
2357 for (
int n = 0; n < p->
nverts; n++) {
2385 float denom = s1*t2 - s2*t1;
2387 if (fabsf(denom) > 0.0001f)
2390 tangent.
x = (t2*P.
x - t1*Q.
x) * tmp;
2391 tangent.
y = (t2*P.
y - t1*Q.
y) * tmp;
2392 tangent.
z = (t2*P.
z - t1*Q.
z) * tmp;
2396 binormal.
x = (s1*Q.
x - s2*P.
x) * tmp;
2397 binormal.
y = (s1*Q.
y - s2*P.
y) * tmp;
2398 binormal.
z = (s1*Q.
z - s2*P.
z) * tmp;
2415 ZeroMemory(
this,
sizeof(
Segment));
2419 : npolys(n), polys(p), material(mtl), model(mod), video_data(0)
2427 ZeroMemory(
this,
sizeof(
Segment));
2435 : model(0), pname(0), pnverts(0), pnpolys(0), pradius(0)