Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
wbview3d.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19// wbview3d.cpp : implementation file
20//
21
22#include "stdafx.h"
23#include "resource.h"
24#include "wwmath.h"
25#include "ww3d.h"
26#include "scene.h"
27#include "rendobj.h"
28#include "camera.h"
29#include "intersec.h"
32#include "agg_def.h"
33#include "msgloop.h"
34#include "part_ldr.h"
35#include "rendobj.h"
36#include "hanim.h"
37#include "dx8wrapper.h"
38#include "dx8indexbuffer.h"
39#include "dx8vertexbuffer.h"
40#include "dx8renderer.h"
41#include "dx8fvf.h"
42#include "vertmaterial.h"
43#include "font3d.h"
44#include "render2d.h"
45#include "rddesc.h"
46#include "textdraw.h"
47#include "rect.h"
48#include "mesh.h"
49#include "meshmdl.h"
50#include "line3d.h"
51#include "dynamesh.h"
52#include "sphereobj.h"
53#include "ringobj.h"
54#include "surfaceclass.h"
55#include "vector2i.h"
56#include "bmp2d.h"
57#include "decalsys.h"
58#include "shattersystem.h"
59#include "light.h"
60#include "texproject.h"
61#include "keyboard.h"
62#include "MapSettings.h"
63#include "predlod.h"
64#include "SelectMacrotexture.h"
65#include "WorldBuilderView.h"
66#include "WHeightMapEdit.h"
67#include "WorldBuilderDoc.h"
68#include "MainFrm.h"
72#include "WBHeightMap.h"
76#include "DrawObject.h"
77#include "common/MapObject.h"
78#include "common/GlobalData.h"
79#include "ShadowOptions.h"
80#include "worldbuilder.h"
81#include "wbview3d.h"
82#include "Common/Debug.h"
83#include "Common/ThingFactory.h"
84#include "GameClient/Water.h"
87#include "Common/Language.h"
88#include "Common/FileSystem.h"
90#include "GameLogic/SidesList.h"
92#include "GameClient/View.h"
93#include "GlobalLightOptions.h"
94#include "LayersList.h"
95#include "ImpassableOptions.h"
96
97
98#include <d3dx8.h>
99
100#ifdef _INTERNAL
101// for occasional debugging...
102//#pragma optimize("", off)
103//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
104#endif
105
106// ----------------------------------------------------------------------------
107// Misc. Forward Declarations
108// ----------------------------------------------------------------------------
110
111// ----------------------------------------------------------------------------
112// Constants:
113// ----------------------------------------------------------------------------
114#define MAX_LOADSTRING 100
115#define WINDOW_WIDTH 640
116#define WINDOW_HEIGHT 480
117#define UPDATE_TIME 100 /* 10 frames a second */
118#define MOUSE_WHEEL_FACTOR 32
119
120#define SAMPLE_DYNAMIC_LIGHT 1
121#ifdef SAMPLE_DYNAMIC_LIGHT
122static W3DDynamicLight * theDynamicLight = NULL;
123static Real theLightXOffset = 0.1f;
124static Real theLightYOffset = 0.07f;
125static Int theFlashCount = 0;
126#endif
127
128// ----------------------------------------------------------------------------
129// Global Variables:
130// ----------------------------------------------------------------------------
131
132// ----------------------------------------------------------------------------
133// Static Functions
134// ----------------------------------------------------------------------------
135
136static void WWDebug_Message_Callback(DebugType type, const char * message);
137static void WWAssert_Callback(const char * message);
138static void Debug_Refs(void);
139
140// ----------------------------------------------------------------------------
141static void WWDebug_Message_Callback(DebugType type, const char * message)
142{
143#ifdef _DEBUG
144 ::OutputDebugString(message);
145#endif
146}
147
148// ----------------------------------------------------------------------------
149static void WWAssert_Callback(const char * message)
150{
151#ifdef _DEBUG
152 ::OutputDebugString(message);
153 ::DebugBreak();
154#endif
155}
156
157
158// The W3DShadowManager accesses TheTacticalView, so we have to create
159// a stub class & object in Worldbuilder for it to access.
160class PlaceholderView : public View
161{
162protected:
165
166protected:
167 virtual View *prependViewToList( View *list ) {return NULL;};
168 virtual View *getNextView( void ) { return NULL; }
169public:
170
171 virtual void init( void ){};
172
173 virtual UnsignedInt getID( void ) { return 1; }
174
175 virtual Drawable *pickDrawable( const ICoord2D *screen, Bool forceAttack, PickType pickType ){return NULL;};
176
178 virtual Int iterateDrawablesInRegion( IRegion2D *screenRegion,
179 Bool (*callback)( Drawable *draw, void *userData ),
180 void *userData ) {return 0;};
182 virtual void screenToWorld( const ICoord2D *s, Coord3D *w ) {};
183 virtual void screenToTerrain( const ICoord2D *screen, Coord3D *world ) {};
184 virtual void screenToWorldAtZ( const ICoord2D *s, Coord3D *w, Real z ) {};
188
189 virtual void drawView( void ) {};
190 virtual void updateView( void ) {};
191
192 virtual void setZoomLimited( Bool limit ) {}
193 virtual Bool isZoomLimited( void ) { return TRUE; }
194
195 virtual void setWidth( Int width ) { m_width = width; }
196 virtual Int getWidth( void ) { return m_width; }
197 virtual void setHeight( Int height ) { m_height = height; }
198 virtual Int getHeight( void ) { return m_height; }
199 virtual void setOrigin( Int x, Int y) { m_originX=x; m_originY=y;}
200 virtual void getOrigin( Int *x, Int *y) { *x=m_originX; *y=m_originY;}
201
202 virtual void forceRedraw() { }
203
204 virtual void lookAt( const Coord3D *o ){};
205 virtual void initHeightForMap( void ) {};
206 virtual void scrollBy( Coord2D *delta ){};
207 virtual void moveCameraTo(const Coord3D *o, Int frames, Int shutter,
208 Bool orient, Real easeIn, Real easeOut) {lookAt(o);};
209 virtual void moveCameraAlongWaypointPath(Waypoint *way, Int frames, Int shutter,
210 Bool orient, Real easeIn, Real easeOut) {};
211 virtual Bool isCameraMovementFinished(void) {return true;};
212 virtual void resetCamera(const Coord3D *location, Int frames, Real easeIn, Real easeOut) {};
213 virtual void rotateCamera(Real rotations, Int frames, Real easeIn, Real easeOut) {};
214 virtual void rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMilliseconds, Real easeIn, Real easeOut) {};
215 virtual void cameraModFinalZoom(Real finalZoom, Real easeIn, Real easeOut){};
216 virtual void cameraModRollingAverage(Int framesToAverage){};
217 virtual void cameraModFinalTimeMultiplier(Int finalMultiplier){};
218 virtual void cameraModFinalPitch(Real finalPitch, Real easeIn, Real easeOut){};
219 virtual void cameraModFreezeTime(void){}
220 virtual void cameraModFreezeAngle(void){}
221 virtual void cameraModLookToward(Coord3D *pLoc){}
222 virtual void cameraModFinalLookToward(Coord3D *pLoc){}
223 virtual void cameraModFinalMoveTo(Coord3D *pLoc){ };
224 virtual Bool isTimeFrozen(void){ return false;}
225 virtual Int getTimeMultiplier(void) {return 1;};
226 virtual void setTimeMultiplier(Int multiple) {};
227 virtual void setDefaultView(Real pitch, Real angle, Real maxHeight) {};
228 virtual void zoomCamera( Real finalZoom, Int milliseconds, Real easeIn, Real easeOut ) {};
229 virtual void pitchCamera( Real finalPitch, Int milliseconds, Real easeIn, Real easeOut ) {};
230
231 virtual void setAngle( Real angle ){};
232 virtual Real getAngle( void ) { return 0; }
233 virtual void setPitch( Real angle ){};
234 virtual Real getPitch( void ) { return 0; }
235 virtual void setAngleAndPitchToDefault( void ){};
236 virtual void getPosition(Coord3D *pos) { ;}
237
238 virtual Real getHeightAboveGround() { return 1; }
239 virtual void setHeightAboveGround(Real z) { }
240 virtual Real getZoom() { return 1; }
241 virtual void setZoom(Real z) { }
242 virtual void zoomIn( void ) { }
243 virtual void zoomOut( void ) { }
244 virtual void setZoomToDefault( void ) { }
245 virtual Real getMaxZoom( void ) { return 0.0f; }
246 virtual void setOkToAdjustHeight( Bool val ) { }
247
248 virtual Real getTerrainHeightUnderCamera() { return 0.0f; }
250 virtual Real getCurrentHeightAboveGround() { return 0.0f; }
252
253 virtual void getLocation ( ViewLocation *location ) {};
254 virtual void setLocation ( const ViewLocation *location ){};
255
256 virtual ObjectID getCameraLock() const { return INVALID_ID; }
257 virtual void setCameraLock(ObjectID id) { }
258 virtual void snapToCameraLock( void ) { }
259 virtual void setSnapMode( CameraLockType lockType, Real lockDist ) { }
260
261 virtual Drawable *getCameraLockDrawable() const { return NULL; }
262 virtual void setCameraLockDrawable(Drawable *drawable) { }
263
264 virtual void setMouseLock( Bool mouseLocked ) {}
265 virtual Bool isMouseLocked( void ) { return FALSE; }
266
267 virtual void setFieldOfView( Real angle ) {};
268 virtual Real getFieldOfView( void ) {return 0;};
269
270 virtual Bool setViewFilterMode(enum FilterModes) {return FALSE;}
271 virtual void setViewFilterPos(const Coord3D *pos) {};
272 virtual void setFadeParameters(Int fadeFrames, Int direction) {};
273 virtual void set3DWireFrameMode(Bool enable) { };
274 virtual Bool setViewFilter( enum FilterTypes m_viewFilterMode) { return FALSE;}
275 virtual enum FilterModes getViewFilterMode(void) {return (enum FilterModes)0;}
276 virtual enum FilterTypes getViewFilterType(void) {return (enum FilterTypes)0;}
277
278 virtual void shake( const Coord3D *epicenter, CameraShakeType shakeType ) {};
279
280 virtual Real getFXPitch( void ) const { return 1.0f; }
281 virtual void forceCameraConstraintRecalc(void) { }
282 virtual void rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds, Real easeIn, Real easeOut, Bool reverseRotation) {};
283
284 virtual const Coord3D& get3DCameraPosition() const { static Coord3D dummy; return dummy; }
285
286 virtual void setGuardBandBias( const Coord2D *gb ) {};
287
288};
289
291
292
293
294// ----------------------------------------------------------------------------
295// Customized scene for worldbuilder preview window.
296// ----------------------------------------------------------------------------
297
312
313
315{
316 Bool found = false;
317 SceneIterator *sceneIter = Create_Iterator();
318 sceneIter->First();
319 while(!sceneIter->Is_Done()) {
320 if (obj==sceneIter->Current_Item()) {
321 found = true;
322 break;
323 }
324 sceneIter->Next();
325 }
326 Destroy_Iterator(sceneIter);
327 return found;
328}
329
330// ----------------------------------------------------------------------------
331
333{
334 if (RenderList.Contains(obj)) {
335 RenderObjClass *refPtr = NULL;
336 REF_PTR_SET(refPtr, obj); // ref it, as when it gets removed from the scene, may get deleted otherwise.
338 REF_PTR_RELEASE(refPtr);
339 }
340}
341
342
343void WbView3d::setObjTracking(MapObject *pMapObj, Coord3D pos, Real angle, Bool show)
344{
345 m_showObjToolTrackingObj = show;
346 if (!show) return;
347 Real scale;
348 AsciiString modelName = getModelNameAndScale(pMapObj, &scale, BODY_PRISTINE);
349 if (modelName != m_objectToolTrackingModelName) {
350 m_objectToolTrackingModelName = modelName;
351 REF_PTR_RELEASE(m_objectToolTrackingObj);
352 m_objectToolTrackingObj = m_assetManager->Create_Render_Obj( modelName.str(), scale, 0);
353 }
354 if (m_objectToolTrackingObj == NULL) {
355 return;
356 }
357 pos.z += m_heightMapRenderObj->getHeightMapHeight(pos.x, pos.y, NULL);
358 Matrix3D renderObjPos(true); // init to identity
359 renderObjPos.Translate(pos.x, pos.y, pos.z);
360 renderObjPos.Rotate_Z(angle);
361 m_objectToolTrackingObj->Set_Transform( renderObjPos );
362}
363
364// ----------------------------------------------------------------------------
365// WbView3d
366// ----------------------------------------------------------------------------
367
368// ----------------------------------------------------------------------------
369IMPLEMENT_DYNCREATE(WbView3d, WbView)
370
371// ----------------------------------------------------------------------------
373 m_assetManager(NULL),
374 m_scene(NULL),
375 m_overlayScene(NULL),
376 m_transparentObjectsScene(NULL),
377 m_baseBuildScene(NULL),
378 m_objectToolTrackingObj(NULL),
379 m_showObjToolTrackingObj(false),
380 m_camera(NULL),
381 m_heightMapRenderObj(NULL),
382 m_mouseWheelOffset(0),
383 m_actualWinSize(0, 0),
384 m_cameraAngle(0.0),
385 m_FXPitch(1.0f),
386 m_actualHeightAboveGround(0.0f),
387 m_doPitch(false),
388 m_theta(0.0),
389 m_time(0),
390 m_updateCount(0),
391 m_needToLoadRoads(0),
392 m_timer(NULL),
393 m_drawObject(NULL),
394 m_layer(NULL),
395 m_buildLayer(NULL),
396 m_intersector(NULL),
397 m_showEntireMap(false),
398 m_partialMapSize(129),
399 m_showWireframe(false),
400 m_projection(false),
401 m_showShadows(false),
402 m_firstPaint(true),
403 m_groundLevel(10),
404 m_curTrackingZ(10),
405 m_ww3dInited(false),
406 m_showLayersList(false),
407 m_showMapBoundaries(false),
408 m_showBoundingBoxes(false),
409 m_showSightRanges(false),
410 m_showWeaponRanges(false),
411 m_highlightTestArt(false),
412 m_showLetterbox(false),
413 m_showSoundCircles(false)
414{
416 m_actualWinSize.x = ::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "Width", THREE_D_VIEW_WIDTH);
417 m_actualWinSize.y = ::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "Height", THREE_D_VIEW_HEIGHT);
418 m_cameraOffset.x = m_cameraOffset.y = m_cameraOffset.z = 1;
419
420 for (Int i=0; i<MAX_GLOBAL_LIGHTS; i++)
421 {
422 m_globalLight[i] = NEW_REF( LightClass, (LightClass::DIRECTIONAL) );
423 m_lightFeedbackMesh[i]=NULL;
424 }
425
426 m_showWireframe = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowWireframe", 0) != 0);
427 m_showEntireMap = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowEntireMap", 1) != 0);
428 m_projection = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowTopDownView", 0) != 0);
429 m_showShadows = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowShadows", 1) != 0);
430 TheWritableGlobalData->m_useShadowDecals = m_showShadows;
431 TheWritableGlobalData->m_useShadowVolumes = m_showShadows;
432 TheWritableGlobalData->m_showSoftWaterEdge = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowSoftWater", 1) != 0);
433 TheWritableGlobalData->m_use3WayTerrainBlends = (::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowExtraBlends", 1) > 1 ? 2 : 1);
434 setShowModels(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowModels", 1) != 0);
435 setShowBoundingBoxes(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowBoundingBoxes", 0) != 0);
436 setShowSightRanges(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowSightRanges", 0) != 0);
437 setShowWeaponRanges(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowWeaponRanges", 0) != 0);
438 setShowGarrisoned(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowGarrisoned", 0) != 0);
439 setHighlightTestArt(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "HighlightTestArt", 0) != 0);
440 setShowLetterbox(::AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowLetterbox", 0) != 0);
441}
442
443// ----------------------------------------------------------------------------
445{
446 for (Int i=0; i<MAX_GLOBAL_LIGHTS; i++)
447 {
448 if (m_lightFeedbackMesh[i] != NULL)
449 { m_lightFeedbackMesh[i]->Remove();
450 REF_PTR_RELEASE(m_lightFeedbackMesh[i]);
451 }
452 }
453 REF_PTR_RELEASE(m_drawObject) ;
454 REF_PTR_RELEASE(m_heightMapRenderObj);
456 shutdownWW3D();
457}
458// ----------------------------------------------------------------------------
460{
461 if (m_intersector) {
462 delete m_intersector;
463 m_intersector = NULL;
464 }
465
466 if (m_layer) {
467 delete m_layer;
468 m_layer = NULL;
469 }
470 if (m_buildLayer) {
471 delete m_buildLayer;
472 m_buildLayer = NULL;
473 }
474 if (m3DFont) {
475 m3DFont->Release();
476 m3DFont = NULL;
477 }
478 if (m_ww3dInited) {
479 m_lightList.Reset_List();
480
481 if (m_assetManager) {
483 m_assetManager->Free_Assets();
484 delete m_assetManager;
485 m_assetManager = NULL;
486 }
487
489 {
490 TheW3DShadowManager->removeAllShadows();
491 delete TheW3DShadowManager;
493 }
494 REF_PTR_RELEASE(m_transparentObjectsScene);
495 REF_PTR_RELEASE(m_overlayScene);
496 REF_PTR_RELEASE(m_baseBuildScene);
497 REF_PTR_RELEASE(m_objectToolTrackingObj);
498 REF_PTR_RELEASE(m_scene);
499 REF_PTR_RELEASE(m_camera);
500 REF_PTR_RELEASE(m_heightMapRenderObj);
501 REF_PTR_RELEASE(m_drawObject);
502 for (Int i=0; i<MAX_GLOBAL_LIGHTS; i++)
503 REF_PTR_RELEASE(m_globalLight[i]);
504#ifdef SAMPLE_DYNAMIC_LIGHT
505 REF_PTR_RELEASE(theDynamicLight);
506#endif
508
510 }
511 m_ww3dInited = false;
512}
513
514//=============================================================================
515// WbView3d::ReleaseResources
516//=============================================================================
518//=============================================================================
520{
522 TheTerrainRenderObject->ReleaseResources();
523 }
524 if (m3DFont) {
525 m3DFont->Release();
526 }
527 m3DFont = NULL;
528 if (m_drawObject) {
529 m_drawObject->freeMapResources();
530 }
531}
532
533//=============================================================================
534// WbView3d::ReAcquireResources
535//=============================================================================
537//=============================================================================
539{
541 TheTerrainRenderObject->ReAcquireResources();
542 TheTerrainRenderObject->loadRoadsAndBridges(NULL,FALSE);
543 TheTerrainRenderObject->worldBuilderUpdateBridgeTowers( m_assetManager, m_scene );
544 }
545 m_drawObject->initData();
546 IDirect3DDevice8* pDev = DX8Wrapper::_Get_D3D_Device8();
547 if (pDev) {
548
549// CDC* pDC = GetDC();
550 LOGFONT logFont;
551 logFont.lfHeight = 20;
552 logFont.lfWidth = 0;
553 logFont.lfEscapement = 0;
554 logFont.lfOrientation = 0;
555 logFont.lfWeight = FW_REGULAR;
556 logFont.lfItalic = FALSE;
557 logFont.lfUnderline = FALSE;
558 logFont.lfStrikeOut = FALSE;
559 logFont.lfCharSet = ANSI_CHARSET;
560 logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
561 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
562 logFont.lfQuality = DEFAULT_QUALITY;
563 logFont.lfPitchAndFamily = DEFAULT_PITCH;
564 strcpy(logFont.lfFaceName, "Arial");
565
566 HFONT hFont = CreateFontIndirect(&logFont);
567 if (hFont) {
568 D3DXCreateFont(pDev, hFont, &m3DFont);
569 DeleteObject(hFont);
570 } else {
571 m3DFont = NULL;
572 }
573
574 } else {
575 m3DFont = NULL;
576 }
577
578}
579
580// ----------------------------------------------------------------------------
582{
583 if (m_timer != NULL) {
584 KillTimer(m_timer);
585 m_timer = NULL;
586 }
587}
588
589// ----------------------------------------------------------------------------
591{
592 if (m_actualWinSize.x == width &&
593 m_actualWinSize.y == height) {
594 return;
595 }
596 bogusTacticalView.setWidth(width);
597 bogusTacticalView.setHeight(height);
598 bogusTacticalView.setOrigin(0,0);
599 m_actualWinSize.x = width;
600 m_actualWinSize.y = height;
601 if (m_ww3dInited) {
602 WW3D::Set_Device_Resolution(m_actualWinSize.x, m_actualWinSize.y, true);
603 }
604}
605
606// ----------------------------------------------------------------------------
608{
609
610 m_assetManager = new W3DAssetManager;
612 m_assetManager->Register_Prototype_Loader(&_AggregateLoader);
613 m_assetManager->Set_WW3D_Load_On_Demand(true);
614}
615
616// ----------------------------------------------------------------------------
617#define TERRAIN_SAMPLE_SIZE 40.0f
618static Real getHeightAroundPos(WBHeightMap *heightMap, Real x, Real y)
619{
620 Real terrainHeight = heightMap->getHeightMapHeight(x, y, NULL);
621
622 // find best approximation of max terrain height we can see
623 Real terrainHeightMax = terrainHeight;
624 terrainHeightMax = max(terrainHeightMax, heightMap->getHeightMapHeight(x+TERRAIN_SAMPLE_SIZE, y-TERRAIN_SAMPLE_SIZE, NULL));
625 terrainHeightMax = max(terrainHeightMax, heightMap->getHeightMapHeight(x-TERRAIN_SAMPLE_SIZE, y-TERRAIN_SAMPLE_SIZE, NULL));
626 terrainHeightMax = max(terrainHeightMax, heightMap->getHeightMapHeight(x+TERRAIN_SAMPLE_SIZE, y+TERRAIN_SAMPLE_SIZE, NULL));
627 terrainHeightMax = max(terrainHeightMax, heightMap->getHeightMapHeight(x-TERRAIN_SAMPLE_SIZE, y+TERRAIN_SAMPLE_SIZE, NULL));
628
629 return terrainHeightMax;
630}
631
632// ----------------------------------------------------------------------------
634{
635 Matrix3D camtransform(1);
636 float zOffset = - m_mouseWheelOffset / 1200;
637 Real zoom = 1.0f;
638 if (zOffset != 0) {
639 Real zPos = (m_cameraOffset.length()-m_groundLevel)/m_cameraOffset.length();
640 Real zAbs = zOffset + zPos;
641 if (zAbs<0) zAbs = -zAbs;
642 if (zAbs<0.01) zAbs = 0.01f;
643 //DEBUG_LOG(("zOffset = %.2f, zAbs = %.2f, zPos = %.2f\n", zOffset, zAbs, zPos));
644 if (zOffset > 0) {
645 zOffset *= zAbs;
646 } else if (zOffset < -0.3f) {
647 zOffset = -0.15f + zOffset/2.0f;
648 }
649 if (zOffset < -0.6f) {
650 zOffset = -0.3f + zOffset/2.0f;
651 }
652 //DEBUG_LOG(("zOffset = %.2f\n", zOffset));
653 zoom = zAbs;
654 }
655
657 Vector3 sourcePos, targetPos;
658
659 Real angle = m_cameraAngle;
660 Real pitch = 0;
661 Coord3D pos;
662 pos.x = m_centerPt.X* MAP_XY_FACTOR;
663 pos.y = m_centerPt.Y* MAP_XY_FACTOR;
664 pos.z = m_centerPt.Z* MAP_XY_FACTOR;
665
666 Real groundLevel = m_heightMapRenderObj?getHeightAroundPos(m_heightMapRenderObj, pos.x, pos.y) : 0;
667
668 // set position of camera itself
669 /*
670 sourcePos.X = m_cameraOffset.x;
671 sourcePos.Y = m_cameraOffset.y;
672 sourcePos.Z = m_cameraOffset.z;
673 */
674 sourcePos.X = m_cameraOffset.x * zoom;
675 sourcePos.Y = m_cameraOffset.y * zoom;
676 sourcePos.Z = m_cameraOffset.z * zoom;
677
678 // camera looking at origin
679 targetPos.X = 0;
680 targetPos.Y = 0;
681 targetPos.Z = 0;
682
683
684 Real factor = 1.0 - (groundLevel/sourcePos.Z );
685
686 // construct a matrix to rotate around the up vector by the given angle
687 Matrix3D angleTransform( Vector3( 0.0f, 0.0f, 1.0f ), angle );
688
689 // construct a matrix to rotate around the horizontal vector by the given angle
690 Matrix3D pitchTransform( Vector3( 1.0f, 0.0f, 0.0f ), pitch );
691
692 // rotate camera position (pitch, then angle)
693#ifdef ALLOW_TEMPORARIES
694 sourcePos = pitchTransform * sourcePos;
695 sourcePos = angleTransform * sourcePos;
696#else
697 pitchTransform.mulVector3(sourcePos);
698 angleTransform.mulVector3(sourcePos);
699#endif
700 //sourcePos *= factor+zOffset;
701 sourcePos *= factor;
702
703 // translate to current XY position
704 sourcePos.X += pos.x;
705 sourcePos.Y += pos.y;
706 sourcePos.Z += pos.z+groundLevel;
707
708 targetPos.X += pos.x;
709 targetPos.Y += pos.y;
710 targetPos.Z += pos.z+groundLevel;
711
712 // do fxPitch adjustment
713 Real height = sourcePos.Z - targetPos.Z;
714 height *= m_FXPitch;
715 targetPos.Z = sourcePos.Z - height;
716
717 // Just for kicks, lets see how high we are above the ground
718 m_actualHeightAboveGround = m_cameraOffset.z * zoom - groundLevel;
719 m_cameraSource = sourcePos;
720 m_cameraTarget = targetPos;
721 /*
722 DEBUG_LOG(("Camera: pos=(%g,%g) height=%g pitch=%g FXPitch=%g yaw=%g groundLevel=%g\n",
723 targetPos.X, targetPos.Y,
724 m_actualHeightAboveGround,
725 pitch,
726 m_FXPitch,
727 angle, m_groundLevel));
728 */
729
730 // build new camera transform
731 camtransform.Make_Identity();
732 if (factor < 0) { //WST 11/11/02. Fix camera flipping over when near the ground too early
733 targetPos = sourcePos + (sourcePos-targetPos);
734 }
735 camtransform.Look_At( sourcePos, targetPos, 0 );
737 targetPos.Z = 0;
738 Real lookDistance = (targetPos-sourcePos).Length();
739 Real nearZ, farZ;
740 if (lookDistance < 300) lookDistance = 300;
741 m_camera->Get_Clip_Planes(nearZ, farZ);
742 m_camera->Set_Clip_Planes(lookDistance/200, lookDistance*3);
743
744 if (m_heightMapRenderObj) {
745 if (m_projection) {
746 camtransform.Make_Identity();
747 camtransform.Set_Translation(Vector3(targetPos.X, targetPos.Y, lookDistance));
748 m_heightMapRenderObj->setFlattenHeights(true);
749 //m_camera->Set_Projection_Type(CameraClass::ORTHO);
750 } else {
751 m_heightMapRenderObj->setFlattenHeights(false);
752 //m_camera->Set_Projection_Type(CameraClass::PERSPECTIVE);
753 }
754 }
755 m_camera->Set_Transform( camtransform );
756 if (m_heightMapRenderObj) {
757 m_heightMapRenderObj->setDrawEntireMap(m_showEntireMap);
758 }
759// not needed, handled in OnSize
760// m_camera->Set_Aspect_Ratio((float)m_actualWinSize.x/(float)m_actualWinSize.y);
761}
762
763// ----------------------------------------------------------------------------
765{
766 // build scene
767 REF_PTR_RELEASE(m_overlayScene);
768 REF_PTR_RELEASE(m_transparentObjectsScene);
769 REF_PTR_RELEASE(m_baseBuildScene);
770 REF_PTR_RELEASE(m_scene);
771 REF_PTR_RELEASE(m_camera);
772 REF_PTR_RELEASE(m_heightMapRenderObj);
773
774 m_scene = NEW_REF(SkeletonSceneClass,());
775#ifdef SAMPLE_DYNAMIC_LIGHT
776 REF_PTR_RELEASE(theDynamicLight);
777 theDynamicLight = NEW_REF(W3DDynamicLight, ());
778 Real red = 1;
779 Real green = 1;
780 Real blue = 0;
781 if(red==0 && blue==0 && green==0) {
782 red = green = blue = 1;
783 }
784 theDynamicLight->Set_Ambient( Vector3( red, green, blue ) );
785 theDynamicLight->Set_Diffuse( Vector3( red, green, blue) );
786 theDynamicLight->Set_Position(Vector3(211, 363, 10));
787 theDynamicLight->Set_Far_Attenuation_Range(5, 15);
788 // Note: Don't Add_Render_Object dynamic lights.
789 m_scene->addDynamicLight( theDynamicLight );
790#endif
791 m_overlayScene = NEW_REF(SkeletonSceneClass,());
792 m_baseBuildScene = NEW_REF(SkeletonSceneClass,());
793 m_transparentObjectsScene = NEW_REF(SkeletonSceneClass,());
794// m_scene->Set_Polygon_Mode(SceneClass::LINE);
795 m_scene->Set_Ambient_Light(Vector3(0.5f,0.5f,0.5f));
796 m_overlayScene->Set_Ambient_Light(Vector3(0.5f,0.5f,0.5f));
797 m_baseBuildScene->Set_Ambient_Light(Vector3(0.5f,0.5f,0.5f));
798
799 // Scene needs camera to be rendered with ----------------------------------
800 m_camera = NEW_REF(CameraClass,());
801
802}
803
804// ----------------------------------------------------------------------------
806{
807 if (!m_scene) return;
808 if (TheW3DShadowManager) {
809 TheW3DShadowManager->removeAllShadows();
810 }
811
812 SceneIterator *sceneIter = m_scene->Create_Iterator();
813 sceneIter->First();
814 while(!sceneIter->Is_Done()) {
815 RenderObjClass * robj = sceneIter->Current_Item();
816 robj->Add_Ref();
817 m_scene->Remove_Render_Object(robj);
818 robj->Release_Ref();
819 sceneIter->Next();
820 }
821 m_scene->Destroy_Iterator(sceneIter);
822 sceneIter = m_baseBuildScene->Create_Iterator();
823 sceneIter->First();
824 while(!sceneIter->Is_Done()) {
825 RenderObjClass * robj = sceneIter->Current_Item();
826 robj->Add_Ref();
827 m_baseBuildScene->Remove_Render_Object(robj);
828 robj->Release_Ref();
829 sceneIter->Next();
830 }
831 m_baseBuildScene->Destroy_Iterator(sceneIter);
833 // Erase references to render objs that have been removed.
834 while (pMapObj)
835 {
836 pMapObj->setRenderObj(NULL);
837 pMapObj = pMapObj->getNext();
838 }
839
840 Int i;
841 for (i=0; i<TheSidesList->getNumSides(); i++) {
842 SidesInfo *pSide = TheSidesList->getSideInfo(i);
843 BuildListInfo *pBuild = pSide->getBuildList();
844 while (pBuild) {
845 pBuild->setRenderObj(NULL);
846 pBuild = pBuild->getNext();
847 }
848 }
849
850 m_needToLoadRoads = true; // load roads next time we redraw.
851
853 TheW3DShadowManager->Reset();
854
855 updateLights();
856 if (m_heightMapRenderObj) {
857 m_scene->Add_Render_Object(m_heightMapRenderObj);
858 m_heightMapRenderObj->removeAllTrees();
859 m_heightMapRenderObj->removeAllProps();
860 }
861}
862
863// ----------------------------------------------------------------------------
865{
866 TheWritableGlobalData->m_timeOfDay = (TimeOfDay)(TheGlobalData->m_timeOfDay+1);
867 if (TheGlobalData->m_timeOfDay >= TIME_OF_DAY_COUNT) {
869 }
872}
873
874// ----------------------------------------------------------------------------
875void WbView3d::setLighting(const GlobalData::TerrainLighting *tl, Int whichLighting, Int whichLight)
876{
877 if (whichLighting == GlobalLightOptions::K_TERRAIN) {
878 TheWritableGlobalData->m_terrainLighting[TheGlobalData->m_timeOfDay][whichLight]= *tl;
879 } else if (whichLighting == GlobalLightOptions::K_OBJECTS) {
880 TheWritableGlobalData->m_terrainObjectsLighting[TheGlobalData->m_timeOfDay][whichLight] = *tl;
881 } else if (whichLighting == GlobalLightOptions::K_BOTH) {
882 TheWritableGlobalData->m_terrainObjectsLighting[TheGlobalData->m_timeOfDay][whichLight] = *tl;
883 TheWritableGlobalData->m_terrainLighting[TheGlobalData->m_timeOfDay][whichLight] = *tl;
884 }
885 const GlobalData::TerrainLighting *ol = &TheGlobalData->m_terrainObjectsLighting[TheGlobalData->m_timeOfDay][whichLight];
886 TheWritableGlobalData->setTimeOfDay(TheGlobalData->m_timeOfDay);
887 if( m_globalLight ) {
888 m_globalLight[whichLight]->Set_Ambient( Vector3( 0.0f, 0.0f, 0.0f ) );
889 m_globalLight[whichLight]->Set_Diffuse( Vector3(ol->diffuse.red, ol->diffuse.green, ol->diffuse.blue ) );
890 m_globalLight[whichLight]->Set_Specular( Vector3(0,0,0) );
891 Matrix3D mtx;
892 mtx.Set(Vector3(1,0,0), Vector3(0,1,0), Vector3(ol->lightPos.x, ol->lightPos.y, ol->lightPos.z), Vector3(0,0,0));
893 m_globalLight[whichLight]->Set_Transform(mtx);
894 if( m_scene && whichLight == 0) { //only let the first light contribute to ambient
895 m_scene->Set_Ambient_Light( Vector3(ol->ambient.red, ol->ambient.green, ol->ambient.blue) );
896 m_baseBuildScene->Set_Ambient_Light( Vector3(ol->ambient.red, ol->ambient.green, ol->ambient.blue) );
897 }
898 }
900 TheTerrainRenderObject->setTimeOfDay(TheGlobalData->m_timeOfDay);
901 }
902 if (TheW3DShadowManager) {
903 TheW3DShadowManager->setTimeOfDay(TheGlobalData->m_timeOfDay);
904 }
905 m_needToLoadRoads = true; // load roads next time we redraw.
906 Invalidate(false);
907}
908
909// ----------------------------------------------------------------------------
911{
912 ++m_updateCount;
913
914 // Update lights list.
915 m_lightList.Reset_List();
916
917 {
918 TheWritableGlobalData->setTimeOfDay(TheGlobalData->m_timeOfDay);
919 const GlobalData::TerrainLighting *ol = &TheGlobalData->m_terrainObjectsLighting[TheGlobalData->m_timeOfDay][0];
920
921 if( m_scene )
922 {
923 m_scene->Set_Ambient_Light( Vector3(ol->ambient.red, ol->ambient.green, ol->ambient.blue) );
924 m_baseBuildScene->Set_Ambient_Light( Vector3(ol->ambient.red, ol->ambient.green, ol->ambient.blue) );
925 }
926
927 if (TheW3DShadowManager) {
928 TheW3DShadowManager->setTimeOfDay(TheGlobalData->m_timeOfDay);
929 }
930
931 for (Int i=0; i<MAX_GLOBAL_LIGHTS; i++)
932 {
933
934 if( m_globalLight[i] )
935 {
936 ol = &TheGlobalData->m_terrainObjectsLighting[TheGlobalData->m_timeOfDay][i];
937 m_globalLight[i]->Set_Ambient( Vector3( 0.0f, 0.0f, 0.0f ) );
938 m_globalLight[i]->Set_Diffuse( Vector3(ol->diffuse.red, ol->diffuse.green, ol->diffuse.blue ) );
939 m_globalLight[i]->Set_Specular( Vector3(0,0,0) );
940 Matrix3D mtx;
941 mtx.Set(Vector3(1,0,0), Vector3(0,1,0), Vector3(ol->lightPos.x, ol->lightPos.y, ol->lightPos.z), Vector3(0,0,0));
942 m_globalLight[i]->Set_Transform(mtx);
943 m_scene->setGlobalLight(m_globalLight[i],i);
944 m_baseBuildScene->setGlobalLight(m_globalLight[i],i);
945 }
946 }
948 TheTerrainRenderObject->setTimeOfDay(TheGlobalData->m_timeOfDay);
949 }
950
951
952 }
953
955 while (pMapObj && m_heightMapRenderObj) {
956 if (pMapObj->isLight()) {
957 Coord3D loc = *pMapObj->getLocation();
958 loc.z += m_heightMapRenderObj->getHeightMapHeight(loc.x, loc.y, NULL);
959 RenderObjClass *renderObj= pMapObj->getRenderObj();
960 if (renderObj) {
961 m_scene->Remove_Render_Object(renderObj);
962 pMapObj->setRenderObj(NULL);
963 }
964 // It is a light, and handled at the device level. jba.
966
967 Dict *props = pMapObj->getProperties();
968
969 Real lightHeightAboveTerrain, lightInnerRadius, lightOuterRadius;
970 RGBColor lightAmbientColor, lightDiffuseColor;
971 lightHeightAboveTerrain = props->getReal(TheKey_lightHeightAboveTerrain);
972 lightInnerRadius = props->getReal(TheKey_lightInnerRadius);
973 lightOuterRadius = props->getReal(TheKey_lightOuterRadius);
974 lightAmbientColor.setFromInt(props->getInt(TheKey_lightAmbientColor));
975 lightDiffuseColor.setFromInt(props->getInt(TheKey_lightDiffuseColor));
976
977 lightP->Set_Ambient( Vector3( lightAmbientColor.red, lightAmbientColor.green, lightAmbientColor.blue ) );
978 lightP->Set_Diffuse( Vector3( lightDiffuseColor.red, lightDiffuseColor.green, lightDiffuseColor.blue) );
979
980 lightP->Set_Position(Vector3(loc.x, loc.y, loc.z+lightHeightAboveTerrain));
981
982 lightP->Set_Far_Attenuation_Range(lightInnerRadius, lightOuterRadius);
983
984 m_lightList.Add(lightP);
985 m_scene->Add_Render_Object(lightP);
986 pMapObj->setRenderObj(lightP);
987 REF_PTR_RELEASE( lightP );
988 }
989 pMapObj = pMapObj->getNext();
990 }
991
992 --m_updateCount;
993}
994
995// ----------------------------------------------------------------------------
997{
998 TheTerrainRenderObject->clearAllScorches();
999 MapObject *pMapObj;
1000 for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext())
1001 {
1002 if (pMapObj->isScorch())
1003 {
1004 const Coord3D *pos = pMapObj->getLocation();
1005 Real radius = pMapObj->getProperties()->getReal(TheKey_objectRadius);
1006 Scorches type = (Scorches) pMapObj->getProperties()->getInt(TheKey_scorchType);
1007
1008 Vector3 loc(pos->x, pos->y, pos->z);
1009 TheTerrainRenderObject->addScorch(loc, radius, type);
1010 }
1011 }
1012}
1013
1014// ----------------------------------------------------------------------------
1016{
1017 TheTerrainRenderObject->removeAllTrees();
1018 TheTerrainRenderObject->removeAllProps();
1019 MapObject *pMapObj;
1020 for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext())
1021 {
1022 const ThingTemplate *tTemplate;
1023
1024 tTemplate = pMapObj->getThingTemplate();
1025 if (tTemplate && tTemplate->isKindOf(KINDOF_OPTIMIZED_TREE) )
1026 {
1027 Real scale = tTemplate->getAssetScale();
1028 const ModuleInfo& mi = tTemplate->getDrawModuleInfo();
1029 if (mi.getCount() > 0)
1030 {
1031 const ModuleData* mdd = mi.getNthData(0);
1033 const W3DTreeDrawModuleData* md = mdd ? mdd->getAsW3DTreeDrawModuleData(): NULL;
1034 if (md)
1035 {
1036 Coord3D pos = *pMapObj->getLocation();
1037 if (m_heightMapRenderObj) {
1038 pos.z += m_heightMapRenderObj->getHeightMapHeight(pos.x, pos.y, NULL);
1039 TheTerrainRenderObject->addTree((DrawableID)(Int)pMapObj, pos, scale, pMapObj->getAngle(),
1040 0.0f /*no random scaling*/, md);
1041 }
1042 }
1043 }
1044 }
1045 }
1046}
1047
1048// ----------------------------------------------------------------------------
1049void WbView3d::invalidateCellInView(int xIndex, int yIndex)
1050{
1051 Invalidate(false);
1052}
1053
1054// ----------------------------------------------------------------------------
1056{
1057 MapObject *pMapObj;
1058 for (pMapObj = pObject; pMapObj; pMapObj = pMapObj->getNext())
1059 {
1060
1061 Coord3D loc = *pMapObj->getLocation();
1062 loc.z += m_heightMapRenderObj->getHeightMapHeight(loc.x, loc.y, NULL);
1063
1064 RenderObjClass *renderObj=NULL;
1065 REF_PTR_SET( renderObj, pMapObj->getRenderObj() );
1066 if (!renderObj) {
1067 Real scale = 1.0;
1068 AsciiString modelName = getModelNameAndScale(pMapObj, &scale, BODY_PRISTINE);
1069 // set render object, or create if we need to
1070 if( renderObj == NULL && modelName.isEmpty() == FALSE &&
1071 strncmp( modelName.str(), "No ", 3 ) )
1072 {
1073
1074 renderObj = m_assetManager->Create_Render_Obj( modelName.str(), scale, 0);
1075
1076 } // end if
1077 }
1078
1079 if (renderObj) {
1080 pMapObj->setRenderObj(renderObj);
1081
1082 // set item's position to loc, and get scale from item and apply it.
1083
1084 Matrix3D renderObjPos(true); // init to identity
1085 renderObjPos.Translate(loc.x, loc.y, loc.z);
1086 renderObjPos.Rotate_Z(pMapObj->getAngle());
1087 renderObj->Set_Transform( renderObjPos );
1088
1089
1090 m_scene->Add_Render_Object(renderObj);
1091
1092 REF_PTR_RELEASE(renderObj); // belongs to m_scene now.
1093 }
1094 }
1095
1096 Invalidate(false);
1097}
1098
1099
1100// ----------------------------------------------------------------------------
1102{
1103 MapObject *pMapObj;
1104 for (pMapObj = pObject; pMapObj; pMapObj = pMapObj->getNext())
1105 {
1106 if (pMapObj->getRenderObj()) {
1107 m_scene->Remove_Render_Object(pMapObj->getRenderObj());
1108 pMapObj->setRenderObj(NULL);
1109 }
1110 }
1111
1112 Invalidate(false);
1113}
1114
1115// ----------------------------------------------------------------------------
1118{
1119 if (tt)
1120 {
1121 const ModuleInfo& mi = tt->getDrawModuleInfo();
1122 if (mi.getCount() > 0)
1123 {
1124// const W3DModelDrawModuleData* md = dynamic_cast<const W3DModelDrawModuleData*>(mi->getNthData(0));
1125 const ModuleData* mdd = mi.getNthData(0);
1126 const W3DModelDrawModuleData* md = mdd ? mdd->getAsW3DModelDrawModuleData() : NULL;
1127 if (md)
1128 {
1129 return md->getBestModelNameForWB(c);
1130 }
1131 }
1132 }
1133 // removing this crash as sounds can (and should) have no model - jkmcd
1135}
1136
1137// ----------------------------------------------------------------------------
1139{
1140 Int i;
1141 Bool found = false;
1142
1143 for (i=0; i<TheSidesList->getNumSides(); i++) {
1144 SidesInfo *pSide = TheSidesList->getSideInfo(i);
1145
1146 // find which player color we should use
1147 Int playerColor = 0xFFFFFF;
1148 const Dict *sideDict = pSide->getDict();
1149 if (sideDict)
1150 {
1151 Bool exists = false;
1152 Int color = sideDict->getInt(TheKey_playerColor, &exists);
1153 if (exists)
1154 {
1155 playerColor = color;
1156 }
1157 }
1158
1159
1160 for (BuildListInfo *pBuild = pSide->getBuildList(); pBuild; pBuild = pBuild->getNext()) {
1161 if (pBuildToInval == pBuild) {
1162 found = true;
1163 }
1164 if (!found && pBuildToInval) {
1165 continue;
1166 }
1167 if (!BuildListTool::isActive() && !pBuild->isInitiallyBuilt()) {
1168 continue;
1169 }
1170 // Update.
1171 Coord3D loc = *pBuild->getLocation();
1172 loc.z += m_heightMapRenderObj->getHeightMapHeight(loc.x, loc.y, NULL);
1173 RenderObjClass *renderObj=NULL;
1174 Shadow *shadowObj=NULL;
1175 // Build list render obj is not refcounted, so check & make sure it exists in the scene.
1176 if (pBuild->getRenderObj()) {
1177 if (!m_baseBuildScene->safeContains(pBuild->getRenderObj())) {
1178 pBuild->setRenderObj(NULL);
1179 }
1180 }
1181
1182 REF_PTR_SET(renderObj, pBuild->getRenderObj());
1183 if (!renderObj) {
1184 Real scale = 1.0;
1185 AsciiString thingName = pBuild->getTemplateName();
1186 const ThingTemplate *tTemplate = TheThingFactory->findTemplate(thingName);
1187
1188 AsciiString modelName = "No Model Name";
1189 if (tTemplate) {
1190 ModelConditionFlags state;
1191 state.clear();
1192 modelName = getBestModelName(tTemplate, state);
1193 scale = tTemplate->getAssetScale();
1194 }
1195 // set render object, or create if we need to
1196 if( renderObj == NULL && modelName.isEmpty() == FALSE &&
1197 strncmp( modelName.str(), "No ", 3 ) )
1198 {
1199
1200 renderObj = m_assetManager->Create_Render_Obj( modelName.str(), scale, playerColor);
1201 if( m_showShadows && tTemplate->getShadowType() != SHADOW_NONE)
1202 {
1203 //add correct type of shadow
1204 Shadow::ShadowTypeInfo shadowInfo;
1205 shadowInfo.allowUpdates=FALSE; //shadow image will never update
1206 shadowInfo.allowWorldAlign=TRUE; //shadow image will wrap around world objects
1207 strcpy(shadowInfo.m_ShadowName,tTemplate->getShadowTextureName().str());
1208 DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now"));
1209 shadowInfo.m_type=(ShadowType)tTemplate->getShadowType();
1210 shadowInfo.m_sizeX=tTemplate->getShadowSizeX();
1211 shadowInfo.m_sizeY=tTemplate->getShadowSizeY();
1212 shadowInfo.m_offsetX=tTemplate->getShadowOffsetX();
1213 shadowInfo.m_offsetY=tTemplate->getShadowOffsetY();
1214 shadowObj=TheW3DShadowManager->addShadow(renderObj, &shadowInfo);
1215 }
1216 } // end if
1217 }
1218 if (renderObj) {
1219 pBuild->setRenderObj(renderObj);
1220 pBuild->setShadowObj(shadowObj);
1221 // set item's position to loc.
1222 Matrix3D renderObjPos(true); // init to identity
1223 renderObjPos.Translate(loc.x, loc.y, loc.z);
1224 renderObjPos.Rotate_Z(pBuild->getAngle());
1225 renderObj->Set_Transform( renderObjPos );
1226
1227 m_baseBuildScene->Add_Render_Object(renderObj);
1228
1229 REF_PTR_RELEASE(renderObj); // belongs to m_scene now.
1230 }
1231 if (found) break;
1232 }
1233 }
1234
1235 // Build list render obj is not refcounted, so check & make sure it exists in the scene.
1236 if (!found && pBuildToInval && pBuildToInval->getRenderObj()) {
1237 if (!m_baseBuildScene->safeContains(pBuildToInval->getRenderObj())) {
1238 pBuildToInval->setRenderObj(NULL);
1239 }
1240 }
1241 if (!found && pBuildToInval && pBuildToInval->getRenderObj()) {
1242 m_baseBuildScene->Remove_Render_Object(pBuildToInval->getRenderObj());
1243 pBuildToInval->setRenderObj(NULL);
1244 }
1245 Invalidate(false);
1246}
1247
1248
1250{
1251 ModelConditionFlags state;
1252 switch (curDamageState)
1253 {
1254 case BODY_PRISTINE:
1255 default:
1256 state.clear();
1257 break;
1258
1259 case BODY_DAMAGED:
1261 break;
1262
1263 case BODY_REALLYDAMAGED:
1265 break;
1266
1267 case BODY_RUBBLE:
1269 break;
1270 }
1271
1272 if (getShowGarrisoned())
1273 {
1275 }
1276 Int objWeather = 0;
1277 Bool exists;
1278 if (pMapObj && pMapObj->getProperties())
1279 {
1280 objWeather = pMapObj->getProperties()->getInt(TheKey_objectWeather, &exists);
1281 }
1282 switch (objWeather)
1283 {
1284 default:
1285 case 0:
1286 if (TheGlobalData->m_weather == WEATHER_SNOWY)
1287 {
1288 state.set(MODELCONDITION_SNOW);
1289 }
1290 break;
1291 case 2:
1292 state.set(MODELCONDITION_SNOW);
1293 break;
1294 }
1295
1296 Int objTime = 0;
1297 if (pMapObj && pMapObj->getProperties())
1298 {
1299 objTime = pMapObj->getProperties()->getInt(TheKey_objectTime, &exists);
1300 }
1301 switch (objTime)
1302 {
1303 default:
1304 case 0:
1305 if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT)
1306 {
1308 }
1309 break;
1310 case 2:
1312 break;
1313 }
1314
1315 AsciiString modelName("No Model Name");
1316 *scale = 1.0f;
1317 Int i;
1318 char buffer[ _MAX_PATH ];
1319 if (strncmp(TEST_STRING, pMapObj->getName().str(), strlen(TEST_STRING)) == 0)
1320 {
1321 /* Handle test art models here */
1322 strcpy(buffer, pMapObj->getName().str());
1323
1324 for (i=0; buffer[i]; i++) {
1325 if (buffer[i] == '/') {
1326 i++;
1327 break;
1328 }
1329 }
1330 modelName = buffer+i;
1331 }
1332 else
1333 {
1334 modelName = "No Model Name"; // must be this while GDF exists (it's the default)
1335 const ThingTemplate *tTemplate;
1336
1337 tTemplate = pMapObj->getThingTemplate();
1338 if( tTemplate && !(pMapObj->getFlags() & FLAG_DONT_RENDER))
1339 {
1340
1341 // get visual data from the thing template
1342 modelName = getBestModelName(tTemplate, state);
1343 *scale = tTemplate->getAssetScale();
1344
1345 } // end if
1346 } // end else
1347 return modelName;
1348}
1349
1350// ----------------------------------------------------------------------------
1352{
1353 ++m_updateCount;
1354 Bool updateAllTrees = false;
1355 if (m_heightMapRenderObj == NULL) {
1356 m_heightMapRenderObj = NEW_REF(WBHeightMap,());
1357
1358 m_scene->Add_Render_Object(m_heightMapRenderObj);
1359 }
1360 if (pMapObjIn == NULL) {
1362 }
1363 Bool found = false;
1364 Bool isRoad = false;
1365 Bool isLight = false;
1366 Bool isScorch = false;
1367 if (pMapObjIn == NULL)
1368 isScorch = true;
1369 MapObject *pMapObj;
1370 for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext())
1371 {
1372 if (found) break;
1373 if (pMapObjIn == pMapObj)
1374 found = true;
1375 if (pMapObjIn != NULL && !found) {
1376 continue;
1377 }
1378 if (pMapObj->getFlags() & (FLAG_ROAD_FLAGS|FLAG_BRIDGE_FLAGS)) {
1379 isRoad = true;
1380 continue; // Roads don't create drawable objects.
1381 }
1382 if (pMapObj->isLight() ) {
1383 isLight = true;
1384 continue; // Lights don't create drawable objects.
1385 }
1386 if (pMapObj->isScorch()) {
1387 if (pMapObj == pMapObjIn) {
1388 isScorch = true;
1389 }
1390 continue;
1391 }
1392
1393
1394 Coord3D loc = *pMapObj->getLocation();
1395 loc.z += m_heightMapRenderObj->getHeightMapHeight(loc.x, loc.y, NULL);
1396
1397 const ThingTemplate *tTemplate = pMapObj->getThingTemplate();
1398 if (tTemplate && tTemplate->isKindOf(KINDOF_OPTIMIZED_TREE)) {
1399 if (!m_heightMapRenderObj->updateTreePosition((DrawableID)(Int)pMapObj, loc, pMapObj->getAngle())) {
1400 // Couldn't find it, so update them all. [5/27/2003]
1401 updateAllTrees = true;
1402 }
1403 if (found) break;
1404 }
1405
1406 RenderObjClass *renderObj=NULL;
1407 Shadow *shadowObj=NULL;
1408
1409 REF_PTR_SET( renderObj, pMapObj->getRenderObj() );
1410 Int playerColor = 0xFFFFFF;
1411 BodyDamageType curDamageState = BODY_PRISTINE;
1412 Bool isVehicle = false;
1413
1414 Bool exists;
1415 if (tTemplate && !(pMapObj->getFlags() & FLAG_DONT_RENDER))
1416 {
1417 isVehicle = tTemplate->isKindOf(KINDOF_VEHICLE);
1418 AsciiString objectTeamName = pMapObj->getProperties()->getAsciiString(TheKey_originalOwner, &exists);
1419 if (exists) {
1420 TeamsInfo *teamInfo = TheSidesList->findTeamInfo(objectTeamName);
1421 if (teamInfo) {
1422 AsciiString teamOwner = teamInfo->getDict()->getAsciiString(TheKey_teamOwner);
1423 SidesInfo* pSide = TheSidesList->findSideInfo(teamOwner);
1424 if (pSide) {
1425 Bool hasColor = false;
1426 Int color = pSide->getDict()->getInt(TheKey_playerColor, &hasColor);
1427 if (hasColor) {
1428 playerColor = color;
1429 } else {
1430 AsciiString tmplname = pSide->getDict()->getAsciiString(TheKey_playerFaction);
1431 const PlayerTemplate* pt = ThePlayerTemplateStore->findPlayerTemplate(NAMEKEY(tmplname));
1432 if (pt) {
1434 }
1435 }
1436 }
1437 }
1438 }
1439 }
1440 Int health = 100;
1441 health = pMapObj->getProperties()->getInt(TheKey_objectInitialHealth, &exists);
1442 Real ratio = health/100.0;
1443 if (ratio > TheGlobalData->m_unitDamagedThresh)
1444 {
1445 curDamageState = BODY_PRISTINE;
1446 }
1447 else if (ratio > TheGlobalData->m_unitReallyDamagedThresh)
1448 {
1449 curDamageState = BODY_DAMAGED;
1450 }
1451 else if (ratio > 0.0f)
1452 {
1453 curDamageState = BODY_REALLYDAMAGED;
1454 }
1455 else
1456 {
1457 curDamageState = BODY_RUBBLE;
1458 }
1459
1460
1461 if (!renderObj) {
1462 Real scale = 1.0;
1463 AsciiString modelName = getModelNameAndScale(pMapObj, &scale, curDamageState);
1464 // set render object, or create if we need to
1465 if( renderObj == NULL && modelName.isEmpty() == FALSE &&
1466 strncmp( modelName.str(), "No ", 3 ) )
1467 {
1468
1469 if (!getShowModels()) {
1470 continue;
1471 }
1472 renderObj = m_assetManager->Create_Render_Obj( modelName.str(), scale, playerColor);
1473 if( m_showShadows )
1474 {
1475 Shadow::ShadowTypeInfo shadowInfo;
1476 shadowInfo.allowUpdates=FALSE; //shadow image will never update
1477 shadowInfo.allowWorldAlign=TRUE; //shadow image will wrap around world objects
1478 if (tTemplate && tTemplate->getShadowType() != SHADOW_NONE && !(pMapObj->getFlags() & FLAG_DONT_RENDER))
1479 { //add correct type of shadow
1480 strcpy(shadowInfo.m_ShadowName,tTemplate->getShadowTextureName().str());
1481 DEBUG_ASSERTCRASH(shadowInfo.m_ShadowName[0] != '\0', ("this should be validated in ThingTemplate now"));
1482 shadowInfo.m_type=(ShadowType)tTemplate->getShadowType();
1483 shadowInfo.m_sizeX=tTemplate->getShadowSizeX();
1484 shadowInfo.m_sizeY=tTemplate->getShadowSizeY();
1485 shadowInfo.m_offsetX=tTemplate->getShadowOffsetX();
1486 shadowInfo.m_offsetY=tTemplate->getShadowOffsetY();
1487 shadowObj=TheW3DShadowManager->addShadow(renderObj, &shadowInfo);
1488 } else if (!tTemplate) {
1489 shadowInfo.m_type=(ShadowType)SHADOW_VOLUME;
1490 shadowObj=TheW3DShadowManager->addShadow(renderObj, &shadowInfo);
1491 }
1492 }
1493 } // end if
1494 }
1495
1496 if (renderObj && !(pMapObj->getFlags() & FLAG_DONT_RENDER)) {
1497 pMapObj->setRenderObj(renderObj);
1498 pMapObj->setShadowObj(shadowObj);
1499
1500 // set item's position to loc, and get scale from item and apply it.
1501
1502 Matrix3D renderObjPos(true); // init to identity
1503 renderObjPos.Translate(loc.x, loc.y, loc.z);
1504 renderObjPos.Rotate_Z(pMapObj->getAngle());
1505 renderObj->Set_Transform( renderObjPos );
1506
1507 if (isVehicle) {
1508 // note that this affects our orientation, but NOT our position... specifically,
1509 // it does NOT force us to "stick" to the ground!
1510 Matrix3D mtx;
1511 Coord3D terrainNormal;
1512 m_heightMapRenderObj->getHeightMapHeight(loc.x, loc.y, &terrainNormal );
1513 makeAlignToNormalMatrix(pMapObj->getAngle(), loc, terrainNormal, mtx);
1514 renderObj->Set_Transform( mtx );
1515 }
1516
1517 m_scene->Add_Render_Object(renderObj);
1518
1519 REF_PTR_RELEASE(renderObj); // belongs to m_scene now.
1520 } else if (renderObj) {
1521 m_scene->Remove_Render_Object(renderObj);
1522 }
1523 if (found) break;
1524 }
1525 if (!found && pMapObjIn) {
1526 if (pMapObjIn->getFlags() & (FLAG_ROAD_FLAGS|FLAG_BRIDGE_FLAGS)) {
1527 isRoad = true;
1528 }
1529 const ThingTemplate *tTemplate = pMapObjIn->getThingTemplate();
1530 if (tTemplate && tTemplate->isKindOf(KINDOF_OPTIMIZED_TREE)) {
1531 updateAllTrees = true;
1532 }
1533 }
1534 if (!found && pMapObjIn && pMapObjIn->getRenderObj()) {
1535 if( m_showShadows ) {
1538 --m_updateCount;
1539 return;
1540 }
1541 m_scene->Remove_Render_Object(pMapObjIn->getRenderObj());
1542 pMapObjIn->setRenderObj(NULL);
1543 }
1544
1545 if (isRoad) {
1546 m_needToLoadRoads = true; // load roads next time we redraw.
1547 }
1548 if (updateAllTrees) {
1549 updateTrees();
1550 }
1551 if (isLight) {
1552 updateLights();
1553 }
1554 if (isScorch) {
1555 updateScorches();
1556 }
1557 Invalidate(false);
1558
1559 --m_updateCount;
1560}
1561
1562
1563// ----------------------------------------------------------------------------
1564void WbView3d::updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange)
1565{
1566 if (htMap == NULL)
1567 return;
1568 ++m_updateCount;
1569
1570 if (m_heightMapRenderObj == NULL) {
1571 m_heightMapRenderObj = NEW_REF(WBHeightMap,());
1572 m_scene->Add_Render_Object(m_heightMapRenderObj);
1573 partial = false;
1574 }
1575
1576
1577 if (m_heightMapRenderObj) {
1578
1579 Int curTicks = ::GetTickCount();
1580
1581 RefRenderObjListIterator lightListIt(&m_lightList);
1582 if (partial) {
1583 m_heightMapRenderObj->doPartialUpdate(partialRange, htMap, &lightListIt);
1584 } else {
1585 if (m_showEntireMap) {
1586 htMap->setDrawOrg(0, 0);
1587 htMap->setDrawWidth(htMap->getXExtent());
1588 htMap->setDrawHeight(htMap->getYExtent());
1589 m_heightMapRenderObj->initHeightData(htMap->getXExtent(), htMap->getYExtent(), htMap, &lightListIt);
1590 } else {
1591 htMap->setDrawWidth(m_partialMapSize);
1592 htMap->setDrawHeight(m_partialMapSize);
1593 m_heightMapRenderObj->initHeightData(htMap->getDrawWidth(), htMap->getDrawHeight(), htMap, &lightListIt);
1594 }
1595 m_heightMapRenderObj->updateViewImpassableAreas();
1596 }
1597 curTicks = GetTickCount() - curTicks;
1598 if (curTicks < 1) curTicks = 1;
1599 }
1600
1601 invalObjectInView(NULL); // update all the map objects, to account for ground changes
1602
1603 --m_updateCount;
1604}
1605
1606// ----------------------------------------------------------------------------
1608{
1609 if (x != m_centerPt.X || y != m_centerPt.Y) {
1610 m_centerPt.X = x;
1611 m_centerPt.Y = y;
1613 redraw();
1615 drawLabels();
1617 }
1618}
1619
1620//=============================================================================
1621// WbView3d::picked3dObjectInView
1622//=============================================================================
1624//=============================================================================
1626{
1627 // This code picks on all 3d objects.
1628 if (m_intersector && m_layer) {
1629 CRect client;
1630 this->GetClientRect(&client);
1631 float logX = (Real)viewPt.x / (Real)client.Width();
1632 float logY = (Real)viewPt.y / (Real)client.Height();
1633 //m_intersector->Result.CollisionType = COLLISION_TYPE_0|COLLISION_TYPE_1;
1634 // do the intersection using W3D intersector class
1635 Bool hit = m_intersector->Intersect_Screen_Point_Layer( logX, logY, *m_layer );
1636 if( hit )
1637 {
1638 MapObject *pObj;
1639 for (pObj = MapObject::getFirstMapObject(); pObj; pObj = pObj->getNext()) {
1640 if (pObj->getRenderObj() == m_intersector->Result.IntersectedRenderObject) {
1641 return pObj;
1642 }
1643 }
1644 }
1645 }
1646
1647 return NULL;
1648}
1649
1650//=============================================================================
1651// WbView3d::pickedBuildObjectInView
1652//=============================================================================
1654//=============================================================================
1656{
1657 Coord3D cpt;
1658 Int i;
1659 viewToDocCoords(viewPt, &cpt, false);
1660 for (i=0; i<TheSidesList->getNumSides(); i++) {
1661 SidesInfo *pSide = TheSidesList->getSideInfo(i);
1662 for (BuildListInfo *pBuild = pSide->getBuildList(); pBuild; pBuild = pBuild->getNext()) {
1663 Coord3D center = *pBuild->getLocation();
1664 center.x -= cpt.x;
1665 center.y -= cpt.y;
1666 center.z = 0;
1667 Real len = center.length();
1668 // Check and see if we are within 1.5 cell size of the center.
1669 if (len < 1.5f*MAP_XY_FACTOR) {
1670 return pBuild;
1671 }
1672 }
1673 }
1674 // This code picks on all 3d build objects.
1675 if (m_intersector && m_buildLayer) {
1676 CRect client;
1677 this->GetClientRect(&client);
1678 float logX = (Real)viewPt.x / (Real)client.Width();
1679 float logY = (Real)viewPt.y / (Real)client.Height();
1680
1681 // do the intersection using W3D intersector class
1682 Bool hit = m_intersector->Intersect_Screen_Point_Layer( logX, logY, *m_buildLayer );
1683 if( hit ) {
1684 for (i=0; i<TheSidesList->getNumSides(); i++) {
1685 SidesInfo *pSide = TheSidesList->getSideInfo(i);
1686 for (BuildListInfo *pBuild = pSide->getBuildList(); pBuild; pBuild = pBuild->getNext()) {
1687 if (pBuild->getRenderObj() == m_intersector->Result.IntersectedRenderObject) {
1688 return pBuild;
1689 }
1690 }
1691 }
1692 }
1693 }
1694
1695 return NULL;
1696}
1697
1698// ----------------------------------------------------------------------------
1699Bool WbView3d::viewToDocCoords(CPoint curPt, Coord3D *newPt, Bool constrain)
1700{
1701 DEBUG_ASSERTCRASH((this),("oops"));
1702// const Int VIEW_BORDER = 3000; // keeps you from falling off the edge of the world.
1703 Bool result = false;
1704 CRect client;
1705 this->GetClientRect(&client);
1706
1707 // get our "logical" or relative screen coords
1708 float logX = (Real)curPt.x / (Real)client.Width();
1709 float logY = (Real)curPt.y / (Real)client.Height();
1710 Vector3 intersection(0,0,0);
1711 // determine the ray corresponding to the camera and distance to projection plane
1712 Matrix3D camera_matrix = m_camera->Get_Transform();
1713
1714 Vector3 camera_location = m_camera->Get_Position();
1715
1716 Vector3 rayLocation;
1717 Vector3 rayDirection;
1718 Vector3 rayDirectionPt;
1719 // the projected ray has the same origin as the camera
1720 rayLocation = camera_location;
1721 // determine the location of the screen coordinate in camera-model space
1722 const ViewportClass &viewport = m_camera->Get_Viewport();
1723
1724 Vector2 min,max;
1725 m_camera->Get_View_Plane(min,max);
1726 float xscale = (max.X - min.X);
1727 float yscale = (max.Y - min.Y);
1728
1729 float zmod = -1.0; // Scene->vpd; // Note: view plane distance is now always 1.0 from the camera
1730 float xmod = (-logX + 0.5 + viewport.Min.X) * zmod * xscale;// / aspect;
1731 float ymod = (logY - 0.5 - viewport.Min.Y) * zmod * yscale;// * aspect;
1732
1733 // transform the screen coordinates by the camera's matrix into world coordinates.
1734 float x = zmod * camera_matrix[0][2] + xmod * camera_matrix[0][0] + ymod * camera_matrix[0][1];
1735 float y = zmod * camera_matrix[1][2] + xmod * camera_matrix[1][0] + ymod * camera_matrix[1][1];
1736 float z = zmod * camera_matrix[2][2] + xmod * camera_matrix[2][0] + ymod * camera_matrix[2][1];
1737
1738 rayDirection.Set(x,y,z);
1739 rayDirection.Normalize();
1740 float MaxDistance = m_camera->Get_Depth()*MAP_XY_FACTOR;
1741 rayDirectionPt = rayLocation + rayDirection*MaxDistance;
1742
1743 LineSegClass ray(rayLocation, rayDirectionPt);
1744
1745 // Note - there are 2 ways to track. One is for tools (like paint texture)
1746 // that follow the terrain. They want to track the terrain, so the texturing
1747 // follows the cursor. Most tools, however, don't want to jump up & down clifs
1748 // and such. So they use a fixed z plane when tracking, so things don't move
1749 // depending what you move over.
1750 Bool followTerrain = true;
1751 if (WbApp()->isCurToolLocked()) {
1752 followTerrain = WbApp()->getCurTool()->followsTerrain();
1753 }
1754 if (followTerrain && TheTerrainRenderObject) {
1755 CastResultStruct castResult;
1756 RayCollisionTestClass rayCollide(ray, &castResult) ;
1757 if( TheTerrainRenderObject->Cast_Ray(rayCollide) )
1758 {
1759 // get the point of intersection according to W3D
1760 intersection = castResult.ContactPoint;
1761 m_curTrackingZ = intersection.Z;
1762 result = true;
1763 } // end if
1764 }
1765 if (!result) {
1766 intersection.X = Vector3::Find_X_At_Z(m_curTrackingZ, rayLocation, rayDirectionPt);
1767 intersection.Y = Vector3::Find_Y_At_Z(m_curTrackingZ, rayLocation, rayDirectionPt);
1768 result = true;
1769 }
1770 newPt->x = intersection.X;
1771 newPt->y = intersection.Y;
1772 newPt->z = MAGIC_GROUND_Z;
1773 if (constrain) {
1774#if 1
1775 if (m_doLockAngle) {
1776 Real dy = fabs(m_mouseDownDocPoint.y - newPt->y);
1777 Real dx = fabs(m_mouseDownDocPoint.x - newPt->x);
1778 if (dx>2*dy) {
1779 // lock to dx.
1780 newPt->y = m_mouseDownDocPoint.y;
1781 } else if (dy>2*dx) {
1782 //lock to dy.
1783 newPt->x = m_mouseDownDocPoint.x;
1784 } else {
1785 // Lock to 45 degree.
1786 dx = (dx+dy)/2;
1787 dy = dx;
1788 if (newPt->x < m_mouseDownDocPoint.x) dx = -dx;
1789 if (newPt->y < m_mouseDownDocPoint.y) dy = -dy;
1790 newPt->x = m_mouseDownDocPoint.x+dx;
1791 newPt->y = m_mouseDownDocPoint.y+dy;
1792 }
1793 }
1794#else
1795 if (m_cameraAngle > PI) {
1796 m_cameraAngle -= 2*PI;
1797 }
1798 if (m_cameraAngle < -PI) {
1799 m_cameraAngle += 2*PI;
1800 }
1801 Bool flip = false;
1802 // If we are looking sideways, flip the locks.
1803 if (PI/4<m_cameraAngle && m_cameraAngle < 3*PI/4) {
1804 flip = true;
1805 }
1806 if (-PI/4>m_cameraAngle && m_cameraAngle > -3*PI/4) {
1807 flip = true;
1808 }
1809
1810 if (flip) {
1811 if (m_doLockVertical) {
1812 newPt->y = m_mouseDownDocPoint.y;
1813 } else if (m_doLockHorizontal) {
1814 newPt->x = m_mouseDownDocPoint.x;
1815 }
1816 } else {
1817 if (m_doLockHorizontal) {
1818 newPt->y = m_mouseDownDocPoint.y;
1819 } else if (m_doLockVertical) {
1820 newPt->x = m_mouseDownDocPoint.x;
1821 }
1822 }
1823#endif
1824 }
1825 return result;
1826}
1827
1828// ----------------------------------------------------------------------------
1829Bool WbView3d::viewToDocCoordZ(CPoint curPt, Coord3D *newPt, Real theZ)
1830{
1831 DEBUG_ASSERTCRASH((this),("oops"));
1832 CRect client;
1833 this->GetClientRect(&client);
1834
1835 // get our "logical" or relative screen coords
1836 float logX = (Real)curPt.x / (Real)client.Width();
1837 float logY = (Real)curPt.y / (Real)client.Height();
1838 Vector3 intersection(0,0,0);
1839 // determine the ray corresponding to the camera and distance to projection plane
1840 Matrix3D camera_matrix = m_camera->Get_Transform();
1841
1842 Vector3 camera_location = m_camera->Get_Position();
1843
1844 Vector3 rayLocation;
1845 Vector3 rayDirection;
1846 Vector3 rayDirectionPt;
1847 // the projected ray has the same origin as the camera
1848 rayLocation = camera_location;
1849 // determine the location of the screen coordinate in camera-model space
1850 const ViewportClass &viewport = m_camera->Get_Viewport();
1851
1852 Vector2 min,max;
1853 m_camera->Get_View_Plane(min,max);
1854 float xscale = (max.X - min.X);
1855 float yscale = (max.Y - min.Y);
1856
1857 float zmod = -1.0; // Scene->vpd; // Note: view plane distance is now always 1.0 from the camera
1858 float xmod = (-logX + 0.5 + viewport.Min.X) * zmod * xscale;// / aspect;
1859 float ymod = (logY - 0.5 - viewport.Min.Y) * zmod * yscale;// * aspect;
1860
1861 // transform the screen coordinates by the camera's matrix into world coordinates.
1862 float x = zmod * camera_matrix[0][2] + xmod * camera_matrix[0][0] + ymod * camera_matrix[0][1];
1863 float y = zmod * camera_matrix[1][2] + xmod * camera_matrix[1][0] + ymod * camera_matrix[1][1];
1864 float z = zmod * camera_matrix[2][2] + xmod * camera_matrix[2][0] + ymod * camera_matrix[2][1];
1865
1866 rayDirection.Set(x,y,z);
1867 rayDirection.Normalize();
1868 float MaxDistance = m_camera->Get_Depth()*MAP_XY_FACTOR;
1869 rayDirectionPt = rayLocation + rayDirection*MaxDistance;
1870
1871 LineSegClass ray(rayLocation, rayDirectionPt);
1872
1873 intersection.X = Vector3::Find_X_At_Z(theZ, rayLocation, rayDirectionPt);
1874 intersection.Y = Vector3::Find_Y_At_Z(theZ, rayLocation, rayDirectionPt);
1875
1876 newPt->x = intersection.X;
1877 newPt->y = intersection.Y;
1878 newPt->z = theZ;
1879 return true;
1880}
1881
1882// ----------------------------------------------------------------------------
1884{
1885 CRect client;
1886 GetClientRect(&client);
1887 CPoint curPt;
1888 curPt.x = (client.left+client.right)/2;
1889 curPt.y = (client.bottom+client.top)/2;
1890 // get our "logical" or relative screen coords
1891 float logX = (Real)curPt.x / (Real)client.Width();
1892 float logY = (Real)curPt.y / (Real)client.Height();
1893 Vector3 intersection(0,0,0);
1894 // determine the ray corresponding to the camera and distance to projection plane
1895 Matrix3D camera_matrix = m_camera->Get_Transform();
1896
1897 Vector3 camera_location = m_camera->Get_Position();
1898
1899 Vector3 rayLocation;
1900 Vector3 rayDirection;
1901 Vector3 rayDirectionPt;
1902 // the projected ray has the same origin as the camera
1903 rayLocation = camera_location;
1904 // determine the location of the screen coordinate in camera-model space
1905 const ViewportClass &viewport = m_camera->Get_Viewport();
1906
1907 Vector2 min,max;
1908 m_camera->Get_View_Plane(min,max);
1909 float xscale = (max.X - min.X);
1910 float yscale = (max.Y - min.Y);
1911
1912 float zmod = -1.0; // Scene->vpd; // Note: view plane distance is now always 1.0 from the camera
1913 float xmod = (-logX + 0.5 + viewport.Min.X) * zmod * xscale;// / aspect;
1914 float ymod = (logY - 0.5 - viewport.Min.Y) * zmod * yscale;// * aspect;
1915
1916 // transform the screen coordinates by the camera's matrix into world coordinates.
1917 float x = zmod * camera_matrix[0][2] + xmod * camera_matrix[0][0] + ymod * camera_matrix[0][1];
1918 float y = zmod * camera_matrix[1][2] + xmod * camera_matrix[1][0] + ymod * camera_matrix[1][1];
1919 float z = zmod * camera_matrix[2][2] + xmod * camera_matrix[2][0] + ymod * camera_matrix[2][1];
1920
1921 rayDirection.Set(x,y,z);
1922 rayDirectionPt = rayLocation + rayDirection;
1923
1924 intersection.X = Vector3::Find_X_At_Z(m_curTrackingZ, rayLocation, rayDirectionPt);
1925 intersection.Y = Vector3::Find_Y_At_Z(m_curTrackingZ, rayLocation, rayDirectionPt);
1926
1927 // Calculate the point offset by 3 pixels.
1928 logX = (Real)(curPt.x+3) / (Real)client.Width();
1929 Vector3 offset(0,0,0);
1930
1931 xmod = (-logX + 0.5 + viewport.Min.X) * zmod * xscale;// / aspect;
1932 ymod = (logY - 0.5 - viewport.Min.Y) * zmod * yscale;// * aspect;
1933
1934 // transform the screen coordinates by the camera's matrix into world coordinates.
1935 x = zmod * camera_matrix[0][2] + xmod * camera_matrix[0][0] + ymod * camera_matrix[0][1];
1936 y = zmod * camera_matrix[1][2] + xmod * camera_matrix[1][0] + ymod * camera_matrix[1][1];
1937 z = zmod * camera_matrix[2][2] + xmod * camera_matrix[2][0] + ymod * camera_matrix[2][1];
1938 rayDirection.Set(x,y,z);
1939 rayDirectionPt = rayLocation + rayDirection;
1940 offset.X = Vector3::Find_X_At_Z(m_curTrackingZ, rayLocation, rayDirectionPt);
1941 offset.Y = Vector3::Find_Y_At_Z(m_curTrackingZ, rayLocation, rayDirectionPt);
1942 offset = offset - intersection;
1943 m_hysteresis = offset.Length();
1944
1945 logX = (Real)(curPt.x) / (Real)client.Width();
1946 logY = (Real)(curPt.y+3) / (Real)client.Height();
1947
1948 xmod = (-logX + 0.5 + viewport.Min.X) * zmod * xscale;// / aspect;
1949 ymod = (logY - 0.5 - viewport.Min.Y) * zmod * yscale;// * aspect;
1950
1951 // transform the screen coordinates by the camera's matrix into world coordinates.
1952 x = zmod * camera_matrix[0][2] + xmod * camera_matrix[0][0] + ymod * camera_matrix[0][1];
1953 y = zmod * camera_matrix[1][2] + xmod * camera_matrix[1][0] + ymod * camera_matrix[1][1];
1954 z = zmod * camera_matrix[2][2] + xmod * camera_matrix[2][0] + ymod * camera_matrix[2][1];
1955 rayDirection.Set(x,y,z);
1956 rayDirectionPt = rayLocation + rayDirection;
1957 offset.X = Vector3::Find_X_At_Z(m_curTrackingZ, rayLocation, rayDirectionPt);
1958 offset.Y = Vector3::Find_Y_At_Z(m_curTrackingZ, rayLocation, rayDirectionPt);
1959 offset = offset - intersection;
1960 if (m_hysteresis < offset.Length()) m_hysteresis = offset.Length();
1961
1962 CPoint pt1, pt2;
1963 Coord3D loc;
1964 loc.x = intersection.X;
1965 loc.y = intersection.Y;
1966 loc.z = intersection.Z;
1967 this->docToViewCoords(loc, &pt1);
1968 loc.x += MAP_XY_FACTOR*0.4f;
1969 loc.y += MAP_XY_FACTOR*0.4f;
1970 this->docToViewCoords(loc, &pt2);
1971 Int dx = pt1.x-pt2.x;
1972 if (dx<0) dx = -dx;
1973 Int dy = pt1.y-pt2.y;
1974 if (dy<0) dy = -dy;
1975 if (dx<dy) dx = dy;
1976 if (dx<4) dx = 3;
1977 m_pickPixels = dx+3;
1978
1979}
1980
1981// ----------------------------------------------------------------------------
1983{
1984 Bool coordInsideFrustrum = true;
1985 Vector3 world;
1986 Vector3 screen;
1987 newPt->x = -1000;
1988 newPt->y = -1000;
1989 if (m_heightMapRenderObj) {
1990 curPt.z += m_heightMapRenderObj->getHeightMapHeight(curPt.x, curPt.y, NULL);
1991 }
1992
1993 world.Set( curPt.x, curPt.y, curPt.z );
1994 if (m_camera->Project( screen, world ) != CameraClass::INSIDE_FRUSTUM) {
1995 coordInsideFrustrum = false;
1996 } else {
1997 coordInsideFrustrum = true;
1998 }
1999
2000 CRect rClient;
2001 GetClientRect(&rClient);
2002
2003 //
2004 // note that the screen coord returned from the project W3D camera
2005 // gave us a screen coords that range from (-1,-1) bottom left to
2006 // (1,1) top right ... we are turning that into (0,0) upper left
2007 // coords now
2008 //
2009 Int sx, sy;
2010 W3DLogicalScreenToPixelScreen( screen.X, screen.Y,
2011 &sx, &sy,
2012 rClient.right-rClient.left, rClient.bottom-rClient.top );
2013
2014 newPt->x = rClient.left + sx;
2015 newPt->y = rClient.top + sy;
2016
2017 return coordInsideFrustrum;
2018}
2019
2020// ----------------------------------------------------------------------------
2022{
2023 if (m_updateCount > 0) {
2024 return;
2025 }
2026 if (IsIconic()) {
2027 return;
2028 }
2029 if (!IsWindowVisible()) {
2030 return;
2031 }
2032 if (!m_ww3dInited) {
2033 return;
2034 }
2035
2036 setupCamera();
2037
2038 DEBUG_ASSERTCRASH((m_heightMapRenderObj),("oops"));
2039 if (m_heightMapRenderObj) {
2040 if (m_needToLoadRoads) {
2041 m_heightMapRenderObj->loadRoadsAndBridges(NULL,FALSE);
2042 m_heightMapRenderObj->worldBuilderUpdateBridgeTowers( m_assetManager, m_scene );
2043 m_needToLoadRoads = false;
2044 }
2045 ++m_updateCount;
2046 Int curTicks = GetTickCount();
2047 RefRenderObjListIterator lightListIt(&m_lightList);
2048 m_heightMapRenderObj->updateCenter(m_camera, &lightListIt);
2049 m_heightMapRenderObj->On_Frame_Update();
2050 --m_updateCount;
2051
2052 curTicks = GetTickCount()-curTicks;
2053// if (curTicks>2) {
2054// WWDEBUG_SAY(("%d ms for updateCenter, %d FPS\n", curTicks, 1000/curTicks));
2055// }
2056 }
2057 if (m_drawObject) {
2058 m_drawObject->setDrawObjects(m_showObjects,
2061 m_showBoundingBoxes, m_showSightRanges, m_showWeaponRanges, m_showSoundCircles, m_highlightTestArt, m_showLetterbox);
2062 }
2063
2064 WW3D::Sync( GetTickCount() );
2065 m_buildRedMultiplier += (GetTickCount()-m_time)/500.0f;
2066 if (m_buildRedMultiplier>4.0f || m_buildRedMultiplier<0) {
2067 m_buildRedMultiplier = 0;
2068 }
2069 render();
2070 m_time = ::GetTickCount();
2071}
2072
2073// ----------------------------------------------------------------------------
2075{
2076 ++m_updateCount;
2077
2078 if (WW3D::Begin_Render(true,true,Vector3(0.5f,0.5f,0.5f), TheWaterTransparency->m_minWaterOpacity) == WW3D_ERROR_OK)
2079 {
2080
2081 DEBUG_ASSERTCRASH((m_heightMapRenderObj),("oops"));
2082
2083
2084 if (m_heightMapRenderObj) {
2085 m_heightMapRenderObj->Set_Hidden((m_showTerrain ? 0 : 1));
2086 m_heightMapRenderObj->doTextures(true);
2087 }
2088 m_scene->Set_Polygon_Mode(SceneClass::FILL);
2089 // Render 3D scene
2090 WW3D::Render(m_scene,m_camera);
2091 Vector3 amb = m_baseBuildScene->Get_Ambient_Light();
2092 Vector3 newAmb(amb);
2093 Real mul = m_buildRedMultiplier;
2094 if (mul>2.0f) mul = 4.0f-mul;
2095 Real gMul = 2.0-mul;
2096 newAmb.X *= mul;
2097 newAmb.Y *= gMul;
2098 if (newAmb.X>1) newAmb.X = 1;
2099 m_baseBuildScene->Set_Ambient_Light(newAmb);
2100 WW3D::Render(m_baseBuildScene,m_camera);
2101 m_baseBuildScene->Set_Ambient_Light(amb);
2102
2103 if (m_showWireframe) {
2104 if (m_heightMapRenderObj) {
2105 m_heightMapRenderObj->doTextures(false);
2106 m_scene->Set_Polygon_Mode(SceneClass::LINE);
2107 // Render 3D scene
2108 WW3D::Render(m_scene,m_camera);
2109 WW3D::Render(m_baseBuildScene,m_camera);
2110 m_heightMapRenderObj->doTextures(true);
2111 }
2112 }
2113 if (m_showObjToolTrackingObj && m_objectToolTrackingObj) {
2114 m_transparentObjectsScene->Add_Render_Object(m_objectToolTrackingObj);
2116 TheDX8MeshRenderer.Enable_Lighting(false);
2117 Real lightLevel = 1.0f;
2118 m_transparentObjectsScene->Set_Ambient_Light(Vector3(lightLevel,lightLevel,lightLevel));
2119 WW3D::Render(m_transparentObjectsScene, m_camera);
2120 TheDX8MeshRenderer.Enable_Lighting(true);
2122 m_transparentObjectsScene->Remove_Render_Object(m_objectToolTrackingObj);
2123 }
2124
2125 // Draw the 3d obj icons on top of the rest of the data.
2126 WW3D::Render(m_overlayScene,m_camera);
2127 //if (mytext) mytext->Render();
2128 if (m3DFont) {
2130 }
2131
2132
2134 }
2135 --m_updateCount;
2136}
2137
2138// ----------------------------------------------------------------------------
2139BEGIN_MESSAGE_MAP(WbView3d, WbView)
2140 //{{AFX_MSG_MAP(WbView3d)
2141 ON_WM_CREATE()
2142 ON_WM_PAINT()
2143 ON_WM_SIZE()
2144 ON_WM_MOUSEWHEEL()
2145 ON_WM_TIMER()
2146 ON_WM_DESTROY()
2147 ON_WM_SHOWWINDOW()
2148 ON_COMMAND(ID_VIEW_SHOWWIREFRAME, OnViewShowwireframe)
2149 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWWIREFRAME, OnUpdateViewShowwireframe)
2150 ON_WM_ERASEBKGND()
2151 ON_COMMAND(ID_VIEW_SHOWENTIRE3DMAP, OnViewShowentire3dmap)
2152 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWENTIRE3DMAP, OnUpdateViewShowentire3dmap)
2153 ON_COMMAND(ID_VIEW_SHOWTOPDOWNVIEW, OnViewShowtopdownview)
2154 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWTOPDOWNVIEW, OnUpdateViewShowtopdownview)
2155 ON_COMMAND(ID_VIEW_SHOWCLOUDS, OnViewShowclouds)
2156 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWCLOUDS, OnUpdateViewShowclouds)
2157 ON_COMMAND(ID_VIEW_SHOWMACROTEXTURE, OnViewShowmacrotexture)
2158 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWMACROTEXTURE, OnUpdateViewShowmacrotexture)
2159 ON_COMMAND(ID_EDIT_SELECTMACROTEXTURE, OnEditSelectmacrotexture)
2160 ON_COMMAND(ID_VIEW_SHOWSOFTWATER, OnViewShowSoftWater)
2161 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWEXTRABLENDS, OnUpdateViewShowExtraBlends)
2162 ON_COMMAND(ID_VIEW_SHOWEXTRABLENDS, OnViewExtraBlends)
2163 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSOFTWATER, OnUpdateViewShowSoftWater)
2164 ON_COMMAND(ID_VIEW_SHOWSHADOWS, OnViewShowshadows)
2165 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWSHADOWS, OnUpdateViewShowshadows)
2166 ON_COMMAND(ID_EDIT_SHADOWS, OnEditShadows)
2167 ON_COMMAND(ID_EDIT_MAPSETTINGS, OnEditMapSettings)
2168 ON_COMMAND(ID_VIEW_SHOWIMPASSABLEAREAS, OnViewShowimpassableareas)
2169 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWIMPASSABLEAREAS, OnUpdateViewShowimpassableareas)
2170 ON_COMMAND(ID_VIEW_IMPASSABLEAREAOPTIONS, OnImpassableAreaOptions)
2171 ON_COMMAND(ID_VIEW_PARTIALMAPSIZE_96X96, OnViewPartialmapsize96x96)
2172 ON_UPDATE_COMMAND_UI(ID_VIEW_PARTIALMAPSIZE_96X96, OnUpdateViewPartialmapsize96x96)
2173 ON_COMMAND(ID_VIEW_PARTIALMAPSIZE_192X192, OnViewPartialmapsize192x192)
2174 ON_UPDATE_COMMAND_UI(ID_VIEW_PARTIALMAPSIZE_192X192, OnUpdateViewPartialmapsize192x192)
2175 ON_COMMAND(ID_VIEW_PARTIALMAPSIZE_160X160, OnViewPartialmapsize160x160)
2176 ON_UPDATE_COMMAND_UI(ID_VIEW_PARTIALMAPSIZE_160X160, OnUpdateViewPartialmapsize160x160)
2177 ON_COMMAND(ID_VIEW_PARTIALMAPSIZE_128X128, OnViewPartialmapsize128x128)
2178 ON_UPDATE_COMMAND_UI(ID_VIEW_PARTIALMAPSIZE_128X128, OnUpdateViewPartialmapsize128x128)
2179 ON_COMMAND(ID_VIEW_SHOWMODELS, OnViewShowModels)
2180 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWMODELS, OnUpdateViewShowModels)
2181 ON_COMMAND(ID_VIEW_BOUNDINGBOXES, OnViewBoundingBoxes)
2182 ON_UPDATE_COMMAND_UI(ID_VIEW_BOUNDINGBOXES, OnUpdateViewBoundingBoxes)
2183 ON_COMMAND(ID_VIEW_SIGHTRANGES, OnViewSightRanges)
2184 ON_UPDATE_COMMAND_UI(ID_VIEW_SIGHTRANGES, OnUpdateViewSightRanges)
2185 ON_COMMAND(ID_VIEW_WEAPONRANGES, OnViewWeaponRanges)
2186 ON_UPDATE_COMMAND_UI(ID_VIEW_WEAPONRANGES, OnUpdateViewWeaponRanges)
2187 ON_COMMAND(ID_HIGHLIGHT_TESTART, OnHighlightTestArt)
2188 ON_UPDATE_COMMAND_UI(ID_HIGHLIGHT_TESTART, OnUpdateHighlightTestArt)
2189 ON_COMMAND(ID_SHOW_LETTERBOX, OnShowLetterbox)
2190 ON_UPDATE_COMMAND_UI(ID_SHOW_LETTERBOX, OnUpdateShowLetterbox)
2191 ON_COMMAND(ID_VIEW_GARRISONED, OnViewGarrisoned)
2192 ON_UPDATE_COMMAND_UI(ID_VIEW_GARRISONED, OnUpdateViewGarrisoned)
2193 ON_COMMAND(ID_VIEW_LAYERS_LIST, OnViewLayersList)
2194 ON_UPDATE_COMMAND_UI(ID_VIEW_LAYERS_LIST, OnUpdateViewLayersList)
2195 ON_COMMAND(ID_VIEW_SHOWMAPBOUNDARIES, OnViewShowMapBoundaries)
2196 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWMAPBOUNDARIES, OnUpdateViewShowMapBoundaries)
2197 ON_COMMAND(ID_VIEW_SHOWAMBIENTSOUNDS, OnViewShowAmbientSounds)
2198 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWAMBIENTSOUNDS, OnUpdateViewShowAmbientSounds)
2199 ON_COMMAND(ID_VIEW_SHOW_SOUND_CIRCLES, OnViewShowSoundCircles)
2200 ON_UPDATE_COMMAND_UI(ID_VIEW_SHOW_SOUND_CIRCLES, OnUpdateViewShowSoundCircles)
2201 //}}AFX_MSG_MAP
2202END_MESSAGE_MAP()
2203
2204// ----------------------------------------------------------------------------
2205// WbView3d drawing
2206
2207void WbView3d::OnDraw(CDC* pDC)
2208{
2209 // Not used. See OnPaint.
2210}
2211
2212// ----------------------------------------------------------------------------
2213// WbView3d diagnostics
2214
2215#ifdef _DEBUG
2216// ----------------------------------------------------------------------------
2217void WbView3d::AssertValid() const
2218{
2219 WbView::AssertValid();
2220}
2221
2222// ----------------------------------------------------------------------------
2223void WbView3d::Dump(CDumpContext& dc) const
2224{
2225 WbView::Dump(dc);
2226}
2227#endif //_DEBUG
2228
2229// ----------------------------------------------------------------------------
2231{
2232 // only want to do once per instance, but do lazily.
2233 if (!m_ww3dInited) {
2234
2235
2236
2237 m_ww3dInited = true;
2238
2239 WWMath::Init();
2240
2242
2243 initAssets();
2244 WW3D::Init(m_hWnd);
2247
2248 bogusTacticalView.setWidth(m_actualWinSize.x);
2249 bogusTacticalView.setHeight(m_actualWinSize.y);
2250 bogusTacticalView.setOrigin(0,0);
2251 if (WW3D::Set_Render_Device(0, m_actualWinSize.x, m_actualWinSize.y, 32, true, true) != WW3D_ERROR_OK)
2252 {
2253 // Getting the device at the default bit depth (32) didn't work, so try
2254 // getting a 16 bit display. (Voodoo 1-3 only supported 16 bit.) jba.
2255 if (WW3D::Set_Render_Device(0, m_actualWinSize.x, m_actualWinSize.y, 16, true, true) != WW3D_ERROR_OK)
2256 {
2257 DEBUG_CRASH(("Couldn't set render device."));
2258 }
2259 }
2260
2261 IDirect3DDevice8* pDev = DX8Wrapper::_Get_D3D_Device8();
2262 if (pDev) {
2263
2264// CDC* pDC = GetDC();
2265 LOGFONT logFont;
2266 logFont.lfHeight = 20;
2267 logFont.lfWidth = 0;
2268 logFont.lfEscapement = 0;
2269 logFont.lfOrientation = 0;
2270 logFont.lfWeight = FW_REGULAR;
2271 logFont.lfItalic = FALSE;
2272 logFont.lfUnderline = FALSE;
2273 logFont.lfStrikeOut = FALSE;
2274 logFont.lfCharSet = ANSI_CHARSET;
2275 logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
2276 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
2277 logFont.lfQuality = DEFAULT_QUALITY;
2278 logFont.lfPitchAndFamily = DEFAULT_PITCH;
2279 strcpy(logFont.lfFaceName, "Arial");
2280
2281 HFONT hFont = CreateFontIndirect(&logFont);
2282 if (hFont) {
2283 D3DXCreateFont(pDev, hFont, &m3DFont);
2284 DeleteObject(hFont);
2285 } else {
2286 m3DFont = NULL;
2287 }
2288
2289 } else {
2290 m3DFont = NULL;
2291 }
2292
2296
2298 init3dScene();
2299 m_layer = new LayerClass( m_scene, m_camera );
2300 m_buildLayer = new LayerClass( m_baseBuildScene, m_camera );
2301 m_intersector = new IntersectionClass();
2302 m_drawObject = new DrawObject();
2303 m_overlayScene->Add_Render_Object(m_drawObject);
2304
2305#if 1
2306 TheWritableGlobalData->m_useShadowVolumes = true;
2307 TheWritableGlobalData->m_useShadowDecals = true;
2308 TheWritableGlobalData->m_enableBehindBuildingMarkers = false; //this is only for the game.
2311 TheW3DShadowManager->init();
2312 }
2313#endif
2314 updateLights();
2316 }
2317}
2318
2319// ----------------------------------------------------------------------------
2320// WbView3d message handlers
2321
2322// ----------------------------------------------------------------------------
2323int WbView3d::OnCreate(LPCREATESTRUCT lpCreateStruct)
2324{
2325 if (WbView::OnCreate(lpCreateStruct) == -1)
2326 return -1;
2327
2328 // install debug callbacks
2329 WWDebug_Install_Message_Handler(WWDebug_Message_Callback);
2330 WWDebug_Install_Assert_Handler(WWAssert_Callback);
2331
2332 m_timer = SetTimer(0, UPDATE_TIME, NULL);
2333
2334 initWW3D();
2335 TheWritableGlobalData->m_useCloudMap = AfxGetApp()->GetProfileInt("GameOptions", "cloudMap", 0);
2336 AfxGetApp()->WriteProfileInt("GameOptions", "cloudMap", TheGlobalData->m_useCloudMap); // Just in case it wasn't already there
2337 m_partialMapSize = AfxGetApp()->GetProfileInt("GameOptions", "partialMapSize", 97);
2338
2339 m_showLayersList = AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowLayersList", 0);
2340 m_showMapBoundaries = AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowMapBoundaries", 0);
2341 m_showAmbientSounds = AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowAmbientSounds", 0);
2342 m_showSoundCircles = AfxGetApp()->GetProfileInt(MAIN_FRAME_SECTION, "ShowSoundCircles", 0);
2343
2344 DrawObject::setDoBoundaryFeedback(m_showMapBoundaries);
2345 DrawObject::setDoAmbientSoundFeedback(m_showAmbientSounds);
2346 return 0;
2347}
2348
2349// ----------------------------------------------------------------------------
2351{
2352
2353 PAINTSTRUCT ps;
2354 HDC hdc = ::BeginPaint(m_hWnd, &ps);
2355 if (!m_firstPaint) {
2356 redraw();
2357 }
2358 drawLabels(hdc);
2359 ::EndPaint(m_hWnd, &ps);
2360 if (m_firstPaint) {
2362 m_firstPaint = false;
2363 }
2365
2366}
2367
2370void WbView3d::drawCircle( HDC hdc, const Coord3D & centerPoint, Real radius, COLORREF color )
2371{
2372 CPoint rulerPoints[2];
2373 Coord3D pnt;
2374 Real angle = 0.0f;
2375 Real inc = PI/4.0f;
2376
2377 // Create and select a correctly colored pen. Remember the old one so that it can be restored.
2378 HPEN pen = CreatePen(PS_SOLID, 2, color);
2379 HPEN penOld = (HPEN)SelectObject(hdc, pen);
2380
2381
2382 // Get the starting point on the circumference of the circle.
2383 pnt.x = centerPoint.x + radius * (Real)cosf(angle);
2384 pnt.y = centerPoint.y + radius * (Real)sinf(angle);
2385 pnt.z = centerPoint.z;
2386 docToViewCoords(pnt, &rulerPoints[0]);
2387
2388 angle += inc;
2389 for(; angle <= 2.0f * PI; angle += inc) {
2390 // Get a new point on the circumference of the circle.
2391 pnt.x = centerPoint.x + radius * (Real)cosf(angle);
2392 pnt.y = centerPoint.y + radius * (Real)sinf(angle);
2393 pnt.z = centerPoint.z;
2394
2395 docToViewCoords(pnt, &rulerPoints[1]);
2396
2397 ::Polyline(hdc, rulerPoints, 2);
2398
2399 // Remember the last point to use as the starting point for the next line.
2400 rulerPoints[0].x = rulerPoints[1].x;
2401 rulerPoints[0].y = rulerPoints[1].y;
2402 }
2403
2404 // Restore previous pen.
2405 SelectObject(hdc, penOld);
2406 // Delete new pen.
2407 DeleteObject(pen);
2408}
2409
2410
2412{
2413 CDC * pDC = GetDC();
2414 drawLabels(pDC->m_hDC);
2415 ReleaseDC(pDC);
2416}
2417
2420{
2421 Coord3D selectedPos; //position of selected object
2422 Real selectedRadius=120.0f; //default distance of lightfeeback model from object
2423 selectedPos.x=0;selectedPos.y=0;selectedPos.z=0;
2424
2425 // Draw labels.
2426 MapObject *pMapObj;
2427 if (isNamesVisible())
2428 {
2429 for (pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) {
2430 AsciiString name;
2431 Coord3D pos;
2432
2433 if (pMapObj->getFlags() & FLAG_DONT_RENDER) {
2434 continue;
2435 }
2436
2437 if (m_doLightFeedback && pMapObj->isSelected())
2438 { //find out position of selected object in order to use it for light feedback tracking.
2439 selectedPos=*pMapObj->getLocation();
2440 selectedPos.z = m_heightMapRenderObj->getHeightMapHeight(selectedPos.x, selectedPos.y, NULL);
2441 RenderObjClass *selRobj=pMapObj->getRenderObj();
2442 if (selRobj)
2443 {
2444 SphereClass sphere;
2445 selRobj->Get_Obj_Space_Bounding_Sphere(sphere);
2446 selectedRadius=sphere.Radius + sphere.Center.Length()+20.0f;
2447 }
2448
2449 }
2450
2451 if (pMapObj->isWaypoint() && m_showWaypoints) {
2452 name = pMapObj->getWaypointName();
2453 pos = *pMapObj->getLocation();
2454 pos.z = m_heightMapRenderObj->getHeightMapHeight(pos.x, pos.y, NULL);
2455 } else if (pMapObj->getThingTemplate() && !(pMapObj->getFlags() & (FLAG_ROAD_FLAGS|FLAG_BRIDGE_FLAGS)) &&
2456 pMapObj->getRenderObj() == NULL && !pMapObj->getThingTemplate()->isKindOf(KINDOF_OPTIMIZED_TREE)) {
2457 name = pMapObj->getThingTemplate()->getName();
2458 pos = *pMapObj->getLocation();
2459 pos.z += m_heightMapRenderObj->getHeightMapHeight(pos.x, pos.y, NULL);
2460 }
2461 Int i;
2462 for (i=0; i<4; i++) {
2463 Bool exists;
2464 switch(i) {
2465 case 0 : break;
2466 case 1: name = pMapObj->getProperties()->getAsciiString(TheKey_waypointPathLabel1, &exists); break;
2467 case 2: name = pMapObj->getProperties()->getAsciiString(TheKey_waypointPathLabel2, &exists);; break;
2468 case 3: name = pMapObj->getProperties()->getAsciiString(TheKey_waypointPathLabel3, &exists);; break;
2469 default: name.clear();
2470 }
2471 if (!name.isEmpty() && m_showWaypoints) {
2472 CPoint pt;
2473 Vector3 world, screen;
2474 world.Set( pos.x+MAP_XY_FACTOR/2, pos.y, pos.z );
2475 if (CameraClass::INSIDE_FRUSTUM != m_camera->Project( screen, world )) {
2476 continue;
2477 }
2478 if (!name.isEmpty()) {
2479 CPoint pt;
2480 Vector3 world, screen;
2481 world.Set( pos.x+MAP_XY_FACTOR/2, pos.y, pos.z );
2482 if (CameraClass::INSIDE_FRUSTUM != m_camera->Project( screen, world )) {
2483 continue;
2484 }
2485
2486 CRect rClient;
2487 GetClientRect(&rClient);
2488
2489 //
2490 // note that the screen coord returned from the project W3D camera
2491 // gave us a screen coords that range from (-1,-1) bottom left to
2492 // (1,1) top right ... we are turning that into (0,0) upper left
2493 // coords now
2494 //
2495 Int sx, sy;
2496 W3DLogicalScreenToPixelScreen( screen.X, screen.Y,
2497 &sx, &sy,
2498 rClient.right-rClient.left, rClient.bottom-rClient.top );
2499 pt.x = rClient.left+sx;
2500 pt.y = rClient.top+sy;
2501 pt.y += i*15;
2502
2503 Int red, green;
2504 if (i==0) {
2505 red = 0; green = 255;
2506 } else {
2507 red = 255, green = 0;
2508 }
2509
2510 if (m3DFont && !hdc) {
2511 RECT rct;
2512 pt.y -= 5;
2513 pt.x += 1;
2514 rct.top = rct.bottom = pt.y;
2515 rct.left = rct.right = pt.x;
2516 m3DFont->DrawText(name.str(), name.getLength(), &rct,
2517 DT_LEFT | DT_NOCLIP | DT_TOP | DT_SINGLELINE, 0xAF000000 + (red<<16) + (green<<8));
2518
2519 } else if (!m3DFont) {
2520 //docToViewCoords(pos, &pt);
2521 ::SetBkMode(hdc, TRANSPARENT);
2522 pt.y -= 5;
2523 pt.x += 1;
2524 ::SetTextColor(hdc, RGB(red,green,0));
2525 ::TextOut(hdc, pt.x, pt.y, name.str(), name.getLength());
2526 }
2527 }
2528 }
2529 }
2530 }
2531 }
2532
2533 // Draw tracking box.
2534 if (hdc && m_doRectFeedback) {
2535 CBrush brush;
2536 // green brush for drawing the grid.
2537 brush.CreateSolidBrush(RGB(0,255,0));
2538 ::FrameRect(hdc, &m_feedbackBox, (HBRUSH)brush.GetSafeHandle());
2539 }
2540
2541 if (hdc && m_doRulerFeedback) {
2543 // Change world coords to screen viewport coords.
2544 CPoint rulerPoints[2];
2545 docToViewCoords(m_rulerPoints[0], &rulerPoints[0]);
2546 docToViewCoords(m_rulerPoints[1], &rulerPoints[1]);
2547
2548 // Create and select a green pen. Remember the old one so that it can be restored.
2549 HPEN pen = CreatePen(PS_SOLID, 2, RGB(0,255,0));
2550 HPEN penOld = (HPEN)SelectObject(hdc, pen);
2551 // Draw the line ruler.
2552 ::Polyline(hdc, rulerPoints, 2);
2553
2554 // Restore previous pen.
2555 SelectObject(hdc, penOld);
2556 // Delete new pen.
2557 DeleteObject(pen);
2558 } else if (m_doRulerFeedback == RULER_CIRCLE) {
2559 drawCircle( hdc, m_rulerPoints[0], m_rulerLength, RGB( 0, 255, 0 ) );
2560 }
2561 }
2562
2563 if (hdc && m_doLightFeedback)
2564 { //Draw Lines to indicate the direction of each light source
2565// Int LightColors[MAX_GLOBAL_LIGHTS]={RGB(255,0,0),RGB(0,255,0),RGB(0,0,255)};
2566
2567 for (Int lIndex=0; lIndex<MAX_GLOBAL_LIGHTS; lIndex++)
2568 {
2569 Vector3 worldStart, screenStart; //start of line
2570 Vector3 worldEnd, screenEnd; //end of line
2571
2572 worldStart.Set( selectedPos.x, selectedPos.y, selectedPos.z );
2573 worldEnd.Set(selectedPos.x - m_lightDirection[lIndex].x*selectedRadius,
2574 selectedPos.y - m_lightDirection[lIndex].y*selectedRadius,
2575 selectedPos.z - m_lightDirection[lIndex].z*selectedRadius);
2576
2577 if (m_lightFeedbackMesh[lIndex] == NULL)
2578 { char nameBuf[64];
2579 sprintf(nameBuf,"WB_LIGHT%d",lIndex+1);
2580 m_lightFeedbackMesh[lIndex]=WW3DAssetManager::Get_Instance()->Create_Render_Obj(nameBuf);
2581 }
2582 if (m_lightFeedbackMesh[lIndex]==NULL) {
2583 break;
2584 }
2585 Matrix3D lightMat;
2586
2587 lightMat.Look_At(worldEnd,worldStart,0);
2588 lightMat.Set_Translation(worldEnd);
2589
2590 m_lightFeedbackMesh[lIndex]->Add(m_scene);
2591 m_lightFeedbackMesh[lIndex]->Set_Transform(lightMat);
2592#ifdef DRAW_LIGHT_DIRECTION_RAYS
2593 if (CameraClass::INSIDE_FRUSTUM == m_camera->Project( screenStart, worldStart ) &&
2594 CameraClass::INSIDE_FRUSTUM == m_camera->Project( screenEnd, worldEnd ))
2595 {
2596 CRect rClient;
2597 GetClientRect(&rClient);
2598
2599 //
2600 // note that the screen coord returned from the project W3D camera
2601 // gave us a screen coords that range from (-1,-1) bottom left to
2602 // (1,1) top right ... we are turning that into (0,0) upper left
2603 // coords now
2604 //
2605 Int sxStart, syStart;
2606 Int sxEnd, syEnd;
2607
2608 W3DLogicalScreenToPixelScreen( screenStart.X, screenStart.Y, &sxStart, &syStart,rClient.right-rClient.left, rClient.bottom-rClient.top );
2609 W3DLogicalScreenToPixelScreen( screenEnd.X, screenEnd.Y, &sxEnd, &syEnd,rClient.right-rClient.left, rClient.bottom-rClient.top );
2610
2611 POINT rayPoints[2];
2612
2613 rayPoints[0].x = rClient.left+sxStart;
2614 rayPoints[0].y= rClient.top+syStart;
2615
2616 rayPoints[1].x = rClient.left+sxEnd;
2617 rayPoints[1].y= rClient.top+syEnd;
2618
2619 HPEN pen=CreatePen( PS_SOLID,2, LightColors[lIndex]);
2620 HPEN penOld = (HPEN)SelectObject(hdc, pen);
2621 Polyline(hdc,rayPoints,2);
2622 SelectObject(hdc, penOld); //restore previous pen
2623 DeleteObject(pen); //delete new pen
2624 }
2625#endif //DRAW_LIGHT_DIRECTION_RAYS
2626 }//end for
2627 }
2628 else
2629 { if (!m_doLightFeedback)
2630 { //not in light feedback mode. Make sure the temporary feeback models are gone
2631
2632 for (Int lIndex=0; lIndex<MAX_GLOBAL_LIGHTS; lIndex++)
2633 {
2634 if (m_lightFeedbackMesh[lIndex] != NULL)
2635 { m_lightFeedbackMesh[lIndex]->Remove();
2636 REF_PTR_RELEASE(m_lightFeedbackMesh[lIndex]);
2637 }
2638 }
2639 }
2640 }
2641}
2642
2643
2644// ----------------------------------------------------------------------------
2645void WbView3d::OnSize(UINT nType, int cx, int cy)
2646{
2647 WbView::OnSize(nType, cx, cy);
2648
2649}
2650
2651// ----------------------------------------------------------------------------
2652BOOL WbView3d::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
2653{
2654 if (m_trackingMode == TRACK_NONE) {
2655
2656 //WST 11/21/02 New Triple speed camera zoom request by designers
2657 if (getCurrentZoom() > 2.0f)
2658 {
2659 m_mouseWheelOffset += zDelta;
2660 }
2661 else if (getCurrentZoom() > 1.0f)
2662 {
2663 m_mouseWheelOffset += zDelta/2;
2664 }
2665 else
2666 {
2667 m_mouseWheelOffset += zDelta/8;
2668 }
2669
2670 MSG msg;
2671 while (::PeekMessage(&msg, m_hWnd, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_REMOVE)) {
2672 zDelta = (short) HIWORD(msg.wParam); // wheel rotation
2673 m_mouseWheelOffset += zDelta;
2674 }
2675 redraw();
2677 drawLabels();
2679 }
2680 return true;
2681}
2682
2683// ----------------------------------------------------------------------------
2685{
2686
2687 m_mouseWheelOffset = 0;
2688 m_cameraAngle = 0;
2689 m_FXPitch = 1.0f;
2690 if (m_centerPt.X < 0) m_centerPt.X = 0;
2691 if (m_centerPt.Y < 0) m_centerPt.Y = 0;
2693 if (pDoc) {
2694 WorldHeightMapEdit *pMap = pDoc->GetHeightMap();
2695 if (pMap) {
2696 if (m_centerPt.X > pMap->getXExtent()) {
2697 m_centerPt.X = pMap->getXExtent();
2698 }
2699 if (m_centerPt.Y > pMap->getYExtent()) {
2700 m_centerPt.Y = pMap->getYExtent();
2701 }
2702 }
2703 }
2704 m_groundLevel = 10.0;
2705 Coord3D pos;
2706 pos.x = m_centerPt.X;
2707 pos.y = m_centerPt.Y;
2708 pos.z = m_centerPt.Z;
2709 AsciiString startingCamName = TheNameKeyGenerator->keyToName(TheKey_InitialCameraPosition);
2711 while (pMapObj) {
2712 if (pMapObj->isWaypoint()) {
2713 if (startingCamName == pMapObj->getWaypointName()) {
2714 pos = *pMapObj->getLocation();
2715 }
2716 }
2717 pMapObj = pMapObj->getNext();
2718 }
2719
2720 if (m_heightMapRenderObj) {
2721 m_groundLevel = m_heightMapRenderObj->getHeightMapHeight(pos.x, pos.y, NULL);
2722 }
2723
2724 //m_cameraOffset.z = m_groundLevel+TheGlobalData->m_cameraHeight;
2725 m_cameraOffset.z = m_groundLevel+TheGlobalData->m_maxCameraHeight;
2726 m_cameraOffset.y = -(m_cameraOffset.z / tan(TheGlobalData->m_cameraPitch * (PI / 180.0)));
2727 m_cameraOffset.x = -(m_cameraOffset.y * tan(TheGlobalData->m_cameraYaw * (PI / 180.0)));
2728
2729 m_cameraOffset.x *= 1.0f;
2730 m_cameraOffset.y *= 1.0f;
2731 m_cameraOffset.z *= 1.0f;
2732 /*
2733 m_cameraOffset.x *= TheGlobalData->m_maxZoom;
2734 m_cameraOffset.y *= TheGlobalData->m_maxZoom;
2735 m_cameraOffset.z *= TheGlobalData->m_maxZoom;
2736 */
2737
2738 redraw();
2739 drawLabels();
2741}
2742
2743// ----------------------------------------------------------------------------
2745{
2746 if (m_projection) return; // camera doesn't rotate in top down view.
2747 m_cameraAngle += delta;
2748 redraw();
2749 drawLabels();
2751}
2752
2753// ----------------------------------------------------------------------------
2755{
2756 if (m_projection) return; // camera doesn't pitch in top down view.
2757 m_FXPitch += delta;
2758 redraw();
2759 drawLabels();
2761}
2762
2763// ----------------------------------------------------------------------------
2765{
2766 if (m_projection) return; // camera doesn't pitch in top down view.
2767 m_FXPitch = absolutePitch;
2768 redraw();
2769 drawLabels();
2771}
2772
2773// ----------------------------------------------------------------------------
2775{
2776 return m_FXPitch;
2777}
2778
2779
2780//WST 10.17.2002 ----------------------------------------------------------------------------
2782{
2783 float zOffset = - m_mouseWheelOffset / 1200; //WST 11/21/02 new triple speed camera zoom.
2784 Real zoom = 1.0f;
2785 if (zOffset != 0) {
2786 Real zPos = (m_cameraOffset.length()-m_groundLevel)/m_cameraOffset.length();
2787 Real zAbs = zOffset + zPos;
2788 if (zAbs<0) zAbs = -zAbs;
2789 if (zAbs<0.01) zAbs = 0.01f;
2790 //DEBUG_LOG(("zOffset = %.2f, zAbs = %.2f, zPos = %.2f\n", zOffset, zAbs, zPos));
2791 if (zOffset > 0) {
2792 zOffset *= zAbs;
2793 } else if (zOffset < -0.3f) {
2794 zOffset = -0.15f + zOffset/2.0f;
2795 }
2796 if (zOffset < -0.6f) {
2797 zOffset = -0.3f + zOffset/2.0f;
2798 }
2799 //DEBUG_LOG(("zOffset = %.2f\n", zOffset));
2800 zoom = zAbs;
2801 }
2802 return zoom;
2803}
2804
2805// ----------------------------------------------------------------------------
2807{
2808 if (getLastDrawTime()+UPDATE_TIME<::GetTickCount())
2809 {
2810 Invalidate(false);
2811 }
2812}
2813
2814// ----------------------------------------------------------------------------
2816{
2817 killTheTimer();
2818 WbView::OnDestroy();
2819}
2820
2821// ----------------------------------------------------------------------------
2822void WbView3d::OnShowWindow(BOOL bShow, UINT nStatus)
2823{
2824 WbView::OnShowWindow(bShow, nStatus);
2825}
2826
2827//=============================================================================
2828// CWorldBuilderView::scroll
2829//=============================================================================
2831//=============================================================================
2832void WbView3d::scrollInView(Real xScroll, Real yScroll, Bool end)
2833{
2834 m_centerPt.X += xScroll;
2835 m_centerPt.Y += yScroll;
2837 redraw();
2838 drawLabels();
2839 if (end)
2842}
2843
2845{
2846 m_showWireframe = !m_showWireframe;
2847 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowWireframe", m_showWireframe?1:0);
2848}
2849
2851{
2852 pCmdUI->SetCheck(m_showWireframe?1:0);
2853
2854}
2855
2857{
2858 // Never erase the background. The 3d view always draws the entire
2859 // window, so erasing just makes it flicker. jba.
2860 return true; // act like we erased.
2861}
2862
2864{
2865 m_showEntireMap = !m_showEntireMap;
2866 IRegion2D range = {0,0,0,0};
2867 this->updateHeightMapInView(WbDoc()->GetHeightMap(), false, range);
2868 Invalidate(false);
2869 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowEntireMap", m_showEntireMap?1:0);
2870}
2871
2873{
2874 pCmdUI->SetCheck(m_showEntireMap?1:0);
2875}
2876
2878{
2879 m_projection = !m_projection;
2880 m_heightMapRenderObj->setFlattenHeights(m_projection);
2882 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowTopDownView", m_projection?1:0);
2883}
2884
2886{
2887 pCmdUI->SetCheck(m_projection?1:0);
2888}
2889
2891{
2892 TheWritableGlobalData->m_useCloudMap = !TheGlobalData->m_useCloudMap;
2893 AfxGetApp()->WriteProfileInt("GameOptions", "cloudMap", TheGlobalData->m_useCloudMap);
2894}
2895
2897{
2898 pCmdUI->SetCheck(TheGlobalData->m_useCloudMap?1:0);
2899}
2900
2902{
2903 Bool show = !TheGlobalData->m_useLightMap;
2904 TheWritableGlobalData->m_useLightMap = show;
2905}
2906
2908{
2909 pCmdUI->SetCheck(TheGlobalData->m_useLightMap?1:0);
2910}
2911
2913{
2915
2916 // The macrotexture dialog sets the macrotexture in the 3d engine.
2917 dlg.DoModal();
2918
2919}
2920
2922{
2923 m_showShadows = !m_showShadows;
2924 if (m_showShadows) {
2925 int w,h,bits;
2926 Bool windowed;
2927 WW3D::Get_Device_Resolution(w,h,bits,windowed);
2928
2929 if (bits != 32) {
2930 ::AfxMessageBox("Shadows require a 32 bit color desktop.", IDOK);
2931 m_showShadows = false;
2932 } else {
2935 }
2936 } else {
2937 TheW3DShadowManager->removeAllShadows();
2938 }
2939 TheWritableGlobalData->m_useShadowDecals = m_showShadows;
2940 TheWritableGlobalData->m_useShadowVolumes = m_showShadows;
2941 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowShadows", m_showShadows?1:0);
2942}
2943
2945{
2946 pCmdUI->SetCheck(m_showShadows?1:0);
2947}
2948
2950{
2951 TheWritableGlobalData->m_showSoftWaterEdge = !TheGlobalData->m_showSoftWaterEdge;
2952 if (TheGlobalData->m_showSoftWaterEdge)
2953 { //we just turned it on, so recompute shoreline tiles since they may not exist.
2954 TheTerrainRenderObject->updateShorelineTiles(0,0,WbDoc()->GetHeightMap()->getXExtent()-1,WbDoc()->GetHeightMap()->getYExtent()-1,
2955 WbDoc()->GetHeightMap());
2956 }
2957
2958 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowSoftWater", TheGlobalData->m_showSoftWaterEdge ? 1 : 0);
2959}
2960
2962{
2963 pCmdUI->SetCheck(TheGlobalData->m_showSoftWaterEdge ? 1 : 0);
2964}
2965
2967{
2968 if (TheGlobalData->m_use3WayTerrainBlends==1)
2969 TheWritableGlobalData->m_use3WayTerrainBlends = 2; //debug mode which draws the tiles in black
2970 else
2971 TheWritableGlobalData->m_use3WayTerrainBlends = 1;
2972
2973 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowExtraBlends", TheGlobalData->m_use3WayTerrainBlends > 1 ? 1 : 0);
2974}
2975
2977{
2978 pCmdUI->SetCheck(TheGlobalData->m_use3WayTerrainBlends > 1 ? 1 : 0);
2979}
2980
2982{
2983 MapSettings dlg;
2984
2985 if (dlg.DoModal() == IDOK) {
2988 }
2989}
2990
2992{
2993 if (!m_showShadows) {
2994 OnViewShowshadows(); // turn them on.
2995 }
2996 ShadowOptions dlg;
2997 dlg.DoModal();
2998}
2999
3001{
3003 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowModels", getShowModels()?1:0);
3006}
3008{
3009 pCmdUI->SetCheck(getShowModels()?1:0);
3010}
3011
3012// MLL C&C3
3014{
3016 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowBoundingBoxes", getShowBoundingBoxes()?1:0);
3019}
3020// MLL C&C3
3022{
3023 pCmdUI->SetCheck(getShowBoundingBoxes()?1:0);
3024}
3025
3026
3027// MLL C&C3
3029{
3031 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowSightRanges", getShowSightRanges()?1:0);
3034}
3035// MLL C&C3
3037{
3038 pCmdUI->SetCheck(getShowSightRanges()?1:0);
3039}
3040
3041// MLL C&C3
3043{
3045 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowWeaponRanges", getShowWeaponRanges()?1:0);
3048}
3049// MLL C&C3
3051{
3052 pCmdUI->SetCheck(getShowWeaponRanges()?1:0);
3053}
3054
3055// MLL C&C3
3057{
3059 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "HighlightTestArt", getHighlightTestArt()?1:0);
3062}
3063// MLL C&C3
3065{
3066 pCmdUI->SetCheck(getHighlightTestArt()?1:0);
3067}
3068
3069
3070// MLL C&C3
3072{
3074 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowLetterBox", getShowLetterbox()?1:0);
3075}
3076// MLL C&C3
3078{
3079 pCmdUI->SetCheck(getShowLetterbox()?1:0);
3080}
3081
3082
3084{
3086 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowGarrisoned", getShowGarrisoned()?1:0);
3089}
3091{
3092 pCmdUI->SetCheck(getShowGarrisoned()?1:0);
3093}
3094
3096{
3097 Bool showImpassable = false;
3099 showImpassable = TheTerrainRenderObject->getShowImpassableAreas();
3100 TheTerrainRenderObject->setShowImpassableAreas(!showImpassable);
3101 // Force the entire terrain mesh to be rerendered.
3102 IRegion2D range = {0,0,0,0};
3103 updateHeightMapInView(WbDoc()->GetHeightMap(), false, range);
3104 }
3105}
3106
3108{
3109 Bool showImpassable = false;
3111 showImpassable = TheTerrainRenderObject->getShowImpassableAreas();
3112 }
3113 pCmdUI->SetCheck(showImpassable?1:0);
3114}
3115
3117{
3119 {
3120 ImpassableOptions opts;
3121 opts.SetDefaultSlopeToShow(TheTerrainRenderObject->getViewImpassableAreaSlope());
3122 if (opts.DoModal() == IDOK) {
3123 TheTerrainRenderObject->setViewImpassableAreaSlope(opts.GetSlopeToShow());
3124 } else {
3125 TheTerrainRenderObject->setViewImpassableAreaSlope(opts.GetDefaultSlope());
3126 }
3127 }
3128
3129 IRegion2D range = {0,0,0,0};
3130 updateHeightMapInView(WbDoc()->GetHeightMap(), false, range);
3131 }
3132}
3133
3135{
3136 m_partialMapSize = 97;
3137 AfxGetApp()->WriteProfileInt("GameOptions", "partialMapSize", m_partialMapSize);
3138 m_showEntireMap = false;
3139 IRegion2D range = {0,0,0,0};
3140 WbDoc()->GetHeightMap()->setDrawOrg(0, 0);
3141 updateHeightMapInView(WbDoc()->GetHeightMap(), false, range);
3142 Invalidate(false);
3143}
3144
3146{
3147 pCmdUI->SetCheck(m_partialMapSize == 97?1:0);
3148}
3149
3151{
3152 m_partialMapSize = 192;
3153 AfxGetApp()->WriteProfileInt("GameOptions", "partialMapSize", m_partialMapSize);
3154 m_showEntireMap = false;
3155 IRegion2D range = {0,0,0,0};
3156 WbDoc()->GetHeightMap()->setDrawOrg(0, 0);
3157 updateHeightMapInView(WbDoc()->GetHeightMap(), false, range);
3158 Invalidate(false);
3159}
3160
3162{
3163 pCmdUI->SetCheck(m_partialMapSize == 192?1:0);
3164}
3165
3167{
3168 m_partialMapSize = 161;
3169 AfxGetApp()->WriteProfileInt("GameOptions", "partialMapSize", m_partialMapSize);
3170 m_showEntireMap = false;
3171 IRegion2D range = {0,0,0,0};
3172 WbDoc()->GetHeightMap()->setDrawOrg(0, 0);
3173 updateHeightMapInView(WbDoc()->GetHeightMap(), false, range);
3174 Invalidate(false);
3175}
3176
3178{
3179 pCmdUI->SetCheck(m_partialMapSize == 161?1:0);
3180}
3181
3183{
3184 m_partialMapSize = 129;
3185 AfxGetApp()->WriteProfileInt("GameOptions", "partialMapSize", m_partialMapSize);
3186 m_showEntireMap = false;
3187 IRegion2D range = {0,0,0,0};
3188 WbDoc()->GetHeightMap()->setDrawOrg(0, 0);
3189 updateHeightMapInView(WbDoc()->GetHeightMap(), false, range);
3190 Invalidate(false);
3191}
3192
3194{
3195 pCmdUI->SetCheck(m_partialMapSize == 129?1:0);
3196}
3197
3199{
3200 m_showLayersList = !m_showLayersList;
3201 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowLayersList", m_showLayersList ? 1 : 0);
3202 TheLayersList->ShowWindow(m_showLayersList ? SW_SHOW : SW_HIDE);
3203 if (m_showLayersList) {
3204 TheLayersList->enableUpdates();
3205 } else {
3206 TheLayersList->disableUpdates();
3207 }
3208}
3209
3211{
3212 pCmdUI->SetCheck(m_showLayersList ? 1 : 0);
3213}
3214
3216{
3217 m_showMapBoundaries = !m_showMapBoundaries;
3218 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowMapBoundaries", m_showMapBoundaries ? 1 : 0);
3219 DrawObject::setDoBoundaryFeedback(m_showMapBoundaries);
3220}
3221
3223{
3224 pCmdUI->SetCheck(m_showMapBoundaries ? 1 : 0);
3225}
3226
3227
3229{
3230 m_showAmbientSounds = !m_showAmbientSounds;
3231 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowAmbientSounds", m_showAmbientSounds ? 1 : 0);
3232 DrawObject::setDoAmbientSoundFeedback(m_showAmbientSounds);
3233}
3234
3236{
3237 pCmdUI->SetCheck(m_showAmbientSounds ? 1 : 0);
3238}
3239
3241{
3242 m_showSoundCircles = !m_showSoundCircles;
3243 ::AfxGetApp()->WriteProfileInt(MAIN_FRAME_SECTION, "ShowSoundCircles", m_showSoundCircles ? 1 : 0);
3246}
3247
3249{
3250 pCmdUI->SetCheck(m_showSoundCircles ? 1 : 0);
3251}
3252
BaseHeightMapRenderObjClass * TheTerrainRenderObject
The one-of for the terrain rendering object.
#define NULL
Definition BaseType.h:92
#define PI
Definition BaseType.h:86
bool Bool
Definition BaseType.h:132
#define TRUE
Definition BaseType.h:109
#define FALSE
Definition BaseType.h:113
float Real
Definition BaseType.h:124
#define min(x, y)
Definition BaseType.h:101
#define max(x, y)
Definition BaseType.h:105
unsigned int UnsignedInt
Definition BaseType.h:126
BodyDamageType
Definition BodyModule.h:54
@ BODY_RUBBLE
unit has been reduced to rubble/corpse/exploded-hulk, etc
Definition BodyModule.h:58
@ BODY_REALLYDAMAGED
unit is extremely damaged / nearly destroyed
Definition BodyModule.h:57
@ BODY_PRISTINE
unit should appear in pristine condition
Definition BodyModule.h:55
@ BODY_DAMAGED
unit has been damaged
Definition BodyModule.h:56
FilterTypes
Definition CommandXlat.h:76
FilterModes
Definition CommandXlat.h:87
#define TEST_STRING
Definition FileSystem.h:95
#define DEBUG_ASSERTCRASH(c, m)
Definition Debug.h:193
#define DEBUG_CRASH(m)
Definition Debug.h:192
Color scale(const Color &a, const Color &b)
Definition GameMtl.cpp:722
ObjectID
A unique, generic "identifier" used to access Objects.
Definition GameType.h:42
@ INVALID_ID
Definition GameType.h:43
Scorches
Definition GameType.h:95
TimeOfDay
Definition GameType.h:69
@ TIME_OF_DAY_COUNT
Definition GameType.h:77
@ TIME_OF_DAY_FIRST
Definition GameType.h:71
@ TIME_OF_DAY_NIGHT
Definition GameType.h:75
DrawableID
A unique, generic "identifier" used to access Drawables.
Definition GameType.h:49
@ WEATHER_SNOWY
Definition GameType.h:87
const Int MAX_GLOBAL_LIGHTS
Definition GlobalData.h:56
#define TheGlobalData
Definition GlobalData.h:543
GlobalData * TheWritableGlobalData
The global data singleton.
@ KINDOF_VEHICLE
unit like tank, jeep, plane, helicopter, etc.
Definition KindOf.h:57
@ KINDOF_OPTIMIZED_TREE
An optimized, client side only tree. (The only good kind of tree. jba)
Definition KindOf.h:159
const Color playerColor
LayersList * TheLayersList
unsigned int UINT
Definition bittype.h:63
@ true
Definition bool.h:59
@ false
Definition bool.h:59
#define MAIN_FRAME_SECTION
Definition MainFrm.h:56
#define MAP_XY_FACTOR
Definition MapObject.h:60
@ FLAG_DONT_RENDER
If set, do not render this object. Only WB pays attention to this. (Right now, anyways)
Definition MapObject.h:75
@ FLAG_ROAD_FLAGS
If nonzero, object is a road piece.
Definition MapObject.h:68
@ FLAG_BRIDGE_FLAGS
If nonzero, object is a bridge piece.
Definition MapObject.h:72
@ MODELCONDITION_RUBBLE
Definition ModelState.h:108
@ MODELCONDITION_REALLY_DAMAGED
Definition ModelState.h:107
@ MODELCONDITION_DAMAGED
Definition ModelState.h:106
@ MODELCONDITION_NIGHT
Definition ModelState.h:110
@ MODELCONDITION_GARRISONED
Definition ModelState.h:113
@ MODELCONDITION_SNOW
Definition ModelState.h:111
BitFlags< MODELCONDITION_COUNT > ModelConditionFlags
Definition ModelState.h:250
NameKeyGenerator * TheNameKeyGenerator
just one namespace for now
NameKeyType NAMEKEY(const AsciiString &name)
AsciiString KEYNAME(NameKeyType nk)
PlayerTemplateStore * ThePlayerTemplateStore
singleton instance of PlayerTemplateStore
ShadowType
Definition Shadow.h:42
@ SHADOW_NONE
Definition Shadow.h:43
@ SHADOW_VOLUME
Definition Shadow.h:45
SidesList * TheSidesList
singleton instance of SidesList
void makeAlignToNormalMatrix(Real angle, const Coord3D &pos, const Coord3D &normal, Matrix3D &mtx)
ThingFactory * TheThingFactory
the template singleton
@ TRACK_NONE
Definition Tool.h:32
#define MAGIC_GROUND_Z
Definition Tool.h:41
#define ID_VIEW_SHOWMACROTEXTURE
Definition resource.h:634
#define ID_VIEW_SHOWMODELS
Definition resource.h:678
#define ID_VIEW_PARTIALMAPSIZE_160X160
Definition resource.h:665
#define ID_EDIT_MAPSETTINGS
Definition resource.h:701
#define ID_VIEW_SHOWAMBIENTSOUNDS
Definition resource.h:714
#define ID_VIEW_SHOWCLOUDS
Definition resource.h:625
#define ID_VIEW_LAYERS_LIST
Definition resource.h:688
#define ID_VIEW_SHOWEXTRABLENDS
Definition resource.h:713
#define ID_VIEW_SHOWIMPASSABLEAREAS
Definition resource.h:656
#define ID_VIEW_SHOWWIREFRAME
Definition resource.h:614
#define ID_EDIT_SELECTMACROTEXTURE
Definition resource.h:635
#define ID_VIEW_SHOWSOFTWATER
Definition resource.h:710
#define ID_VIEW_PARTIALMAPSIZE_128X128
Definition resource.h:664
#define ID_VIEW_SHOWENTIRE3DMAP
Definition resource.h:623
#define ID_VIEW_SHOWTOPDOWNVIEW
Definition resource.h:624
#define ID_VIEW_SHOWSHADOWS
Definition resource.h:652
#define ID_VIEW_WEAPONRANGES
Definition resource.h:684
#define ID_VIEW_GARRISONED
Definition resource.h:702
#define ID_HIGHLIGHT_TESTART
Definition resource.h:685
#define ID_VIEW_PARTIALMAPSIZE_192X192
Definition resource.h:666
#define ID_VIEW_SHOW_SOUND_CIRCLES
Definition resource.h:720
#define ID_EDIT_SHADOWS
Definition resource.h:651
#define ID_VIEW_PARTIALMAPSIZE_96X96
Definition resource.h:663
#define ID_VIEW_BOUNDINGBOXES
Definition resource.h:682
#define ID_VIEW_SHOWMAPBOUNDARIES
Definition resource.h:706
#define ID_VIEW_SIGHTRANGES
Definition resource.h:683
#define ID_SHOW_LETTERBOX
Definition resource.h:686
#define ID_VIEW_IMPASSABLEAREAOPTIONS
Definition resource.h:717
PickType
Definition View.h:57
View * TheTacticalView
the main tactical interface to the game world
Definition View.cpp:39
void W3DLogicalScreenToPixelScreen(Real logX, Real logY, Int *screenX, Int *screenY, Int screenWidth, Int screenHeight)
@ bottomLeft
@ bottomRight
@ topLeft
@ topRight
W3DShadowManager * TheW3DShadowManager
Definition W3DShadow.cpp:58
#define TERRAIN_SAMPLE_SIZE
Definition W3DView.cpp:140
OVERRIDE< WaterTransparencySetting > TheWaterTransparency
Definition Water.cpp:38
#define BOOL
Definition Wnd_File.h:57
CWorldBuilderApp * WbApp()
@ THREE_D_VIEW_WIDTH
@ THREE_D_VIEW_HEIGHT
AggregateLoaderClass _AggregateLoader
Definition agg_def.cpp:60
const char * str() const
static AsciiString TheEmptyString
int getLength() const
Bool isEmpty() const
void set(Int i, Int val=1)
Definition BitFlags.h:146
void clear()
Definition BitFlags.h:203
void setRenderObj(RenderObjClass *pObj)
Definition SidesList.h:342
RenderObjClass * getRenderObj(void)
Definition SidesList.h:343
BuildListInfo * getNext(void) const
Definition SidesList.h:325
static Bool isActive(void)
void adjustWindowSize(void)
Definition MainFrm.cpp:315
static CMainFrame * GetMainFrame()
Definition MainFrm.h:88
void handleCameraChange(void)
Definition MainFrm.cpp:530
static CWorldBuilderDoc * GetActiveDoc()
WorldHeightMapEdit * GetHeightMap()
void syncViewCenters(Real x, Real y)
@ INSIDE_FRUSTUM
Definition camera.h:119
static void SetForceMultiply(bool multiply)
static IDirect3DDevice8 * _Get_D3D_Device8()
Definition dx8wrapper.h:530
static void SetCleanupHook(DX8_CleanupHook *pCleanupHook)
Definition dx8wrapper.h:261
Definition Dict.h:67
Int getInt(NameKeyType key, Bool *exists=NULL) const
Definition Dict.cpp:284
Real getReal(NameKeyType key, Bool *exists=NULL) const
Definition Dict.cpp:299
AsciiString getAsciiString(NameKeyType key, Bool *exists=NULL) const
Definition Dict.cpp:314
static void setDoAmbientSoundFeedback(Bool val)
Definition DrawObject.h:92
static void setDoBoundaryFeedback(Bool val)
Definition DrawObject.h:90
void SetDefaultSlopeToShow(Real slopeToShow)
Real GetSlopeToShow() const
Real GetDefaultSlope() const
void Set_Diffuse(const Vector3 &color)
Definition light.h:113
@ POINT
Definition light.h:63
@ DIRECTIONAL
Definition light.h:64
void Set_Ambient(const Vector3 &color)
Definition light.h:110
void Set_Far_Attenuation_Range(double fStart, double fEnd)
Definition light.h:119
void setRenderObj(RenderObjClass *pObj)
Bool isLight(void) const
Definition MapObject.h:147
Int getFlags(void) const
Definition MapObject.h:142
const Coord3D * getLocation(void) const
Get the center point.
Definition MapObject.h:126
const ThingTemplate * getThingTemplate(void) const
void setShadowObj(Shadow *pObj)
Definition MapObject.h:157
Dict * getProperties()
return the object's property sheet.
Definition MapObject.h:123
static MapObject * getFirstMapObject(void)
Definition MapObject.h:182
Bool isScorch(void) const
Definition MapObject.h:149
AsciiString getName(void) const
Gets the object name.
Definition MapObject.h:130
RenderObjClass * getRenderObj(void) const
Definition MapObject.h:156
Bool isWaypoint(void) const
Definition MapObject.h:148
MapObject * getNext(void) const
Next map object in the list. Not a copy, don't delete it.
Definition MapObject.h:134
Real getAngle(void) const
Get the angle.
Definition MapObject.h:127
Bool isSelected(void) const
Definition MapObject.h:144
AsciiString getWaypointName()
WWINLINE void Set_Translation(const Vector3 &t)
Definition matrix3d.h:219
void mulVector3(const Vector3 &in, Vector3 &out) const
Definition matrix3d.h:1650
void Translate(float x, float y, float z)
Definition matrix3d.h:670
void Rotate_Z(float theta)
Definition matrix3d.h:905
WWINLINE void Make_Identity(void)
Definition matrix3d.h:650
void Look_At(const Vector3 &p, const Vector3 &t, float roll)
Definition matrix3d.cpp:354
WWINLINE void Set(float m[12])
Definition matrix3d.h:506
virtual const W3DTreeDrawModuleData * getAsW3DTreeDrawModuleData() const
Definition Module.h:117
NameKeyType getModuleTagNameKey() const
Definition Module.h:110
virtual const W3DModelDrawModuleData * getAsW3DModelDrawModuleData() const
Definition Module.h:115
Int getCount() const
const ModuleData * getNthData(Int i) const
virtual enum FilterTypes getViewFilterType(void)
Turns on viewport special effect (black & white mode)
Definition wbview3d.cpp:276
virtual void lookAt(const Coord3D *o)
Center the view on the given coordinate.
Definition wbview3d.cpp:204
virtual void zoomIn(void)
Zoom in, closer to the ground, limit to min.
Definition wbview3d.cpp:242
virtual Real getHeightAboveGround()
Definition wbview3d.cpp:238
virtual View * prependViewToList(View *list)
Prepend this view to the given list, return the new list.
Definition wbview3d.cpp:167
virtual void rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMilliseconds, Real easeIn, Real easeOut)
Rotate camera about current viewpoint.
Definition wbview3d.cpp:214
virtual void setZoom(Real z)
Definition wbview3d.cpp:241
virtual ObjectID getCameraLock() const
set the view's current location from to the view location object
Definition wbview3d.cpp:256
virtual void updateView(void)
Render the world visible in this view.
Definition wbview3d.cpp:190
virtual enum FilterModes getViewFilterMode(void)
Turns on viewport special effect (black & white mode)
Definition wbview3d.cpp:275
virtual void setMouseLock(Bool mouseLocked)
lock/unlock the mouse input to the tactical view
Definition wbview3d.cpp:264
virtual void resetCamera(const Coord3D *location, Int frames, Real easeIn, Real easeOut)
Definition wbview3d.cpp:212
virtual void cameraModFinalLookToward(Coord3D *pLoc)
Sets a look at point during camera movement.
Definition wbview3d.cpp:222
virtual void initHeightForMap(void)
Center the view on the given coordinate.
Definition wbview3d.cpp:205
virtual void cameraModFreezeTime(void)
Final pitch for current camera movement.
Definition wbview3d.cpp:219
virtual void setHeight(Int height)
Definition wbview3d.cpp:197
virtual void shake(const Coord3D *epicenter, CameraShakeType shakeType)
Add an impulse force to shake the camera.
Definition wbview3d.cpp:278
virtual Bool setViewFilterMode(enum FilterModes)
Get the horizontal field of view angle.
Definition wbview3d.cpp:270
virtual void setOkToAdjustHeight(Bool val)
Set this to adjust camera height.
Definition wbview3d.cpp:246
virtual void setWidth(Int width)
Definition wbview3d.cpp:195
virtual Int getWidth(void)
Definition wbview3d.cpp:196
virtual Real getFXPitch(void) const
returns the FX pitch angle
Definition wbview3d.cpp:280
virtual void setLocation(const ViewLocation *location)
write the view's current location in to the view location object
Definition wbview3d.cpp:254
virtual Real getCurrentHeightAboveGround()
Definition wbview3d.cpp:250
virtual void zoomCamera(Real finalZoom, Int milliseconds, Real easeIn, Real easeOut)
Definition wbview3d.cpp:228
virtual void cameraModFreezeAngle(void)
Freezes time during the next camera movement.
Definition wbview3d.cpp:220
virtual void getScreenCornerWorldPointsAtZ(Coord3D *topLeft, Coord3D *topRight, Coord3D *bottomLeft, Coord3D *bottomRight, Real z)
transform screen point to world point at the specified world Z value
Definition wbview3d.cpp:185
virtual WorldToScreenReturn worldToScreenTriReturn(const Coord3D *w, ICoord2D *s)
Like worldToScreen(), but with a more informative return value.
Definition wbview3d.cpp:181
virtual Drawable * pickDrawable(const ICoord2D *screen, Bool forceAttack, PickType pickType)
pick drawable given the screen pixel coords. If force attack, picks bridges as well.
Definition wbview3d.cpp:175
virtual void rotateCamera(Real rotations, Int frames, Real easeIn, Real easeOut)
Move camera to location, and reset to default angle & zoom.
Definition wbview3d.cpp:213
virtual Real getPitch(void)
Rotate the view around the horizontal axis to the given angle.
Definition wbview3d.cpp:234
virtual void screenToWorldAtZ(const ICoord2D *s, Coord3D *w, Real z)
transform screen coord to a point on the 3D terrain
Definition wbview3d.cpp:184
virtual Int getTimeMultiplier(void)
Definition wbview3d.cpp:225
virtual void setZoomToDefault(void)
Set zoom to default value.
Definition wbview3d.cpp:244
virtual void cameraModFinalZoom(Real finalZoom, Real easeIn, Real easeOut)
Rotate camera to face an object, and hold on it.
Definition wbview3d.cpp:215
virtual void getOrigin(Int *x, Int *y)
Return location of top-left view corner on display.
Definition wbview3d.cpp:200
virtual void setSnapMode(CameraLockType lockType, Real lockDist)
Definition wbview3d.cpp:259
virtual Bool isZoomLimited(void)
get status of zoom limit
Definition wbview3d.cpp:193
virtual void screenToTerrain(const ICoord2D *screen, Coord3D *world)
Transform screen coordinate "s" into world coordinate "w".
Definition wbview3d.cpp:183
virtual void setPitch(Real angle)
Rotate the view around the horizontal axis to the given angle.
Definition wbview3d.cpp:233
virtual void drawView(void)
Render the world visible in this view.
Definition wbview3d.cpp:189
virtual Bool isMouseLocked(void)
is the mouse input locked to the tactical view?
Definition wbview3d.cpp:265
virtual void cameraModFinalTimeMultiplier(Int finalMultiplier)
Number of frames to average movement for current camera movement.
Definition wbview3d.cpp:217
virtual void setZoomLimited(Bool limit)
Render the world visible in this view.
Definition wbview3d.cpp:192
virtual void setFieldOfView(Real angle)
Set the horizontal field of view angle.
Definition wbview3d.cpp:267
virtual Int iterateDrawablesInRegion(IRegion2D *screenRegion, Bool(*callback)(Drawable *draw, void *userData), void *userData)
pick drawable given the screen pixel coords
Definition wbview3d.cpp:178
virtual void zoomOut(void)
Zoom out, farther away from the ground, limit to max.
Definition wbview3d.cpp:243
virtual void scrollBy(Coord2D *delta)
Init the camera height for the map at the current position.
Definition wbview3d.cpp:206
virtual void setViewFilterPos(const Coord3D *pos)
Definition wbview3d.cpp:271
virtual void setCurrentHeightAboveGround(Real z)
Definition wbview3d.cpp:251
virtual void setCameraLockDrawable(Drawable *drawable)
Definition wbview3d.cpp:262
virtual const Coord3D & get3DCameraPosition() const
Rotate camera to face an object, and hold on it.
Definition wbview3d.cpp:284
virtual void setOrigin(Int x, Int y)
Sets location of top-left view corner on display.
Definition wbview3d.cpp:199
virtual Real getAngle(void)
Rotate the view around the up axis to the given angle.
Definition wbview3d.cpp:232
virtual void screenToWorld(const ICoord2D *s, Coord3D *w)
Transform world coordinate "w" into screen coordinate "s".
Definition wbview3d.cpp:182
virtual Real getFieldOfView(void)
Set the horizontal field of view angle.
Definition wbview3d.cpp:268
Int m_height
Dimensions of the view.
Definition wbview3d.cpp:163
virtual void setCameraLock(ObjectID id)
Definition wbview3d.cpp:257
virtual void getPosition(Coord3D *pos)
Set the view angle back to default.
Definition wbview3d.cpp:236
virtual void setHeightAboveGround(Real z)
Definition wbview3d.cpp:239
virtual void rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds, Real easeIn, Real easeOut, Bool reverseRotation)
Rotate camera to face an object, and hold on it.
Definition wbview3d.cpp:282
virtual void setDefaultView(Real pitch, Real angle, Real maxHeight)
Set the time multiplier.
Definition wbview3d.cpp:227
virtual Real getTerrainHeightUnderCamera()
Definition wbview3d.cpp:248
virtual void cameraModRollingAverage(Int framesToAverage)
Final zoom for current camera movement.
Definition wbview3d.cpp:216
virtual void forceCameraConstraintRecalc(void)
Definition wbview3d.cpp:281
virtual void set3DWireFrameMode(Bool enable)
stub
Definition wbview3d.cpp:273
virtual Bool setViewFilter(enum FilterTypes m_viewFilterMode)
stub
Definition wbview3d.cpp:274
virtual void cameraModFinalPitch(Real finalPitch, Real easeIn, Real easeOut)
Final time multiplier for current camera movement.
Definition wbview3d.cpp:218
virtual Drawable * getCameraLockDrawable() const
Definition wbview3d.cpp:261
virtual View * getNextView(void)
Prepend this view to the given list, return the new list.
Definition wbview3d.cpp:168
virtual void setFadeParameters(Int fadeFrames, Int direction)
stub
Definition wbview3d.cpp:272
virtual Real getZoom()
Definition wbview3d.cpp:240
virtual void forceRedraw()
Definition wbview3d.cpp:202
virtual void pitchCamera(Real finalPitch, Int milliseconds, Real easeIn, Real easeOut)
Definition wbview3d.cpp:229
virtual Int getHeight(void)
Definition wbview3d.cpp:198
virtual Bool isTimeFrozen(void)
Sets a final move to.
Definition wbview3d.cpp:224
virtual void setTerrainHeightUnderCamera(Real z)
Definition wbview3d.cpp:249
virtual void setAngleAndPitchToDefault(void)
Set the view angle back to default.
Definition wbview3d.cpp:235
Int m_originY
Location of top/left view corner.
Definition wbview3d.cpp:164
virtual Bool isCameraMovementFinished(void)
Definition wbview3d.cpp:211
virtual void snapToCameraLock(void)
Definition wbview3d.cpp:258
virtual void getLocation(ViewLocation *location)
write the view's current location in to the view location object
Definition wbview3d.cpp:253
virtual void setAngle(Real angle)
Rotate the view around the up axis to the given angle.
Definition wbview3d.cpp:231
virtual void cameraModFinalMoveTo(Coord3D *pLoc)
Definition wbview3d.cpp:223
virtual void init(void)
Definition wbview3d.cpp:171
virtual void cameraModLookToward(Coord3D *pLoc)
Sets a look at point during camera movement.
Definition wbview3d.cpp:221
virtual void setGuardBandBias(const Coord2D *gb)
Definition wbview3d.cpp:286
virtual void setTimeMultiplier(Int multiple)
Get the time multiplier.
Definition wbview3d.cpp:226
virtual void moveCameraTo(const Coord3D *o, Int frames, Int shutter, Bool orient, Real easeIn, Real easeOut)
Shift the view by the given delta.
Definition wbview3d.cpp:207
virtual UnsignedInt getID(void)
Definition wbview3d.cpp:173
virtual Real getMaxZoom(void)
return max zoom value
Definition wbview3d.cpp:245
virtual void moveCameraAlongWaypointPath(Waypoint *way, Int frames, Int shutter, Bool orient, Real easeIn, Real easeOut)
Definition wbview3d.cpp:209
const RGBColor * getPreferredColor() const
static Bool isActive(void)
Definition PolygonTool.h:71
static void Free(void)
Definition predlod.cpp:380
RTS3DScene()
RTSScene constructor.
Definition W3DScene.cpp:95
WWINLINE void Release_Ref(void) const
Definition refcount.h:146
void Add_Ref(void) const
Definition refcount.cpp:171
virtual void Set_Transform(const Matrix3D &m)
Definition rendobj.cpp:423
virtual void Get_Obj_Space_Bounding_Sphere(SphereClass &sphere) const
Definition rendobj.cpp:932
virtual void Set_Position(const Vector3 &v)
Definition rendobj.cpp:444
virtual void Remove_Render_Object(RenderObjClass *obj)
Definition scene.cpp:195
virtual void Next(void)=0
virtual RenderObjClass * Current_Item(void)=0
virtual void First(void)=0
virtual bool Is_Done(void)=0
BuildListInfo * getBuildList(void)
Gets the build list.
Definition SidesList.h:73
Dict * getDict()
Definition SidesList.h:69
virtual void Destroy_Iterator(SceneIterator *it)
Definition scene.cpp:671
virtual SceneIterator * Create_Iterator(bool onlyvisible=false)
Definition scene.cpp:652
RefRenderObjListClass RenderList
Definition scene.h:258
void Set_Material_Pass(MaterialPassClass *pass)
Definition wbview3d.cpp:304
Bool safeContains(RenderObjClass *obj)
Definition wbview3d.cpp:314
MaterialPassClass * m_testPass
Definition wbview3d.cpp:310
virtual void Remove_Render_Object(RenderObjClass *obj)
Definition wbview3d.cpp:332
float Radius
Definition sphere.h:91
Vector3 Center
Definition sphere.h:90
Dict * getDict()
Definition SidesList.h:88
Real getShadowOffsetY() const
Real getAssetScale() const
return uniform scaling
const ModuleInfo & getDrawModuleInfo() const
Bool isKindOf(KindOfType t) const
return true iff the template has the specified kindOf flag set.
Real getShadowSizeY() const
ShadowType getShadowType() const
const AsciiString & getName() const
return the name of this template
const AsciiString & getShadowTextureName(void) const
Real getShadowSizeX() const
Real getShadowOffsetX() const
virtual Bool followsTerrain(void)
Become not the current tool.
Definition Tool.h:76
float Y
Definition vector2.h:79
float X
Definition vector2.h:74
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
static WWINLINE float Find_Y_At_Z(float z, const Vector3 &p1, const Vector3 &p2)
Definition vector3.h:836
float Y
Definition vector3.h:91
WWINLINE float Length(void) const
Definition vector3.h:453
void Normalize(void)
Definition vector3.h:417
static WWINLINE float Find_X_At_Z(float z, const Vector3 &p1, const Vector3 &p2)
Definition vector3.h:828
WWINLINE void Set(float x, float y, float z)
Definition vector3.h:103
View(void)
Definition View.cpp:42
CameraShakeType
Add an impulse force to shake the camera.
Definition View.h:76
CameraLockType
Definition View.h:219
WorldToScreenReturn
Definition View.h:88
@ WTS_INVALID
Definition View.h:91
Vector2 Min
Definition camera.h:80
AsciiString getBestModelNameForWB(const ModelConditionFlags &c) const
static void shutdown(void)
release resources used by shaders
static void init(void)
determine optimal shaders for current device.
virtual Real getHeightMapHeight(Real x, Real y, Coord3D *normal)
return height and normal at given point
virtual RenderObjClass * Create_Render_Obj(const char *name)
Definition assetmgr.cpp:799
static WW3DAssetManager * Get_Instance(void)
Definition assetmgr.h:205
virtual void Register_Prototype_Loader(PrototypeLoaderClass *loader)
static WW3DErrorType Render(const LayerListClass &layerlist)
Definition ww3d.cpp:876
static WW3DErrorType Set_Render_Device(int dev=-1, int resx=-1, int resy=-1, int bits=-1, int windowed=-1, bool resize_window=false, bool reset_device=false, bool restore_assets=true)
Definition ww3d.cpp:444
static WW3DErrorType Init(void *hwnd, char *defaultpal=NULL, bool lite=false)
Definition ww3d.cpp:268
static WW3DErrorType Set_Device_Resolution(int w=-1, int h=-1, int bits=-1, int windowed=-1, bool resize_window=false)
Definition ww3d.cpp:626
static WW3DErrorType Begin_Render(bool clear=false, bool clearz=true, const Vector3 &color=Vector3(0, 0, 0), float dest_alpha=0.0f, void(*network_callback)(void)=NULL)
Definition ww3d.cpp:791
static WW3DErrorType Shutdown(void)
Definition ww3d.cpp:332
static void Set_Thumbnail_Enabled(bool b)
Definition ww3d.h:216
static void Get_Device_Resolution(int &set_w, int &set_h, int &get_bits, bool &get_windowed)
Definition ww3d.cpp:670
@ PRELIT_MODE_LIGHTMAP_MULTI_PASS
Definition ww3d.h:83
@ PRELIT_MODE_VERTEX
Definition ww3d.h:82
static void Sync(unsigned int sync_time)
Definition ww3d.cpp:1180
static WW3DErrorType End_Render(bool flip_frame=true)
Definition ww3d.cpp:1082
static void Set_Screen_UV_Bias(bool onoff)
Definition ww3d.h:222
static void Enable_Static_Sort_Lists(bool onoff)
Definition ww3d.h:281
static void Set_Collision_Box_Display_Mask(int mask)
Definition ww3d.cpp:1235
static void Set_Prelit_Mode(PrelitModeEnum mode)
Definition ww3d.h:238
static void Init(void)
Definition wwmath.cpp:51
static void Shutdown(void)
Definition wwmath.cpp:73
static Bool isActive(void)
afx_msg void OnUpdateShowLetterbox(CCmdUI *pCmdUI)
afx_msg void OnViewBoundingBoxes()
afx_msg void OnUpdateViewShowwireframe(CCmdUI *pCmdUI)
void init3dScene()
Definition wbview3d.cpp:764
AsciiString getBestModelName(const ThingTemplate *tt, const ModelConditionFlags &c)
afx_msg void OnViewShowmacrotexture()
afx_msg void OnUpdateViewPartialmapsize192x192(CCmdUI *pCmdUI)
void invalBuildListItemInView(BuildListInfo *pBuild)
Invalidates an build list object.
void setLighting(const GlobalData::TerrainLighting *tl, Int whichLighting, Int whichLight=0)
Definition wbview3d.cpp:875
void render()
afx_msg void OnViewShowMapBoundaries()
void resetRenderObjects()
Removes all render objects. Call when swithing to a new map.
Definition wbview3d.cpp:805
virtual BuildListInfo * pickedBuildObjectInView(CPoint viewPt)
void setShowBoundingBoxes(Bool toggle)
Definition wbview3d.h:312
virtual Bool docToViewCoords(Coord3D curPt, CPoint *newPt)
afx_msg void OnUpdateViewGarrisoned(CCmdUI *pCmdUI)
void initAssets()
Definition wbview3d.cpp:607
afx_msg void OnUpdateViewShowclouds(CCmdUI *pCmdUI)
afx_msg void OnViewShowtopdownview()
void setObjTracking(MapObject *pMapObj, Coord3D pos, Real angle, Bool show)
Definition wbview3d.cpp:343
afx_msg void OnUpdateViewShowmacrotexture(CCmdUI *pCmdUI)
afx_msg void OnViewShowentire3dmap()
void updateScorches()
Definition wbview3d.cpp:996
void stepTimeOfDay(void)
Definition wbview3d.cpp:864
afx_msg void OnShowWindow(BOOL bShow, UINT nStatus)
afx_msg void OnViewPartialmapsize160x160()
afx_msg void OnImpassableAreaOptions()
virtual void rotateCamera(Real delta)
afx_msg void OnViewShowModels()
afx_msg void OnUpdateViewPartialmapsize128x128(CCmdUI *pCmdUI)
void drawCircle(HDC hdc, const Coord3D &centerPoint, Real radius, COLORREF color)
Draw a (not very good) circle into the hdc.
void setShowSightRanges(Bool toggle)
Definition wbview3d.h:314
afx_msg void OnSize(UINT nType, int cx, int cy)
afx_msg void OnShowLetterbox()
afx_msg void OnUpdateViewPartialmapsize160x160(CCmdUI *pCmdUI)
afx_msg void OnEditSelectmacrotexture()
afx_msg void OnUpdateHighlightTestArt(CCmdUI *pCmdUI)
afx_msg void OnUpdateViewSightRanges(CCmdUI *pCmdUI)
AsciiString getModelNameAndScale(MapObject *pMapObj, Real *scale, BodyDamageType curDamageState)
void redraw()
Real getCurrentZoom(void)
afx_msg void OnDestroy()
afx_msg void OnViewShowSoftWater()
Bool getShowBoundingBoxes(void)
Definition wbview3d.h:313
afx_msg void OnUpdateViewShowtopdownview(CCmdUI *pCmdUI)
virtual void pitchCamera(Real delta)
void shutdownWW3D()
Definition wbview3d.cpp:459
afx_msg void OnUpdateViewShowModels(CCmdUI *pCmdUI)
void initWW3D()
afx_msg void OnViewSightRanges()
afx_msg void OnHighlightTestArt()
virtual void ReAcquireResources(void)
Reacquire all resources after device reset.
Definition wbview3d.cpp:538
afx_msg void OnViewExtraBlends()
afx_msg void OnViewShowAmbientSounds()
afx_msg void OnViewShowSoundCircles()
afx_msg void OnUpdateViewShowSoundCircles(CCmdUI *pCmdUI)
UINT getLastDrawTime()
Definition wbview3d.h:324
virtual ~WbView3d()
Definition wbview3d.cpp:444
void updateFenceListObjects(MapObject *pObject)
afx_msg void OnUpdateViewShowimpassableareas(CCmdUI *pCmdUI)
virtual void setDefaultCamera()
void reset3dEngineDisplaySize(Int width, Int height)
Closes & reinitializes w3d.
Definition wbview3d.cpp:590
Bool getHighlightTestArt(void)
Definition wbview3d.h:319
afx_msg void OnViewShowclouds()
void updateTrees()
afx_msg void OnUpdateViewLayersList(CCmdUI *pCmdUI)
afx_msg void OnUpdateViewShowSoftWater(CCmdUI *pCmdUI)
afx_msg void OnViewShowwireframe()
void setHighlightTestArt(Bool toggle)
Definition wbview3d.h:318
void setShowLetterbox(Bool toggle)
Definition wbview3d.h:320
void setShowWeaponRanges(Bool toggle)
Definition wbview3d.h:316
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
afx_msg void OnPaint()
virtual Bool viewToDocCoords(CPoint curPt, Coord3D *newPt, Bool constrain=true)
virtual void updateHeightMapInView(WorldHeightMap *htMap, Bool partial, const IRegion2D &partialRange)
Update the height map in the 3d window.
void removeFenceListObjects(MapObject *pObject)
virtual void invalidateCellInView(int xIndex, int yIndex)
Invalidates the area of one height map cell in the 2d view.
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
afx_msg void OnEditShadows()
void drawLabels(void)
Bool getShowSightRanges(void)
Definition wbview3d.h:315
virtual MapObject * picked3dObjectInView(CPoint viewPt)
void updateLights()
Definition wbview3d.cpp:910
virtual Bool viewToDocCoordZ(CPoint curPt, Coord3D *newPt, Real Z)
Bool getShowWeaponRanges(void)
Definition wbview3d.h:317
afx_msg void OnViewPartialmapsize128x128()
afx_msg BOOL OnEraseBkgnd(CDC *pDC)
afx_msg void OnViewShowshadows()
virtual void invalObjectInView(MapObject *pObj)
Invalidates an object. Pass NULL to inval all objects.
afx_msg void OnViewShowimpassableareas()
virtual void ReleaseResources(void)
Release all dx8 resources so the device can be reset.
Definition wbview3d.cpp:519
void killTheTimer()
Definition wbview3d.cpp:581
Real getCameraPitch(void)
afx_msg void OnUpdateViewWeaponRanges(CCmdUI *pCmdUI)
afx_msg void OnUpdateViewShowshadows(CCmdUI *pCmdUI)
Bool getShowLetterbox(void)
Definition wbview3d.h:321
afx_msg void OnViewLayersList()
afx_msg void OnViewPartialmapsize96x96()
afx_msg void OnUpdateViewPartialmapsize96x96(CCmdUI *pCmdUI)
virtual void OnDraw(CDC *pDC)
void setCameraPitch(Real absolutePitch)
virtual void setCenterInView(Real x, Real y)
Set the center for display.
afx_msg void OnViewWeaponRanges()
afx_msg void OnUpdateViewShowMapBoundaries(CCmdUI *pCmdUI)
afx_msg void OnTimer(UINT nIDEvent)
afx_msg void OnViewGarrisoned()
afx_msg void OnEditMapSettings()
afx_msg void OnViewPartialmapsize192x192()
afx_msg void OnUpdateViewShowExtraBlends(CCmdUI *pCmdUI)
afx_msg void OnUpdateViewShowentire3dmap(CCmdUI *pCmdUI)
void updateHysteresis(void)
void setupCamera()
Definition wbview3d.cpp:633
afx_msg void OnUpdateViewShowAmbientSounds(CCmdUI *pCmdUI)
virtual void scrollInView(Real x, Real y, Bool end)
Scrolls the window by this amount.
afx_msg void OnUpdateViewBoundingBoxes(CCmdUI *pCmdUI)
Vector3 m_centerPt
Definition wbview.h:58
afx_msg int OnCreate(LPCREATESTRUCT lpcs)
Definition wbview.cpp:1079
Bool m_showObjects
Flag whether object icons are drawn in the 2d and 3d view.
Definition wbview.h:71
CWorldBuilderDoc * WbDoc()
Definition wbview.h:141
Coord3D m_rulerPoints[2]
Definition wbview.h:92
Bool m_showWaypoints
Definition wbview.h:75
void setShowGarrisoned(Bool show)
Definition wbview.h:156
void constrainCenterPt()
Definition wbview.cpp:434
Bool getShowGarrisoned(void)
Definition wbview.h:157
Bool m_doLightFeedback
Definition wbview.h:97
Coord3D m_lightDirection[3]
Definition wbview.h:96
void setShowModels(Bool show)
Definition wbview.h:152
Bool m_doLockAngle
True if we are currently locking.
Definition wbview.h:83
RECT m_feedbackBox
Definition wbview.h:89
Real m_hysteresis
Definition wbview.h:79
Bool isNamesVisible(void)
Definition wbview.h:151
Coord3D m_mouseDownDocPoint
Definition wbview.h:86
Bool m_doRectFeedback
Definition wbview.h:90
Real m_rulerLength
Definition wbview.h:93
TTrackingMode m_trackingMode
Definition wbview.h:57
Bool m_showPolygonTriggers
Definition wbview.h:76
Bool m_showTerrain
Flag whether terrain is rendered or not. (Useful for debugging)
Definition wbview.h:77
int m_doRulerFeedback
Definition wbview.h:91
Bool getShowModels(void)
Definition wbview.h:153
void setDrawWidth(Int width)
Int getDrawWidth(void)
Int getXExtent(void)
number of vertices in x
Bool setDrawOrg(Int xOrg, Int yOrg)
void setDrawHeight(Int height)
Int getDrawHeight(void)
Int getYExtent(void)
number of vertices in y
DX8MeshRendererClass TheDX8MeshRenderer
ParticleEmitterLoaderClass _ParticleEmitterLoader
Definition part_ldr.cpp:68
MSG msg
Definition patch.cpp:409
#define REF_PTR_RELEASE(x)
Definition refcount.h:80
#define REF_PTR_SET(dst, src)
Definition refcount.h:79
#define NEW_REF(C, P)
Definition refcount.h:62
RefMultiListIterator< RenderObjClass > RefRenderObjListIterator
Definition robjlist.h:60
Vector3 ContactPoint
Definition castres.h:70
Real x
Definition BaseType.h:333
Real y
Definition BaseType.h:333
Real length(void) const
Definition BaseType.h:335
Real z
Definition BaseType.h:333
Real blue
Definition BaseType.h:462
Real green
Definition BaseType.h:462
Int getAsInt() const
Definition BaseType.h:464
Real red
Definition BaseType.h:462
void setFromInt(Int c)
Definition BaseType.h:472
Definition pcx.H:46
char m_ShadowName[64]
Definition Shadow.h:79
ShadowType m_type
Definition Shadow.h:80
@ WW3D_ERROR_OK
Definition w3derr.h:52
PlaceholderView bogusTacticalView
Definition wbview3d.cpp:290
#define UPDATE_TIME
Definition wbview3d.cpp:117
@ RULER_CIRCLE
Definition wbview.h:45
@ RULER_LINE
Definition wbview.h:44
PrintFunc WWDebug_Install_Message_Handler(PrintFunc func)
Definition wwdebug.cpp:97
AssertPrintFunc WWDebug_Install_Assert_Handler(AssertPrintFunc func)
Definition wwdebug.cpp:117
DebugType
Definition wwdebug.h:63