1 /*
2  * Copyright 2011-2012 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23 
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25 
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28 
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31 
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code.  If not, see
33 <http://www.gnu.org/licenses/>.
34 
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38 
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 // Code: Cyril Meynier
44 //
45 // Copyright (c) 1999-2000 ARKANE Studios SA. All rights reserved
46 
47 #include "scene/Scene.h"
48 
49 #include <cstdio>
50 
51 #include "ai/Paths.h"
52 
53 #include "animation/Animation.h"
54 
55 #include "core/Application.h"
56 #include "core/GameTime.h"
57 #include "core/Core.h"
58 
59 #include "game/EntityManager.h"
60 #include "game/Inventory.h"
61 #include "game/Player.h"
62 #include "game/Spells.h"
63 
64 #include "gui/Interface.h"
65 
66 #include "graphics/Draw.h"
67 #include "graphics/GraphicsModes.h"
68 #include "graphics/Math.h"
69 #include "graphics/VertexBuffer.h"
70 #include "graphics/data/TextureContainer.h"
71 #include "graphics/effects/DrawEffects.h"
72 #include "graphics/particle/ParticleEffects.h"
73 #include "graphics/texture/TextureStage.h"
74 
75 #include "input/Input.h"
76 
77 #include "io/log/Logger.h"
78 
79 #include "scene/Light.h"
80 #include "scene/Interactive.h"
81 
82 using std::vector;
83 
84 //-----------------------------------------------------------------------------
85 #define MAX_OUT 4
86 #define VAL_THRESHOLD 100.f
87 #define PASSS 0.5f
88 #define PASS 50.f
89 
90 //-----------------------------------------------------------------------------
91 extern long USE_LIGHT_OPTIM;
92 extern EERIE_3DOBJ * eyeballobj;
93 extern long NEED_TEST_TEXT;
94 extern long EXTERNALVIEW;
95 long LAST_PORTALS_COUNT=0;
96 //-----------------------------------------------------------------------------
97 extern TextureContainer *enviro;
98 extern long ZMAPMODE;
99 extern Color ulBKGColor;
100 
101 EERIEPOLY * TransPol[MAX_TRANSPOL];
102 
103 EERIE_PORTAL_DATA * portals = NULL;
104 
105 static float WATEREFFECT = 0.f;
106 
107 long TRANSPOLYSPOS=0;
108 long FRAME_COUNT=0;
109 
110 long LAST_ROOM=-1;
111 
112 CircularVertexBuffer<SMY_VERTEX3> * pDynamicVertexBuffer;
113 
114 namespace {
115 
116 struct DynamicVertexBuffer {
117 
118 private:
119 
120 	SMY_VERTEX3 * vertices;
121 	size_t start;
122 
123 public:
124 
125 	size_t nbindices;
126 	unsigned short * indices;
127 	size_t offset;
128 
DynamicVertexBuffer__anonb45ffd2a0111::DynamicVertexBuffer129 	DynamicVertexBuffer() : vertices(NULL), nbindices(0), indices(NULL) { }
130 
lock__anonb45ffd2a0111::DynamicVertexBuffer131 	void lock() {
132 
133 		arx_assert(!vertices);
134 
135 		if(!indices) {
136 			indices = new unsigned short[4 * pDynamicVertexBuffer->vb->capacity()];
137 			start = 0;
138 		}
139 
140 		BufferFlags flags = (pDynamicVertexBuffer->pos == 0) ? DiscardBuffer : NoOverwrite | DiscardRange;
141 
142 		vertices =  pDynamicVertexBuffer->vb->lock(flags, pDynamicVertexBuffer->pos);
143 		offset = 0;
144 	}
145 
append__anonb45ffd2a0111::DynamicVertexBuffer146 	SMY_VERTEX3 * append(size_t nbvertices) {
147 
148 		arx_assert(vertices);
149 
150 		if(pDynamicVertexBuffer->pos + nbvertices > pDynamicVertexBuffer->vb->capacity()) {
151 			return NULL;
152 		}
153 
154 		SMY_VERTEX3 * pos = vertices + offset;
155 
156 		pDynamicVertexBuffer->pos += nbvertices, offset += nbvertices;
157 
158 		return pos;
159 	}
160 
unlock__anonb45ffd2a0111::DynamicVertexBuffer161 	void unlock() {
162 		arx_assert(vertices);
163 		pDynamicVertexBuffer->vb->unlock(), vertices = NULL;
164 	}
165 
draw__anonb45ffd2a0111::DynamicVertexBuffer166 	void draw(Renderer::Primitive primitive) {
167 		arx_assert(!vertices);
168 		pDynamicVertexBuffer->vb->drawIndexed(primitive, pDynamicVertexBuffer->pos - start, start, indices, nbindices);
169 	}
170 
done__anonb45ffd2a0111::DynamicVertexBuffer171 	void done() {
172 		arx_assert(!vertices);
173 		start = pDynamicVertexBuffer->pos;
174 		nbindices = 0;
175 	}
176 
reset__anonb45ffd2a0111::DynamicVertexBuffer177 	void reset() {
178 		arx_assert(!vertices);
179 		start = pDynamicVertexBuffer->pos = 0;
180 		nbindices = 0;
181 	}
182 
~DynamicVertexBuffer__anonb45ffd2a0111::DynamicVertexBuffer183 	~DynamicVertexBuffer() {
184 		delete[] indices;
185 	}
186 
187 } dynamicVertices;
188 
189 }
190 
191 EERIE_FRUSTRUM_PLANE efpPlaneNear;
192 
193 static vector<EERIEPOLY*> vPolyWater;
194 static vector<EERIEPOLY*> vPolyLava;
195 
196 bool bOLD_CLIPP=false;
197 
198 void PopAllTriangleListTransparency();
199 
200 static PORTAL_ROOM_DRAW * RoomDraw = NULL;
201 static long NbRoomDraw = 0;
202 static long * RoomDrawList = NULL;
203 static long NbRoomDrawList = 0;
204 long TotalRoomDrawList=0;
205 
206 //*************************************************************************************
207 //*************************************************************************************
ApplyWaterFXToVertex(Vec3f * odtv,TexturedVertex * dtv,float power)208 void ApplyWaterFXToVertex(Vec3f * odtv,TexturedVertex * dtv,float power)
209 {
210 	power=power*0.05f;
211 	dtv->uv.x+=EEsin((WATEREFFECT+odtv->x))*power;
212 	dtv->uv.y+=EEcos((WATEREFFECT+odtv->z))*power;
213 }
214 
ApplyLavaGlowToVertex(Vec3f * odtv,TexturedVertex * dtv,float power)215 static void ApplyLavaGlowToVertex(Vec3f * odtv,TexturedVertex * dtv, float power) {
216 	float f;
217 	long lr, lg, lb;
218 	power = 1.f - (EEsin((WATEREFFECT+odtv->x+odtv->z)) * 0.05f) * power;
219 	f = ((dtv->color >> 16) & 255) * power;
220 	lr = clipByte(f);
221 
222 	f = ((dtv->color >> 8) & 255) * power;
223 	lg = clipByte(f);
224 
225 	f = ((dtv->color) & 255) * power;
226 	lb = clipByte(f);
227 
228 	dtv->color=0xFF000000L | (lr << 16) | (lg << 8) | lb;
229 }
230 
ManageLavaWater(EERIEPOLY * ep,const long to,const unsigned long tim)231 void ManageLavaWater(EERIEPOLY * ep, const long to, const unsigned long tim)
232 {
233 	if ((ep->type & POLY_WATER) || (ep->type & POLY_LAVA) )
234 	{
235 		for(long k = 0; k < to; k++) {
236 			ep->tv[k].uv = ep->v[k].uv;
237 			if(ep->type & POLY_LAVA) {
238 				ApplyWaterFXToVertex(&ep->v[k].p, &ep->tv[k], 0.35f);
239 				ApplyLavaGlowToVertex(&ep->v[k].p,&ep->tv[k],0.6f);
240 			} else {
241 				ApplyWaterFXToVertex(&ep->v[k].p,&ep->tv[k],0.35f);
242 			}
243 		}
244 	}
245 
246 	if (ep->type & POLY_FALL)
247 	{
248 		if (ep->type & POLY_LAVA)
249 			for (long k=0;k<to;k++)
250 			{
251 				ep->tv[k].uv.y-=(float)(tim)*( 1.0f / 12000 );
252 			}
253 			else
254 				for (long k=0;k<to;k++)
255 				{
256 					ep->tv[k].uv.y-=(float)(tim)*( 1.0f / 1000 );
257 				}
258 	}
259 }
260 
ManageWater_VertexBuffer(EERIEPOLY * ep,const long to,const unsigned long tim,SMY_VERTEX * _pVertex)261 void ManageWater_VertexBuffer(EERIEPOLY * ep, const long to, const unsigned long tim, SMY_VERTEX * _pVertex) {
262 
263 	for (long k=0;k<to;k++)
264 	{
265 		ep->tv[k].uv = ep->v[k].uv;
266 
267 		ApplyWaterFXToVertex(&ep->v[k].p,&ep->tv[k],0.35f);
268 
269 		if(ep->type&POLY_FALL)
270 		{
271 			ep->tv[k].uv.y-=(float)(tim)*( 1.0f / 1000 );
272 		}
273 
274 		_pVertex[ep->uslInd[k]].uv = ep->tv[k].uv;
275 	}
276 }
277 
ManageLava_VertexBuffer(EERIEPOLY * ep,const long to,const unsigned long tim,SMY_VERTEX * _pVertex)278 void ManageLava_VertexBuffer(EERIEPOLY * ep, const long to, const unsigned long tim, SMY_VERTEX * _pVertex) {
279 
280 	for (long k=0;k<to;k++)
281 	{
282 		ep->tv[k].uv = ep->v[k].uv;
283 
284 		ApplyWaterFXToVertex(&ep->v[k].p, &ep->tv[k], 0.35f); //0.25f
285 		ApplyLavaGlowToVertex(&ep->v[k].p, &ep->tv[k], 0.6f);
286 
287 		if(ep->type&POLY_FALL)
288 		{
289 			ep->tv[k].uv.y-=(float)(tim)*( 1.0f / 12000 );
290 		}
291 
292 		_pVertex[ep->uslInd[k]].uv = ep->tv[k].uv;
293 	}
294 }
295 
296 
297 
298 extern EERIEMATRIX ProjectionMatrix;
specialEE_RTP2(TexturedVertex * in,TexturedVertex * out)299 void specialEE_RTP2(TexturedVertex * in, TexturedVertex * out) {
300 
301 	EERIE_TRANSFORM * et = (EERIE_TRANSFORM *)&ACTIVECAM->transform;
302 	out->p = in->p - et->pos;
303 
304 	float temp = (out->p.z * et->ycos) - (out->p.x * et->ysin);
305 	out->p.x = (out->p.z * et->ysin) + (out->p.x * et->ycos);
306 	out->p.z = (out->p.y * et->xsin) + (temp * et->xcos);
307 	out->p.y = (out->p.y * et->xcos) - (temp * et->xsin);
308 
309 	float fZTemp = 1.f / out->p.z;
310 
311 	out->p.z = fZTemp * ProjectionMatrix._33 + ProjectionMatrix._43;
312 	out->p.x = out->p.x * ProjectionMatrix._11 * fZTemp + et->mod.x;
313 	out->p.y = out->p.y * ProjectionMatrix._22 * fZTemp + et->mod.y;
314 	out->rhw = fZTemp;
315 }
316 
EERIERTPPoly2(EERIEPOLY * ep)317 long EERIERTPPoly2(EERIEPOLY *ep)
318 {
319 	specialEE_RTP2(&ep->v[0],&ep->tv[0]);
320 	specialEE_RTP2(&ep->v[1],&ep->tv[1]);
321 	specialEE_RTP2(&ep->v[2],&ep->tv[2]);
322 
323 	if (ep->type & POLY_QUAD) specialEE_RTP2(&ep->v[3],&ep->tv[3]);
324 	else ep->tv[3].p.z=1.f;
325 
326 	if ((ep->tv[0].p.z<=0.f) &&
327 		(ep->tv[1].p.z<=0.f) &&
328 		(ep->tv[2].p.z<=0.f) &&
329 		(ep->tv[3].p.z<=0.f) ) return 0;
330 
331 	return 1;
332 }
333 
334 
335 bool IsSphereInFrustrum(float radius,Vec3f * point,EERIE_FRUSTRUM * frustrum);
FrustrumsClipSphere(EERIE_FRUSTRUM_DATA * frustrums,EERIE_SPHERE * sphere)336 bool FrustrumsClipSphere(EERIE_FRUSTRUM_DATA * frustrums,EERIE_SPHERE * sphere)
337 {
338 	float dists=sphere->origin.x*efpPlaneNear.a + sphere->origin.y*efpPlaneNear.b + sphere->origin.z*efpPlaneNear.c + efpPlaneNear.d;
339 
340 	if (dists+sphere->radius>0)
341 	{
342 		for (long i=0;i<frustrums->nb_frustrums;i++)
343 		{
344 			if (IsSphereInFrustrum(sphere->radius, &sphere->origin, &frustrums->frustrums[i]))
345 				return false;
346 		}
347 	}
348 
349 	return true;
350 }
351 
VisibleSphere(float x,float y,float z,float radius)352 bool VisibleSphere(float x, float y, float z, float radius) {
353 
354 	Vec3f pos(x, y, z);
355 	if(distSqr(pos, ACTIVECAM->pos) > square(ACTIVECAM->cdepth*0.5f + radius))
356 		return false;
357 
358 	long room_num = ARX_PORTALS_GetRoomNumForPosition(&pos);
359 
360 	if (room_num>=0)
361 	{
362 		EERIE_SPHERE sphere;
363 		sphere.origin = pos;
364 		sphere.radius = radius;
365 
366 		EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum;
367 
368 		if (FrustrumsClipSphere(frustrums,&sphere))
369 			return false;
370 	}
371 
372 	return true;
373 }
374 bool IsInFrustrum(Vec3f * point,EERIE_FRUSTRUM * frustrum);
375 
IsBBoxInFrustrum(EERIE_3D_BBOX * bbox,EERIE_FRUSTRUM * frustrum)376 bool IsBBoxInFrustrum(EERIE_3D_BBOX * bbox, EERIE_FRUSTRUM * frustrum) {
377 
378 	Vec3f point = bbox->min;
379 	if(IsInFrustrum(&point, frustrum)) {
380 		return true;
381 	}
382 
383 	point = Vec3f(bbox->max.x, bbox->min.y, bbox->min.z);
384 	if(IsInFrustrum(&point, frustrum)) {
385 		return true;
386 	}
387 
388 	point = Vec3f(bbox->max.x, bbox->max.y, bbox->min.z);
389 	if(IsInFrustrum(&point, frustrum)) {
390 		return true;
391 	}
392 
393 	point = Vec3f(bbox->min.x, bbox->max.y, bbox->min.z);
394 	if(IsInFrustrum(&point, frustrum)) {
395 		return true;
396 	}
397 
398 	point = Vec3f(bbox->min.x, bbox->min.y, bbox->max.z);
399 	if(IsInFrustrum(&point, frustrum)) {
400 		return true;
401 	}
402 
403 	point = Vec3f(bbox->max.x, bbox->min.y, bbox->max.z);
404 	if(IsInFrustrum(&point, frustrum)) {
405 		return true;
406 	}
407 
408 	point = bbox->max;
409 	if(IsInFrustrum(&point, frustrum)) {
410 		return true;
411 	}
412 
413 	point = Vec3f(bbox->min.x, bbox->max.y, bbox->max.z);
414 	if(IsInFrustrum(&point, frustrum)) {
415 		return true;
416 	}
417 
418 	return	false;
419 }
420 
FrustrumsClipBBox3D(EERIE_FRUSTRUM_DATA * frustrums,EERIE_3D_BBOX * bbox)421 bool FrustrumsClipBBox3D(EERIE_FRUSTRUM_DATA * frustrums,EERIE_3D_BBOX * bbox)
422 {
423 	for (long i=0;i<frustrums->nb_frustrums;i++)
424 	{
425 		if (IsBBoxInFrustrum(bbox,&frustrums->frustrums[i]))
426 			return false;
427 	}
428 
429 	return false;
430 }
431 
ARX_SCENE_PORTAL_Basic_ClipIO(Entity * io)432 bool ARX_SCENE_PORTAL_Basic_ClipIO(Entity * io) {
433 
434 	if(EDITMODE || io == entities.player() || (io->ioflags & IO_FORCEDRAW)) {
435 		return false;
436 	}
437 
438 	if (USE_PORTALS && portals)
439 	{
440 		Vec3f posi;
441 		posi.x=io->pos.x;
442 		posi.y=io->pos.y-20;
443 		posi.z=io->pos.z;
444 
445 		if (io->room_flags & 1)
446 			UpdateIORoom(io);
447 
448 		long room_num = io->room;
449 
450 		{
451 			if (room_num==-1)
452 			{
453 				posi.y=io->pos.y-120;
454 				room_num=ARX_PORTALS_GetRoomNumForPosition(&posi);
455 			}
456 
457 			if (	(room_num>=0)
458 				&&	(RoomDraw)
459 				&&	(RoomDraw[room_num].count))
460 			{
461 
462 			switch (USE_PORTALS)
463 			{
464 				case 2:
465 				case 3:
466 				case 4:
467 					EERIE_SPHERE sphere;
468 
469 					if (io->ioflags & IO_ITEM)
470 					{
471 						sphere.origin.x=io->pos.x;
472 						sphere.origin.y=io->pos.y-40.f;
473 						sphere.origin.z=io->pos.z;
474 
475 						if (io->ioflags & IO_MOVABLE)
476 							sphere.radius=160.f;
477 							else sphere.radius = 75.f;
478 					}
479 					else if (io->ioflags & IO_FIX)
480 					{
481 						sphere.origin.x=io->pos.x;
482 						sphere.origin.y=io->pos.y-60.f;
483 						sphere.origin.z=io->pos.z;
484 						sphere.radius=340.f;
485 					}
486 					else if (io->ioflags & IO_NPC)
487 					{
488 						sphere.origin.x=io->pos.x;
489 						sphere.origin.y=io->pos.y-120.f;
490 						sphere.origin.z=io->pos.z;
491 						sphere.radius=120.f;
492 					}
493 
494 					EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum;
495 
496 					if (FrustrumsClipSphere(frustrums,&sphere))
497 					{
498 						if (io)
499 						{
500 							io->bbox1.x=(short)-1;
501 							io->bbox2.x=(short)-1;
502 							io->bbox1.y=(short)-1;
503 							io->bbox2.y=(short)-1;
504 						}
505 
506 						return true;
507 					}
508 			}
509 			}
510 			else return false;
511 		}
512 	}
513 
514 	return false;
515 }
516 
517 // USAGE/FUNCTION
518 //   io can be NULL if io is valid io->bbox3D contains 3D world-bbox
519 //   bboxmin & bboxmax ARE in fact 2D-screen BBOXes using only (x,y).
520 // RETURN:
521 //   return true if IO cannot be seen, false if visible
522 // TODO:
523 //   Implement all Portal Methods
524 //   Return a reduced clipbox which can be used for polys clipping in the case of partial visibility
ARX_SCENE_PORTAL_ClipIO(Entity * io,Vec3f * position)525 bool ARX_SCENE_PORTAL_ClipIO(Entity * io, Vec3f * position) {
526 
527 	if (EDITMODE) return false;
528 
529 	if (io==entities.player()) return false;
530 
531 	if ((io) && (io->ioflags & IO_FORCEDRAW)) return false;
532 
533 	if (USE_PORTALS && portals)
534 	{
535 		Vec3f posi;
536 		posi.x=position->x;
537 		posi.y=position->y-60; //20
538 		posi.z=position->z;
539 		long room_num;
540 
541 		if (io)
542 		{
543 			if (io->room_flags & 1)
544 				UpdateIORoom(io);
545 
546 			room_num=io->room;//
547 		}
548 		else
549 		{
550 			room_num=ARX_PORTALS_GetRoomNumForPosition(&posi);
551 		}
552 
553 		if (room_num==-1)
554 		{
555 			posi.y=position->y-120;
556 			room_num=ARX_PORTALS_GetRoomNumForPosition(&posi);
557 		}
558 
559 		if ((room_num >= 0) && (RoomDraw))
560 		{
561 			if (RoomDraw[room_num].count==0)
562 			{
563 				if (io)
564 				{
565 					io->bbox1.x=(short)-1;
566 					io->bbox2.x=(short)-1;
567 					io->bbox1.y=(short)-1;
568 					io->bbox2.y=(short)-1;
569 				}
570 
571 				return true;
572 			}
573 
574 			switch (USE_PORTALS)
575 			{
576 				case 1: // 2D portal
577 				{
578 					EERIE_2D_BBOX * bbox=&RoomDraw[room_num].bbox;
579 
580 					if (	bbox->min.x > BBOXMAX.x || BBOXMIN.x > bbox->max.x
581 						||	bbox->min.y > BBOXMAX.y || BBOXMIN.y > bbox->max.y)
582 					{
583 						if (io)
584 						{
585 							io->bbox1.x=(short)-1;
586 							io->bbox2.x=(short)-1;
587 							io->bbox1.y=(short)-1;
588 							io->bbox2.y=(short)-1;
589 						}
590 
591 						return true;
592 					}
593 				}
594 				break;
595 				case 2:
596 				case 3:
597 				case 4:
598 
599 					if(io) {
600 
601 						EERIE_SPHERE sphere;
602 						sphere.origin = (io->bbox3D.min + io->bbox3D.max) * .5f;
603 						sphere.radius = dist(sphere.origin, io->bbox3D.min) + 10.f;
604 
605 						EERIE_FRUSTRUM_DATA * frustrums=&RoomDraw[room_num].frustrum;
606 
607 						if (FrustrumsClipSphere(frustrums,&sphere))
608 						{
609 							if (io)
610 							{
611 								io->bbox1.x=(short)-1;
612 								io->bbox2.x=(short)-1;
613 								io->bbox1.y=(short)-1;
614 								io->bbox2.y=(short)-1;
615 							}
616 
617 							return true;
618 						}
619 
620 						if (FrustrumsClipBBox3D(frustrums,&io->bbox3D))
621 						{
622 							if (io)
623 							{
624 								io->bbox1.x=(short)-1;
625 								io->bbox2.x=(short)-1;
626 								io->bbox1.y=(short)-1;
627 								io->bbox2.y=(short)-1;
628 							}
629 
630 							return true;
631 						}
632 					}
633 
634 				break;
635 			}
636 		}
637 	}
638 
639 	return false;
640 }
641 
ARX_PORTALS_GetRoomNumForPosition2(Vec3f * pos,long flag,float * height)642 long ARX_PORTALS_GetRoomNumForPosition2(Vec3f * pos,long flag,float * height)
643 {
644 
645 	EERIEPOLY * ep;
646 
647 	if (flag & 1)
648 	{
649 		ep=CheckInPolyPrecis(pos->x,pos->y-150.f,pos->z);
650 
651 		if (!ep)
652 			ep=CheckInPolyPrecis(pos->x,pos->y-1.f,pos->z);
653 	}
654 	else
655 		ep=CheckInPoly(pos->x,pos->y,pos->z);
656 
657 	if ((ep) && (ep->room>-1))
658 	{
659 		if (height) *height=ep->center.y;
660 
661 		return ep->room;
662 	}
663 
664 	// Security... ?
665 	ep=GetMinPoly(pos->x,pos->y,pos->z);
666 
667 	if ((ep) && (ep->room>-1))
668 	{
669 		if (height) *height=ep->center.y;
670 
671 		return ep->room;
672 	}
673 	else if (!(flag & 1))
674 	{
675 		ep=CheckInPolyPrecis(pos->x,pos->y,pos->z);
676 
677 		if ((ep) && (ep->room>-1))
678 		{
679 			if (height) *height=ep->center.y;
680 
681 			return ep->room;
682 		}
683 	}
684 
685 	if (flag & 2)
686 	{
687 		float off=20.f;
688 		ep=CheckInPolyPrecis(pos->x-off,pos->y-off,pos->z);
689 
690 		if ((ep) && (ep->room>-1))
691 		{
692 			if (height) *height=ep->center.y;
693 
694 			return ep->room;
695 		}
696 
697 		ep=CheckInPolyPrecis(pos->x-off,pos->y-20,pos->z-off);
698 
699 		if ((ep) && (ep->room>-1))
700 		{
701 			if (height) *height=ep->center.y;
702 
703 			return ep->room;
704 		}
705 
706 		ep=CheckInPolyPrecis(pos->x-off,pos->y-20,pos->z+off);
707 
708 		if ((ep) && (ep->room>-1))
709 		{
710 			if (height) *height=ep->center.y;
711 
712 			return ep->room;
713 		}
714 
715 		ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z);
716 
717 		if ((ep) && (ep->room>-1))
718 		{
719 			if (height) *height=ep->center.y;
720 
721 			return ep->room;
722 		}
723 
724 		ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z+off);
725 
726 		if ((ep) && (ep->room>-1))
727 		{
728 			if (height) *height=ep->center.y;
729 
730 			return ep->room;
731 		}
732 
733 		ep=CheckInPolyPrecis(pos->x+off,pos->y-20,pos->z-off);
734 
735 		if ((ep) && (ep->room>-1))
736 		{
737 			if (height) *height=ep->center.y;
738 
739 			return ep->room;
740 		}
741 
742 	}
743 
744 	return -1;
745 }
ARX_PORTALS_GetRoomNumForCamera(float * height)746 long ARX_PORTALS_GetRoomNumForCamera(float * height)
747 {
748 	EERIEPOLY * ep;
749 	ep=CheckInPolyPrecis(ACTIVECAM->pos.x,ACTIVECAM->pos.y,ACTIVECAM->pos.z);
750 
751 	if ((ep) && (ep->room>-1))
752 	{
753 		if (height) *height=ep->center.y;
754 
755 		return ep->room;
756 	}
757 
758 	ep=GetMinPoly(ACTIVECAM->pos.x,ACTIVECAM->pos.y,ACTIVECAM->pos.z);
759 
760 	if ((ep) && (ep->room>-1))
761 	{
762 		if (height) *height=ep->center.y;
763 
764 		return ep->room;
765 	}
766 
767 	float dist=0.f;
768 
769 	while (dist<=20.f)
770 	{
771 		float vvv=radians(ACTIVECAM->angle.b);
772 		ep=CheckInPolyPrecis(	ACTIVECAM->pos.x+EEsin(vvv)*dist,
773 								ACTIVECAM->pos.y,
774 								ACTIVECAM->pos.z-EEcos(vvv)*dist);
775 
776 		if ((ep) && (ep->room>-1))
777 		{
778 			if (height) *height=ep->center.y;
779 
780 			return ep->room;
781 		}
782 
783 		dist+=5.f;
784 	}
785 
786 	return -1;
787 }
788 // flag==1 for player
ARX_PORTALS_GetRoomNumForPosition(Vec3f * pos,long flag)789 long ARX_PORTALS_GetRoomNumForPosition(Vec3f * pos,long flag)
790 {
791 	long num;
792 	float height;
793 
794 	if (flag & 1)
795 		num=ARX_PORTALS_GetRoomNumForCamera(&height);
796 	else
797 		num=ARX_PORTALS_GetRoomNumForPosition2(pos,flag,&height);
798 
799 	if (num > -1)
800 	{
801 		long nearest=-1;
802 		float nearest_dist=99999.f;
803 
804 		for (long n=0;n<portals->nb_rooms;n++)
805 		{
806 			for (long lll=0;lll<portals->room[n].nb_portals;lll++)
807 			{
808 				EERIE_PORTALS * po=	&portals->portals[portals->room[n].portals[lll]];
809 				EERIEPOLY *		epp=&po->poly;
810 
811 				if (PointIn2DPolyXZ(epp, pos->x, pos->z))
812 				{
813 					float yy;
814 
815 					if (GetTruePolyY(epp,pos,&yy))
816 					{
817 						if (height>yy)
818 						{
819 							if ((yy>=pos->y) && (yy-pos->y<nearest_dist))
820 							{
821 								if (epp->norm.y>0)
822 									nearest=po->room_2;
823 								else
824 									nearest=po->room_1;
825 
826 								nearest_dist=yy-pos->y;
827 							}
828 						}
829 					}
830 				}
831 			}
832 		}
833 
834 		if (nearest>-1)
835 		num=nearest;
836 	}
837 
838 	return num;
839 			}
840 
ARX_PORTALS_InitDrawnRooms()841 void ARX_PORTALS_InitDrawnRooms()
842 {
843 	if (!portals) return;
844 
845 	EERIE_PORTALS *ep = &portals->portals[0];
846 
847 	for (long i=0;i<portals->nb_total;i++)
848 	{
849 		ep->useportal=0;
850 		ep++;
851 	}
852 
853 
854 	if ((RoomDraw==NULL) || (NbRoomDraw<portals->nb_rooms+1))
855 	{
856 		RoomDraw=(PORTAL_ROOM_DRAW *)realloc(RoomDraw,sizeof(PORTAL_ROOM_DRAW)*(portals->nb_rooms+1));
857 
858 		if (RoomDraw)
859 		{
860 			NbRoomDraw=portals->nb_rooms+1;
861 		}
862 	}
863 
864 	if (RoomDraw)
865 	{
866 		for (long i=0;i<NbRoomDraw;i++)
867 		{
868 			RoomDraw[i].count=0;
869 			RoomDraw[i].flags=0;
870 			RoomDraw[i].frustrum.nb_frustrums=0;
871 		}
872 	}
873 
874 	vPolyWater.clear();
875 	vPolyLava.clear();
876 
877 	if(pDynamicVertexBuffer) {
878 		pDynamicVertexBuffer->vb->setData(NULL, 0, 0, DiscardBuffer);
879 		dynamicVertices.reset();
880 	}
881 
882 }
BBoxClipPoly(EERIE_2D_BBOX * bbox,EERIEPOLY * ep)883 bool BBoxClipPoly(EERIE_2D_BBOX * bbox,EERIEPOLY * ep)
884 {
885 	EERIE_2D_BBOX n_bbox;
886 	long nbv;
887 
888 	if (ep->type & POLY_QUAD)
889 		nbv=4;
890 	else
891 		nbv=3;
892 
893 	n_bbox.max.x=n_bbox.min.x=ep->tv[0].p.x;
894 	n_bbox.max.y=n_bbox.min.y=ep->tv[0].p.y;
895 
896 	for (long i=1;i<nbv;i++)
897 	{
898 		n_bbox.min.x=min(n_bbox.min.x , ep->tv[i].p.x);
899 		n_bbox.min.y=min(n_bbox.min.y , ep->tv[i].p.y);
900 		n_bbox.max.x=max(n_bbox.max.x , ep->tv[i].p.x);
901 		n_bbox.max.y=max(n_bbox.max.y , ep->tv[i].p.y);
902 	}
903 
904 	if (	bbox->min.x > n_bbox.max.x || n_bbox.min.x > bbox->max.x
905 		||	bbox->min.y > n_bbox.max.y || n_bbox.min.y > bbox->max.y)
906 		return true;
907 
908 	return false;
909 
910 }
IsInFrustrum(Vec3f * point,EERIE_FRUSTRUM * frustrum)911 bool IsInFrustrum(Vec3f * point,EERIE_FRUSTRUM * frustrum)
912 {
913 	if (	((point->x*frustrum->plane[0].a + point->y*frustrum->plane[0].b + point->z*frustrum->plane[0].c + frustrum->plane[0].d)>0)
914 		&&	((point->x*frustrum->plane[1].a + point->y*frustrum->plane[1].b + point->z*frustrum->plane[1].c + frustrum->plane[1].d)>0)
915 		&&	((point->x*frustrum->plane[2].a + point->y*frustrum->plane[2].b + point->z*frustrum->plane[2].c + frustrum->plane[2].d)>0)
916 		&&	((point->x*frustrum->plane[3].a + point->y*frustrum->plane[3].b + point->z*frustrum->plane[3].c + frustrum->plane[3].d)>0) )
917 		return true;
918 
919 	return false;
920 }
921 
922 
IsSphereInFrustrum(float radius,Vec3f * point,EERIE_FRUSTRUM * frustrum)923 bool IsSphereInFrustrum(float radius,Vec3f * point,EERIE_FRUSTRUM * frustrum)
924 {
925 	float dists[4];
926 	dists[0]=point->x*frustrum->plane[0].a + point->y*frustrum->plane[0].b + point->z*frustrum->plane[0].c + frustrum->plane[0].d;
927 	dists[1]=point->x*frustrum->plane[1].a + point->y*frustrum->plane[1].b + point->z*frustrum->plane[1].c + frustrum->plane[1].d;
928 	dists[2]=point->x*frustrum->plane[2].a + point->y*frustrum->plane[2].b + point->z*frustrum->plane[2].c + frustrum->plane[2].d;
929 	dists[3]=point->x*frustrum->plane[3].a + point->y*frustrum->plane[3].b + point->z*frustrum->plane[3].c + frustrum->plane[3].d;
930 
931 	if (	(dists[0]+radius>0)
932 		&&	(dists[1]+radius>0)
933 		&&	(dists[2]+radius>0)
934 		&&	(dists[3]+radius>0) )
935 		return true;
936 
937 	return false;
938 
939 }
940 
FrustrumsClipPoly(EERIE_FRUSTRUM_DATA * frustrums,EERIEPOLY * ep)941 bool FrustrumsClipPoly(EERIE_FRUSTRUM_DATA * frustrums,EERIEPOLY * ep)
942 {
943 	for (long i=0;i<frustrums->nb_frustrums;i++)
944 	{
945 		if (IsSphereInFrustrum(ep->v[0].rhw, &ep->center, &frustrums->frustrums[i]))
946 			return false;
947 			}
948 
949 	return true;
950 }
951 
952 
ARX_PORTALS_BlendBBox(long room_num,EERIE_2D_BBOX * bbox)953 void ARX_PORTALS_BlendBBox(long room_num,EERIE_2D_BBOX * bbox) {
954 	if(RoomDraw[room_num].count == 0) {
955 		RoomDraw[room_num].bbox.min = bbox->min;
956 		RoomDraw[room_num].bbox.max = bbox->max;
957 	} else {
958 		RoomDraw[room_num].bbox.min.x = min(RoomDraw[room_num].bbox.min.x, bbox->min.x);
959 		RoomDraw[room_num].bbox.min.y = min(RoomDraw[room_num].bbox.min.y, bbox->min.y);
960 		RoomDraw[room_num].bbox.max.x = max(RoomDraw[room_num].bbox.max.x, bbox->max.x);
961 		RoomDraw[room_num].bbox.max.y = max(RoomDraw[room_num].bbox.max.y, bbox->max.y);
962 	}
963 }
964 
Frustrum_Set(EERIE_FRUSTRUM * fr,long plane,float a,float b,float c,float d)965 void Frustrum_Set(EERIE_FRUSTRUM * fr,long plane,float a,float b,float c,float d)
966 {
967 	fr->plane[plane].a=a;
968 	fr->plane[plane].b=b;
969 	fr->plane[plane].c=c;
970 	fr->plane[plane].d=d;
971 }
972 
CreatePlane(EERIE_FRUSTRUM * frustrum,long numplane,Vec3f * orgn,Vec3f * pt1,Vec3f * pt2)973 void CreatePlane(EERIE_FRUSTRUM * frustrum,long numplane,Vec3f * orgn,Vec3f * pt1,Vec3f * pt2)
974 {
975 	float Ax, Ay, Az, Bx, By, Bz, epnlen;
976 	Ax=pt1->x-orgn->x;
977 	Ay=pt1->y-orgn->y;
978 	Az=pt1->z-orgn->z;
979 
980 	Bx=pt2->x-orgn->x;
981 	By=pt2->y-orgn->y;
982 	Bz=pt2->z-orgn->z;
983 
984 	frustrum->plane[numplane].a=Ay*Bz-Az*By;
985 	frustrum->plane[numplane].b=Az*Bx-Ax*Bz;
986 	frustrum->plane[numplane].c=Ax*By-Ay*Bx;
987 
988 	epnlen = (float)sqrt(	frustrum->plane[numplane].a * frustrum->plane[numplane].a
989 						+	frustrum->plane[numplane].b * frustrum->plane[numplane].b
990 						+	frustrum->plane[numplane].c * frustrum->plane[numplane].c	);
991 	epnlen=1.f/epnlen;
992 	frustrum->plane[numplane].a*=epnlen;
993 	frustrum->plane[numplane].b*=epnlen;
994 	frustrum->plane[numplane].c*=epnlen;
995 	frustrum->plane[numplane].d=-(	orgn->x * frustrum->plane[numplane].a +
996 									orgn->y * frustrum->plane[numplane].b +
997 									orgn->z * frustrum->plane[numplane].c		);
998 
999 
1000 }
1001 void CreateScreenFrustrum(EERIE_FRUSTRUM * frustrum);
CreateFrustrum(EERIE_FRUSTRUM * frustrum,EERIEPOLY * ep,long cull)1002 void CreateFrustrum(EERIE_FRUSTRUM * frustrum, EERIEPOLY * ep, long cull) {
1003 
1004 	long to = (ep->type & POLY_QUAD) ? 4 : 3;
1005 
1006 	if(cull) {
1007 		CreatePlane(frustrum, 0, &ACTIVECAM->pos, &ep->v[0].p, &ep->v[1].p);
1008 		CreatePlane(frustrum, 1, &ACTIVECAM->pos, &ep->v[3].p, &ep->v[2].p);
1009 		CreatePlane(frustrum, 2, &ACTIVECAM->pos, &ep->v[1].p, &ep->v[3].p);
1010 		CreatePlane(frustrum, 3, &ACTIVECAM->pos, &ep->v[2].p, &ep->v[0].p);
1011 	} else {
1012 		CreatePlane(frustrum, 0, &ACTIVECAM->pos, &ep->v[1].p, &ep->v[0].p);
1013 		CreatePlane(frustrum, 1, &ACTIVECAM->pos, &ep->v[2].p, &ep->v[3].p);
1014 		CreatePlane(frustrum, 2, &ACTIVECAM->pos, &ep->v[3].p, &ep->v[1].p);
1015 		CreatePlane(frustrum, 3, &ACTIVECAM->pos, &ep->v[0].p, &ep->v[2].p);
1016 	}
1017 
1018 	frustrum->nb = to;
1019 }
1020 
CreateScreenFrustrum(EERIE_FRUSTRUM * frustrum)1021 void CreateScreenFrustrum(EERIE_FRUSTRUM * frustrum) {
1022 
1023 	Vec3f vEyePt(ACTIVECAM->pos.x, -ACTIVECAM->pos.y, ACTIVECAM->pos.z);
1024 	Vec3f vTout(0.0f, 0.0f, 10000.0f);
1025 
1026 	Vec3f vTarget;
1027 	vTarget.y = -(vTout.z * ACTIVECAM->Xsin);
1028 	vTarget.z = -(vTout.z * ACTIVECAM->Xcos);
1029 	vTarget.x =  (vTarget.z * ACTIVECAM->Ysin);
1030 	vTarget.z = -(vTarget.z * ACTIVECAM->Ycos);
1031 	vTarget.x += ACTIVECAM->pos.x;
1032 	vTarget.y -= ACTIVECAM->pos.y;
1033 	vTarget.z += ACTIVECAM->pos.z;
1034 
1035 	Vec3f vUpVec(0.f, 1.f, 0.f);
1036 
1037 	// Set the app view matrix for normal viewing
1038 	GRenderer->SetViewMatrix(vEyePt, vTarget, vUpVec);
1039 
1040 	EERIEMATRIX matProj;
1041 	GRenderer->GetProjectionMatrix(matProj);
1042 
1043 	EERIEMATRIX matView;
1044 	GRenderer->GetViewMatrix(matView);
1045 
1046 	EERIEMATRIX matres;
1047 	MatrixMultiply(&matres, &matView, &matProj);
1048 
1049 	float a,b,c,d,n;
1050 	a=matres._14-matres._11;
1051 	b=matres._24-matres._21;
1052 	c=matres._34-matres._31;
1053 	d=matres._44-matres._41;
1054  b=-b;
1055 	n = (float)(1.f /sqrt(a*a+b*b+c*c));
1056 
1057 	Frustrum_Set(frustrum,0,a*n,b*n,c*n,d*n);
1058 	a=matres._14+matres._11;
1059 	b=matres._24+matres._21;
1060 	c=matres._34+matres._31;
1061 	d=matres._44+matres._41;
1062  b=-b;
1063 	n = (float)(1.f/sqrt(a*a+b*b+c*c));
1064 
1065 	Frustrum_Set(frustrum,1,a*n,b*n,c*n,d*n);
1066 	a=matres._14-matres._12;
1067 	b=matres._24-matres._22;
1068 	c=matres._34-matres._32;
1069 	d=matres._44-matres._42;
1070  b=-b;
1071 	n = (float)(1.f/sqrt(a*a+b*b+c*c));
1072 
1073 	Frustrum_Set(frustrum,2,a*n,b*n,c*n,d*n);
1074 	a=matres._14+matres._12;
1075 	b=matres._24+matres._22;
1076 	c=matres._34+matres._32;
1077 	d=matres._44+matres._42;
1078  b=-b;
1079 	n = (float)(1.f/sqrt(a*a+b*b+c*c));
1080 
1081 	Frustrum_Set(frustrum,3,a*n,b*n,c*n,d*n);
1082 
1083 	frustrum->nb=4;
1084 
1085 	a=matres._14+matres._13;
1086 	b=matres._24+matres._23;
1087 	c=matres._34+matres._33;
1088 	d=matres._44+matres._43;
1089  b=-b;
1090 	n = (float)(1.f/sqrt(a*a+b*b+c*c));
1091 	efpPlaneNear.a=a*n;
1092 	efpPlaneNear.b=b*n;
1093 	efpPlaneNear.c=c*n;
1094 	efpPlaneNear.d=d*n;
1095 }
1096 
RoomDrawRelease()1097 void RoomDrawRelease() {
1098 	free(RoomDrawList), RoomDrawList = NULL;
1099 	free(RoomDraw), RoomDraw = NULL;
1100 }
1101 
RoomDrawListAdd(long num)1102 void RoomDrawListAdd(long num) {
1103 
1104 	if(TotalRoomDrawList <= NbRoomDrawList) {
1105 		RoomDrawList = (long *)realloc(RoomDrawList, sizeof(long) * (NbRoomDrawList + 1));
1106 		TotalRoomDrawList=NbRoomDrawList+1;
1107 	}
1108 
1109 	RoomDrawList[NbRoomDrawList]=num;
1110 	NbRoomDrawList++;
1111 }
1112 
RoomFrustrumAdd(long num,EERIE_FRUSTRUM * fr)1113 void RoomFrustrumAdd(long num,EERIE_FRUSTRUM * fr)
1114 {
1115 	if (RoomDraw[num].frustrum.nb_frustrums<MAX_FRUSTRUMS-1)
1116 	{
1117 		memcpy(&RoomDraw[num].frustrum.frustrums
1118 			[RoomDraw[num].frustrum.nb_frustrums],fr,sizeof(EERIE_FRUSTRUM));
1119 		RoomDraw[num].frustrum.nb_frustrums++;
1120 
1121 	}
1122 }
1123 void ARX_PORTALS_RenderRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim);
ARX_PORTALS_RenderRooms(long prec,long tim)1124 void ARX_PORTALS_RenderRooms(long prec,long tim)
1125 {
1126 	for (long i=0;i<NbRoomDrawList;i++)
1127 	{
1128 		ARX_PORTALS_RenderRoom(RoomDrawList[i],&RoomDraw[RoomDrawList[i]].bbox,prec,tim);
1129 	}
1130 
1131 	NbRoomDrawList=0;
1132 }
1133 void ARX_PORTALS_Frustrum_RenderRoom(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim);
ARX_PORTALS_Frustrum_RenderRooms(long prec,long tim)1134 void ARX_PORTALS_Frustrum_RenderRooms(long prec,long tim)
1135 {
1136 	for (long i=0;i<NbRoomDrawList;i++)
1137 	{
1138 		ARX_PORTALS_Frustrum_RenderRoom(RoomDrawList[i],&RoomDraw[RoomDrawList[i]].frustrum,prec,tim);
1139 	}
1140 
1141 	NbRoomDrawList=0;
1142 }
1143 
RenderWaterBatch()1144 static void RenderWaterBatch() {
1145 
1146 	if(!dynamicVertices.nbindices) {
1147 		return;
1148 	}
1149 
1150 	GRenderer->GetTextureStage(1)->SetColorOp(TextureStage::OpModulate4X, TextureStage::ArgTexture, TextureStage::ArgCurrent);
1151 	GRenderer->GetTextureStage(1)->DisableAlpha();
1152 
1153 	GRenderer->GetTextureStage(2)->SetColorOp(TextureStage::OpModulate, TextureStage::ArgTexture, TextureStage::ArgCurrent);
1154 	GRenderer->GetTextureStage(2)->DisableAlpha();
1155 
1156 	dynamicVertices.draw(Renderer::TriangleList);
1157 
1158 	GRenderer->GetTextureStage(1)->DisableColor();
1159 	GRenderer->GetTextureStage(2)->DisableColor();
1160 
1161 }
1162 
RenderWater()1163 static void RenderWater() {
1164 
1165 	if(vPolyWater.empty()) {
1166 		return;
1167 	}
1168 
1169 	size_t iNbIndice = 0;
1170 	int iNb = vPolyWater.size();
1171 
1172 	dynamicVertices.lock();
1173 
1174 	GRenderer->SetBlendFunc(Renderer::BlendDstColor, Renderer::BlendOne);
1175 	GRenderer->SetTexture(0, enviro);
1176 	GRenderer->SetTexture(2, enviro);
1177 
1178 	unsigned short * indices = dynamicVertices.indices;
1179 
1180 	while(iNb--) {
1181 		EERIEPOLY * ep = vPolyWater[iNb];
1182 
1183 		unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3;
1184 		SMY_VERTEX3 * pVertex = dynamicVertices.append(iNbVertex);
1185 
1186 		if(!pVertex) {
1187 			dynamicVertices.unlock();
1188 			RenderWaterBatch();
1189 			dynamicVertices.reset();
1190 			dynamicVertices.lock();
1191 			iNbIndice = 0;
1192 			indices = dynamicVertices.indices;
1193 			pVertex = dynamicVertices.append(iNbVertex);
1194 		}
1195 
1196 		pVertex->p.x = ep->v[0].p.x;
1197 		pVertex->p.y = -ep->v[0].p.y;
1198 		pVertex->p.z = ep->v[0].p.z;
1199 		pVertex->color = 0xFF505050;
1200 		float fTu = ep->v[0].p.x*(1.f/1000) + sin(ep->v[0].p.x*(1.f/200) + arxtime.get_frame_time()*(1.f/1000)) * (1.f/32);
1201 		float fTv = ep->v[0].p.z*(1.f/1000) + cos(ep->v[0].p.z*(1.f/200) + arxtime.get_frame_time()*(1.f/1000)) * (1.f/32);
1202 		if(ep->type & POLY_FALL) {
1203 			fTv += arxtime.get_frame_time() * (1.f/4000);
1204 		}
1205 		pVertex->uv[0].x = fTu;
1206 		pVertex->uv[0].y = fTv;
1207 		fTu = (ep->v[0].p.x + 30.f)*(1.f/1000) + sin((ep->v[0].p.x + 30)*(1.f/200) + arxtime.get_frame_time()*(1.f/1000))*(1.f/28);
1208 		fTv = (ep->v[0].p.z + 30.f)*(1.f/1000) - cos((ep->v[0].p.z + 30)*(1.f/200) + arxtime.get_frame_time()*(1.f/1000))*(1.f/28);
1209 		if (ep->type & POLY_FALL) {
1210 			fTv += arxtime.get_frame_time() * (1.f/4000);
1211 		}
1212 		pVertex->uv[1].x=fTu;
1213 		pVertex->uv[1].y=fTv;
1214 		fTu=(ep->v[0].p.x+60.f)*( 1.0f / 1000 )-EEsin((ep->v[0].p.x+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1215 		fTv=(ep->v[0].p.z+60.f)*( 1.0f / 1000 )-EEcos((ep->v[0].p.z+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1216 
1217 		if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1218 
1219 		pVertex->uv[2].x=fTu;
1220 		pVertex->uv[2].y=fTv;
1221 
1222 		pVertex++;
1223 		pVertex->p.x=ep->v[1].p.x;
1224 		pVertex->p.y=-ep->v[1].p.y;
1225 		pVertex->p.z=ep->v[1].p.z;
1226 		pVertex->color=0xFF505050;
1227 		fTu=ep->v[1].p.x*( 1.0f / 1000 )+EEsin((ep->v[1].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1228 		fTv=ep->v[1].p.z*( 1.0f / 1000 )+EEcos((ep->v[1].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1229 
1230 		if(ep->type&POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1231 
1232 		pVertex->uv[0].x=fTu;
1233 		pVertex->uv[0].y=fTv;
1234 		fTu=(ep->v[1].p.x+30.f)*( 1.0f / 1000 )+EEsin((ep->v[1].p.x+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1235 		fTv=(ep->v[1].p.z+30.f)*( 1.0f / 1000 )-EEcos((ep->v[1].p.z+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1236 
1237 		if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1238 
1239 		pVertex->uv[1].x=fTu;
1240 		pVertex->uv[1].y=fTv;
1241 		fTu=(ep->v[1].p.x+60.f)*( 1.0f / 1000 )-EEsin((ep->v[1].p.x+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1242 		fTv=(ep->v[1].p.z+60.f)*( 1.0f / 1000 )-EEcos((ep->v[1].p.z+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1243 
1244 		if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1245 
1246 		pVertex->uv[2].x=fTu;
1247 		pVertex->uv[2].y=fTv;
1248 		pVertex++;
1249 		pVertex->p.x=ep->v[2].p.x;
1250 		pVertex->p.y=-ep->v[2].p.y;
1251 		pVertex->p.z=ep->v[2].p.z;
1252 		pVertex->color=0xFF505050;
1253 		fTu=ep->v[2].p.x*( 1.0f / 1000 )+EEsin((ep->v[2].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1254 		fTv=ep->v[2].p.z*( 1.0f / 1000 )+EEcos((ep->v[2].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1255 
1256 		if(ep->type&POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1257 
1258 		pVertex->uv[0].x=fTu;
1259 		pVertex->uv[0].y=fTv;
1260 		fTu=(ep->v[2].p.x+30.f)*( 1.0f / 1000 )+EEsin((ep->v[2].p.x+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1261 		fTv=(ep->v[2].p.z+30.f)*( 1.0f / 1000 )-EEcos((ep->v[2].p.z+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1262 
1263 		if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1264 
1265 		pVertex->uv[1].x=fTu;
1266 		pVertex->uv[1].y=fTv;
1267 		fTu=(ep->v[2].p.x+60.f)*( 1.0f / 1000 )-EEsin((ep->v[2].p.x+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1268 		fTv=(ep->v[2].p.z+60.f)*( 1.0f / 1000 )-EEcos((ep->v[2].p.z+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1269 
1270 		if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1271 
1272 		pVertex->uv[2].x=fTu;
1273 		pVertex->uv[2].y=fTv;
1274 		pVertex++;
1275 
1276 		*indices++ = iNbIndice++;
1277 		*indices++ = iNbIndice++;
1278 		*indices++ = iNbIndice++;
1279 		dynamicVertices.nbindices += 3;
1280 
1281 		if(iNbVertex == 4)
1282 		{
1283 			pVertex->p.x=ep->v[3].p.x;
1284 			pVertex->p.y=-ep->v[3].p.y;
1285 			pVertex->p.z=ep->v[3].p.z;
1286 			pVertex->color=0xFF505050;
1287 			fTu=ep->v[3].p.x*( 1.0f / 1000 )+EEsin((ep->v[3].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1288 			fTv=ep->v[3].p.z*( 1.0f / 1000 )+EEcos((ep->v[3].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 32 );
1289 
1290 			if(ep->type&POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1291 
1292 			pVertex->uv[0].x=fTu;
1293 			pVertex->uv[0].y=fTv;
1294 			fTu=(ep->v[3].p.x+30.f)*( 1.0f / 1000 )+EEsin((ep->v[3].p.x+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1295 			fTv=(ep->v[3].p.z+30.f)*( 1.0f / 1000 )-EEcos((ep->v[3].p.z+30)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 28 );
1296 
1297 			if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1298 
1299 			pVertex->uv[1].x=fTu;
1300 			pVertex->uv[1].y=fTv;
1301 			fTu=(ep->v[3].p.x+60.f)*( 1.0f / 1000 )-EEsin((ep->v[3].p.x+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1302 			fTv=(ep->v[3].p.z+60.f)*( 1.0f / 1000 )-EEcos((ep->v[3].p.z+60)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 1000 ))*( 1.0f / 40 );
1303 
1304 			if (ep->type & POLY_FALL) fTv+=arxtime.get_frame_time()*( 1.0f / 4000 );
1305 
1306 			pVertex->uv[2].x=fTu;
1307 			pVertex->uv[2].y=fTv;
1308 			pVertex++;
1309 
1310 			*indices++ = iNbIndice++;
1311 			*indices++ = iNbIndice - 2;
1312 			*indices++ = iNbIndice - 3;
1313 			dynamicVertices.nbindices += 3;
1314 		}
1315 
1316 	}
1317 
1318 	dynamicVertices.unlock();
1319 	RenderWaterBatch();
1320 	dynamicVertices.done();
1321 
1322 	vPolyWater.clear();
1323 
1324 }
1325 
RenderLavaBatch()1326 void RenderLavaBatch() {
1327 
1328 	GRenderer->SetBlendFunc(Renderer::BlendDstColor, Renderer::BlendOne);
1329 	GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate2X, TextureStage::ArgTexture, TextureStage::ArgDiffuse);
1330 
1331 	if(!dynamicVertices.nbindices) {
1332 		return;
1333 	}
1334 
1335 	GRenderer->GetTextureStage(1)->SetColorOp(TextureStage::OpModulate4X, TextureStage::ArgTexture, TextureStage::ArgCurrent);
1336 	GRenderer->GetTextureStage(1)->DisableAlpha();
1337 
1338 	GRenderer->GetTextureStage(2)->SetColorOp(TextureStage::OpModulate, TextureStage::ArgTexture, TextureStage::ArgCurrent);
1339 	GRenderer->GetTextureStage(2)->DisableAlpha();
1340 
1341 	dynamicVertices.draw(Renderer::TriangleList);
1342 
1343 	GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
1344 	GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate);
1345 
1346 	dynamicVertices.draw(Renderer::TriangleList);
1347 
1348 	GRenderer->GetTextureStage(1)->DisableColor();
1349 	GRenderer->GetTextureStage(2)->DisableColor();
1350 
1351 }
1352 
RenderLava()1353 void RenderLava() {
1354 
1355 	if(vPolyLava.empty()) {
1356 		return;
1357 	}
1358 
1359 	size_t iNbIndice = 0;
1360 	int iNb=vPolyLava.size();
1361 
1362 	dynamicVertices.lock();
1363 
1364 	GRenderer->SetBlendFunc(Renderer::BlendDstColor, Renderer::BlendOne);
1365 	GRenderer->SetTexture(0, enviro);
1366 	GRenderer->SetTexture(2, enviro);
1367 
1368 	unsigned short * indices = dynamicVertices.indices;
1369 
1370 	while(iNb--) {
1371 		EERIEPOLY * ep = vPolyLava[iNb];
1372 
1373 		unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3;
1374 		SMY_VERTEX3 * pVertex = dynamicVertices.append(iNbVertex);
1375 
1376 		if(!pVertex) {
1377 			dynamicVertices.unlock();
1378 			RenderLavaBatch();
1379 			dynamicVertices.reset();
1380 			dynamicVertices.lock();
1381 			iNbIndice = 0;
1382 			indices = dynamicVertices.indices;
1383 			pVertex = dynamicVertices.append(iNbVertex);
1384 		}
1385 
1386 		pVertex->p.x=ep->v[0].p.x;
1387 		pVertex->p.y=-ep->v[0].p.y;
1388 		pVertex->p.z=ep->v[0].p.z;
1389 		pVertex->color=0xFF666666;
1390 		float fTu=ep->v[0].p.x*( 1.0f / 1000 )+EEsin((ep->v[0].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1391 		float fTv=ep->v[0].p.z*( 1.0f / 1000 )+EEcos((ep->v[0].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1392 		pVertex->uv[0].x=fTu;
1393 		pVertex->uv[0].y=fTv;
1394 		fTu=ep->v[0].p.x*( 1.0f / 1000 )+EEsin((ep->v[0].p.x)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1395 		fTv=ep->v[0].p.z*( 1.0f / 1000 )+EEcos((ep->v[0].p.z)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1396 		pVertex->uv[1].x=fTu;
1397 		pVertex->uv[1].y=fTv;
1398 		fTu=ep->v[0].p.x*( 1.0f / 600 )+EEsin((ep->v[0].p.x)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1399 		fTv=ep->v[0].p.z*( 1.0f / 600 )+EEcos((ep->v[0].p.z)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1400 
1401 		pVertex->uv[2].x=fTu;
1402 		pVertex->uv[2].y=fTv;
1403 		pVertex++;
1404 		pVertex->p.x=ep->v[1].p.x;
1405 		pVertex->p.y=-ep->v[1].p.y;
1406 		pVertex->p.z=ep->v[1].p.z;
1407 		pVertex->color=0xFF666666;
1408 		fTu=ep->v[1].p.x*( 1.0f / 1000 )+EEsin((ep->v[1].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1409 		fTv=ep->v[1].p.z*( 1.0f / 1000 )+EEcos((ep->v[1].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1410 		pVertex->uv[0].x=fTu;
1411 		pVertex->uv[0].y=fTv;
1412 		fTu=ep->v[1].p.x*( 1.0f / 1000 )+EEsin((ep->v[1].p.x)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1413 		fTv=ep->v[1].p.z*( 1.0f / 1000 )+EEcos((ep->v[1].p.z)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1414 		pVertex->uv[1].x=fTu;
1415 		pVertex->uv[1].y=fTv;
1416 		fTu=ep->v[1].p.x*( 1.0f / 600 )+EEsin((ep->v[1].p.x)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1417 		fTv=ep->v[1].p.z*( 1.0f / 600 )+EEcos((ep->v[1].p.z)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1418 
1419 		pVertex->uv[2].x=fTu;
1420 		pVertex->uv[2].y=fTv;
1421 		pVertex++;
1422 		pVertex->p.x=ep->v[2].p.x;
1423 		pVertex->p.y=-ep->v[2].p.y;
1424 		pVertex->p.z=ep->v[2].p.z;
1425 		pVertex->color=0xFF666666;
1426 		fTu=ep->v[2].p.x*( 1.0f / 1000 )+EEsin((ep->v[2].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1427 		fTv=ep->v[2].p.z*( 1.0f / 1000 )+EEcos((ep->v[2].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1428 		pVertex->uv[0].x=fTu;
1429 		pVertex->uv[0].y=fTv;
1430 		fTu=ep->v[2].p.x*( 1.0f / 1000 )+EEsin((ep->v[2].p.x)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1431 		fTv=ep->v[2].p.z*( 1.0f / 1000 )+EEcos((ep->v[2].p.z)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1432 		pVertex->uv[1].x=fTu;
1433 		pVertex->uv[1].y=fTv;
1434 		fTu=ep->v[2].p.x*( 1.0f / 600 )+EEsin((ep->v[2].p.x)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1435 		fTv=ep->v[2].p.z*( 1.0f / 600 )+EEcos((ep->v[2].p.z)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1436 
1437 		pVertex->uv[2].x=fTu;
1438 		pVertex->uv[2].y=fTv;
1439 		pVertex++;
1440 
1441 		*indices++ = iNbIndice++;
1442 		*indices++ = iNbIndice++;
1443 		*indices++ = iNbIndice++;
1444 		dynamicVertices.nbindices += 3;
1445 
1446 		if(iNbVertex&4)
1447 		{
1448 			pVertex->p.x=ep->v[3].p.x;
1449 			pVertex->p.y=-ep->v[3].p.y;
1450 			pVertex->p.z=ep->v[3].p.z;
1451 			pVertex->color=0xFF666666;
1452 			fTu=ep->v[3].p.x*( 1.0f / 1000 )+EEsin((ep->v[3].p.x)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1453 			fTv=ep->v[3].p.z*( 1.0f / 1000 )+EEcos((ep->v[3].p.z)*( 1.0f / 200 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 20 );
1454 			pVertex->uv[0].x=fTu;
1455 			pVertex->uv[0].y=fTv;
1456 			fTu=ep->v[3].p.x*( 1.0f / 1000 )+EEsin((ep->v[3].p.x)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1457 			fTv=ep->v[3].p.z*( 1.0f / 1000 )+EEcos((ep->v[3].p.z)*( 1.0f / 100 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 10 );
1458 			pVertex->uv[1].x=fTu;
1459 			pVertex->uv[1].y=fTv;
1460 			fTu=ep->v[3].p.x*( 1.0f / 600 )+EEsin((ep->v[3].p.x)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1461 			fTv=ep->v[3].p.z*( 1.0f / 600 )+EEcos((ep->v[3].p.z)*( 1.0f / 160 )+arxtime.get_frame_time()*( 1.0f / 2000 ))*( 1.0f / 11 );
1462 
1463 			pVertex->uv[2].x=fTu;
1464 			pVertex->uv[2].y=fTv;
1465 			pVertex++;
1466 
1467 			*indices++ = iNbIndice++;
1468 			*indices++ = iNbIndice - 2;
1469 			*indices++ = iNbIndice - 3;
1470 			dynamicVertices.nbindices += 3;
1471 		}
1472 
1473 	}
1474 
1475 	dynamicVertices.unlock();
1476 	RenderLavaBatch();
1477 	dynamicVertices.done();
1478 
1479 	vPolyLava.clear();
1480 
1481 }
1482 
1483 void ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(long room_num);
ARX_PORTALS_Frustrum_RenderRooms_TransparencyT()1484 void ARX_PORTALS_Frustrum_RenderRooms_TransparencyT() {
1485 
1486 	GRenderer->SetFogColor(Color::none);
1487 
1488 	GRenderer->SetRenderState(Renderer::AlphaBlending, true);
1489 	GRenderer->SetCulling(Renderer::CullNone);
1490 	GRenderer->SetRenderState(Renderer::DepthWrite, false);
1491 
1492 	GRenderer->SetAlphaFunc(Renderer::CmpGreater, .5f);
1493 
1494 	for (long i=0;i<NbRoomDrawList;i++)
1495 	{
1496 		if(USE_PORTALS==4)
1497 		{
1498 			ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(RoomDrawList[i]);
1499 		}
1500 		else
1501 		{
1502 			LogWarning << "unimplemented";
1503 		}
1504 	}
1505 
1506 	GRenderer->SetAlphaFunc(Renderer::CmpNotEqual, 0.f);
1507 
1508 	NbRoomDrawList=0;
1509 
1510 
1511 	SetZBias(8);
1512 
1513 	GRenderer->SetRenderState(Renderer::DepthWrite, false);
1514 
1515 	//render all fx!!
1516 	GRenderer->SetCulling(Renderer::CullCW);
1517 
1518 	RenderWater();
1519 	RenderLava();
1520 
1521 	SetZBias(0);
1522 	GRenderer->SetFogColor(ulBKGColor);
1523 	GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate);
1524 	GRenderer->SetRenderState(Renderer::AlphaBlending, false);
1525 }
1526 
1527 void ARX_PORTALS_Frustrum_RenderRoomTCullSoft(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim);
ARX_PORTALS_Frustrum_RenderRoomsTCullSoft(long prec,long tim)1528 void ARX_PORTALS_Frustrum_RenderRoomsTCullSoft(long prec,long tim)
1529 {
1530 	GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
1531 
1532 	for (long i=0;i<NbRoomDrawList;i++)
1533 	{
1534 		ARX_PORTALS_Frustrum_RenderRoomTCullSoft(RoomDrawList[i],&RoomDraw[RoomDrawList[i]].frustrum,prec,tim);
1535 	}
1536 }
ARX_PORTALS_RenderRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim)1537 void ARX_PORTALS_RenderRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim)
1538 {
1539 
1540 	if (RoomDraw[room_num].count)
1541 	{
1542 		EERIEDraw2DRect(bbox->min.x, bbox->min.y ,bbox->max.x, bbox->max.y, 0.0001f, Color::blue);
1543 
1544 	for (long  lll=0;lll<portals->room[room_num].nb_polys;lll++)
1545 	{
1546 
1547 		FAST_BKG_DATA * feg;
1548 		feg=&ACTIVEBKG->fastdata[portals->room[room_num].epdata[lll].px][portals->room[room_num].epdata[lll].py];
1549 
1550 		if (!feg->treat)
1551 			continue;
1552 
1553 		EERIEPOLY * ep=&feg->polydata[portals->room[room_num].epdata[lll].idx];
1554 
1555 		if (ep->type & (POLY_IGNORE | POLY_NODRAW))
1556 			continue;
1557 
1558 			// GO for 3D Backface Culling
1559 			if (ep->type & POLY_DOUBLESIDED)
1560 				GRenderer->SetCulling(Renderer::CullNone);
1561 			else
1562 			{
1563 				Vec3f nrm = ep->v[2].p - ACTIVECAM->pos;
1564 				if ( ep->type & POLY_QUAD)
1565 				{
1566 					if ((dot(ep->norm , nrm) > 0.f) &&
1567 						 (dot(ep->norm2 , nrm) > 0.f) )
1568 						continue;
1569 				}
1570 				else if (dot(ep->norm , nrm) > 0.f)
1571 						continue;
1572 
1573 				GRenderer->SetCulling(Renderer::CullCW);
1574 			}
1575 
1576 			if (!EERIERTPPoly(ep)) // RotTransProject Vertices
1577 				continue;
1578 
1579 			if (BBoxClipPoly(bbox,ep))
1580 				continue;
1581 
1582 			long to;
1583 
1584 			if ( ep->type & POLY_QUAD)
1585 			{
1586 				if (FRAME_COUNT<=0)
1587 					ep->tv[3].color=ep->v[3].color;
1588 
1589 				to=4;
1590 			}
1591 			else to=3;
1592 
1593 			if (ep->type & POLY_TRANS)
1594 			{
1595 				ManageLavaWater(ep,to,tim);
1596 				TransPol[TRANSPOLYSPOS++]=ep;
1597 
1598 				if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1;
1599 
1600 				if (ViewMode)
1601 				{
1602 					if (ViewMode & VIEWMODE_WIRE)
1603 						EERIEPOLY_DrawWired(ep);
1604 
1605 					if (ViewMode & VIEWMODE_NORMALS)
1606 						EERIEPOLY_DrawNormals(ep);
1607 				}
1608 
1609 				continue;
1610 			}
1611 
1612 			if (!Project.improve)  // Normal View...
1613 			{
1614 				if (ep->type & POLY_GLOW)
1615 					ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF;
1616 				else
1617 				{
1618 					if (FRAME_COUNT<=0)
1619 					{
1620 						if (ModeLight & MODE_DYNAMICLIGHT) 	ApplyDynLight(ep);
1621 						else
1622 						{
1623 							ep->tv[0].color=ep->v[0].color;
1624 							ep->tv[1].color=ep->v[1].color;
1625 							ep->tv[2].color=ep->v[2].color;
1626 						}
1627 					}
1628 				}
1629 
1630 				ManageLavaWater(ep,to,tim);
1631 
1632 				Delayed_EERIEDRAWPRIM(ep);
1633 
1634 				if (ViewMode)
1635 				{
1636 					if (ViewMode & VIEWMODE_WIRE)
1637 						EERIEPOLY_DrawWired(ep);
1638 
1639 					if (ViewMode & VIEWMODE_NORMALS)
1640 						EERIEPOLY_DrawNormals(ep);
1641 				}
1642 			}
1643 			else // Improve Vision Activated
1644 			{
1645 				if (FRAME_COUNT<=0)
1646 				{
1647 					if ( ModeLight & MODE_DYNAMICLIGHT ) 	ApplyDynLight(ep);
1648 					else
1649 					{
1650 						ep->tv[0].color=ep->v[0].color;
1651 						ep->tv[1].color=ep->v[1].color;
1652 						ep->tv[2].color=ep->v[2].color;
1653 					}
1654 
1655 
1656 					for (long k=0;k<to;k++)
1657 					{
1658 						long lfr,lfb;
1659 						float fr,fb;
1660 						long lr=(ep->tv[k].color>>16) & 255;
1661 						float ffr=(float)(lr);
1662 
1663 						float dd=(ep->tv[k].p.z*prec);
1664 
1665 						if (dd>1.f) dd=1.f;
1666 
1667 						if (dd<0.f) dd=0.f;
1668 
1669 						fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f;
1670 						fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd);
1671 
1672 						if (fr<0.f) fr=0.f;
1673 						else fr=max(ffr,fr*255.f);
1674 
1675 						fb*=255.f;
1676 						lfr = fr;
1677 						lfb = fb;
1678 						ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) );
1679 						//GG component locked at 0x1E
1680 				}
1681 			}
1682 
1683 			Delayed_EERIEDRAWPRIM(ep);
1684 		}
1685 	}
1686 	}
1687 }
ARX_PORTALS_Frustrum_RenderRoom(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim)1688 void ARX_PORTALS_Frustrum_RenderRoom(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim)
1689 {
1690 
1691 	if (RoomDraw[room_num].count)
1692 	{
1693 
1694 	for (long  lll=0;lll<portals->room[room_num].nb_polys;lll++)
1695 	{
1696 
1697 		FAST_BKG_DATA * feg;
1698 		feg=&ACTIVEBKG->fastdata[portals->room[room_num].epdata[lll].px][portals->room[room_num].epdata[lll].py];
1699 
1700 		if (!feg->treat)
1701 			continue;
1702 
1703 		EERIEPOLY * ep=&feg->polydata[portals->room[room_num].epdata[lll].idx];
1704 
1705 		if (ep->type & (POLY_IGNORE | POLY_NODRAW))
1706 			continue;
1707 
1708 		if (FrustrumsClipPoly(frustrums,ep))
1709 				continue;
1710 
1711 			// GO for 3D Backface Culling
1712 			if (ep->type & POLY_DOUBLESIDED)
1713 				GRenderer->SetCulling(Renderer::CullNone);
1714 			else
1715 			{
1716 				Vec3f nrm = ep->v[2].p - ACTIVECAM->pos;
1717 				if ( ep->type & POLY_QUAD)
1718 				{
1719 					if ( (dot( ep->norm , nrm )>0.f) &&
1720 						 (dot( ep->norm2 , nrm )>0.f) )
1721 						continue;
1722 				}
1723 				else if ( dot( ep->norm , nrm )>0.f)
1724 						continue;
1725 
1726 				GRenderer->SetCulling(Renderer::CullCW);
1727 			}
1728 
1729 			if (!EERIERTPPoly(ep)) // RotTransProject Vertices
1730 				continue;
1731 
1732 			long to;
1733 
1734 			if ( ep->type & POLY_QUAD)
1735 			{
1736 				if (FRAME_COUNT<=0) ep->tv[3].color=ep->v[3].color;
1737 
1738 				to=4;
1739 			}
1740 			else to=3;
1741 
1742 			if (ep->type & POLY_TRANS)
1743 			{
1744 				ManageLavaWater(ep,to,tim);
1745 				TransPol[TRANSPOLYSPOS++]=ep;
1746 
1747 				if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1;
1748 
1749 				if (ViewMode)
1750 				{
1751 					if (ViewMode & VIEWMODE_WIRE)
1752 						EERIEPOLY_DrawWired(ep);
1753 
1754 					if (ViewMode & VIEWMODE_NORMALS)
1755 						EERIEPOLY_DrawNormals(ep);
1756 				}
1757 
1758 				continue;
1759 			}
1760 
1761 			if (!Project.improve)  // Normal View...
1762 			{
1763 				if (ep->type & POLY_GLOW) ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF;
1764 				else
1765 				{
1766 					if (FRAME_COUNT<=0)
1767 					{
1768 						if (ModeLight & MODE_DYNAMICLIGHT) 	ApplyDynLight(ep);
1769 						else
1770 						{
1771 							ep->tv[0].color=ep->v[0].color;
1772 							ep->tv[1].color=ep->v[1].color;
1773 							ep->tv[2].color=ep->v[2].color;
1774 						}
1775 					}
1776 				}
1777 
1778 				ManageLavaWater(ep,to,tim);
1779 
1780 				Delayed_EERIEDRAWPRIM(ep);
1781 
1782 				if (ViewMode)
1783 				{
1784 					if (ViewMode & VIEWMODE_WIRE)
1785 						EERIEPOLY_DrawWired(ep);
1786 
1787 					if (ViewMode & VIEWMODE_NORMALS)
1788 						EERIEPOLY_DrawNormals(ep);
1789 				}
1790 			}
1791 			else // Improve Vision Activated
1792 			{
1793 				if (FRAME_COUNT<=0)
1794 				{
1795 					if ( ModeLight & MODE_DYNAMICLIGHT ) 	ApplyDynLight(ep);
1796 					else
1797 					{
1798 						ep->tv[0].color=ep->v[0].color;
1799 						ep->tv[1].color=ep->v[1].color;
1800 						ep->tv[2].color=ep->v[2].color;
1801 					}
1802 
1803 
1804 					for (long k=0;k<to;k++)
1805 					{
1806 						long lfr,lfb;
1807 						float fr,fb;
1808 						long lr=(ep->tv[k].color>>16) & 255;
1809 						float ffr=(float)(lr);
1810 
1811 						float dd=(ep->tv[k].p.z*prec);
1812 
1813 						if (dd>1.f) dd=1.f;
1814 
1815 						if (dd<0.f) dd=0.f;
1816 
1817 						fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f;
1818 						fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd);
1819 
1820 						if (fr<0.f) fr=0.f;
1821 						else fr=max(ffr,fr*255.f);
1822 
1823 						fb*=255.f;
1824 						lfr = fr;
1825 						lfb = fb;
1826 						ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) );
1827 						//GG component locked at 0x1E
1828 				}
1829 			}
1830 
1831 			Delayed_EERIEDRAWPRIM(ep);
1832 		}
1833 	}
1834 	}
1835 }
1836 
1837 void ApplyDynLight_VertexBuffer(EERIEPOLY *ep,SMY_VERTEX *_pVertex,unsigned short _usInd0,unsigned short _usInd1,unsigned short _usInd2,unsigned short _usInd3);
1838 void ApplyDynLight_VertexBuffer_2(EERIEPOLY *ep,short x,short y,SMY_VERTEX *_pVertex,unsigned short _usInd0,unsigned short _usInd1,unsigned short _usInd2,unsigned short _usInd3);
1839 
1840 TILE_LIGHTS tilelights[MAX_BKGX][MAX_BKGZ];
1841 
InitTileLights()1842 void InitTileLights()
1843 {
1844 	for (long j=0;j<MAX_BKGZ;j++)
1845 	for (long i=0;i<MAX_BKGZ;i++)
1846 	{
1847 		tilelights[i][j].el=NULL;
1848 		tilelights[i][j].max=0;
1849 		tilelights[i][j].num=0;
1850 	}
1851 }
1852 
ComputeTileLights(short x,short z)1853 void ComputeTileLights(short x,short z)
1854 {
1855 	tilelights[x][z].num=0;
1856 	float xx=((float)x+0.5f)*ACTIVEBKG->Xdiv;
1857 	float zz=((float)z+0.5f)*ACTIVEBKG->Zdiv;
1858 
1859 	for (long i=0;i<TOTPDL;i++)
1860 	{
1861 		if(closerThan(Vec2f(xx, zz), Vec2f(PDL[i]->pos.x, PDL[i]->pos.z), PDL[i]->fallend + 60.f)) {
1862 
1863 			if (tilelights[x][z].num>=tilelights[x][z].max)
1864 			{
1865 				tilelights[x][z].max++;
1866 				tilelights[x][z].el=(EERIE_LIGHT **)realloc(tilelights[x][z].el,sizeof(EERIE_LIGHT *)*(tilelights[x][z].max));
1867 			}
1868 
1869 			tilelights[x][z].el[tilelights[x][z].num]=PDL[i];
1870 			tilelights[x][z].num++;
1871 		}
1872 	}
1873 }
1874 
ClearTileLights()1875 void ClearTileLights() {
1876 	for(long j = 0; j < MAX_BKGZ; j++) for(long i = 0; i < MAX_BKGZ; i++) {
1877 		tilelights[i][j].max = 0;
1878 		tilelights[i][j].num = 0;
1879 		free(tilelights[i][j].el), tilelights[i][j].el = NULL;
1880 	}
1881 }
1882 
ARX_PORTALS_Frustrum_RenderRoomTCullSoft(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim)1883 void ARX_PORTALS_Frustrum_RenderRoomTCullSoft(long room_num,EERIE_FRUSTRUM_DATA * frustrums,long prec,long tim)
1884 {
1885 
1886 
1887 	if(RoomDraw[room_num].count) {
1888 
1889 		if(!portals->room[room_num].pVertexBuffer) {
1890 			// No need to spam this for every frame as there will already be an
1891 			// earlier warning
1892 			LogDebug("no vertex data for room " << room_num);
1893 			return;
1894 		}
1895 
1896 		SMY_VERTEX * pMyVertex = portals->room[room_num].pVertexBuffer->lock(NoOverwrite);
1897 
1898 		unsigned short *pIndices=portals->room[room_num].pussIndice;
1899 
1900 		FAST_BKG_DATA * feg;
1901 		EERIEPOLY * ep;
1902 		EP_DATA *pEPDATA = &portals->room[room_num].epdata[0];
1903 
1904 		for (long  lll=0; lll<portals->room[room_num].nb_polys; lll++, pEPDATA++)
1905 		{
1906 
1907 			feg = &ACTIVEBKG->fastdata[pEPDATA->px][pEPDATA->py];
1908 
1909 			if (!feg->treat)
1910 			{
1911 				long ix=max(0,pEPDATA->px-1);
1912 				long ax=min(ACTIVEBKG->Xsize-1,pEPDATA->px+1);
1913 				long iz=max(0,pEPDATA->py-1);
1914 				long az=min(ACTIVEBKG->Zsize-1,pEPDATA->py+1);
1915 
1916 				(void)checked_range_cast<short>(iz);
1917 				(void)checked_range_cast<short>(ix);
1918 				(void)checked_range_cast<short>(az);
1919 				(void)checked_range_cast<short>(ax);
1920 
1921 				for (long nz=iz;nz<=az;nz++)
1922 				for (long nx=ix;nx<=ax;nx++)
1923 
1924 				{
1925 					FAST_BKG_DATA * feg2 = &ACTIVEBKG->fastdata[nx][nz];
1926 
1927 					if (!feg2->treat)
1928 					{
1929 						feg2->treat=1;
1930 
1931 						if (USE_LIGHT_OPTIM)
1932 								ComputeTileLights(static_cast<short>(nx), static_cast<short>(nz));
1933 					}
1934 				}
1935 			}
1936 
1937 			ep=&feg->polydata[pEPDATA->idx];
1938 
1939 			if	(!ep->tex)
1940 			{
1941 				continue;
1942 			}
1943 
1944 			if (ep->type & (POLY_IGNORE | POLY_NODRAW| POLY_HIDE))
1945 			{
1946 				continue;
1947 			}
1948 
1949 			if (FrustrumsClipPoly(frustrums,ep))
1950 			{
1951 				continue;
1952 			}
1953 
1954 			//Clipp ZNear + Distance pour les ZMapps!!!
1955 			float fDist=(ep->center.x*efpPlaneNear.a + ep->center.y*efpPlaneNear.b + ep->center.z*efpPlaneNear.c + efpPlaneNear.d);
1956 
1957 			if(ep->v[0].rhw<-fDist)
1958 			{
1959 				continue;
1960 			}
1961 
1962 			fDist-=ep->v[0].rhw;
1963 
1964 			Vec3f nrm = ep->v[2].p - ACTIVECAM->pos;
1965 			int to;
1966 			if(ep->type&POLY_QUAD)
1967 			{
1968 				if(	(!(ep->type&POLY_DOUBLESIDED))&&
1969 					(dot( ep->norm , nrm )>0.f)&&
1970 					(dot( ep->norm2 , nrm )>0.f) )
1971 				{
1972 					continue;
1973 				}
1974 
1975 				to=4;
1976 			}
1977 			else
1978 			{
1979 				if(	(!(ep->type&POLY_DOUBLESIDED))&&
1980 					(dot( ep->norm , nrm )>0.f) )
1981 				{
1982 					continue;
1983 				}
1984 
1985 				to=3;
1986 			}
1987 
1988 			unsigned short *pIndicesCurr;
1989 			unsigned long *pNumIndices;
1990 
1991 			if(ep->type&POLY_TRANS)
1992 			{
1993 				if(ep->transval>=2.f)  //MULTIPLICATIVE
1994 				{
1995 					pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TMultiplicative+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative;
1996 					pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative;
1997 				}
1998 				else
1999 				{
2000 					if(ep->transval>=1.f) //ADDITIVE
2001 					{
2002 						pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TAdditive+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TAdditive;
2003 						pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TAdditive;
2004 					}
2005 					else
2006 					{
2007 						if(ep->transval>0.f) //NORMAL TRANS
2008 						{
2009 							pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TNormalTrans+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans;
2010 							pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans;
2011 						}
2012 						else
2013 						{
2014 							//SUBTRACTIVE
2015 							pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull_TSubstractive+ep->tex->tMatRoom[room_num].uslNbIndiceCull_TSubstractive;
2016 							pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull_TSubstractive;
2017 						}
2018 					}
2019 				}
2020 			}
2021 			else
2022 			{
2023 				pIndicesCurr=pIndices+ep->tex->tMatRoom[room_num].uslStartCull+ep->tex->tMatRoom[room_num].uslNbIndiceCull;
2024 				pNumIndices=&ep->tex->tMatRoom[room_num].uslNbIndiceCull;
2025 
2026 				if(ZMAPMODE)
2027 				{
2028 					if((fDist<200)&&(ep->tex->TextureRefinement))
2029 					{
2030 						ep->tex->TextureRefinement->vPolyZMap.push_back(ep);
2031 					}
2032 				}
2033 			}
2034 
2035 			SMY_VERTEX *pMyVertexCurr;
2036 
2037 				*pIndicesCurr++=ep->uslInd[0];
2038 				*pIndicesCurr++=ep->uslInd[1];
2039 				*pIndicesCurr++=ep->uslInd[2];
2040 
2041 				if(to&4)
2042 				{
2043 					*pIndicesCurr++=ep->uslInd[3];
2044 					*pIndicesCurr++=ep->uslInd[2];
2045 					*pIndicesCurr++=ep->uslInd[1];
2046 					*pNumIndices+=6;
2047 				}
2048 				else
2049 				{
2050 					*pNumIndices+=3;
2051 				}
2052 				pMyVertexCurr=&pMyVertex[ep->tex->tMatRoom[room_num].uslStartVertex];
2053 
2054 
2055 			if (!Project.improve)  // Normal View...
2056 			{
2057 				if(ep->type&POLY_GLOW)
2058 				{
2059 					pMyVertexCurr[ep->uslInd[0]].color=pMyVertexCurr[ep->uslInd[1]].color=pMyVertexCurr[ep->uslInd[2]].color=0xFFFFFFFF;
2060 
2061 					if(to&4)
2062 					{
2063 						pMyVertexCurr[ep->uslInd[3]].color=0xFFFFFFFF;
2064 					}
2065 				}
2066 				else
2067 				{
2068 					if(ep->type&POLY_LAVA)
2069 					{
2070 						if((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS)))
2071 						{
2072 							if(ModeLight & MODE_DYNAMICLIGHT)
2073 							{
2074 								ApplyDynLight(ep);
2075 							}
2076 							else
2077 							{
2078 								ep->tv[0].color=ep->v[0].color;
2079 								ep->tv[1].color=ep->v[1].color;
2080 								ep->tv[2].color=ep->v[2].color;
2081 
2082 								if(to&4)
2083 								{
2084 									ep->tv[3].color=ep->v[3].color;
2085 								}
2086 							}
2087 						}
2088 
2089 						ManageLava_VertexBuffer(ep,to,tim,pMyVertexCurr);
2090 
2091 						vPolyLava.push_back(ep);
2092 
2093 						pMyVertexCurr[ep->uslInd[0]].color=ep->tv[0].color;
2094 						pMyVertexCurr[ep->uslInd[1]].color=ep->tv[1].color;
2095 						pMyVertexCurr[ep->uslInd[2]].color=ep->tv[2].color;
2096 
2097 						if(to&4)
2098 						{
2099 							pMyVertexCurr[ep->uslInd[3]].color=ep->tv[3].color;
2100 						}
2101 					}
2102 					else
2103 					{
2104 						if((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS)))
2105 						{
2106 							if(ModeLight & MODE_DYNAMICLIGHT)
2107 							{
2108 
2109 									if (USE_LIGHT_OPTIM)
2110 									ApplyDynLight_VertexBuffer_2(	ep,pEPDATA->px,pEPDATA->py,
2111 																pMyVertexCurr,
2112 																ep->uslInd[0],
2113 																ep->uslInd[1],
2114 																ep->uslInd[2],
2115 																ep->uslInd[3]);
2116 
2117 									else
2118 									ApplyDynLight_VertexBuffer(	ep,
2119 																pMyVertexCurr,
2120 																ep->uslInd[0],
2121 																ep->uslInd[1],
2122 																ep->uslInd[2],
2123 																ep->uslInd[3]);
2124 
2125 								}
2126 							else
2127 							{
2128 										pMyVertexCurr[ep->uslInd[0]].color=ep->v[0].color;
2129 										pMyVertexCurr[ep->uslInd[1]].color=ep->v[1].color;
2130 										pMyVertexCurr[ep->uslInd[2]].color=ep->v[2].color;
2131 
2132 									if(to&4)
2133 									{
2134 											pMyVertexCurr[ep->uslInd[3]].color=ep->v[3].color;
2135 										}
2136 									}
2137 								}
2138 
2139 						if(ep->type&POLY_WATER)
2140 						{
2141 							ManageWater_VertexBuffer(ep,to,tim,pMyVertexCurr);
2142 							vPolyWater.push_back(ep);
2143 						}
2144 					}
2145 				}
2146 
2147 				if ((ViewMode & VIEWMODE_WIRE))
2148 				{
2149 					if (EERIERTPPoly(ep))
2150 						EERIEPOLY_DrawWired(ep);
2151 				}
2152 
2153 					}
2154 			else // Improve Vision Activated
2155 			{
2156 				//!!!!!!!!! NOT OPTIMIZED T&L !!!!!!!!!!
2157 				if ((FRAME_COUNT<=0)&&(!(ep->type&POLY_TRANS)))
2158 				{
2159 					if (!EERIERTPPoly(ep)) // RotTransProject Vertices
2160 					{
2161 						continue;
2162 					}
2163 
2164 					if ( ModeLight & MODE_DYNAMICLIGHT ) 	ApplyDynLight(ep);
2165 					else
2166 					{
2167 						ep->tv[0].color=ep->v[0].color;
2168 						ep->tv[1].color=ep->v[1].color;
2169 						ep->tv[2].color=ep->v[2].color;
2170 
2171 						if(to&4)
2172 						{
2173 							ep->tv[3].color=ep->v[3].color;
2174 						}
2175 					}
2176 
2177 					for (long k=0;k<to;k++)
2178 					{
2179 						long lfr,lfb;
2180 						float fr,fb;
2181 						long lr=(ep->tv[k].color>>16) & 255;
2182 						float ffr=(float)(lr);
2183 
2184 						float dd=(ep->tv[k].rhw*prec);
2185 
2186 						if (dd>1.f) dd=1.f;
2187 
2188 						if (dd<0.f) dd=0.f;
2189 
2190 						fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f;
2191 						fr = ((0.6f - dd) * 6.f + (EEfabs(ep->nrml[k].z) + EEfabs(ep->nrml[k].y))) * 0.125f;
2192 
2193 						if (fr<0.f) fr=0.f;
2194 						else fr=max(ffr,fr*255.f);
2195 
2196 						fr=min(fr,255.f);
2197 						fb*=255.f;
2198 						fb=min(fb,255.f);
2199 						lfr = fr;
2200 						lfb = fb;
2201 
2202 						ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) );
2203 
2204 					}
2205 
2206 					pMyVertexCurr[ep->uslInd[0]].color=ep->tv[0].color;
2207 					pMyVertexCurr[ep->uslInd[1]].color=ep->tv[1].color;
2208 					pMyVertexCurr[ep->uslInd[2]].color=ep->tv[2].color;
2209 
2210 					if(to&4)
2211 					{
2212 						pMyVertexCurr[ep->uslInd[3]].color=ep->tv[3].color;
2213 					}
2214 				}
2215 			}
2216 		}
2217 
2218 		portals->room[room_num].pVertexBuffer->unlock();
2219 
2220 		//render opaque
2221 		GRenderer->SetCulling(Renderer::CullNone);
2222 		int iNbTex=portals->room[room_num].usNbTextures;
2223 		TextureContainer **ppTexCurr=portals->room[room_num].ppTextureContainer;
2224 
2225 		while(iNbTex--)
2226 		{
2227 			TextureContainer *pTexCurr=*ppTexCurr;
2228 
2229 			if (ViewMode & VIEWMODE_FLAT)
2230 				GRenderer->ResetTexture(0);
2231 			else
2232 				GRenderer->SetTexture(0, pTexCurr);
2233 
2234 			if(pTexCurr->userflags&POLY_METAL)
2235 			{
2236 				GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate2X);
2237 			}
2238 			else
2239 			{
2240 				GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate);
2241 			}
2242 
2243 			if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull)
2244 			{
2245 				GRenderer->SetAlphaFunc(Renderer::CmpGreater, .5f);
2246 				portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex,
2247 					&portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull],
2248 					pTexCurr->tMatRoom[room_num].uslNbIndiceCull);
2249 				GRenderer->SetAlphaFunc(Renderer::CmpNotEqual, 0.f);
2250 
2251 				EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull;
2252 				pTexCurr->tMatRoom[room_num].uslNbIndiceCull=0;
2253 						}
2254 
2255 			ppTexCurr++;
2256 		}
2257 
2258 		//////////////////////////////
2259 		//ZMapp
2260 		GRenderer->GetTextureStage(0)->SetColorOp(TextureStage::OpModulate);
2261 
2262 		GRenderer->SetRenderState(Renderer::AlphaBlending, true);
2263 		GRenderer->SetRenderState(Renderer::DepthWrite, false);
2264 
2265 		iNbTex=portals->room[room_num].usNbTextures;
2266 		ppTexCurr=portals->room[room_num].ppTextureContainer;
2267 
2268 		while ( iNbTex-- ) //For each tex in portals->room[room_num]
2269 		{
2270 			TextureContainer * pTexCurr	= *ppTexCurr;
2271 
2272 			if ( pTexCurr->TextureRefinement && pTexCurr->TextureRefinement->vPolyZMap.size() )
2273 			{
2274 					//---------------------------------------------------------------------------
2275 					//																		 INIT
2276 
2277 				GRenderer->SetTexture(0, pTexCurr->TextureRefinement);
2278 
2279 				dynamicVertices.lock();
2280 				unsigned short * pussInd = dynamicVertices.indices;
2281 				unsigned short iNbIndice = 0;
2282 
2283 				vector<EERIEPOLY *>::iterator it		=	pTexCurr->TextureRefinement->vPolyZMap.begin();
2284 
2285 
2286 
2287 				//---------------------------------------------------------------------------
2288 				//																		 LOOP
2289 				for (; it != pTexCurr->TextureRefinement->vPolyZMap.end(); ++it)
2290 				{
2291 					EERIEPOLY * ep = *it;
2292 
2293 					unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3;
2294 					SMY_VERTEX3 * pVertex = dynamicVertices.append(iNbVertex);
2295 
2296 					if(!pVertex) {
2297 						dynamicVertices.unlock();
2298 						if(dynamicVertices.nbindices) {
2299 							dynamicVertices.draw(Renderer::TriangleList);
2300 						}
2301 						dynamicVertices.reset();
2302 						dynamicVertices.lock();
2303 						iNbIndice = 0;
2304 						pussInd = dynamicVertices.indices;
2305 						pVertex = dynamicVertices.append(iNbVertex);
2306 					}
2307 
2308 					//-----------------------------------------------------------------------
2309 					//																PRECALCUL
2310 					float tu[4];
2311 					float tv[4];
2312 					float _fTransp[4];
2313 					unsigned short nu;
2314 					long nrm=0;
2315 
2316 					if	(	(EEfabs(ep->nrml[0].y)>=0.9f)
2317 						||	(EEfabs(ep->nrml[1].y)>=0.9f)
2318 						||	(EEfabs(ep->nrml[2].y)>=0.9f)	)
2319 						nrm=1;
2320 
2321 					for (nu=0;nu<iNbVertex;nu++)
2322 					{
2323 						if (nrm)
2324 						{
2325 							tu[nu]=(ep->v[nu].p.x*( 1.0f / 50 ));
2326 							tv[nu]=(ep->v[nu].p.z*( 1.0f / 50 ));
2327 						}
2328 						else
2329 						{
2330 							tu[nu]=ep->v[nu].uv.x*4.f;
2331 							tv[nu]=ep->v[nu].uv.y*4.f;
2332 						}
2333 
2334 						float t = max(10.f, fdist(ACTIVECAM->pos, ep->v[nu].p) - 80.f);
2335 
2336 						_fTransp[nu] = (150.f - t) * 0.006666666f;
2337 
2338 						if (_fTransp[nu] < 0.f)
2339 							_fTransp[nu]		=	0.f;
2340 						// t cannot be greater than 1.f (b should be negative for that)
2341 					}
2342 
2343 					//-----------------------------------------------------------------------
2344 					//																FILL DATA
2345 					for ( int idx = 0  ; idx < iNbVertex ; ++idx )
2346 					{
2347 						pVertex->p.x				=	ep->v[idx].p.x;
2348 						pVertex->p.y				=	- ep->v[idx].p.y;
2349 						pVertex->p.z				=	ep->v[idx].p.z;
2350 						pVertex->color = Color::gray(_fTransp[idx]).toBGR();
2351 						pVertex->uv[0].x				=	tu[idx];
2352 						pVertex->uv[0].y				=	tv[idx];
2353 						pVertex++;
2354 
2355 						*pussInd++				=	iNbIndice++;
2356 						dynamicVertices.nbindices++;
2357 					}
2358 
2359 					if(iNbVertex&4) {
2360 						*pussInd++=iNbIndice-2;
2361 						*pussInd++=iNbIndice-3;
2362 						dynamicVertices.nbindices += 2;
2363 					}
2364 
2365 				}
2366 
2367 					//---------------------------------------------------------------------------
2368 					//														   CLEAR CURRENT ZMAP
2369 				pTexCurr->TextureRefinement->vPolyZMap.clear();
2370 
2371 				dynamicVertices.unlock();
2372 				if(dynamicVertices.nbindices) {
2373 					dynamicVertices.draw(Renderer::TriangleList);
2374 				}
2375 				dynamicVertices.done();
2376 
2377 			}
2378 
2379 			ppTexCurr++;
2380 		} //END  while ( iNbTex-- ) ----------------------------------------------------------
2381 
2382 		GRenderer->SetRenderState(Renderer::DepthWrite, true);
2383 		GRenderer->SetRenderState(Renderer::AlphaBlending, false);
2384 	}
2385 }
2386 
2387 //-----------------------------------------------------------------------------
2388 
ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(long room_num)2389 void ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(long room_num)
2390 {
2391 	if (RoomDraw[room_num].count)
2392 	{
2393 		//render transparency
2394 		int iNbTex=portals->room[room_num].usNbTextures;
2395 		TextureContainer **ppTexCurr=portals->room[room_num].ppTextureContainer;
2396 
2397 		while(iNbTex--) {
2398 
2399 			TextureContainer * pTexCurr = *ppTexCurr;
2400 			GRenderer->SetTexture(0, pTexCurr);
2401 
2402 			//NORMAL TRANS
2403 			if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans)
2404 			{
2405 				SetZBias(2);
2406 				GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendDstColor);
2407 
2408 				portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TNormalTrans], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans);
2409 
2410 				EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans;
2411 				pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TNormalTrans=0;
2412 			}
2413 
2414 			//MULTIPLICATIVE
2415 			if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative)
2416 			{
2417 				SetZBias(2);
2418 				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
2419 
2420 				portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TMultiplicative], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative);
2421 
2422 				EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative;
2423 				pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TMultiplicative=0;
2424 			}
2425 
2426 			//ADDITIVE
2427 			if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive)
2428 			{
2429 				SetZBias(2);
2430 				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
2431 
2432 				portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TAdditive], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive);
2433 
2434 				EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive;
2435 				pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TAdditive=0;
2436 			}
2437 
2438 			//SUBSTRACTIVE
2439 			if(pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive)
2440 			{
2441 				SetZBias(8);
2442 
2443 				GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
2444 
2445 				portals->room[room_num].pVertexBuffer->drawIndexed(Renderer::TriangleList, pTexCurr->tMatRoom[room_num].uslNbVertex, pTexCurr->tMatRoom[room_num].uslStartVertex, &portals->room[room_num].pussIndice[pTexCurr->tMatRoom[room_num].uslStartCull_TSubstractive], pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive);
2446 
2447 				EERIEDrawnPolys+=pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive;
2448 				pTexCurr->tMatRoom[room_num].uslNbIndiceCull_TSubstractive=0;
2449 			}
2450 
2451 			ppTexCurr++;
2452 		}
2453 	}
2454 }
2455 
2456 
ARX_PORTALS_ComputeRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim)2457 void ARX_PORTALS_ComputeRoom(long room_num,EERIE_2D_BBOX * bbox,long prec,long tim)
2458 {
2459 	if (portals==NULL) return;
2460 
2461 	if (bbox->min.x>=DANAESIZX) return;
2462 
2463 	if (bbox->min.y>=DANAESIZY) return;
2464 
2465 	if (bbox->max.x<0) return;
2466 
2467 	if (bbox->max.y<0) return;
2468 
2469 	if (bbox->min.x>=bbox->max.x) return;
2470 
2471 	if (bbox->min.y>=bbox->max.y) return;
2472 
2473 	if (RoomDraw[room_num].count==0)
2474 		RoomDrawListAdd(room_num);
2475 
2476 	ARX_PORTALS_BlendBBox(room_num,bbox);
2477 	RoomDraw[room_num].count++;
2478 
2479 		// Now Checks For room Portals !!!
2480 	for (long lll=0;lll<portals->room[room_num].nb_portals;lll++)
2481 	{
2482 		if (portals->portals[portals->room[room_num].portals[lll]].useportal) continue;
2483 
2484 		EERIE_PORTALS * po=&portals->portals[portals->room[room_num].portals[lll]];
2485 		EERIEPOLY * epp=&po->poly;
2486 
2487 		float threshold = square(ACTIVECAM->cdepth - ACTIVECAM->cdepth * fZFogEnd);
2488 		if((distSqr(ACTIVECAM->pos, epp->v[0].p) > threshold)
2489 		   && (distSqr(ACTIVECAM->pos, epp->v[2].p) > threshold)
2490 		   && (distSqr(ACTIVECAM->pos, epp->center) > threshold)) {
2491 			portals->portals[portals->room[room_num].portals[lll]].useportal=2;
2492 			continue;
2493 		}
2494 
2495 		if (!EERIERTPPoly2(epp)) continue;
2496 
2497 
2498 		int Cull=BackFaceCull2D(epp->tv);
2499 
2500 
2501 		EERIE_2D_BBOX n_bbox;
2502 		n_bbox.max.x=n_bbox.min.x=epp->tv[0].p.x;
2503 		n_bbox.max.y=n_bbox.min.y=epp->tv[0].p.y;
2504 		long to;
2505 
2506 		if (epp->type & POLY_QUAD)
2507 			to=4;
2508 		else
2509 			to=3;
2510 
2511 		float minz=epp->tv[0].p.z;
2512 		float maxz=epp->tv[0].p.z;
2513 
2514 		for (long nn=1;nn<to;nn++)
2515 		{
2516 			n_bbox.min.x=min(n_bbox.min.x , epp->tv[nn].p.x);
2517 			n_bbox.min.y=min(n_bbox.min.y , epp->tv[nn].p.y);
2518 			n_bbox.max.x=max(n_bbox.max.x , epp->tv[nn].p.x);
2519 			n_bbox.max.y=max(n_bbox.max.y , epp->tv[nn].p.y);
2520 			minz=min(minz,epp->tv[0].p.z);
2521 			maxz=max(maxz,epp->tv[0].p.z);
2522 		}
2523 
2524 		if (minz>0.5f) continue;
2525 
2526 		if (	bbox->min.x > n_bbox.max.x || n_bbox.min.x > bbox->max.x
2527 			||	bbox->min.y > n_bbox.max.y || n_bbox.min.y > bbox->max.y)
2528 			continue;
2529 
2530 		if (Cull)
2531 			EERIEPOLY_DrawWired(epp, Color::red);
2532 		else
2533 			EERIEPOLY_DrawWired(epp, Color::green);
2534 
2535 		n_bbox.min.x=max(n_bbox.min.x,bbox->min.x);
2536 		n_bbox.min.y=max(n_bbox.min.y,bbox->min.y);
2537 		n_bbox.max.x=min(n_bbox.max.x,bbox->max.x);
2538 		n_bbox.max.y=min(n_bbox.max.y,bbox->max.y);
2539 
2540 		if (po->room_1==room_num)
2541 		{
2542 			if (!Cull)
2543 			{
2544 				portals->portals[portals->room[room_num].portals[lll]].useportal=1;
2545 				ARX_PORTALS_ComputeRoom(po->room_2,&n_bbox,prec,tim);
2546 			}
2547 		}
2548 		else if (po->room_2==room_num)
2549 		{
2550 			if (Cull)
2551 			{
2552 				portals->portals[portals->room[room_num].portals[lll]].useportal=1;
2553 				ARX_PORTALS_ComputeRoom(po->room_1,&n_bbox,prec,tim);
2554 			}
2555 		}
2556 	}
2557 }
2558 
ARX_PORTALS_Frustrum_ComputeRoom(long room_num,EERIE_FRUSTRUM * frustrum,long prec,long tim)2559 long ARX_PORTALS_Frustrum_ComputeRoom(long room_num,EERIE_FRUSTRUM * frustrum,long prec,long tim)
2560 {
2561 	long portals_count=0;
2562 
2563 	if (portals==NULL) return 0;
2564 
2565 	if (RoomDraw[room_num].count==0)
2566 	{
2567 		RoomDrawListAdd(room_num);
2568 	}
2569 
2570 	RoomFrustrumAdd(room_num,frustrum);
2571 	RoomDraw[room_num].count++;
2572 
2573 	float fClippZFar=ACTIVECAM->cdepth*(fZFogEnd*1.1f);
2574 
2575 	// Now Checks For room Portals !!!
2576 	for (long lll=0;lll<portals->room[room_num].nb_portals;lll++)
2577 	{
2578 		if (portals->portals[portals->room[room_num].portals[lll]].useportal) continue;
2579 
2580 		EERIE_PORTALS * po=&portals->portals[portals->room[room_num].portals[lll]];
2581 		EERIEPOLY * epp=&po->poly;
2582 
2583 		//clipp NEAR & FAR
2584 		unsigned char ucVisibilityNear=0;
2585 		unsigned char ucVisibilityFar=0;
2586 		float fDist0=(efpPlaneNear.a*epp->v[0].p.x)+(efpPlaneNear.b*epp->v[0].p.y)+(efpPlaneNear.c*epp->v[0].p.z)+efpPlaneNear.d;
2587 
2588 		if(fDist0<0.f) ucVisibilityNear++;
2589 		else
2590 		{
2591 			if(fDist0>fClippZFar) ucVisibilityFar++;
2592 		}
2593 
2594 		fDist0=(efpPlaneNear.a*epp->v[1].p.x)+(efpPlaneNear.b*epp->v[1].p.y)+(efpPlaneNear.c*epp->v[1].p.z)+efpPlaneNear.d;
2595 
2596 		if(fDist0<0.f) ucVisibilityNear++;
2597 		else
2598 		{
2599 			if(fDist0>fClippZFar) ucVisibilityFar++;
2600 		}
2601 
2602 		fDist0=(efpPlaneNear.a*epp->v[2].p.x)+(efpPlaneNear.b*epp->v[2].p.y)+(efpPlaneNear.c*epp->v[2].p.z)+efpPlaneNear.d;
2603 
2604 		if(fDist0<0.f) ucVisibilityNear++;
2605 		else
2606 		{
2607 			if(fDist0>fClippZFar) ucVisibilityFar++;
2608 		}
2609 
2610 		fDist0=(efpPlaneNear.a*epp->v[3].p.x)+(efpPlaneNear.b*epp->v[3].p.y)+(efpPlaneNear.c*epp->v[3].p.z)+efpPlaneNear.d;
2611 
2612 		if(fDist0<0.f) ucVisibilityNear++;
2613 		else
2614 		{
2615 			if(fDist0>fClippZFar) ucVisibilityFar++;
2616 		}
2617 
2618 		if(	(ucVisibilityFar&4)||(ucVisibilityNear&4) )
2619 		{
2620 			portals->portals[portals->room[room_num].portals[lll]].useportal=2;
2621 			continue;
2622 		}
2623 
2624 		Vec3f pos = epp->center - ACTIVECAM->pos;
2625 		float fRes = dot(pos, epp->norm);
2626 		long ret=1;
2627 		if(IsSphereInFrustrum(epp->v[0].rhw, &epp->center, frustrum)) {
2628 			ret=0;
2629 		}
2630 
2631 		if (ret)
2632 		{
2633 			EERIERTPPoly2(epp);
2634 
2635 			if (NEED_TEST_TEXT)
2636 				EERIEPOLY_DrawWired(epp, Color::magenta);
2637 
2638 			continue;
2639 		}
2640 
2641 		portals_count++;
2642 
2643 		EERIERTPPoly2(epp);
2644 
2645 		int Cull;
2646 
2647 		if (fRes<0.f) Cull=0;
2648 		else Cull=1;
2649 
2650 
2651 		EERIE_FRUSTRUM fd;
2652 		CreateFrustrum(&fd,epp,Cull);
2653 
2654 		if (NEED_TEST_TEXT)
2655 		{
2656 			if (Cull)
2657 				EERIEPOLY_DrawWired(epp, Color::red);
2658 			else
2659 				EERIEPOLY_DrawWired(epp, Color::blue);
2660 		}
2661 
2662 
2663 		if (po->room_1==room_num)
2664 		{
2665 			if (!Cull)
2666 			{
2667 				portals->portals[portals->room[room_num].portals[lll]].useportal=1;
2668 				ARX_PORTALS_Frustrum_ComputeRoom(po->room_2,&fd,prec,tim);
2669 			}
2670 		}
2671 		else if (po->room_2==room_num)
2672 		{
2673 			if (Cull)
2674 			{
2675 				portals->portals[portals->room[room_num].portals[lll]].useportal=1;
2676 				ARX_PORTALS_Frustrum_ComputeRoom(po->room_1,&fd,prec,tim);
2677 			}
2678 		}
2679 	}
2680 
2681 	return portals_count;
2682 }
2683 
Clip_Visible(const Vec3f * orgn,Vec3f * dest)2684 bool Clip_Visible(const Vec3f * orgn, Vec3f * dest) {
2685 
2686 	float dx, dy, dz, adx, ady, adz, ix, iz;
2687 	float x0, z0;
2688 	float forr, temp;
2689 
2690 	dx=(dest->x-orgn->x);
2691 	adx=EEfabs(dx);
2692 	dy=(dest->y-orgn->y);
2693 	ady=EEfabs(dy);
2694 	dz=(dest->z-orgn->z);
2695 	adz=EEfabs(dz);
2696 
2697 	x0=orgn->x;
2698 	z0=orgn->z;
2699 
2700 	if ( (adx>=ady) && (adx>=adz))
2701 	{
2702 		if (adx != dx)
2703 		{
2704 			ix = -1.f * PASS;
2705 		}
2706 		else
2707 		{
2708 			ix = 1.f * PASS;
2709 		}
2710 
2711 		forr=adx;
2712 		temp=1.f/(adx/PASS);
2713 		iz=dz*temp;
2714 	}
2715 	else if ( (ady>=adx) && (ady>=adz))
2716 	{
2717 		forr=ady;
2718 		temp=1.f/(ady/PASS);
2719 		ix=dx*temp;
2720 		iz=dz*temp;
2721 	}
2722 	else
2723 	{
2724 		if (adz != dz)
2725 		{
2726 			iz = -1.f * PASS;
2727 		}
2728 		else
2729 		{
2730 			iz = 1.f * PASS;
2731 		}
2732 
2733 		forr=adz;
2734 		temp=1.f/(adz/PASS);
2735 		ix=dx*temp;
2736 	}
2737 
2738 
2739 long curpixel;
2740 	long tot;
2741 	tot=0;
2742 
2743 	long x,y;
2744 	FAST_BKG_DATA * LAST_eg=NULL;
2745 	curpixel=2;
2746 	x0+=ix*2;
2747 		z0+=iz*2;
2748 		forr-=PASS*2;
2749 
2750 	while (forr>PASSS)
2751 	{
2752 			FAST_BKG_DATA * feg;
2753 			x = x0 * ACTIVEBKG->Xmul;
2754 			y = z0 * ACTIVEBKG->Zmul;
2755 			feg=&ACTIVEBKG->fastdata[x][y];
2756 
2757 		if (feg!=LAST_eg)
2758 		{
2759 
2760 			LAST_eg=feg;
2761 
2762 			if (feg->nothing)	tot += 2;
2763 
2764 			if (tot>MAX_OUT) return false;
2765 		}
2766 
2767 		float v=(float)curpixel*( 1.0f / 5 );
2768 
2769 		if (v<1.f) v=1.f;
2770 
2771 		x0+=ix*v;
2772 		z0+=iz*v;
2773 		forr-=PASS*v;
2774 	}
2775 
2776 	return true;//hard;
2777 }
2778 
2779 
2780 
spGetTruePolyY(const EERIEPOLY * ep,const Vec3f * pos,float * ret)2781 bool spGetTruePolyY(const EERIEPOLY * ep, const Vec3f * pos, float * ret) {
2782 
2783 	Vec3f s21 = ep->v[1].p - ep->v[0].p;
2784 	Vec3f s31 = ep->v[2].p - ep->v[0].p;
2785 
2786 	Vec3f n;
2787 	n.y = (s21.z * s31.x) - (s21.x * s31.z);
2788 	n.x = (s21.y * s31.z) - (s21.z * s31.y);
2789 	n.z = (s21.x * s31.y) - (s21.y * s31.x);
2790 
2791 	float d = ep->v[0].p.x * n.x + ep->v[0].p.y * n.y + ep->v[0].p.z * n.z;
2792 	*ret = (d - n.x * pos->x - n.z * pos->z) / n.y;
2793 
2794 	return true;
2795 }
2796 
2797 extern long SPECIAL_DRAGINTER_RENDER;
2798 long MAX_FRAME_COUNT=0;
2799 //*************************************************************************************
2800 // Main Background Rendering Proc.
2801 // ie: Big Mess
2802 //*************************************************************************************
2803 ///////////////////////////////////////////////////////////
ARX_SCENE_Render(long flag)2804 void ARX_SCENE_Render(long flag) {
2805 
2806 	FRAME_COUNT++;
2807 
2808 	if (FRAME_COUNT>MAX_FRAME_COUNT) FRAME_COUNT=0;
2809 
2810 	if (EDITMODE) FRAME_COUNT=0;
2811 
2812 	if ((player.Interface & INTER_MAP ) &&  (!(player.Interface & INTER_COMBATMODE)))
2813 		FRAME_COUNT=0;
2814 
2815 	static long x0=0;
2816 	static long x1=0;
2817 	static long z0=0;
2818 	static long z1=0;
2819 	long i;
2820 	EERIEPOLY * ep;
2821 	FAST_BKG_DATA * feg;
2822 
2823 	unsigned long tim = (unsigned long)(arxtime);
2824 
2825 	WATEREFFECT+=0.0005f*framedelay;
2826 
2827 	if (flag == 3)
2828 		return;
2829 
2830 	float cval=(float)ACTIVECAM->clip3D+4;
2831 	long lcval = cval;
2832 
2833 	//TODO(lubosz): no if / loop ?
2834 
2835 	{
2836 
2837 		PrepareActiveCamera();
2838 		float xx=(float)(ACTIVECAM->pos.x*ACTIVEBKG->Xmul);
2839 		float yy=(float)(ACTIVECAM->pos.z*ACTIVEBKG->Zmul);
2840 
2841 		ACTIVECAM->Xsnap = xx;
2842 		ACTIVECAM->Zsnap = yy;
2843 		ACTIVECAM->Xsnap = clamp(ACTIVECAM->Xsnap,0,ACTIVEBKG->Xsize-1);
2844 		ACTIVECAM->Zsnap = clamp(ACTIVECAM->Zsnap,0,ACTIVEBKG->Zsize-1);
2845 
2846 		x0=ACTIVECAM->Xsnap-lcval;
2847 		x1=ACTIVECAM->Xsnap+lcval;
2848 		z0=ACTIVECAM->Zsnap-lcval;
2849 		z1=ACTIVECAM->Zsnap+lcval;
2850 		x0 = clamp(x0,0,ACTIVEBKG->Xsize-1);
2851 		x1 = clamp(x1,0,ACTIVEBKG->Xsize-1);
2852 		z0 = clamp(z0,0,ACTIVEBKG->Zsize-2);
2853 		z1 = clamp(z1,0,ACTIVEBKG->Xsize-2);
2854 
2855 
2856 		ACTIVEBKG->Backg[ACTIVECAM->Xsnap+ACTIVECAM->Zsnap * ACTIVEBKG->Xsize].treat = 1;
2857 		float prec = 1.f / (ACTIVECAM->cdepth * ACTIVECAM->Zmul);
2858 
2859 
2860 
2861 	long lll;
2862 
2863 	// Temporary Hack...
2864 	long LAST_FC=FRAME_COUNT;
2865 	FRAME_COUNT=0;
2866 
2867 	if ((FRAME_COUNT<=0) && (ModeLight & MODE_DYNAMICLIGHT)) PrecalcDynamicLighting(x0,z0,x1,z1);
2868 
2869 	float temp0=radians(ACTIVECAM->angle.b);
2870 	ACTIVECAM->norm.x=-(float)EEsin(temp0);
2871 	ACTIVECAM->norm.y= (float)EEsin(radians(ACTIVECAM->angle.a));
2872 	ACTIVECAM->norm.z= (float)EEcos(temp0);
2873 
2874 	fnormalize(ACTIVECAM->norm);
2875 
2876 	// Go for a growing-square-spirallike-render around the camera position
2877 	// (To maximize Z-Buffer efficiency)
2878 	temp0=0;
2879 	Vec3f nrm;
2880 
2881 	long zsnap=ACTIVECAM->Zsnap;
2882 	zsnap=min((int)zsnap,ACTIVEBKG->Zsize-1);
2883 	zsnap=max((int)zsnap,1);
2884 	long xsnap=ACTIVECAM->Xsnap;
2885 	xsnap=min((int)xsnap,ACTIVEBKG->Xsize-1);
2886 	xsnap=max((int)xsnap,1);
2887 
2888 
2889 
2890 	if (!USE_LIGHT_OPTIM)
2891 	{
2892  		for (long j=0;j<ACTIVEBKG->Zsize;j++)
2893 		{
2894 			feg=&ACTIVEBKG->fastdata[0][j];
2895 
2896 			for (i=0; i<ACTIVEBKG->Xsize; i++, feg++)
2897 			{
2898 				if (feg->treat)
2899 					feg->treat=0;
2900 			}
2901 		}
2902 	}
2903 	else
2904 	{
2905 		for (long j=z0;j<=z1;j++)
2906 		{
2907 			for (i=x0; i<x1; i++)
2908 			{
2909 				feg=&ACTIVEBKG->fastdata[i][j];
2910 				feg->treat=0;
2911 			}
2912 		}
2913 
2914 		for (long j=0;j<ACTIVEBKG->Zsize;j++)
2915 		for (i=0; i<ACTIVEBKG->Xsize; i++)
2916 		{
2917 			if (tilelights[i][j].num)
2918 				tilelights[i][j].num=0;
2919 		}
2920 			}
2921 
2922 
2923 if (USE_PORTALS && portals)
2924 {
2925 	long room_num=ARX_PORTALS_GetRoomNumForPosition(&ACTIVECAM->pos,1);
2926 	LAST_ROOM=room_num;
2927 
2928 	if (room_num>-1)
2929 	{
2930 		ARX_PORTALS_InitDrawnRooms();
2931 
2932 		long lprec = checked_range_cast<long>(prec);
2933 
2934 		switch (USE_PORTALS)
2935 		{
2936 			case 1: {
2937 				EERIE_2D_BBOX bbox;
2938 				bbox.min = Vec2f::ZERO;
2939 				bbox.max = Vec2f(float(DANAESIZX), float(DANAESIZY));
2940 				ARX_PORTALS_ComputeRoom(room_num, &bbox, lprec, tim);
2941 				ARX_PORTALS_RenderRooms(lprec, tim);
2942 				break;
2943 			}
2944 			case 2: {
2945 				EERIE_FRUSTRUM frustrum;
2946 				CreateScreenFrustrum(&frustrum);
2947 				LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim);
2948 				ARX_PORTALS_Frustrum_RenderRooms(lprec,tim);
2949 				break;
2950 			}
2951 			case 3: {
2952 				EERIE_FRUSTRUM frustrum;
2953 				CreateScreenFrustrum(&frustrum);
2954 				LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim);
2955 				LogWarning << "unimplemented";
2956 				break;
2957 			}
2958 			case 4: {
2959 				EERIE_FRUSTRUM frustrum;
2960 				CreateScreenFrustrum(&frustrum);
2961 				LAST_PORTALS_COUNT=ARX_PORTALS_Frustrum_ComputeRoom(room_num,&frustrum,lprec,tim);
2962 				ARX_PORTALS_Frustrum_RenderRoomsTCullSoft(lprec,tim);
2963 				break;
2964 			}
2965 		}
2966 
2967 
2968 		//ARX_SCENE_DilateBackground();
2969 	}
2970 }
2971 else
2972 {
2973 	for (long n=0;n<=lcval;n++)
2974 	{
2975 		temp0+=100.f;
2976 
2977 	for (long j=zsnap-n;j<=zsnap+n;j++)
2978 	{
2979 	for (i=xsnap-n;i<=xsnap+n;i++)
2980 	{
2981 		if ( (i!=xsnap-n) && (i!=xsnap+n) && (j!=zsnap-n) && (j!=zsnap+n) )
2982 		{
2983 			continue;
2984 		}
2985 
2986 		if ( (i<0) || (j<0) || (i>=ACTIVEBKG->Xsize) || (j>=ACTIVEBKG->Zsize) ) continue;
2987 
2988 		if (i<x0) continue;
2989 
2990 		if (i>x1) continue;
2991 
2992 						feg = &ACTIVEBKG->fastdata[i][j];
2993 
2994 		if (!feg->treat) continue;
2995 
2996 		for ( lll=0;lll<feg->nbpoly;lll++)
2997 		{
2998 			//SPECIFIC INTEL COMPILER
2999 			ep=&feg->polydata[lll];
3000 
3001 			if (ep->type & (POLY_IGNORE | POLY_NODRAW))
3002 				continue;
3003 
3004 			if ((ep->min.y > feg->frustrum_maxy)
3005 				|| (ep->max.y < feg->frustrum_miny))
3006 				continue;
3007 
3008 			// GO for 3D Backface Culling
3009 			if (ep->type & POLY_DOUBLESIDED)
3010 				GRenderer->SetCulling(Renderer::CullNone);
3011 			else
3012 			{
3013 
3014 				nrm = ep->v[2].p - ACTIVECAM->pos;
3015 				if ( ep->type & POLY_QUAD)
3016 				{
3017 					if ( (dot( ep->norm , nrm )>0.f) &&
3018 						 (dot( ep->norm2 , nrm )>0.f) )
3019 						continue;
3020 				}
3021 				else if ( dot( ep->norm , nrm )>0.f)
3022 						continue;
3023 
3024 				GRenderer->SetCulling(Renderer::CullCW);
3025 			}
3026 
3027 							if (!EERIERTPPoly(ep))
3028 				continue;
3029 
3030 			long to;
3031 			if ( ep->type & POLY_QUAD)
3032 			{
3033 				if (FRAME_COUNT<=0) ep->tv[3].color=ep->v[3].color;
3034 
3035 				to=4;
3036 			}
3037 			else to=3;
3038 
3039 			if (ep->type & POLY_TRANS)
3040 			{
3041 				ManageLavaWater(ep,to,tim);
3042 				TransPol[TRANSPOLYSPOS++]=ep;
3043 
3044 				if (TRANSPOLYSPOS>=MAX_TRANSPOL) TRANSPOLYSPOS=MAX_TRANSPOL-1;
3045 
3046 				if (ViewMode)
3047 				{
3048 					if (ViewMode & VIEWMODE_WIRE)
3049 						EERIEPOLY_DrawWired(ep);
3050 
3051 					if (ViewMode & VIEWMODE_NORMALS)
3052 						EERIEPOLY_DrawNormals(ep);
3053 				}
3054 
3055 				continue;
3056 			}
3057 
3058 			if (!Project.improve)  // Normal View...
3059 			{
3060 				if (ep->type & POLY_GLOW) ep->tv[0].color=ep->tv[1].color=ep->tv[2].color=ep->tv[3].color=0xFFFFFFFF;
3061 				else
3062 				{
3063 					if (FRAME_COUNT<=0)
3064 					{
3065 						if (ModeLight & MODE_DYNAMICLIGHT) 	ApplyDynLight(ep);
3066 						else
3067 						{
3068 							ep->tv[0].color=ep->v[0].color;
3069 							ep->tv[1].color=ep->v[1].color;
3070 							ep->tv[2].color=ep->v[2].color;
3071 						}
3072 
3073 					}
3074 				}
3075 
3076 				ManageLavaWater(ep,to,tim);
3077 
3078 				Delayed_EERIEDRAWPRIM(ep);
3079 
3080 				if (ViewMode)
3081 				{
3082 
3083 					if (ViewMode & VIEWMODE_WIRE)
3084 						EERIEPOLY_DrawWired(ep);
3085 
3086 					if (ViewMode & VIEWMODE_NORMALS)
3087 						EERIEPOLY_DrawNormals(ep);
3088 				}
3089 			}
3090 			else // Improve Vision Activated
3091 			{
3092 				if (FRAME_COUNT<=0)
3093 				{
3094 					if ( ModeLight & MODE_DYNAMICLIGHT ) 	ApplyDynLight(ep);
3095 					else
3096 					{
3097 						ep->tv[0].color=ep->v[0].color;
3098 						ep->tv[1].color=ep->v[1].color;
3099 						ep->tv[2].color=ep->v[2].color;
3100 					}
3101 
3102 
3103 					for (long k=0;k<to;k++)
3104 					{
3105 						long lr=(ep->tv[k].color>>16) & 255;
3106 						float ffr=(float)(lr);
3107 
3108 						float dd=(ep->tv[k].p.z*prec);
3109 
3110 						if (dd>1.f) dd=1.f;
3111 
3112 						if (dd<0.f) dd=0.f;
3113 
3114 						float fb=((1.f-dd)*6.f + (EEfabs(ep->nrml[k].x)+EEfabs(ep->nrml[k].y)))*0.125f;
3115 						float fr=((0.6f-dd)*6.f + (EEfabs(ep->nrml[k].z)+EEfabs(ep->nrml[k].y)))*0.125f;//(1.f-dd);
3116 
3117 						if (fr<0.f) fr=0.f;
3118 						else fr=max(ffr,fr*255.f);
3119 
3120 						fb*=255.f;
3121 						long lfb = fb;
3122 						long lfr = fr;
3123 						ep->tv[k].color=( 0xff001E00L | ( (lfr & 255) << 16) | (lfb & 255) );
3124 						//GG component locked at 0x1E
3125 					}
3126 								}
3127 
3128 				Delayed_EERIEDRAWPRIM(ep);
3129 			}
3130 			}
3131 		}
3132 	}
3133 	}
3134 }
3135 
3136 	if(GInput->isKeyPressedNowPressed(Keyboard::Key_J))
3137 		bOLD_CLIPP=!bOLD_CLIPP;
3138 
3139 	if(!Project.improve) {
3140 		ARXDRAW_DrawInterShadows();
3141 	}
3142 
3143 	FRAME_COUNT=LAST_FC;
3144 
3145 	if(USE_PORTALS<3)
3146 			Delayed_FlushAll();
3147 
3148 		ARX_THROWN_OBJECT_Manage(checked_range_cast<unsigned long>(FrameDiff));
3149 
3150 		RenderInter(0.f, 3200.f);
3151 
3152 
3153 	if (DRAGINTER) // To render Dragged objs
3154 	{
3155 		SPECIAL_DRAGINTER_RENDER=1;
3156 		ARX_INTERFACE_RenderCursor();
3157 
3158 		if(USE_PORTALS<3)
3159 			Delayed_FlushAll();
3160 
3161 		SPECIAL_DRAGINTER_RENDER=0;
3162 	}
3163 
3164 	PopAllTriangleList();
3165 
3166 					}
3167 
3168 	if (ACTIVECAM->type!=CAM_TOPVIEW)
3169 	{
3170 
3171 		if ((eyeball.exist!=0) && eyeballobj)
3172 			ARXDRAW_DrawEyeBall();
3173 
3174 
3175 		GRenderer->SetRenderState(Renderer::DepthWrite, false);
3176 
3177 		if (BoomCount)
3178 			ARXDRAW_DrawPolyBoom();
3179 
3180 		PopAllTriangleListTransparency();
3181 
3182 		if(	(USE_PORTALS>2)&&
3183 			(portals) )
3184 		{
3185 			ARX_PORTALS_Frustrum_RenderRooms_TransparencyT();
3186 		}
3187 		else
3188 		{
3189 			if (TRANSPOLYSPOS)
3190 				ARXDRAW_DrawAllTransPolysPos();
3191 		}
3192 	}
3193 
3194 if (HALOCUR>0)
3195 {
3196 	GRenderer->ResetTexture(0);
3197 	GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendOne);
3198 	GRenderer->SetRenderState(Renderer::AlphaBlending, true);
3199 	GRenderer->SetCulling(Renderer::CullNone);
3200 	GRenderer->SetRenderState(Renderer::DepthWrite, false);
3201 
3202 	for (i=0;i<HALOCUR;i++)
3203 	{
3204 		//blue halo rendering (keyword : BLUE HALO RENDERING HIGHLIGHT AURA)
3205 		TexturedVertex * vert=&LATERDRAWHALO[(i<<2)];
3206 
3207 		if (vert[2].color == 0)
3208 		{
3209 			GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
3210 			vert[2].color =0xFF000000;
3211 			EERIEDRAWPRIM(Renderer::TriangleFan, vert, 4);
3212 			GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendOne);
3213 		}
3214 		else EERIEDRAWPRIM(Renderer::TriangleFan, vert, 4);
3215 	}
3216 
3217 		 HALOCUR = 0;
3218 	GRenderer->SetRenderState(Renderer::AlphaBlending, false);
3219 }
3220 
3221 	GRenderer->SetCulling(Renderer::CullCCW);
3222 	GRenderer->SetRenderState(Renderer::AlphaBlending, false);
3223 	GRenderer->SetRenderState(Renderer::DepthWrite, true);
3224 
3225 #ifdef BUILD_EDITOR
3226 	if (EDITION==EDITION_LIGHTS)
3227 		ARXDRAW_DrawAllLights(x0,z0,x1,z1);
3228 #endif
3229 
3230 }
3231 
3232