This file is indexed.

/usr/include/crystalspace-2.0/iengine/engine.h is in libcrystalspace-dev 2.0+dfsg-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
/*
    Crystal Space 3D Engine
    Copyright (C) 1998-2002 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __CS_IENGINE_ENGINE_H__
#define __CS_IENGINE_ENGINE_H__

/**\file 
 * Crystal Space 3D Engine Interface
 */

/**
 * \addtogroup engine3d
 * @{ */
 
#include "csutil/scf_interface.h"

#include "csgeom/vector3.h"

#include "iengine/collection.h"
#include "iengine/light.h"
#include "iutil/threadmanager.h"
#include "ivideo/rendermesh.h"

class csBox3;
class csColor;
class csFrustum;

struct iCacheManager;
struct iCamera;
struct iCameraPosition;
struct iCameraPositionList;
struct iClipper2D;
struct iCustomMatrixCamera;
struct iDataBuffer;
struct iLight;
struct iLightIterator;
struct iLoaderContext;
struct iMaterial;
struct iMaterialList;
struct iMaterialWrapper;
struct iMeshFactoryList;
struct iMeshFactoryWrapper;
struct iMeshList;
struct iMeshObject;
struct iMeshObjectFactory;
struct iMeshObjectType;
struct iMeshWrapper;
struct iMeshWrapperIterator;
struct iObject;
struct iObjectIterator;
struct iObjectWatcher;
struct iPerspectiveCamera;
struct iPortal;
struct iProgressMeter;
struct iRenderLoop;
struct iRenderLoopManager;
struct iRenderManager;
struct iRenderView;
struct iSector;
struct iSectorIterator;
struct iSectorList;
struct iSharedVariableList;
struct iTextureHandle;
struct iTextureList;
struct iTextureWrapper;
struct iThreadedLoader;

struct iEngine;

/** \name RegisterRenderPriority() flags
 * @{ */
enum csRenderPrioritySorting
{
  /**
  * Do not sort this priority.
  */
  CS_RENDPRI_SORT_NONE = 0,

  /**
  * Sort this priority back to front.
  */
  CS_RENDPRI_SORT_BACK2FRONT = 1,

  /**
  * Sort this priority front to back.
  */
  CS_RENDPRI_SORT_FRONT2BACK = 2
};
/** @} */

namespace CS
{
  /// Render grouping for mesh multipass rendering
  enum RenderPriorityGrouping
  {
    /**
     * This first renders layer 1 for all meshes, then layer 2 for all meshes and
     * and so on. This is the faster way of multipass rendering; however, some
     * multipass effects produce incorrect results with this (especially when
     * alpha transparency is involved).
     */
    rpgByLayer = 0,
    /**
     * This all layers in order for the first mesh, then all layers in order for
     * the second mesh and so on. This is the slower way of multipass rendering;
     * however, it always results in correct results (and should thus be used
     * when alpha transparency is involved).
     */
    rpgByMesh = 1
  };
} // namespace CS

/**
 * A callback that will be fired whenever the engine starts drawing
 * a frame.
 *
 * This callback is used by:
 * - iEngine
 */
struct iEngineFrameCallback : public virtual iBase
{
  SCF_INTERFACE(iEngineFrameCallback,1,0,0);
  /**
   * Start a new frame.
   */
  virtual void StartFrame (iEngine* engine, iRenderView* rview) = 0;
};

/**
 * A callback that will be fired whenever a sector is created or
 * removed from the engine.
 *
 * This callback is used by:
 * - iEngine
 */
struct iEngineSectorCallback : public virtual iBase
{
  SCF_INTERFACE(iEngineSectorCallback,2,0,0);
  /**
   * New sector.
   */
  virtual void NewSector (iEngine* engine, iSector* sector) = 0;

  /**
   * Remove sector.
   */
  virtual void RemoveSector (iEngine* engine, iSector* sector) = 0;
};


/**
 * This interface is the main interface to the 3D engine.
 * The engine is responsible for creating new engine-specific objects
 * such as sectors, mesh objects, mesh object factories, lights, and so on.
 *
 * Main creators of instances implementing this interface:
 * - 3D Engine plugin (crystalspace.engine.3d)
 *
 * Main ways to get pointers to this interface:
 * - csQueryRegistry<iEngine> ()
 *
 * Main users of this interface:
 * - Application.
 */
struct iEngine : public virtual iBase
{
  SCF_INTERFACE(iEngine, 8, 0, 1);
  
  /// Get the iObject for the engine.
  virtual iObject *QueryObject() = 0;

  /**\name Preparation and relighting methods
   * @{ */
  
  /**
   * Prepare the engine. This function must be called after you loaded/created 
   * the world and before it is rendered.
   *
   * Actions include:
   * - Preparation of all lightmaps for use
   * - Registering of textures with texture manager and freeing of loaded
   *   images (as the texture manager will have created textures from them)
   * The optional progress meter will be used to report progress.
   *
   * The behaviour regarding cached lighting depends on the flag
   * you can set with the SetLightingCacheMode() function. The default
   * behaviour is to read the lightmap cache when present but don't
   * calculate lighting if cache is not present.
   * \param meter If supplied, the meter object will be called back
   * periodically to report the progress of engine preparation.
   */
  virtual bool Prepare (iProgressMeter* meter = 0) = 0;

  /**
   * Prepare the textures. It will initialise all loaded textures
   * for the texture manager. (Normally you shouldn't call this function
   * directly, because it will be called by Prepare() for you.
   * This function will also prepare all loaded materials after preparing
   * the textures.
   */
  virtual void PrepareTextures () = 0;

  /**
   * Calls UpdateMove for all meshes to initialise bounding boxes.
   * Prepare() will call this function automatically so you normally 
   * don't have to call it.
   */
  virtual void PrepareMeshes () = 0;

  /**
   * Set the cache manager that the engine will use. If this is not
   * done then the engine will use its own cache manager based on VFS.
   * This will do an incref on the given cache manager and a decref
   * on the old one. The engine will release the cache manager at
   * destruction time. To set the cache manager to the default VFS
   * based cache manager for a given VFS directory you can use the
   * following code:
   * \code
   * engine->SetVFSCacheManager ("/bla/bla");
   * \endcode
   */
  virtual void SetCacheManager (iCacheManager* cache_mgr) = 0;

  /**
   * Set the cache manager to the default VFS based cache manager.
   * Note that this function will not change the VFS current directory.
   * \param vfspath is the path that will be used for the cache manager.
   * If 0 then the current VFS directory will be used instead.
   */
  virtual void SetVFSCacheManager (const char* vfspath = 0) = 0;

  /**
   * Get the cache manager that the engine is currently using.
   */
  virtual iCacheManager* GetCacheManager () = 0;

  /** @} */

  /**\name Render priority functions
   * @{ */

  /**
   * Register a new render priority.  Render priorities are assigned to objects
   * and controls the order in which objects are rendered by the engine.
   * \param name a name to refer to this render priority
   * \param priority a numerical priority; this is used to order the
   * render priorities where lower numbers are rendered before higher 
   * numbers.
   * \param rendsort One of the CS_RENDPRI_... flags.
   * By default this is #CS_RENDPRI_SORT_NONE. The following values are
   * possible:
   * - #CS_RENDPRI_SORT_NONE: objects in this render priority are not sorted.
   * - #CS_RENDPRI_SORT_FRONT2BACK: sort objects front to back (as seen from
   *   camera viewpoint).
   * - #CS_RENDPRI_SORT_BACK2FRONT: sort objects back to front.
   *
   * \note The default render priorities are:
   * - init: 1
   * - sky: 2
   * - sky2: 3
   * - portal: 4
   * - wall: 5
   * - wall2: 6
   * - object: 7
   * - object2: 8
   * - transp: 9
   * - alpha: 10 (uses back2front sorting for meshes)
   * - final: 11
   * (in that priority order, where 'init' is rendered first and 
   * 'final' is rendered last).  Should you wish to add your own render 
   * priority, you must call ClearRenderPriorities() and re-add the 
   * default render priorities (using RegisterDefaultRenderPriorities())
   * along with your own new priorities.
   *
   * Priorities are identified by their number, not their name:
   * If you call RegisterRenderPriority() twice, with the same
   * priority number, but different names, the second call will
   * <em>change the name</em>.
   */
  virtual void RegisterRenderPriority (const char* name, uint priority,
  	csRenderPrioritySorting rendsort = CS_RENDPRI_SORT_NONE,
        CS::RenderPriorityGrouping grouping = CS::rpgByLayer) = 0;
  /**
   * Register default render priorities.
   * \sa RegisterRenderPriority for list of default render priorities.
   */
  virtual void RegisterDefaultRenderPriorities () = 0;

  /**
   * Get a render priority by name.
   * \param name is the name you want (one of the standard names
   * or your own if you have defined your own render priorities).
   * \return -1 if render priority doesn't exist.
   */
  virtual CS::Graphics::RenderPriority GetRenderPriority (const char* name) const = 0;
  /// Get the render priority sorting flag.
  virtual csRenderPrioritySorting GetRenderPrioritySorting (
  	const char* name) const = 0;
  /// Get the render priority sorting flag.
  virtual csRenderPrioritySorting GetRenderPrioritySorting (
  	CS::Graphics::RenderPriority priority) const = 0;
  //@{
  /// Get the render priority grouping flag.
  virtual CS::RenderPriorityGrouping GetRenderPriorityGrouping (
  	const char* name) const = 0;
  virtual CS::RenderPriorityGrouping GetRenderPriorityGrouping (
  	CS::Graphics::RenderPriority priority) const = 0;
  //@}
  /// Get the render priority for sky objects (attached to 'sky' name).
  virtual CS::Graphics::RenderPriority GetSkyRenderPriority () = 0;
  /// Get the render priority for portal objects (attached to 'portal' name).
  virtual CS::Graphics::RenderPriority GetPortalRenderPriority () = 0;
  /// Get the render priority for wall objects (attached to 'wall' name).
  virtual CS::Graphics::RenderPriority GetWallRenderPriority () = 0;
  /// Get the render priority for general objects (attached to 'object' name).
  virtual CS::Graphics::RenderPriority GetObjectRenderPriority () = 0;
  /// Get the render priority for alpha objects (attached to 'alpha' name).
  virtual CS::Graphics::RenderPriority GetAlphaRenderPriority () = 0;
  /// Clear all render priorities.
  virtual void ClearRenderPriorities () = 0;
  /// Get the number of render priorities.
  virtual size_t GetRenderPriorityCount () const = 0;
  /// Get the name of the render priority or 0 if it's not valid or registered.
  virtual const char* GetRenderPriorityName (CS::Graphics::RenderPriority priority) const = 0;

  /** @} */
  
  /**\name Material handling
   * @{ */

  /**
   * Create a base material that can be used to give to the texture
   * manager. Assign to a csRef.
   * \param txt The texture map this material will use. Note that this
   * can be 0 in which case a base material without texture will be created.
   * \note You will need to call iMaterialWrapper::Register() and 
   * iMaterialWrapper::GetMaterialHandler()->Prepare() on you new material
   * if you load the material after iEngine::Prepare() has been called.
   */
  virtual csPtr<iMaterial> CreateBaseMaterial (iTextureWrapper* txt) = 0;

  /**
   * Register a material to be loaded during Prepare()
   * \param name engine name for this material
   * \param texture texture to use for this material
   */
  virtual iMaterialWrapper* CreateMaterial (const char *name,
  	iTextureWrapper* texture) = 0;

  /// Get the list of all materials.
  virtual iMaterialList* GetMaterialList () const = 0;

  /**
   * Find the given material. The name can be a normal
   * name. In that case this function will look in all collection
   * except if collection is not 0 in which case it will only
   * look in that collection.
   * If the name is specified as 'collectionname/objectname' then
   * this function will only look in the specified collection and return
   * 0 if that collection doesn't contain the object or the collection
   * doesn't exist. In this case the collection parameter is ignored.
   * \param name the engine name of the desired material
   * \param collection if specified, search only this collection (also see note above)
   */

  virtual iMaterialWrapper* FindMaterial (const char* name,
  	iCollection* collection = 0) = 0;

  /** @} */
  
  /**\name Texture handling
   * @{ */

  /**
   * Create a texture from a file.
   * \param name The name to use for this texture in the engine
   * \param fileName the filename (on the VFS!) of the texture to load
   * \param transp pixels in the image with this key color will be considered
   * transparent instead of being drawn
   * \param flags One or more texturing flags OR'd together, flag include
   * - CS_TEXTURE_2D image will be used only for 2D drawing
   * - CS_TEXTURE_3D image will be textured onto 3D polygon
   *   (this is almost always the flag you want)
   * - CS_TEXTURE_NOMIPMAPS texture will not be mipmapped before use
   *
   * \note You will need to call iTextureWrapper::Register()
   * on you new texture if you load the texture after iEngine::Prepare()
   * has been called.
   */
  virtual iTextureWrapper* CreateTexture (const char *name,
  	const char *fileName, csColor *transp, int flags) = 0;

  /**
   * Create a black texture. This is mostly useful for procedural textures.
   * \param name The name to use for this texture in the engine
   * \param w the texture width (must be a power of 2, eg 64, 128, 256, 512...)
   * \param h the texture height (must be a power of 2, eg 64, 128, 256, 512...)
   * \param transp pixels in the image with this key color will be considered
   * transparent instead of being drawn
   * \param flags see CreateTexture()
   * \see CreateTexture() note about registering textures.
   */
  virtual iTextureWrapper* CreateBlackTexture (const char *name,
	int w, int h, csColor *transp, int flags) = 0;

  /**
   * Query the format to load textures (usually this depends on texture
   * manager)
   */
  virtual int GetTextureFormat () const = 0;

  /// Get the list of all textures.
  virtual iTextureList* GetTextureList () const = 0;

  /**
   * Find the given texture. The name can be a normal
   * name. In that case this function will look in all collections
   * except if collection is not 0 in which case it will only
   * look in that collection.
   * If the name is specified as 'collectionname/objectname' then
   * this function will only look in the specified collection and return
   * 0 if that collection doesn't contain the object or the collection
   * doesn't exist. In this case the collection parameter is ignored.
   * \param name the engine name of the desired texture
   * \param collection if specified, search only this collection (also see note above)
   */
  virtual iTextureWrapper* FindTexture (const char* name,
  	iCollection* collection = 0) = 0;

  /** @} */
  
  /**\name Light handling
   * @{ */

  /**
   * Create a static/pseudo-dynamic light.
   * Assign to a csRef.
   * \param name the engine name for this light (may be 0)
   * \param pos the position of this light in world coordinates
   * \param radius the maximum distance at which this light will affect
   * objects 
   * \param color the color of this light (also affects light intensity)
   * \param dyntype is the type of the light. This can be
   * #CS_LIGHT_DYNAMICTYPE_DYNAMIC, #CS_LIGHT_DYNAMICTYPE_PSEUDO,
   * or #CS_LIGHT_DYNAMICTYPE_STATIC.
   * Note that after creating a light you must add it to a sector
   * by calling sector->GetLights ()->Add (light);
   * If the light is dynamic you also must call Setup() to calculate lighting.
   * Otherwise you must use engine->ForceRelight() if you create a light
   * after calling engine->Prepare(). Otherwise you can let engine->Prepare()
   * do it.
   * <p>
   * Note! If you are using a system with hardware accelerated lighting
   * (i.e. no lightmaps) then the discussion above is not relevant.
   */
  virtual csPtr<iLight> CreateLight (const char* name, const csVector3& pos,
  	float radius, const csColor& color,
	csLightDynamicType dyntype = CS_LIGHT_DYNAMICTYPE_STATIC) = 0;

  /** Find a static/pseudo-dynamic light by name.
   * \param Name the engine name of the desired light
   * \param RegionOnly (parameter presently unused)
   */
  virtual iLight* FindLight (const char *Name, bool RegionOnly = false)
    const = 0;

  /**
   * Find a static/pseudo-dynamic light by id. 
   * \param light_id a 16-byte MD5 checksum for the light.
   */
  virtual iLight* FindLightID (const char* light_id) const = 0;

  /**
   * Create an iterator to iterate over all static lights of the engine.
   * Assign to a csRef.
   * \param collection only iterate over the lights in this collection
   * (otherwise iterate over all lights)
   */
  virtual csPtr<iLightIterator> GetLightIterator (iCollection* collection = 0) = 0;

  /**
   * Remove a light and update all lightmaps. This function only works
   * correctly for dynamic or pseudo-dynamic static lights. If you give a normal
   * static light then the light will be removed but lightmaps will not
   * be affected. You can call ForceRelight() to force relighting then.
   * <p>
   * The current flags set with SetLightingCacheMode() controls if the
   * lightmaps will be cached or not.
   * \param light the light to remove
   */
  virtual void RemoveLight (iLight* light) = 0;

  /**
   * Set the amount of ambient light. This has no effect until you
   * recalculate the lightmaps.
   */
  virtual void SetAmbientLight (const csColor &) = 0;
  /// Return the amount of ambient light
  virtual void GetAmbientLight (csColor &) const = 0;
  /// Return the default amount of ambient light
  virtual void GetDefaultAmbientLight (csColor &c) const = 0;

  /**
   * This routine returns all lights which might affect an object
   * at some position.
   * <br>
   * It will only return as many lights as the size that you specified
   * for the light array. The returned lights are not guaranteed to be sorted
   * but they are guaranteed to be the specified number of lights closest to
   * the given position.<br>
   * This function returns the actual number of lights added to the 'lights'
   * array.
   */
  virtual int GetNearbyLights (iSector* sector, const csVector3& pos,
  	iLight** lights, int max_num_lights) = 0;

  /**
   * This routine returns all lights which might affect an object
   * with some bounding box.
   * <br>
   * It will only return as many lights as the size that you specified
   * for the light array. The returned lights are not guaranteed to be sorted
   * but they are guaranteed to be the specified number of lights closest to
   * the given position.<br>
   * This function returns the actual number of lights added to the 'lights'
   * array.
   */
  virtual int GetNearbyLights (iSector* sector, const csBox3& box,
  	iLight** lights, int max_num_lights) = 0;

  /** @} */
  
  /**\name Sector handling
   * @{ */

  /**
   * Create a empty sector with given name.
   * \param name the sector name
   */
  virtual iSector *CreateSector (const char *name, bool addToList = true) = 0;

  /// Get the list of sectors
  virtual iSectorList* GetSectors () = 0;

  /**
   * Find the given sector. The name can be a normal
   * name. In that case this function will look in all collection
   * except if collection is not 0 in which case it will only
   * look in that collection.
   * If the name is specified as 'collectionname/objectname' then
   * this function will only look in the specified region and return
   * 0 if that region doesn't contain the object or the collection
   * doesn't exist. In this case the collection parameter is ignored.
   * \param name the engine name of the desired sector
   * \param collection if specified, search only this collection (also see note above)
   */
  virtual iSector* FindSector (const char* name,
  	iCollection* collection = 0) = 0;

  /**
   * This routine returns an iterator to iterate over all nearby sectors.
   * Assign to a csRef. In the iterator you can also fetch the
   * position for every sector. Normally that position will be equal to
   * the given input position here (pos) but if there are space warping
   * portals involved then the position returned by the iterator is the
   * warped position relative to the sector returned by the iterator.
   */
  virtual csPtr<iSectorIterator> GetNearbySectors (iSector* sector,
  	const csVector3& pos, float radius) = 0;

  /**
   * This routine returns an iterator to iterate over all nearby sectors.
   * Assign to a csRef. In the iterator you can also fetch the
   * position for every sector. Normally that position will be equal to
   * the given input position here (pos) but if there are space warping
   * portals involved then the position returned by the iterator is the
   * warped position relative to the sector returned by the iterator.
   */
  virtual csPtr<iSectorIterator> GetNearbySectors (iSector* sector,
  	const csBox3& box) = 0;

  /**
   * Add a frame callback. This will call IncRef() on the callback
   * So make sure you call DecRef() to release your own reference.
   */
  virtual void AddEngineFrameCallback (iEngineFrameCallback* cb) = 0;

  /**
   * Remove a frame callback.
   */
  virtual void RemoveEngineFrameCallback (iEngineFrameCallback* cb) = 0;

  /**
   * Add a sector callback. This will call IncRef() on the callback
   * So make sure you call DecRef() to release your own reference.
   */
  virtual void AddEngineSectorCallback (iEngineSectorCallback* cb) = 0;

  /**
   * Remove a sector callback.
   */
  virtual void RemoveEngineSectorCallback (iEngineSectorCallback* cb) = 0;

  /** @} */

  /**\name Mesh handling
   * @{ */

  /**
   * Convenience function to create a mesh object for a given factory.
   * 
   * \param factory the factory that will produce this mesh
   * \param name The engine name for the mesh wrapper; may be null.  
   * Different mesh objects can have the same name (in contrast 
   * with factory objects).
   * \param sector the sector to initially place this mesh in
   * If 'sector' is 0 then the mesh object will not be set to a position.
   * \param pos the position in the sector
   * \return The meshwrapper on success (assign to a csRef),
   * or 0 on failure.
   */
  virtual csPtr<iMeshWrapper> CreateMeshWrapper (iMeshFactoryWrapper* factory,
  	const char* name, iSector* sector = 0, const csVector3& pos = csVector3 (0, 0, 0),
    bool addToList = true) = 0;

  /**
   * Create a mesh wrapper for an existing mesh object.
   * \param meshobj the mesh object
   * \param name The engine name for the mesh wrapper; may be null.  
   * Different mesh objects can have the same name (in contrast 
   * with factory objects).
   * \param sector the sector to initially place this mesh in
   * If 'sector' is 0 then the mesh object will not be set to a position.
   * \param pos the position in the sector
   * \return The meshwrapper on success (assign to a csRef),
   * or 0 on failure.
   */
  virtual csPtr<iMeshWrapper> CreateMeshWrapper (iMeshObject* meshobj,
  	const char* name, iSector* sector = 0, const csVector3& pos = csVector3 (0, 0, 0),
    bool addToList = true) = 0;

  /**
   * Create a mesh wrapper from a class id.
   * This function will first make a factory from the plugin and then
   * see if that factory itself implements iMeshObject too.
   * If that fails this function
   * will call NewInstance() on the factory and return that object then.
   * \param classid The SCF name of the plugin 
   * (like 'crystalspace.mesh.object.ball').  The type plugin will only 
   * be loaded if needed.
   * \param name The engine name for the mesh wrapper; may be null.  
   * Different mesh objects can have the same name (in contrast 
   * with factory objects).
   * \param sector the sector to initially place this mesh in
   * If 'sector' is 0 then the mesh object will not be set to a position.
   * \param pos the position in the sector
   * \return The meshwrapper on success (assign to a csRef),
   * or 0 on failure.
   */
  virtual csPtr<iMeshWrapper> CreateMeshWrapper (const char* classid,
  	const char* name, iSector* sector = 0, const csVector3& pos = csVector3 (0, 0, 0),
    bool addToList = true) = 0;

  /**
   * Create an uninitialized mesh wrapper
   * Assign to a csRef.
   */
  virtual csPtr<iMeshWrapper> CreateMeshWrapper (const char* name, bool addToList = true) = 0;

  /**
   * Convenience function to load a mesh object from a given loader plugin.
   * \param name The engine name for the mesh wrapper; may be null.  
   * Different mesh objects can have the same name (in contrast 
   * with factory objects).
   * \param loaderClassId the SCF class of the loader to use to 
   * create the meshwrapper
   * \param input data passed to the loader to generate the mesh
   * \param sector the sector to initially place this mesh in
   * If 'sector' is 0 then the mesh object will not be set to a position.
   * \param pos the position in the sector
   * \return The meshwrapper on success (assign to a csRef),
   * or 0 on failure.
   */
  virtual csPtr<iMeshWrapper> LoadMeshWrapper (
  	const char* name, const char* loaderClassId,
	iDataBuffer* input, iSector* sector, const csVector3& pos) = 0;

  /**
   * Convenience function to add a mesh and all children of that
   * mesh to the engine.
   */
  THREADED_INTERFACE1(AddMeshAndChildren, iMeshWrapper* mesh);

  /**
   * This routine returns an iterator to iterate over
   * all meshes that are within a radius of a given position.
   * If crossPortals is true it will search through
   * portals. Otherwise it will limit the search to the sector passed in.
   */
  virtual csPtr<iMeshWrapperIterator> GetNearbyMeshes (iSector* sector,
    const csVector3& pos, float radius, bool crossPortals = true) = 0;

  /**
   * This routine returns an iterator to iterate over
   * all meshes that are in a box.
   * If crossPortals is true it will search through
   * portals. Otherwise it will limit the search to the sector passed in.
   * Portal visibility is tested with the center of the box.
   */
  virtual csPtr<iMeshWrapperIterator> GetNearbyMeshes (iSector* sector,
    const csBox3& box, bool crossPortals = true) = 0;

  /**
   * This routine returns an iterator to iterate over
   * all meshes that intersect with a beam.
   * If crossPortals is true it will search through
   * portals. Otherwise it will limit the search to the sector passed in.
   * Portal visibility is tested fromt the start of the beam.
   */
  virtual csPtr<iMeshWrapperIterator> GetNearbyMeshes (iSector* sector,
    const csVector3& start, const csVector3& end,
    bool crossPortals = true) = 0;

  /// Get the list of meshes
  virtual iMeshList* GetMeshes () = 0;

  /**
   * Find the given mesh object. The name can be a normal
   * name. In that case this function will look in all collections
   * except if collection is not 0 in which case it will only
   * look in that collection.
   * If the name is specified as 'collectionname/objectname' then
   * this function will only look in the specified collection and return
   * 0 if that collection doesn't contain the object or the collection
   * doesn't exist. In this case the collection parameter is ignored.
   * \param name the engine name of the desired mesh
   * \param collection if specified, search only this collection (also see note above)
   */
  virtual iMeshWrapper* FindMeshObject (const char* name,
  	iCollection* collection = 0) = 0;

  /**
   * Sometimes a mesh wants to destruct itself (for example
   * a particle system that has only limited lifetime). It can do that
   * by calling this function on itself. The engine will then remove
   * the object before the next frame.
   */
  virtual void WantToDie (iMeshWrapper* mesh) = 0;

  /** @} */
  
  /**\name Mesh factory handling
   * @{ */

  /**
   * Convenience function to create a mesh factory from a given type.
   * \param classId the SCF name of the plugin 
   * (like 'crystalspace.mesh.object.ball'). The type plugin will only 
   * be loaded if needed. 
   * \param name The factory will be registered with the engine
   * under the given name. If there is already a factory with that name
   * no new factory will be created but the found one is returned instead.
   * If the name is 0 then no name will be set and no check will happen
   * if the factory already exists.
   * \return 0 on failure; you must assign the result to a csRef or 
   * use DecRef().
   */
  virtual csPtr<iMeshFactoryWrapper> CreateMeshFactory (const char* classId,
  	const char* name, bool addToList = true) = 0;

  /**
   * Create a mesh factory wrapper for an existing mesh factory
   * Assign to a csRef.
   * \param factory the mesh factory to be wrapped, the engine doesn't
   * "know" about a mesh factory until associated with a FactoryWrapper
   * \param name the engine name for the factory wrapper
   */
  virtual csPtr<iMeshFactoryWrapper> CreateMeshFactory (
  	iMeshObjectFactory * factory, const char* name,
    bool addToList = true) = 0;

  /**
   * Create an uninitialized mesh factory wrapper
   * Assign to a csRef.
   * \param name the engine name for the factory wrapper
   */
  virtual csPtr<iMeshFactoryWrapper> CreateMeshFactory (const char* name,
    bool addToList = true) = 0;

  /**
   * Convenience function to load a mesh factory from a given loader plugin.
   * \param name engine name for the mesh factory
   * \param loaderClassId the SCF class name of the desired mesh factory plugin
   * \param input data to initialize the mesh factory (plugin-specific)
   * Assign to a csRef.
   */
  virtual csPtr<iMeshFactoryWrapper> LoadMeshFactory (
  	const char* name, const char* loaderClassId,
	iDataBuffer* input, bool addToList = true) = 0;

  /**
   * Find the given mesh factory. The name can be a normal
   * name. In that case this function will look in all collections
   * except if collection is not 0 in which case it will only
   * look in that collection.
   * If the name is specified as 'collectionname/objectname' then
   * this function will only look in the specified collection and return
   * 0 if that collection doesn't contain the object or the collection
   * doesn't exist. In this case the collection parameter is ignored.
   * \param name the engine name of the desired mesh factory
   * \param collection if specified, search only this collection (also see note above)
   */
  virtual iMeshFactoryWrapper* FindMeshFactory (const char* name,
  	iCollection* collection = 0) = 0;

  /// Get the list of mesh factories
  virtual iMeshFactoryList* GetMeshFactories () = 0;

  /** @} */
  
  /**\name Collection handling
   * @{ */

  /**
   * Create a new collection with the given name.
   */
  virtual iCollection* CreateCollection (const char* name) = 0;

  /**
   * Get the collection of the given name.
   */
  virtual iCollection* GetCollection (const char* name) const = 0;

  /**
   * Return all collections created.
   */
  virtual csPtr<iCollectionArray> GetCollections () = 0;

  /**
   * Remove the given collection from the list of collections.
   */
  virtual void RemoveCollection (iCollection* collect) = 0;

  /**
   * Remove the collection of the given name.
   */
  virtual void RemoveCollection (const char* name) = 0;

  /**
   * Remove all the collections.
   */
  virtual void RemoveAllCollections () = 0;

  /** @} */
  
  /**\name Camera handling
   * @{ */

  /**
   * Create a new camera.
   * Assign to a csRef.
   */
  CS_DEPRECATED_METHOD_MSG("Use CreatePerspectiveCamera instead")
  virtual csPtr<iCamera> CreateCamera () = 0;

  /**
   * Find the given camera position. The name can be a normal
   * name. In that case this function will look in all collection
   * except if collection is not 0 in which case it will only
   * look in that collection.
   * If the name is specified as 'collectionname/objectname' then
   * this function will only look in the specified collection and return
   * 0 if that collection doesn't contain the object or the collection
   * doesn't exist. In this case the collection parameter is ignored.
   * \param name the engine name of the desired camera position
   * \param collection if specified, search only this collection (also see note above)
   */
  virtual iCameraPosition* FindCameraPosition (const char* name,
  	iCollection* collection = 0) = 0;

  /// Get the list of camera positions.
  virtual iCameraPositionList* GetCameraPositions () = 0;

  /** @} */
  
  /**\name Portal handling
   * @{ */
  
  /**
   * Convenience function to create a portal from one sector to another
   * and make this portal a child mesh of another mesh. Use scfQueryInterface<
   * iPortalContainer> on the returned mesh for more control over the
   * portal(s) in the portal object.
   * \param name is the name of the portal container mesh to create the portal
   * in. If the parentMesh already has a mesh with that name then that will
   * be used. If there is already a mesh with that name but it is not a
   * portal container then a new mesh will be created.
   * \param parentMesh is the mesh where the portal container will be placed
   * as a child.
   * \param destSector is the sector where the single portal that is created
   * inside the portal object will point too.
   * \param vertices list of vertices comprising the portal.
   * \param num_vertices number of elements in 'vertices'.
   * \param portal is a return value for the created portal.
   * \return The meshwrapper on success (assign to a csRef),
   * or 0 on failure.
   */
  virtual csPtr<iMeshWrapper> CreatePortal (
  	const char* name,
  	iMeshWrapper* parentMesh, iSector* destSector,
	csVector3* vertices, int num_vertices,
	iPortal*& portal) = 0;

  /**
   * Convenience function to create a portal from one sector to another.
   * Use scfQueryInterface<iPortalContainer> on the returned mesh for
   * more control over the portal(s) in the portal object.
   * \param name is the name of the portal container mesh to create the portal
   * in. If the sourceSector already has a mesh with that name then that will
   * be used. If there is already a mesh with that name but it is not a
   * portal container then a new mesh will be created.
   * \param sourceSector is the sector where the portal container will be
   * placed.
   * \param pos the position inside that sector.
   * \param destSector the sector where the single portal that is created
   * inside the portal object will point too.
   * \param vertices list of vertices comprising the portal.
   * \param num_vertices number of elements in 'vertices'.
   * \param portal return value for the created portal.
   * \return The meshwrapper on success (assign to a csRef),
   * or 0 on failure.
   */
  virtual csPtr<iMeshWrapper> CreatePortal (
  	const char* name,
  	iSector* sourceSector, const csVector3& pos,
	iSector* destSector,
	csVector3* vertices, int num_vertices,
	iPortal*& portal) = 0;

  /**
   * Create an empty portal container in some sector. Use this portal
   * container to create portals to other sectors. Use scfQueryInterface<
   * iPortalContainer> on the mesh object inside the returned mesh to
   * control the portals.
   * \param name of the portal mesh.
   * \param sector is the location of the portal object and not the sector
   * the portals will point too. If not given then the portal container is
   * not put in any mesh.
   * \param pos is an optional position inside the sector (if given).
   * \return The meshwrapper on success (assign to a csRef),
   * or 0 on failure.
   */
  virtual csPtr<iMeshWrapper> CreatePortalContainer (const char* name,
  	iSector* sector = 0, const csVector3& pos = csVector3 (0, 0, 0)) = 0;

  /** @} */
  
  /**\name Drawing related
   * @{ */

  /**
   * Require that the Z-buffer is cleared every frame. The engine
   * itself will not use this setting but will only return the
   * correct flag in GetBeginDrawFlags() so that the Z-buffer is actually
   * cleared. Note that this requires that the application actually
   * uses GetBeginDrawFlags() in the call to g3d->BeginDraw() (which it should).
   * By default this flag is false. It is useful to set this flag to true
   * if you have a level that doesn't itself have another way to initialize
   * the Z-buffer.
   * \param yesno true to clear the Z buffer after each frame, 
   * false to leave the zbuffer as-is
   */
  CS_DEPRECATED_METHOD_MSG("Z buffer clearing handled by the rendermanager.")
  virtual void SetClearZBuf (bool yesno) = 0;

  /**
   * Get the value of the clear Z-buffer flag set with SetClearZBuf().
   */
  CS_DEPRECATED_METHOD_MSG("Z buffer clearing handled by the rendermanager.")
  virtual bool GetClearZBuf () const = 0;

  /// Get default clear z-buffer flag.
  CS_DEPRECATED_METHOD_MSG("Z buffer clearing handled by the rendermanager.")
  virtual bool GetDefaultClearZBuf () const = 0;

  /**
   * Require that the screen is cleared every frame. The engine
   * itself will not use this setting but will only return the
   * correct flag in GetBeginDrawFlags() so that the screen is actually
   * cleared. Note that this requires that the application actually
   * uses GetBeginDrawFlags() in the call to g3d->BeginDraw() (which it should).
   * By default this flag is false. It is useful to set this flag to true
   * if you have a level that doesn't itself have another way to initialize
   * the screen.
   * \param yesno true to clear the screen before each frame, 
   * false to leave the screen as-is (which may leave garbage on the screen)
   */
  CS_DEPRECATED_METHOD_MSG("Screen clearing handled by the rendermanager.")
  virtual void SetClearScreen (bool yesno) = 0;

  /**
   * Get the value of the clear screen flag set with SetClearScreen().
   */
  CS_DEPRECATED_METHOD_MSG("Screen clearing handled by the rendermanager.")
  virtual bool GetClearScreen () const = 0;

  /// Get default clear screen flag
  CS_DEPRECATED_METHOD_MSG("Screen clearing handled by the rendermanager.")
  virtual bool GetDefaultClearScreen () const = 0;

  /**
   * Get the required flags for 3D->BeginDraw() which should be called
   * from the application. These flags must be or-ed with optional other
   * flags that the application might be interested in. Use SetClearZBuf()
   * to let this function return that the Z-buffer must be cleared.
   */
  CS_DEPRECATED_METHOD_MSG("Screen and Z buffer clearing handled by the rendermanager.")
  virtual int GetBeginDrawFlags () const = 0;

  /**
   * Get the top-level clipper.
   */
  virtual iRenderView* GetTopLevelClipper () const = 0;

  /**
   * Precache a single mesh.
   */
  virtual void PrecacheMesh (iMeshWrapper* s) = 0;

  /**
   * This function precaches all meshes by calling GetRenderMeshes()
   * on them. By doing this the level will run smoother if you walk
   * through it because all meshes will have had a chance to update
   * caches and stuff.
   * \param collection is an optional collection. If given then only objects
   *        in that collection will be precached.
   */
  virtual void PrecacheDraw (iCollection* collection = 0) = 0;

  /**
   * Draw the 3D world given a camera and a clipper. Note that
   * in order to be able to draw using the given 3D driver
   * all textures must have been registered to that driver (using
   * Prepare()). Note that you need to call Prepare() again if
   * you switch to another 3D driver.
   * <p>
   * If a mesh is given then only that single mesh is rendered.
   * Note that in that case the mesh will only be rendered if it
   * is in the same sector as the camera!
   */
  virtual void Draw (iCamera* c, iClipper2D* clipper,
      iMeshWrapper* mesh = 0) = 0;

  /**
   * Set the drawing context. This is a texture handle that is used
   * as the procedural texture to render on. If this is 0 then the
   * screen is assumed.
   */
  virtual void SetContext (iTextureHandle* ctxt) = 0;
  /// Return the current drawing context.
  virtual iTextureHandle *GetContext () const = 0;

  /**
   * Retrieve the render loop manager.
   */
  virtual iRenderLoopManager* GetRenderLoopManager () = 0;
  
  /**
   * Returns the current render loop.
   * \remark This will the loop that is set to be the current default
   *  with SetCurrentDefaultRenderloop(). This doesn't have to be the engine's
   *  default render loop (note the difference between the "current" and 
   *  "default" render loop - former one is the loop used currently for 
   *  drawing, latter one is a default loop created at engine initialization 
   *  time.) To retrieve the default loop, use 
   * \code
   *  GetRenderLoopManager()->Retrieve (#CS_DEFAULT_RENDERLOOP_NAME);
   * \endcode
   */
  virtual iRenderLoop* GetCurrentDefaultRenderloop () = 0;

  /**
   * Set the current render loop.
   * \param loop The loop to be made the current render loop.
   * \return Whether the change was successful (a value of 0 for \p will 
   *   let the method fail.)
   */
  virtual bool SetCurrentDefaultRenderloop (iRenderLoop* loop) = 0;

  /**
   * Get the current framenumber. This should be incremented once every Draw
   */
  virtual uint GetCurrentFrameNumber () const = 0;

  /**
   * Update the engine and animations etc for a new frame
   */
  virtual void UpdateNewFrame () = 0;
  /** @} */

  /**\name Adaptive progressive LODs
   * @{ */

  /**
   * Enable adaptive LODs.
   */
  virtual void EnableAdaptiveLODs(bool enable, float target_fps) = 0;

  /**
   * Must be called once per frame if you use adaptive LODs.
   */
  virtual void UpdateAdaptiveLODs() = 0;

  /**
   * Get a multiplier based on the average elapsed time for the last n frames.
   */
  virtual float GetAdaptiveLODsMultiplier() const = 0;
  /** @} */

  /**\name Saving/loading
   * @{ */

  /**
   * Set whether saving should be possible (default OFF).
   * To allow saving of a world after it has been loaded, some objects may 
   * need to keep track of extra data that would otherwise not be needed if 
   * the world will never be written out again. The 'saveable' flag informs
   * those objects about whether to keep that information or not. Saving
   * a world with this flag disables is still possible, but the result might
   * incomplete.
   */
  virtual void SetSaveableFlag (bool enable) = 0;

  /**
   * Get whether saving should be possible (default OFF).
   */
  virtual bool GetSaveableFlag () = 0;

  /**
   * Create a loader context that you can give to loader plugins.
   * It will basically allow loader plugins to find materials.
   * \param collection optional loader collection
   * \param searchCollectionOnly if collection is valid and searchCollectionOnly is true 
   * then only that collection will be searched. 
   * Assign to a csRef.
   */
  virtual csPtr<iLoaderContext> CreateLoaderContext (
  	iCollection* collection = 0, bool searchCollectionOnly = true) = 0;

  /**
   * Set the default value for the "keep image" flag of texture wrappers.
   */
  virtual void SetDefaultKeepImage (bool enable) = 0;

  /**
   * Get the default value for the "keep image" flag of texture wrappers 
    *(default OFF).
   */
  virtual bool GetDefaultKeepImage () = 0;

  /** @} */
  
  /**\name Other
   * @{ */

  /**
   * This routine returns an iterator to iterate over
   * all objects that are within a radius of a given position.
   * The current implementation only does meshes but in future
   * lights will also be supported.
   * You can use #scfQueryInterface to get any interface from the
   * returned objects. If crossPortals is true it will search through
   * portals. Otherwise it will limit the search to the sector passed in.
   * If you only want to have meshes then it is more efficient to
   * call GetNearbyMeshes() as you can then avoid the call to
   * #scfQueryInterface.
   */
  virtual csPtr<iObjectIterator> GetNearbyObjects (iSector* sector,
    const csVector3& pos, float radius, bool crossPortals = true ) = 0;

  

  /**
   * This routine returns an iterator to iterate over
   * all objects that are potentially visible as seen from a given position.
   * This routine assumes full 360 degree visibility.
   * You can use #scfQueryInterface to get any interface from the
   * returned objects.<p>
   * If you only want meshes then use GetVisibleMeshes().
   * CURRENTLY NOT IMPLEMENTED!
   */
  virtual csPtr<iObjectIterator> GetVisibleObjects (iSector* sector,
    const csVector3& pos) = 0;

  /**
   * This routine returns an iterator to iterate over
   * all meshes that are potentially visible as seen from a given position.
   * This routine assumes full 360 degree visibility.
   * CURRENTLY NOT IMPLEMENTED!
   */
  virtual csPtr<iMeshWrapperIterator> GetVisibleMeshes (iSector* sector,
    const csVector3& pos) = 0;

  /**
   * This routine returns an iterator to iterate over
   * all objects that are potentially visible as seen from a given position.
   * This routine has a frustum restricting the view.
   * You can use #scfQueryInterface to get any interface from the
   * returned objects.<p>
   * If you only want meshes then use GetVisibleMeshes().
   * CURRENTLY NOT IMPLEMENTED!
   */
  virtual csPtr<iObjectIterator> GetVisibleObjects (iSector* sector,
    const csFrustum& frustum) = 0;

  /**
   * This routine returns an iterator to iterate over
   * all meshes that are potentially visible as seen from a given position.
   * This routine has a frustum restricting the view.
   * CURRENTLY NOT IMPLEMENTED!
   */
  virtual csPtr<iMeshWrapperIterator> GetVisibleMeshes (iSector* sector,
    const csFrustum& frustum) = 0;

  /**
   * Create an object watcher instance that you can use to watch
   * other objects. The engine will not keep a reference to this object.
   */
  virtual csPtr<iObjectWatcher> CreateObjectWatcher () = 0;

    /// Get the list of all shared variables.
  virtual iSharedVariableList* GetVariableList () const = 0;

  /**
   * Convenience function to 'remove' a CS object from the engine.
   * This will not clear the object but it will remove all references
   * to that object that the engine itself keeps. This function works
   * for: iCameraPosition, iLight, iMaterialWrapper, 
   * iMeshFactoryWrapper,iMeshWrapper, iSector and iTextureWrapper.
   * Note that the object is only removed if the resulting ref count will
   * become zero. So basically this function only releases the references
   * that the engine holds.
   * <p>
   * This function returns true if the engine recognized the object as
   * one on which it can operate.
   * <p>
   * This function will also remove the object from the region it may be in.
   */
  virtual bool RemoveObject (iBase* object) = 0;

  /**
   * This function can be used to remove an object after a specific amount
   * of time. This is mostly useful for particle systems (like explosions)
   * that you want to live for a specific time before they are automatically
   * cleaned up by the engine. Note that calling this function will cause
   * the engine to keep an additional reference until it is time to delete
   * the object.
   */
  virtual void DelayedRemoveObject (csTicks delay, iBase* object) = 0;

  /**
   * Clear all delayed removals.
   * \param remove if true then the objects will also be removed from engine.
   * Otherwise they are simply removed from this list.
   */
  virtual void RemoveDelayedRemoves (bool remove = false) = 0;
 
  /// Delete everything in the engine.
  THREADED_INTERFACE(DeleteAll);

  /**
   * Reset a subset of flags/settings (which may differ from one world/map to 
   * another) to its defaults. This currently includes:
   *   - clear z buffer flag
   *   - lightmap cell size
   *   - maximum lightmap size
   */
  virtual void ResetWorldSpecificSettings() = 0;  
  
  /** @} */

  /// Fire all frame callbacks
  virtual void FireStartFrame (iRenderView* rview) = 0;
  
  /**\name Camera handling
   * @{ */

  /**
   * Create a new perspective projection camera.
   */
  virtual csPtr<iPerspectiveCamera> CreatePerspectiveCamera () = 0;

  /**
   * Create a new custom projection camera.
   * \param copyFrom If given, the new camera's initial tranform, settings 
   *   and projection matrix are copied from that camera.
   */
  virtual csPtr<iCustomMatrixCamera> CreateCustomMatrixCamera (
    iCamera* copyFrom = 0) = 0;
  /** @} */

  /**\name Render manager
   * @{ */
  /// Get the default render manager
  virtual iRenderManager* GetRenderManager () = 0;
  /**
   * Set the default render manager.
   * \remarks Also replaces the iRenderManager in the object registry.
   */
  virtual void SetRenderManager (iRenderManager*) = 0;
  
  /**
   * Reload the default render manager given the current configuration
   * settings.
   */
  virtual void ReloadRenderManager() = 0;
  /** @} */

  // @{
  /**
   * Loader List Sync
   */
  THREADED_INTERFACE1(SyncEngineLists, csRef<iThreadedLoader> loader);
  virtual void SyncEngineListsNow(csRef<iThreadedLoader> loader) = 0;
  // @}
  
  /**\name Camera default properties
   * @{ */
  /// Retrieve default near plane clipping distance for perspective cameras
  virtual float GetDefaultNearClipDistance () const = 0;
  /// Set default near plane clipping distance for perspective cameras
  virtual void SetDefaultNearClipDistance (float dist) = 0;
  /**@} */
};

/** @} */

#endif // __CS_IENGINE_ENGINE_H__