aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--externals/PackageList.txt2
-rw-r--r--externals/g3dlite/G3D.lib/include/G3D/Discovery.h589
-rw-r--r--externals/g3dlite/G3D.lib/source/AABox.cpp342
-rw-r--r--externals/g3dlite/G3D.lib/source/AnyVal.cpp1381
-rw-r--r--externals/g3dlite/G3D.lib/source/BinaryFormat.cpp81
-rw-r--r--externals/g3dlite/G3D.lib/source/BinaryInput.cpp568
-rw-r--r--externals/g3dlite/G3D.lib/source/BinaryOutput.cpp518
-rw-r--r--externals/g3dlite/G3D.lib/source/Box.cpp393
-rw-r--r--externals/g3dlite/G3D.lib/source/Capsule.cpp179
-rw-r--r--externals/g3dlite/G3D.lib/source/CollisionDetection.cpp2152
-rw-r--r--externals/g3dlite/G3D.lib/source/Color1.cpp40
-rw-r--r--externals/g3dlite/G3D.lib/source/Color1uint8.cpp38
-rw-r--r--externals/g3dlite/G3D.lib/source/Color3.cpp321
-rw-r--r--externals/g3dlite/G3D.lib/source/Color3uint8.cpp45
-rw-r--r--externals/g3dlite/G3D.lib/source/Color4.cpp140
-rw-r--r--externals/g3dlite/G3D.lib/source/Color4uint8.cpp47
-rw-r--r--externals/g3dlite/G3D.lib/source/Cone.cpp79
-rw-r--r--externals/g3dlite/G3D.lib/source/ConvexPolyhedron.cpp449
-rw-r--r--externals/g3dlite/G3D.lib/source/CoordinateFrame.cpp381
-rw-r--r--externals/g3dlite/G3D.lib/source/Crypto.cpp70
-rw-r--r--externals/g3dlite/G3D.lib/source/Crypto_md5.cpp471
-rw-r--r--externals/g3dlite/G3D.lib/source/Cylinder.cpp176
-rw-r--r--externals/g3dlite/G3D.lib/source/Discovery.cpp170
-rw-r--r--externals/g3dlite/G3D.lib/source/GCamera.cpp399
-rw-r--r--externals/g3dlite/G3D.lib/source/GImage.cpp1065
-rw-r--r--externals/g3dlite/G3D.lib/source/GImage_bayer.cpp298
-rw-r--r--externals/g3dlite/G3D.lib/source/GImage_bmp.cpp716
-rw-r--r--externals/g3dlite/G3D.lib/source/GImage_jpeg.cpp445
-rw-r--r--externals/g3dlite/G3D.lib/source/GImage_png.cpp245
-rw-r--r--externals/g3dlite/G3D.lib/source/GImage_ppm.cpp185
-rw-r--r--externals/g3dlite/G3D.lib/source/GImage_tga.cpp179
-rw-r--r--externals/g3dlite/G3D.lib/source/GLight.cpp143
-rw-r--r--externals/g3dlite/G3D.lib/source/GThread.cpp203
-rw-r--r--externals/g3dlite/G3D.lib/source/GUniqueID.cpp78
-rw-r--r--externals/g3dlite/G3D.lib/source/Image1.cpp224
-rw-r--r--externals/g3dlite/G3D.lib/source/Image1uint8.cpp212
-rw-r--r--externals/g3dlite/G3D.lib/source/Image3.cpp224
-rw-r--r--externals/g3dlite/G3D.lib/source/Image3uint8.cpp225
-rw-r--r--externals/g3dlite/G3D.lib/source/Image4.cpp226
-rw-r--r--externals/g3dlite/G3D.lib/source/Image4uint8.cpp222
-rw-r--r--externals/g3dlite/G3D.lib/source/ImageFormat.cpp440
-rw-r--r--externals/g3dlite/G3D.lib/source/ImageFormat_convert.cpp1305
-rw-r--r--externals/g3dlite/G3D.lib/source/Line.cpp89
-rw-r--r--externals/g3dlite/G3D.lib/source/LineSegment.cpp236
-rw-r--r--externals/g3dlite/G3D.lib/source/Log.cpp157
-rw-r--r--externals/g3dlite/G3D.lib/source/Matrix.cpp1801
-rw-r--r--externals/g3dlite/G3D.lib/source/Matrix3.cpp1725
-rw-r--r--externals/g3dlite/G3D.lib/source/Matrix4.cpp433
-rw-r--r--externals/g3dlite/G3D.lib/source/MeshAlg.cpp733
-rw-r--r--externals/g3dlite/G3D.lib/source/MeshAlgAdjacency.cpp729
-rw-r--r--externals/g3dlite/G3D.lib/source/MeshAlgWeld.cpp213
-rw-r--r--externals/g3dlite/G3D.lib/source/MeshAlgWeld2.cpp377
-rw-r--r--externals/g3dlite/G3D.lib/source/MeshBuilder.cpp113
-rw-r--r--externals/g3dlite/G3D.lib/source/NetAddress.cpp164
-rw-r--r--externals/g3dlite/G3D.lib/source/NetworkDevice.cpp1362
-rw-r--r--externals/g3dlite/G3D.lib/source/PhysicsFrame.cpp77
-rw-r--r--externals/g3dlite/G3D.lib/source/Plane.cpp149
-rw-r--r--externals/g3dlite/G3D.lib/source/Quat.cpp583
-rw-r--r--externals/g3dlite/G3D.lib/source/Ray.cpp112
-rw-r--r--externals/g3dlite/G3D.lib/source/RegistryUtil.cpp290
-rw-r--r--externals/g3dlite/G3D.lib/source/Sphere.cpp196
-rw-r--r--externals/g3dlite/G3D.lib/source/SplineBase.cpp162
-rw-r--r--externals/g3dlite/G3D.lib/source/Stopwatch.cpp96
-rw-r--r--externals/g3dlite/G3D.lib/source/System.cpp1864
-rw-r--r--externals/g3dlite/G3D.lib/source/TextInput.cpp988
-rw-r--r--externals/g3dlite/G3D.lib/source/TextOutput.cpp452
-rw-r--r--externals/g3dlite/G3D.lib/source/ThreadSet.cpp147
-rw-r--r--externals/g3dlite/G3D.lib/source/Triangle.cpp135
-rw-r--r--externals/g3dlite/G3D.lib/source/UprightFrame.cpp132
-rw-r--r--externals/g3dlite/G3D.lib/source/Vector2.cpp211
-rw-r--r--externals/g3dlite/G3D.lib/source/Vector2int16.cpp47
-rw-r--r--externals/g3dlite/G3D.lib/source/Vector3.cpp493
-rw-r--r--externals/g3dlite/G3D.lib/source/Vector3int16.cpp49
-rw-r--r--externals/g3dlite/G3D.lib/source/Vector3int32.cpp57
-rw-r--r--externals/g3dlite/G3D.lib/source/Vector4.cpp475
-rw-r--r--externals/g3dlite/G3D.lib/source/Vector4int8.cpp58
-rw-r--r--externals/g3dlite/G3D.lib/source/WinMain.cpp155
-rw-r--r--externals/g3dlite/G3D.lib/source/debugAssert.cpp392
-rw-r--r--externals/g3dlite/G3D.lib/source/fileutils.cpp1092
-rw-r--r--externals/g3dlite/G3D.lib/source/filter.cpp32
-rw-r--r--externals/g3dlite/G3D.lib/source/format.cpp164
-rw-r--r--externals/g3dlite/G3D.lib/source/g3dmath.cpp70
-rw-r--r--externals/g3dlite/G3D.lib/source/license.cpp70
-rw-r--r--externals/g3dlite/G3D.lib/source/prompt.cpp716
-rw-r--r--externals/g3dlite/G3D.lib/source/stringutils.cpp231
-rw-r--r--externals/g3dlite/G3D.lib/source/uint128.cpp155
-rw-r--r--externals/g3dlite/G3D/AABox.h (renamed from externals/g3dlite/G3D.lib/include/G3D/AABox.h)37
-rw-r--r--externals/g3dlite/G3D/Any.h570
-rw-r--r--externals/g3dlite/G3D/AnyVal.h (renamed from externals/g3dlite/G3D.lib/include/G3D/AnyVal.h)6
-rw-r--r--externals/g3dlite/G3D/AreaMemoryManager.h93
-rw-r--r--externals/g3dlite/G3D/Array.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Array.h)226
-rw-r--r--externals/g3dlite/G3D/AtomicInt32.h (renamed from externals/g3dlite/G3D.lib/include/G3D/AtomicInt32.h)28
-rw-r--r--externals/g3dlite/G3D/BinaryFormat.h (renamed from externals/g3dlite/G3D.lib/include/G3D/BinaryFormat.h)2
-rw-r--r--externals/g3dlite/G3D/BinaryInput.h (renamed from externals/g3dlite/G3D.lib/include/G3D/BinaryInput.h)6
-rw-r--r--externals/g3dlite/G3D/BinaryOutput.h (renamed from externals/g3dlite/G3D.lib/include/G3D/BinaryOutput.h)0
-rw-r--r--externals/g3dlite/G3D/BoundsTrait.h (renamed from externals/g3dlite/G3D.lib/include/G3D/BoundsTrait.h)4
-rw-r--r--externals/g3dlite/G3D/Box.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Box.h)24
-rw-r--r--externals/g3dlite/G3D/Box2D.h121
-rw-r--r--externals/g3dlite/G3D/BumpMapPreprocess.h61
-rw-r--r--externals/g3dlite/G3D/Capsule.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Capsule.h)2
-rw-r--r--externals/g3dlite/G3D/CollisionDetection.h (renamed from externals/g3dlite/G3D.lib/include/G3D/CollisionDetection.h)139
-rw-r--r--externals/g3dlite/G3D/Color1.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Color1.h)21
-rw-r--r--externals/g3dlite/G3D/Color1uint8.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Color1uint8.h)20
-rw-r--r--externals/g3dlite/G3D/Color3.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Color3.h)92
-rw-r--r--externals/g3dlite/G3D/Color3uint8.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Color3uint8.h)47
-rw-r--r--externals/g3dlite/G3D/Color4.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Color4.h)60
-rw-r--r--externals/g3dlite/G3D/Color4uint8.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Color4uint8.h)46
-rw-r--r--externals/g3dlite/G3D/Cone.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Cone.h)2
-rw-r--r--externals/g3dlite/G3D/ConvexPolyhedron.h (renamed from externals/g3dlite/G3D.lib/include/G3D/ConvexPolyhedron.h)67
-rw-r--r--externals/g3dlite/G3D/CoordinateFrame.h (renamed from externals/g3dlite/G3D.lib/include/G3D/CoordinateFrame.h)42
-rw-r--r--externals/g3dlite/G3D/Crypto.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Crypto.h)2
-rw-r--r--externals/g3dlite/G3D/Cylinder.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Cylinder.h)2
-rw-r--r--externals/g3dlite/G3D/EqualsTrait.h (renamed from externals/g3dlite/G3D.lib/include/G3D/EqualsTrait.h)4
-rw-r--r--externals/g3dlite/G3D/G3D.h (renamed from externals/g3dlite/G3D.lib/include/G3D/G3D.h)34
-rw-r--r--externals/g3dlite/G3D/G3DAll.h (renamed from externals/g3dlite/G3D.lib/include/G3D/G3DAll.h)4
-rw-r--r--externals/g3dlite/G3D/G3DGameUnits.h (renamed from externals/g3dlite/G3D.lib/include/G3D/G3DGameUnits.h)6
-rw-r--r--externals/g3dlite/G3D/GCamera.h (renamed from externals/g3dlite/G3D.lib/include/G3D/GCamera.h)83
-rw-r--r--externals/g3dlite/G3D/GImage.h (renamed from externals/g3dlite/G3D.lib/include/G3D/GImage.h)309
-rw-r--r--externals/g3dlite/G3D/GLight.h (renamed from externals/g3dlite/G3D.lib/include/G3D/GLight.h)56
-rw-r--r--externals/g3dlite/G3D/GMutex.h123
-rw-r--r--externals/g3dlite/G3D/GThread.h (renamed from externals/g3dlite/G3D.lib/include/G3D/GThread.h)78
-rw-r--r--externals/g3dlite/G3D/GUniqueID.h (renamed from externals/g3dlite/G3D.lib/include/G3D/GUniqueID.h)2
-rw-r--r--externals/g3dlite/G3D/HashTrait.h (renamed from externals/g3dlite/G3D.lib/include/G3D/HashTrait.h)55
-rw-r--r--externals/g3dlite/G3D/Image1.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Image1.h)6
-rw-r--r--externals/g3dlite/G3D/Image1uint8.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Image1uint8.h)2
-rw-r--r--externals/g3dlite/G3D/Image3.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Image3.h)6
-rw-r--r--externals/g3dlite/G3D/Image3uint8.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Image3uint8.h)2
-rw-r--r--externals/g3dlite/G3D/Image4.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Image4.h)16
-rw-r--r--externals/g3dlite/G3D/Image4uint8.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Image4uint8.h)2
-rw-r--r--externals/g3dlite/G3D/ImageFormat.h (renamed from externals/g3dlite/G3D.lib/include/G3D/ImageFormat.h)115
-rw-r--r--externals/g3dlite/G3D/Intersect.h55
-rw-r--r--externals/g3dlite/G3D/KDTree.h (renamed from externals/g3dlite/G3D.lib/include/G3D/AABSPTree.h)146
-rw-r--r--externals/g3dlite/G3D/Line.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Line.h)2
-rw-r--r--externals/g3dlite/G3D/LineSegment.h (renamed from externals/g3dlite/G3D.lib/include/G3D/LineSegment.h)2
-rw-r--r--externals/g3dlite/G3D/Log.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Log.h)12
-rw-r--r--externals/g3dlite/G3D/Map2D.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Map2D.h)40
-rw-r--r--externals/g3dlite/G3D/Matrix.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Matrix.h)2
-rw-r--r--externals/g3dlite/G3D/Matrix2.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Matrix2.h)0
-rw-r--r--externals/g3dlite/G3D/Matrix3.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Matrix3.h)61
-rw-r--r--externals/g3dlite/G3D/Matrix4.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Matrix4.h)67
-rw-r--r--externals/g3dlite/G3D/MemoryManager.h93
-rw-r--r--externals/g3dlite/G3D/MeshAlg.h (renamed from externals/g3dlite/G3D.lib/include/G3D/MeshAlg.h)107
-rw-r--r--externals/g3dlite/G3D/MeshBuilder.h (renamed from externals/g3dlite/G3D.lib/include/G3D/MeshBuilder.h)2
-rw-r--r--externals/g3dlite/G3D/NetAddress.h (renamed from externals/g3dlite/G3D.lib/include/G3D/NetAddress.h)0
-rw-r--r--externals/g3dlite/G3D/NetworkDevice.h (renamed from externals/g3dlite/G3D.lib/include/G3D/NetworkDevice.h)4
-rw-r--r--externals/g3dlite/G3D/ParseError.h59
-rw-r--r--externals/g3dlite/G3D/PhysicsFrame.h (renamed from externals/g3dlite/G3D.lib/include/G3D/PhysicsFrame.h)2
-rw-r--r--externals/g3dlite/G3D/Plane.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Plane.h)2
-rw-r--r--externals/g3dlite/G3D/PointHashGrid.h (renamed from externals/g3dlite/G3D.lib/include/G3D/PointHashGrid.h)65
-rw-r--r--externals/g3dlite/G3D/PointKDTree.h (renamed from externals/g3dlite/G3D.lib/include/G3D/PointAABSPTree.h)30
-rw-r--r--externals/g3dlite/G3D/Pointer.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Pointer.h)71
-rw-r--r--externals/g3dlite/G3D/PositionTrait.h (renamed from externals/g3dlite/G3D.lib/include/G3D/PositionTrait.h)0
-rw-r--r--externals/g3dlite/G3D/PrecomputedRandom.h110
-rw-r--r--externals/g3dlite/G3D/Quat.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Quat.h)8
-rw-r--r--externals/g3dlite/G3D/Quat.inl36
-rw-r--r--externals/g3dlite/G3D/Queue.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Queue.h)13
-rw-r--r--externals/g3dlite/G3D/Random.h139
-rw-r--r--externals/g3dlite/G3D/Ray.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Ray.h)116
-rw-r--r--externals/g3dlite/G3D/Rect2D.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Rect2D.h)126
-rw-r--r--externals/g3dlite/G3D/ReferenceCount.h (renamed from externals/g3dlite/G3D.lib/include/G3D/ReferenceCount.h)101
-rw-r--r--externals/g3dlite/G3D/RegistryUtil.h (renamed from externals/g3dlite/G3D.lib/include/G3D/RegistryUtil.h)0
-rw-r--r--externals/g3dlite/G3D/Set.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Set.h)46
-rw-r--r--externals/g3dlite/G3D/SmallArray.h155
-rw-r--r--externals/g3dlite/G3D/Sphere.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Sphere.h)9
-rw-r--r--externals/g3dlite/G3D/Spline.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Spline.h)10
-rw-r--r--externals/g3dlite/G3D/Stopwatch.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Stopwatch.h)50
-rw-r--r--externals/g3dlite/G3D/System.h (renamed from externals/g3dlite/G3D.lib/include/G3D/System.h)385
-rw-r--r--externals/g3dlite/G3D/Table.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Table.h)526
-rw-r--r--externals/g3dlite/G3D/TextInput.h (renamed from externals/g3dlite/G3D.lib/include/G3D/TextInput.h)214
-rw-r--r--externals/g3dlite/G3D/TextOutput.h (renamed from externals/g3dlite/G3D.lib/include/G3D/TextOutput.h)6
-rw-r--r--externals/g3dlite/G3D/ThreadSet.h (renamed from externals/g3dlite/G3D.lib/include/G3D/ThreadSet.h)12
-rw-r--r--externals/g3dlite/G3D/Triangle.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Triangle.h)25
-rw-r--r--externals/g3dlite/G3D/UprightFrame.h (renamed from externals/g3dlite/G3D.lib/include/G3D/UprightFrame.h)2
-rw-r--r--externals/g3dlite/G3D/Vector2.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Vector2.h)29
-rw-r--r--externals/g3dlite/G3D/Vector2.inl18
-rw-r--r--externals/g3dlite/G3D/Vector2int16.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Vector2int16.h)16
-rw-r--r--externals/g3dlite/G3D/Vector3.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Vector3.h)247
-rw-r--r--externals/g3dlite/G3D/Vector3.inl249
-rw-r--r--externals/g3dlite/G3D/Vector3int16.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Vector3int16.h)29
-rw-r--r--externals/g3dlite/G3D/Vector3int32.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Vector3int32.h)20
-rw-r--r--externals/g3dlite/G3D/Vector4.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Vector4.h)33
-rw-r--r--externals/g3dlite/G3D/Vector4.inl191
-rw-r--r--externals/g3dlite/G3D/Vector4int8.h (renamed from externals/g3dlite/G3D.lib/include/G3D/Vector4int8.h)2
-rw-r--r--externals/g3dlite/G3D/WeakCache.h (renamed from externals/g3dlite/G3D.lib/include/G3D/WeakCache.h)32
-rw-r--r--externals/g3dlite/G3D/Welder.h82
-rw-r--r--externals/g3dlite/G3D/WrapMode.h (renamed from externals/g3dlite/G3D.lib/include/G3D/WrapMode.h)26
-rw-r--r--externals/g3dlite/G3D/constants.h129
-rw-r--r--externals/g3dlite/G3D/debug.h (renamed from externals/g3dlite/G3D.lib/include/G3D/debug.h)2
-rw-r--r--externals/g3dlite/G3D/debugAssert.h (renamed from externals/g3dlite/G3D.lib/include/G3D/debugAssert.h)33
-rw-r--r--externals/g3dlite/G3D/debugPrintf.h (renamed from externals/g3dlite/G3D.lib/include/G3D/debugPrintf.h)2
-rw-r--r--externals/g3dlite/G3D/enumclass.h (renamed from externals/g3dlite/G3D.lib/include/G3D/enumclass.h)20
-rw-r--r--externals/g3dlite/G3D/fileutils.h (renamed from externals/g3dlite/G3D.lib/include/G3D/fileutils.h)52
-rw-r--r--externals/g3dlite/G3D/filter.h (renamed from externals/g3dlite/G3D.lib/include/G3D/filter.h)2
-rw-r--r--externals/g3dlite/G3D/format.h (renamed from externals/g3dlite/G3D.lib/include/G3D/format.h)2
-rw-r--r--externals/g3dlite/G3D/g3dfnmatch.h83
-rw-r--r--externals/g3dlite/G3D/g3dmath.h (renamed from externals/g3dlite/G3D.lib/include/G3D/g3dmath.h)169
-rw-r--r--externals/g3dlite/G3D/g3dmath.inl288
-rw-r--r--externals/g3dlite/G3D/platform.h (renamed from externals/g3dlite/G3D.lib/include/G3D/platform.h)133
-rw-r--r--externals/g3dlite/G3D/prompt.h (renamed from externals/g3dlite/G3D.lib/include/G3D/prompt.h)2
-rw-r--r--externals/g3dlite/G3D/serialize.h (renamed from externals/g3dlite/G3D.lib/include/G3D/serialize.h)0
-rw-r--r--externals/g3dlite/G3D/splinefunc.h (renamed from externals/g3dlite/G3D.lib/include/G3D/splinefunc.h)6
-rw-r--r--externals/g3dlite/G3D/stringutils.h (renamed from externals/g3dlite/G3D.lib/include/G3D/stringutils.h)12
-rw-r--r--externals/g3dlite/G3D/uint128.h (renamed from externals/g3dlite/G3D.lib/include/G3D/uint128.h)2
-rw-r--r--externals/g3dlite/G3D/units.h126
-rw-r--r--externals/g3dlite/G3D/vectorMath.h (renamed from externals/g3dlite/G3D.lib/include/G3D/vectorMath.h)2
-rw-r--r--externals/g3dlite/doc-files/changelog.dox1872
-rw-r--r--externals/g3dlite/doc-files/contributors.dox85
-rw-r--r--externals/g3dlite/doc-files/license.dox120
-rw-r--r--externals/g3dlite/win/VC90/g3dlite.vcproj463
-rw-r--r--externals/g3dlite/win/g3dlite.sln25
-rw-r--r--externals/g3dlite/zip.lib/include/zip/ioapi.h75
-rw-r--r--externals/g3dlite/zip.lib/include/zip/unzip.h354
-rw-r--r--externals/g3dlite/zip.lib/include/zip/zip.h235
-rw-r--r--externals/g3dlite/zip.lib/source/crypt.h132
-rw-r--r--externals/g3dlite/zip.lib/source/ioapi.c177
-rw-r--r--externals/g3dlite/zip.lib/source/iowin32.c272
-rw-r--r--externals/g3dlite/zip.lib/source/iowin32.h23
-rw-r--r--externals/g3dlite/zip.lib/source/unzip.c1604
-rw-r--r--externals/g3dlite/zip.lib/source/zip.c1221
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.h8
-rw-r--r--src/server/collision/CMakeLists.txt5
-rw-r--r--src/server/collision/Management/VMapManager2.h4
-rw-r--r--src/server/collision/Maps/TileAssembler.cpp2
223 files changed, 5779 insertions, 42119 deletions
diff --git a/externals/PackageList.txt b/externals/PackageList.txt
index 52341a01cd4..168d0428983 100644
--- a/externals/PackageList.txt
+++ b/externals/PackageList.txt
@@ -6,7 +6,7 @@ ACE (ADAPTIVE Communication Environment)
bzip2 (a freely available, patent free, high-quality data compressor)
http://www.bzip.org/
-G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License)
+G3D 6.09 (a commercial-grade C++ 3D engine available as Open Source (BSD License)
http://g3d.sourceforge.net/
jemalloc (a general-purpose scalable concurrent malloc-implementation)
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Discovery.h b/externals/g3dlite/G3D.lib/include/G3D/Discovery.h
deleted file mode 100644
index acd1c2c01d0..00000000000
--- a/externals/g3dlite/G3D.lib/include/G3D/Discovery.h
+++ /dev/null
@@ -1,589 +0,0 @@
-/**
- @file Discovery.h
-
- <H2>Discovery</H2>
- Discovery is the process by which computers on a Local Area Network (LAN) find
- one another. The Discovery API allows clients to make a list of servers running
- the same application. The application typically presents this list to the user
- so he can choose which server to connect to.
- <P>
- Features of the Discovery API:
- <P>
- Low network traffic
- <BR> - Broadcasts mainly occur only when a new machine enters/leaves the network
- <BR>Responsive
- <BR> - Servers appear immediately after launching
- <BR> - Servers disappear immedatiately after they shut down
- <BR>Extensible
- <BR> - Add your own game information (e.g. score, num players, map name)
- <BR>Versioned
- <BR> - Tracks incompatible servers so end-users know to upgrade their client/server
-
- <H2>Using the Discovery API</H2>
-
- Subclass DiscoveryAdvertisement to add fields describing a server running your
- application. For a game, these might be the current map name and the number
- of players.
- <P>
- On the client, create an instance of DiscoveryClient<your advertisement subclass>.
- On the server, create an instance of DiscoveryServer and initialize it with an
- instance of your advertisement subclass. From your main loop, call doNetwork()
- on the client and server instances. When your server shuts down, invoke cleanup()
- on it.
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-06-26
- @edited 2008-11-24
- */
-
-#ifndef G3D_DISCOVERY_H
-#define G3D_DISCOVERY_H
-
-#include "G3D/platform.h"
-#include "G3D/G3DGameUnits.h"
-#include "G3D/NetworkDevice.h"
-#include "G3D/Log.h"
-#include <time.h>
-
-/**
- Different versions of G3D discovery protocols can't communicate with each other.
- */
-#define G3D_DISCOVERY_PROTOCOL_NAME "G3D DISC"
-#define G3D_DISCOVERY_PROTOCOL_VERSION 1
-
-namespace G3D {
-
-/**
- If a machine is running two different programs using discovery they
- must have different ports. However different programs can share the
- same ports if they run on the same LAN with different servers.
-
- @deprecated See Discovery2::Settings
- */
-class DiscoverySettings {
-public:
-
- /**
- Name of the program using discovery; used so that mutliple
- programs can use the same discovery ports on the same network.
- */
- const char* appProtocolName;
-
- /**
- Version of the network protocol of the program using discovery.
- Used so that discovery can identify incompatible versions of
- the server.
- */
- int appProtocolVersion;
-
- /**
- Port on which the server broadcasts its identity. The client
- and server must agree on this value.
- */
- uint16 serverBroadcastPort;
-
- /**
- Port on which the client broadcasts a server request. The client
- and server must agree on this value.
- */
- uint16 clientBroadcastPort;
-
- /**
- Clients connect into this port using a reliable conduit
- to receive the advertisement from a server. The client
- doesn't look at this value; it uses whatever the server
- sends it.
- */
- uint16 serverAdvertisementPort;
-
- /**
- You can use the default G3D discovery ports as long as no other
- program with the same protocol name is using this port. You
- <B>can</B> run two different G3D discovery programs on the same
- two ports as long as they have different application protocol
- strings.
- */
- DiscoverySettings(
- const char* _appProtocolName,
- int _appProtocolVersion,
- uint16 _serverBroadcast = 6173,
- uint16 _clientBroadcast = 6174,
- uint16 _serverAdvertisementPort = 6175) :
- appProtocolName(_appProtocolName),
- appProtocolVersion(_appProtocolVersion),
- serverBroadcastPort(_serverBroadcast),
- clientBroadcastPort(_clientBroadcast),
- serverAdvertisementPort(_serverAdvertisementPort) {}
-};
-
-/**
- Make your own subclass of this advertisement. Add fields
- (e.g. numPlayers, currentScore) to increase the amount
- of information advertised.
-
- Overrides must provide a default constructor.
- @deprecated See Discovery2::Settings
- */
-class DiscoveryAdvertisement {
-public:
-
- /**
- Address to connect to on the server for the actual game.
- The IP portion is ignored (the client figures out the IP
- address from the packet itself) but the port is essential.
- Note that this port must not be the discovery port.
- */
- NetAddress address;
-
- /**
- (Only used on the client)
- Time since this advertisement was updated.
- */
- RealTime lastUpdateTime;
-
- /**
- Overrides must call DiscoveryAdvertisement::serialize(b) first.
- */
- virtual void serialize(BinaryOutput& b) const;
-
- /**
- Overrides must call DiscoveryAdvertisement::deserialize(b) first.
- */
- virtual void deserialize(BinaryInput& b);
-
- /**
- An empty virtual destructor for virtual methods.
- */
- virtual ~DiscoveryAdvertisement() {}
-};
-
-
-/**
- Sent by servers to describe their location.
- */
-class DiscoveryServerAddressMessage {
-public:
-
- /**
- Not part of the message; these settings are used to determine
- if the correct protocol is being used.
- */
- const DiscoverySettings* settings;
-
-
- /**
- Set to true if this server is running the correct protocol.
- */
- bool correctProtocol;
-
- /**
- This is set during the serialize process from the server's settings.
- If different from the client's settings the discovery system will
- classify this server as incompatible.
- */
- int serverProtocolVersion[2];
-
- Array<NetAddress> address;
-
- DiscoveryServerAddressMessage() {}
- DiscoveryServerAddressMessage(const DiscoverySettings* s) : settings(s) {}
-
- void serialize(BinaryOutput& b) const;
-
- void deserialize(BinaryInput& b);
-};
-
-
-/**
- Base class for DiscoveryClient and DiscoveryServer.
- */
-class Discovery {
-public:
-
- const DiscoverySettings* settings;
-
- enum {
- SERVER_SHUTDOWN_MESSAGE = 2,
- SERVER_BROADCAST_MESSAGE = 3,
- CLIENT_BROADCAST_MESSAGE = 4};
-
- /**
- Only called from subclasses.
- */
- virtual void init(
- const DiscoverySettings* _settings) {
- settings = _settings;
- }
-
- /**
- An empty virtual destructor for virtual methods.
- */
- virtual ~Discovery() {}
-};
-
-/** @deprecated See Discovery2::Server*/
-class DiscoveryServer : private Discovery {
-private:
-
- class ShutdownMessage {
- public:
- void serialize(BinaryOutput& b) const { (void)b; }
-
- void deserialize(BinaryInput& b) { (void)b; }
- };
-
- /**
- For broadcast.
- */
- LightweightConduitRef net;
-
- /**
- Listen for clients wanting to hear the advertisement over
- a reliable connection.
- */
- NetListenerRef listener;
-
- DiscoveryAdvertisement* advertisement;
-
- /**
- Broadcast across the lightweight conduit.
- */
- DiscoveryServerAddressMessage addressMessage;
-
- /**
- Servers periodically broadcast (unsolicited) in case
- anyone missed the previous message.
- */
- RealTime lastBroadcast;
-
- void sendAnnouncement() const;
-
- void sendShutDown() const;
-
-public:
-
- /**
- You may update the advertisement (synchronously with calling doNetwork)
- after it has been passed in. This allows a server to change the advertised
- number of players or score for a game, for example.
-
- You must set the port of the @a _advertisement G3D::DiscoveryAdvertisement::address
- to the port which the G3D::NetListener for the actual program protocol (not discovery)
- is running. That field how the client knows what address to connect to using
- G3D::ReliableConduit or G3D::LightweightConduit to actually initiate communication.
- */
- virtual void init(
- const DiscoverySettings* _settings,
- DiscoveryAdvertisement* _advertisement);
-
- /** Returns the broadcast address in use.*/
- NetAddress broadcastAddress() const;
-
- /**
- Returns true if this discovery server has been initialized
- and is functioning properly.
- */
- bool ok() const;
-
- /**
- Call periodically to let the server do its job.
- */
- void doNetwork();
-
- /**
- Broadcast a shutdown message.
- */
- void cleanup();
-};
-
-
-/**
- Used by DiscoveryClient to report servers running a different version
- of this application's protocol.
- */
-class IncompatibleServerDescription {
-public:
- NetAddress address;
- int protocolVersion[2];
- RealTime lastUpdateTime;
-
- std::string toString() const;
-};
-
-
-/**
- Only one DiscoveryClient can be active on a given port at a time on
- a single computer.
-
- AdType must be a subclass of DiscoveryAdvertisement.
-
- @deprecated See Discovery2::Client
- */
-template<class AdType>
-class DiscoveryClient : private Discovery {
-public:
-
- /**
- List of servers. Do not access on a second thread while in
- doNetwork.
- */
- Array<AdType> serverList;
-
- /**
- List of servers running the same application but a different protocol.
- It is useful to show these to users to help them recognize version
- conflicts between client and server.
- Do not access on a second thread while in doNetwork.
- */
- Array<IncompatibleServerDescription> incompatibleServerList;
-
-private:
-
- class BroadcastMessage {
- public:
- void serialize(BinaryOutput& b) const {}
-
- void deserialize(BinaryInput& b) {}
- };
-
- /**
- The client periodically checks servers to make sure they are still up
- and to update its information about them.
- */
- RealTime lastServerCheck;
-
- LightweightConduitRef net;
-
- /**
- Returns an index in serverList of the server with the given address.
- Returns -1 if there is none. Only checks IP addresses.
- */
- int findServerListIndex(const NetAddress& addr) const {
- for (int i = 0; i < serverList.size(); ++i) {
- if (addr.ip() == serverList[i].address.ip()) {
- return i;
- }
- }
-
- return -1;
- }
-
- /**
- Returns true if this discovery client has been initialized
- and is functioning properly.
- */
- bool ok() const {
- return net->ok();
- }
-
- /**
- Adds a server to the incompatible list if it is not already there.
- */
- void addToIncompatibleList(const NetAddress& addr, uint32 p0, uint32 p1) {
- const RealTime now = System::time();
-
- bool alreadyHere = false;
-
- // Incorrect protocol; add to the incompatible list
- for (int i = 0; i < incompatibleServerList.size(); ++i) {
- IncompatibleServerDescription& server = incompatibleServerList[i];
-
- if (server.address == addr) {
- server.lastUpdateTime = now;
- alreadyHere = true;
- break;
- }
- }
-
- if (! alreadyHere) {
- IncompatibleServerDescription server;
-
- server.lastUpdateTime = now;
- server.address = addr;
- server.protocolVersion[0] = p0;
- server.protocolVersion[1] = p1;
-
- incompatibleServerList.append(server);
- }
- }
-
- /**
- Connects to the specified server, reads its advertisement,
- and adds it to the active server list. Returns true if the server
- can be reached.
- */
- bool readAdvertisement(const NetAddress& address) {
- std::string hostname = address.toString();
-
- RealTime TIMEOUT = 2.0;
-
- ReliableConduitRef server = ReliableConduit::create(address);
-
- if (! server->ok()) {
- return false;
- }
-
- AdType advertisement;
-
- // Read the advertisement
- RealTime stopWaiting = System::time() + TIMEOUT;
- bool timedOut = false;
-
- while (! server->messageWaiting() && ! timedOut && server->ok()) {
- System::sleep(0.1);
- timedOut = (System::time() > stopWaiting);
- }
-
- if (timedOut) {
- Log::common()->printf("Discovery: Timed out while reading advertisment from %s\n",
- hostname.c_str());
- return false;
- }
-
-
- if (! server->ok()) {
- Log::common()->printf("Discovery: Server %s dropped connection\n", hostname.c_str());
- return false;
- }
-
- // Read the advertisement
- debugAssert(server->messageWaiting());
- if (! server->receive(advertisement)) {
- Log::common()->printf("Discovery: Server %s failed to send advertisement\n", hostname.c_str());
- return false;
- }
-
- // Update existing server info or create a new entry
- int index = findServerListIndex(address);
- if (index == -1) {
- index = serverList.size();
- serverList.resize(index + 1);
- }
-
- // Update element index
- advertisement.address = address;
- serverList[index] = advertisement;
-
- return true;
- }
-
- /**
- Remove this address from our list if we previously
- had a server there.
- */
- void removeServer(const NetAddress& address) {
- int index = findServerListIndex(address);
- if (index > -1) {
- serverList.fastRemove(index);
- }
- }
-
- /**
- Tries to connect to the server through the addresses in the array.
- */
- void addToServerList(const Array<NetAddress>& addressArray) {
- // Try to connect to each address listed
- for (int a = addressArray.size() - 1; a >= 0; --a) {
- const NetAddress& address = addressArray[a];
-
- if (readAdvertisement(address)) {
- // We've connected to the server
- break;
- } else {
- removeServer(address);
- }
- }
- }
-
- void checkRandomServer() {
- if (serverList.size() >= 1) {
- int index = iRandom(0, serverList.size() - 1);
-
- Array<NetAddress> address;
- address.append(serverList[index].address);
-
- // Remove this server
- serverList.fastRemove(index);
-
- // Add it back with new info (or leave it removed if no response)
- addToServerList(address);
- }
- }
-
-public:
-
- void init(
- const DiscoverySettings* _settings) {
-
- Discovery::init(_settings);
-
- lastServerCheck = System::time();
-
- net = LightweightConduit::create(settings->serverBroadcastPort, true, true);
-
- // Send announcement
- NetAddress broadcast(NetworkDevice::instance()->broadcastAddressArray()[0],
- settings->clientBroadcastPort);
- BroadcastMessage tmp;
- net->send(broadcast, CLIENT_BROADCAST_MESSAGE, tmp);
- }
-
- /** Shut down the discovery client. */
- void cleanup() {
- net = NULL;
- }
-
- /**
- Call this regularly (several times per second) to
- update the server list. Not threadsafe-- you must not touch
- the server list while this is running. This will not block.
- */
- void doNetwork() {
- if (net->messageWaiting()) {
- NetAddress sender;
-
- switch (net->waitingMessageType()) {
- case SERVER_SHUTDOWN_MESSAGE:
- // Remove the server
- net->receive(sender);
- removeServer(sender);
- break;
-
- case SERVER_BROADCAST_MESSAGE:
- // Check the G3D protocol and the network protocol, then read the ad
- DiscoveryServerAddressMessage msg(settings);
- net->receive(sender, msg);
-
- if (msg.correctProtocol && (msg.address.size() > 0)) {
- // Add the actual return address as the first one to be tried.
- msg.address.append(NetAddress(sender.ip(), msg.address[0].port()));
-
- addToServerList(msg.address);
-
- } else {
-
- addToIncompatibleList(
- sender,
- msg.serverProtocolVersion[0],
- msg.serverProtocolVersion[1]);
- }
- break;
- }
- }
-
- // Periodically re-check servers in the list to see if they crashed
- // (if they shut down, they should have broadcast a shut down message).
- RealTime now = System::time();
- const RealTime UPDATE_TIME_INTERVAL = 30;
-
- if (now > lastServerCheck + UPDATE_TIME_INTERVAL) {
- lastServerCheck = now;
- checkRandomServer();
- }
- }
-};
-
-}
-
-#endif
diff --git a/externals/g3dlite/G3D.lib/source/AABox.cpp b/externals/g3dlite/G3D.lib/source/AABox.cpp
deleted file mode 100644
index 9e871aa8af7..00000000000
--- a/externals/g3dlite/G3D.lib/source/AABox.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/**
- @file AABox.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2004-01-10
- @edited 2006-01-11
-*/
-
-#include "G3D/platform.h"
-#include "G3D/AABox.h"
-#include "G3D/Box.h"
-#include "G3D/Plane.h"
-#include "G3D/Sphere.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-
-namespace G3D {
-
-
-void AABox::serialize(class BinaryOutput& b) const {
- b.writeVector3(lo);
- b.writeVector3(hi);
-}
-
-
-void AABox::deserialize(class BinaryInput& b) {
- lo = b.readVector3();
- hi = b.readVector3();
-}
-
-
-void AABox::split(const Vector3::Axis& axis, float location, AABox& low, AABox& high) const {
- // Low, medium, and high along the chosen axis
- float L = G3D::min(location, lo[axis]);
- float M = G3D::min(G3D::max(location, lo[axis]), hi[axis]);
- float H = G3D::max(location, hi[axis]);
-
- // Copy over this box.
- high = low = *this;
-
- // Now move the split points along the special axis
- low.lo[axis] = L;
- low.hi[axis] = M;
- high.lo[axis] = M;
- high.hi[axis] = H;
-}
-
-
-Vector3 AABox::randomSurfacePoint() const {
- Vector3 extent = hi - lo;
- float aXY = extent.x * extent.y;
- float aYZ = extent.y * extent.z;
- float aZX = extent.z * extent.x;
-
- float r = (float)uniformRandom(0.0f, aXY + aYZ + aZX);
-
- // Choose evenly between positive and negative face planes
- float d = ((float)uniformRandom(0, 1) < 0.5f) ? 0.0f : 1.0f;
-
- // The probability of choosing a given face is proportional to
- // its area.
- if (r < aXY) {
- return
- lo +
- Vector3(
- (float)uniformRandom(0.0f, extent.x),
- (float)uniformRandom(0.0f, extent.y),
- d * extent.z);
- } else if (r < aYZ) {
- return
- lo +
- Vector3(
- d * extent.x,
- (float)uniformRandom(0, extent.y),
- (float)uniformRandom(0, extent.z));
- } else {
- return
- lo +
- Vector3(
- (float)uniformRandom(0, extent.x),
- d * extent.y,
- (float)uniformRandom(0, extent.z));
- }
-}
-
-
-Vector3 AABox::randomInteriorPoint() const {
- return Vector3(
- (float)uniformRandom(lo.x, hi.x),
- (float)uniformRandom(lo.y, hi.y),
- (float)uniformRandom(lo.z, hi.z));
-}
-
-
-bool AABox::intersects(const AABox& other) const {
- // Must be overlap along all three axes.
- // Try to find a separating axis.
-
- for (int a = 0; a < 3; ++a) {
-
- // |--------|
- // |------|
-
- if ((lo[a] > other.hi[a]) ||
- (hi[a] < other.lo[a])) {
- return false;
- }
- }
-
- return true;
-}
-
-int AABox::dummy = 0;
-
-
-bool AABox::culledBy(
- const Array<Plane>& plane,
- int& cullingPlane,
- const uint32 _inMask,
- uint32& childMask) const {
-
- uint32 inMask = _inMask;
- assert(plane.size() < 31);
-
- childMask = 0;
-
- const bool finite =
- (abs(lo.x) < G3D::inf()) &&
- (abs(hi.x) < G3D::inf()) &&
- (abs(lo.y) < G3D::inf()) &&
- (abs(hi.y) < G3D::inf()) &&
- (abs(lo.z) < G3D::inf()) &&
- (abs(hi.z) < G3D::inf());
-
- // See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < plane.size(); ++p) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
-
- Vector3 corner;
-
- int numContained = 0;
- int v = 0;
-
- // We can early-out only if we have found one point on each
- // side of the plane (i.e. if we are straddling). That
- // occurs when (numContained < v) && (numContained > 0)
- for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) {
- // Unrolling these 3 if's into a switch decreases performance
- // by about 2x
- corner.x = (v & 1) ? hi.x : lo.x;
- corner.y = (v & 2) ? hi.y : lo.y;
- corner.z = (v & 4) ? hi.z : lo.z;
-
- if (finite) { // this branch is highly predictable
- if (plane[p].halfSpaceContainsFinite(corner)) {
- ++numContained;
- }
- } else {
- if (plane[p].halfSpaceContains(corner)) {
- ++numContained;
- }
- }
- }
-
- if (numContained == 0) {
- // Plane p culled the box
- cullingPlane = p;
-
- // The caller should not recurse into the children,
- // since the parent is culled. If they do recurse,
- // make them only test against this one plane, which
- // will immediately cull the volume.
- childMask = 1 << p;
- return true;
-
- } else if (numContained < v) {
- // The bounding volume straddled the plane; we have
- // to keep testing against this plane
- childMask |= (1 << p);
- }
- }
-
- // Move on to the next bit.
- inMask = inMask >> 1;
- }
-
- // None of the planes could cull this box
- cullingPlane = -1;
- return false;
-}
-
-
-bool AABox::culledBy(
- const Array<Plane>& plane,
- int& cullingPlane,
- const uint32 _inMask) const {
-
- uint32 inMask = _inMask;
- assert(plane.size() < 31);
-
- const bool finite =
- (abs(lo.x) < G3D::inf()) &&
- (abs(hi.x) < G3D::inf()) &&
- (abs(lo.y) < G3D::inf()) &&
- (abs(hi.y) < G3D::inf()) &&
- (abs(lo.z) < G3D::inf()) &&
- (abs(hi.z) < G3D::inf());
-
- // See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < plane.size(); ++p) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
-
- bool culled = true;
- Vector3 corner;
-
- int v;
-
- // Assume this plane culls all points. See if there is a point
- // not culled by the plane... early out when at least one point
- // is in the positive half space.
- for (v = 0; (v < 8) && culled; ++v) {
-
- // Unrolling these 3 if's into a switch decreases performance
- // by about 2x
- corner.x = (v & 1) ? hi.x : lo.x;
- corner.y = (v & 2) ? hi.y : lo.y;
- corner.z = (v & 4) ? hi.z : lo.z;
-
- if (finite) { // this branch is highly predictable
- culled = ! plane[p].halfSpaceContainsFinite(corner);
- } else {
- culled = ! plane[p].halfSpaceContains(corner);
- }
- }
-
- if (culled) {
- // Plane p culled the box
- cullingPlane = p;
-
- return true;
- }
- }
-
- // Move on to the next bit.
- inMask = inMask >> 1;
- }
-
- // None of the planes could cull this box
- cullingPlane = -1;
- return false;
-}
-
-
-bool AABox::intersects(const class Sphere& sphere) const {
- double d = 0;
-
- //find the square of the distance
- //from the sphere to the box
- for (int i = 0; i < 3; ++i) {
- if (sphere.center[i] < lo[i]) {
- d += square(sphere.center[i] - lo[i]);
- } else if (sphere.center[i] > hi[i]) {
- d += square(sphere.center[i] - hi[i]);
- }
- }
-
- return d <= square(sphere.radius);
-}
-
-Vector3 AABox::corner(int index) const {
-
- // default constructor inits all components to 0
- Vector3 v;
-
- switch (index)
- {
- case 0:
- v.x = lo.x;
- v.y = lo.y;
- v.z = hi.z;
- break;
-
- case 1:
- v.x = hi.x;
- v.y = lo.y;
- v.z = hi.z;
- break;
-
- case 2:
- v.x = hi.x;
- v.y = hi.y;
- v.z = hi.z;
- break;
-
- case 3:
- v.x = lo.x;
- v.y = hi.y;
- v.z = hi.z;
- break;
-
- case 4:
- v.x = lo.x;
- v.y = lo.y;
- v.z = lo.z;
- break;
-
- case 5:
- v.x = hi.x;
- v.y = lo.y;
- v.z = lo.z;
- break;
-
- case 6:
- v.x = hi.x;
- v.y = hi.y;
- v.z = lo.z;
- break;
-
- case 7:
- v.x = lo.x;
- v.y = hi.y;
- v.z = lo.z;
- break;
-
- default:
- debugAssertM(false, "Invalid corner index");
- break;
- }
-
- return v;
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/AnyVal.cpp b/externals/g3dlite/G3D.lib/source/AnyVal.cpp
deleted file mode 100644
index 45fb41df534..00000000000
--- a/externals/g3dlite/G3D.lib/source/AnyVal.cpp
+++ /dev/null
@@ -1,1381 +0,0 @@
-/**
- @file AnyVal.cpp
- @author Morgan McGuire
- @maintainer Morgan McGuire
- @created 2006-06-11
- @edited 2008-07-14
- */
-
-#include "G3D/AnyVal.h"
-#include "G3D/Array.h"
-#include "G3D/stringutils.h"
-#include "G3D/Table.h"
-#include "G3D/Vector2.h"
-#include "G3D/Vector3.h"
-#include "G3D/Vector4.h"
-#include "G3D/Color1.h"
-#include "G3D/Color3.h"
-#include "G3D/Color4.h"
-#include "G3D/Matrix2.h"
-#include "G3D/Matrix3.h"
-#include "G3D/Matrix4.h"
-#include "G3D/Rect2D.h"
-#include "G3D/AABox.h"
-#include "G3D/CoordinateFrame.h"
-#include "G3D/Quat.h"
-#include "G3D/TextInput.h"
-#include "G3D/TextOutput.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-AnyVal AnyVal::fromFile(const std::string& filename) {
- TextInput t(filename);
- return AnyVal(t);
-}
-
-
-void AnyVal::load(const std::string& filename) {
- *this = fromFile(filename);
-}
-
-
-void AnyVal::save(const std::string& filename) const {
- TextOutput t(filename);
- serialize(t);
- t.commit();
-}
-
-
-AnyVal::AnyVal() : m_type(NIL), m_value(NULL), m_referenceCount(NULL) {
-}
-
-
-AnyVal::AnyVal(bool b) : m_type(BOOLEAN), m_value(new bool(b)), m_referenceCount(NULL) {
-}
-
-
-AnyVal::AnyVal(G3D::TextInput& t) : m_type(NIL), m_value(NULL), m_referenceCount(NULL) {
- deserialize(t);
-}
-
-
-/*AnyVal::AnyVal(G3D::BinaryInput& b) {
- deserialize(b);
-}
-*/
-
-AnyVal::AnyVal(double v) : m_type(NUMBER), m_referenceCount(NULL) {
- m_value = new double(v);
-}
-
-
-AnyVal::AnyVal(int v) : m_type(NUMBER), m_referenceCount(NULL) {
- m_value = new double(v);
-}
-
-
-AnyVal::AnyVal(const Rect2D& v) : m_type(RECT2D), m_referenceCount(NULL) {
- m_value = new Rect2D(v);
-}
-
-
-AnyVal::AnyVal(const AABox& v) : m_type(AABOX), m_referenceCount(NULL) {
- m_value = new AABox(v);
-}
-
-
-AnyVal::AnyVal(const Vector2& v) : m_type(VECTOR2), m_referenceCount(NULL) {
- m_value = new Vector2(v);
-}
-
-
-AnyVal::AnyVal(const Vector3& v) : m_type(VECTOR3), m_referenceCount(NULL) {
- m_value = new Vector3(v);
-}
-
-
-AnyVal::AnyVal(const Vector4& v) : m_type(VECTOR4), m_referenceCount(NULL) {
- m_value = new Vector4(v);
-}
-
-
-AnyVal::AnyVal(const Color1& v) : m_type(COLOR1), m_referenceCount(NULL) {
- m_value = new Color1(v);
-}
-
-
-AnyVal::AnyVal(const Color3& v) : m_type(COLOR3), m_referenceCount(NULL) {
- m_value = new Color3(v);
-}
-
-
-AnyVal::AnyVal(const Color4& v) : m_type(COLOR4), m_referenceCount(NULL) {
- m_value = new Color4(v);
-}
-
-
-AnyVal::AnyVal(const std::string& v) : m_type(STRING), m_referenceCount(NULL) {
- m_value = new std::string(v);
-}
-
-
-AnyVal::AnyVal(const char* v) : m_type(STRING), m_referenceCount(NULL) {
- m_value = new std::string(v);
-}
-
-
-AnyVal::AnyVal(const Quat& v) : m_type(QUAT), m_referenceCount(NULL) {
- m_value = new Quat(v);
-}
-
-
-AnyVal::AnyVal(const CoordinateFrame& v) : m_type(COORDINATEFRAME), m_referenceCount(NULL) {
- m_value = new CoordinateFrame(v);
-}
-
-
-AnyVal::AnyVal(const Matrix2& v) : m_type(MATRIX2), m_referenceCount(NULL) {
- m_value = new Matrix2(v);
-}
-
-AnyVal::AnyVal(const Matrix3& v) : m_type(MATRIX3), m_referenceCount(NULL) {
- m_value = new Matrix3(v);
-}
-
-
-AnyVal::AnyVal(const Matrix4& v) : m_type(MATRIX4), m_referenceCount(NULL) {
- m_value = new Matrix4(v);
-}
-
-
-AnyVal::AnyVal(const AnyVal& c) : m_type(NIL), m_value(NULL), m_referenceCount(NULL) {
- *this = c;
-}
-
-
-AnyVal::AnyVal(Type arrayOrTable) : m_type(NIL), m_value(NULL), m_referenceCount(new int(1)) {
- // TODO: make AnyVal::createArray()
- switch (arrayOrTable) {
- case ARRAY:
- m_type = ARRAY;
- m_value = new Array<AnyVal>();
- break;
-
- case TABLE:
- m_type = TABLE;
- m_value = new Table<std::string, AnyVal>();
- break;
-
- default:
- debugAssertM(false, "Cannot construct AnyVal from constants except ARRAY or TABLE.");
- }
-}
-
-
-AnyVal::~AnyVal() {
- deleteValue();
-}
-
-
-void AnyVal::deleteValue() {
- if (m_referenceCount) {
- --(*m_referenceCount);
- if (*m_referenceCount <= 0) {
- delete m_referenceCount;
- m_referenceCount = NULL;
- // Pass through and delete the real object now
- } else {
- // Someone else is holding a reference, so we can't delete
- // the object.
- m_referenceCount = NULL;
- return;
- }
- }
-
- switch (m_type) {
- case NIL:
- // Nothing to do
- break;
-
- case NUMBER:
- delete (double*)m_value;
- break;
-
- case BOOLEAN:
- delete (bool*)m_value;
- break;
-
- case STRING:
- delete (std::string*)m_value;
- break;
-
- case RECT2D:
- delete (Rect2D*)m_value;
- break;
-
- case AABOX:
- delete (AABox*)m_value;
- break;
-
- case VECTOR2:
- delete (Vector2*)m_value;
- break;
-
- case VECTOR3:
- delete (Vector3*)m_value;
- break;
-
- case VECTOR4:
- delete (Vector4*)m_value;
- break;
-
- case MATRIX2:
- delete (Matrix2*)m_value;
- break;
-
- case MATRIX3:
- delete (Matrix3*)m_value;
- break;
-
- case MATRIX4:
- delete (Matrix4*)m_value;
- break;
-
- case QUAT:
- delete (Quat*)m_value;
- break;
-
- case COORDINATEFRAME:
- delete (CoordinateFrame*)m_value;
- break;
-
- case COLOR1:
- delete (Color1*)m_value;
- break;
-
- case COLOR3:
- delete (Color3*)m_value;
- break;
-
- case COLOR4:
- delete (Color4*)m_value;
- break;
-
- case ARRAY:
- delete (Array<AnyVal>*)m_value;
- break;
-
- case TABLE:
- delete (Table<std::string, AnyVal>*)m_value;
- break;
-
- default:
- debugAssertM(false, "Internal error: no destructor for this type.");
- }
-
- m_value = NULL;
-}
-
-
-AnyVal& AnyVal::operator=(const AnyVal& v) {
- deleteValue();
-
- m_type = v.m_type;
-
- m_referenceCount = v.m_referenceCount;
-
- if (isSharedType()) {
- ++(*m_referenceCount);
- m_value = v.m_value;
- } else {
- m_value = v.copyValue();
- }
-
- return *this;
-}
-
-
-void* AnyVal::copyValue() const {
- switch (m_type) {
- case NIL:
- return NULL;
-
- case NUMBER:
- return new double(*(double*)m_value);
-
- case BOOLEAN:
- return new bool(*(bool*)m_value);
-
- case STRING:
- return new std::string(*(std::string*)m_value);
-
- case RECT2D:
- return new Rect2D(*(Rect2D*)m_value);
-
- case AABOX:
- return new AABox(*(AABox*)m_value);
-
- case VECTOR2:
- return new Vector2(*(Vector2*)m_value);
-
- case VECTOR3:
- return new Vector3(*(Vector3*)m_value);
-
- case VECTOR4:
- return new Vector4(*(Vector4*)m_value);
-
- case MATRIX2:
- return new Matrix2(*(Matrix2*)m_value);
-
- case MATRIX3:
- return new Matrix3(*(Matrix3*)m_value);
-
- case MATRIX4:
- return new Matrix4(*(Matrix4*)m_value);
-
- case QUAT:
- return new Quat(*(Quat*)m_value);
-
- case COORDINATEFRAME:
- return new CoordinateFrame(*(CoordinateFrame*)m_value);
-
- case COLOR1:
- return new Color1(*(Color1*)m_value);
-
- case COLOR3:
- return new Color3(*(Color3*)m_value);
-
- case COLOR4:
- return new Color4(*(Color4*)m_value);
-
- case ARRAY:
- return new Array<AnyVal>(*(Array<AnyVal>*)m_value);
-
- case TABLE:
- return new Table<std::string, AnyVal>(*(Table<std::string, AnyVal>*)m_value);
-
- default:
- debugAssertM(false, "Internal error: no assignment operator for this type.");
- return NULL;
- }
-}
-
-AnyVal::Type AnyVal::type() const {
- return m_type;
-}
-
-
-static bool legalIdentifier(const std::string& s) {
- if (s.size() == 0) {
- return false;
- }
-
- if (! isLetter(s[0]) || (s[0] == '_')) {
- return false;
- }
-
- bool ok = true;
-
- for (unsigned int i = 1; i < s.size(); ++i) {
- ok &= isDigit(s[i]) || isLetter(s[i]) || (s[i] == '_');
- }
-
- return ok;
-}
-
-
-void AnyVal::serialize(G3D::TextOutput& t) const {
- switch (m_type) {
- case NIL:
- t.writeSymbol("Nil");
- break;
-
- case NUMBER:
- t.printf("%g", *(double*)m_value);
- break;
-
- case BOOLEAN:
- t.writeBoolean(*(bool*)m_value);
- break;
-
- case STRING:
- t.writeString(*(std::string*)m_value);
- break;
-
- case RECT2D:
- t.printf("R(%g, %g, %g, %g)", ((Rect2D*)m_value)->x0(), ((Rect2D*)m_value)->y0(),
- ((Rect2D*)m_value)->width(), ((Rect2D*)m_value)->height());
- break;
-
- case AABOX:
- t.printf("AAB(V3(%g, %g, %g), V3(%g, %g, %g))",
- aabox().low().x,
- aabox().low().y,
- aabox().low().z,
- aabox().high().x,
- aabox().high().y,
- aabox().high().z);
- break;
-
- case VECTOR2:
- t.printf("V2(%g, %g)", ((Vector2*)m_value)->x, ((Vector2*)m_value)->y);
- break;
-
- case VECTOR3:
- t.printf("V3(%g, %g, %g)", ((Vector3*)m_value)->x, ((Vector3*)m_value)->y, ((Vector3*)m_value)->z);
- break;
-
- case VECTOR4:
- t.printf("V4(%g, %g, %g, %g)", ((Vector4*)m_value)->x, ((Vector4*)m_value)->y, ((Vector4*)m_value)->z, ((Vector4*)m_value)->w);
- break;
-
- case MATRIX2:
- {
- const Matrix2& m = *(Matrix2*)m_value;
- t.printf("M2(\n");
- t.pushIndent();
- t.printf("%10.5f, %10.5f,\n%10.5f, %10.5f)",
- m[0][0], m[0][1],
- m[1][0], m[1][1]);
- t.popIndent();
- }
- break;
-
- case MATRIX3:
- {
- const Matrix3& m = *(Matrix3*)m_value;
- t.printf("M3(\n");
- t.pushIndent();
- t.printf("%10.5f, %10.5f, %10.5f,\n%10.5f, %10.5f, %10.5f,\n%10.5f, %10.5f, %10.5f)",
- m[0][0], m[0][1], m[0][2],
- m[1][0], m[1][1], m[1][2],
- m[2][0], m[2][1], m[2][2]);
- t.popIndent();
- }
- break;
-
- case MATRIX4:
- {
- const Matrix4& m = *(Matrix4*)m_value;
- t.printf("M4(\n");
- t.pushIndent();
- t.printf(
- "%10.5f, %10.5f, %10.5f, %10.5f,\n"
- "%10.5f, %10.5f, %10.5f, %10.5f,\n"
- "%10.5f, %10.5f, %10.5f, %10.5f,\n"
- "%10.5f, %10.5f, %10.5f, %10.5f)",
- m[0][0], m[0][1], m[0][2], m[0][3],
- m[1][0], m[1][1], m[1][2], m[1][3],
- m[2][0], m[2][1], m[2][2], m[2][3],
- m[3][0], m[3][1], m[3][2], m[3][3]);
- t.popIndent();
- }
- break;
-
- case QUAT:
- t.printf("Q(%g, %g, %g, %g)", ((Quat*)m_value)->x, ((Quat*)m_value)->y, ((Quat*)m_value)->z, ((Quat*)m_value)->w);
- break;
-
- case COORDINATEFRAME:
- {
- const CoordinateFrame& c = *(CoordinateFrame*)m_value;
- float x,y,z,yaw,pitch,roll;
- c.getXYZYPRDegrees(x,y,z,yaw,pitch,roll);
- t.printf("CF(V3(%g,%g,%g), %g, %g, %g)", x, y, z, yaw, pitch, roll);
- /*
- t.pushIndent();
- t.printf(
- "CF(\n%10.5f, %10.5f, %10.5f, %10.5f,\n"
- "%10.5f, %10.5f, %10.5f, %10.5f,\n"
- "%10.5f, %10.5f, %10.5f, %10.5f)",
- c.rotation[0][0], c.rotation[0][1], c.rotation[0][2], c.translation.x,
- c.rotation[1][0], c.rotation[1][1], c.rotation[1][2], c.translation.y,
- c.rotation[2][0], c.rotation[2][1], c.rotation[2][2], c.translation.z);
- t.popIndent();
- */
- }
- break;
-
- case COLOR1:
- t.printf("C1(%g)", ((Color1*)m_value)->value);
- break;
-
- case COLOR3:
- t.printf("C3(%g, %g, %g)", ((Color3*)m_value)->r, ((Color3*)m_value)->g, ((Color3*)m_value)->b);
- break;
-
- case COLOR4:
- t.printf("C4(%g, %g, %g, %g)", ((Color4*)m_value)->r, ((Color4*)m_value)->g, ((Color4*)m_value)->b, ((Color4*)m_value)->a);
- break;
-
- case ARRAY:
- {
- const Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
- t.printf("[\n");
- t.pushIndent();
- for (int i = 0; i < a.size(); ++i) {
- a[i].serialize(t);
- if (i != a.size() - 1) {
- t.printf(", \n");
- }
- }
- t.printf("]");
- t.popIndent();
- }
- break;
-
- case TABLE:
- {
- const Table<std::string, AnyVal>& a = *(Table<std::string, AnyVal>*)m_value;
- t.printf("{\n");
- t.pushIndent();
- Table<std::string, AnyVal>::Iterator i = a.begin();
- const Table<std::string, AnyVal>::Iterator end = a.end();
- while (i != end) {
- // Quote names that are not legal C++ identifiers
- if (! legalIdentifier(i->key)) {
- t.printf("'%s' ", i->key.c_str());
- } else {
- t.writeSymbol(i->key);
- }
- t.printf("= ");
-
- i->value.serialize(t);
-
- if (i != end) {
- t.printf("\n");
- }
- ++i;
- }
- t.popIndent();
- t.printf("}");
- }
- break;
-
- default:
- debugAssertM(false, "Internal error: no serialize method for this type.");
- }
-}
-
-
-std::string AnyVal::toString() const {
- TextOutput t;
- serialize(t);
- std::string s;
- t.commitString(s);
- return s;
-}
-
-/*
-void AnyVal::serialize(G3D::BinaryOutput& t) const {
- alwaysAssertM(false, "TODO");
-}
-*/
-
-void AnyVal::deserialize(G3D::TextInput& t) {
- deleteValue();
- m_type = NIL;
- m_value = NULL;
-
- if (! t.hasMore()) {
- return;
- }
-
- switch (t.peek().type()) {
- case Token::END:
- // should never get here because of the hasMore check above
- return;
- break;
-
- case Token::NUMBER:
- m_type = NUMBER;
- m_value = new double(t.readNumber());
- break;
-
- case Token::STRING:
- m_type = STRING;
- m_value = new std::string(t.readString());
- break;
-
- case Token::BOOLEAN:
- m_type = BOOLEAN;
- m_value = new bool(t.readBoolean());
- break;
-
- case Token::SYMBOL:
- {
- std::string s = t.readSymbol();
- if (s == "NIL") {
- break;
-
- } else if (s == "true") {
-
- m_type = BOOLEAN;
- m_value = new bool(true);
-
- } else if (s == "false") {
-
- m_type = BOOLEAN;
- m_value = new bool(false);
-
- } else if (s == "R") {
-
- m_type = RECT2D;
- t.readSymbol("(");
- float x,y,w,h;
- x = (float)t.readNumber();
- t.readSymbol(",");
- y = (float)t.readNumber();
- t.readSymbol(",");
- w = (float)t.readNumber();
- t.readSymbol(",");
- h = (float)t.readNumber();
- t.readSymbol(")");
- m_value = new Rect2D(Rect2D::xywh(x, y, w, h));
-
- } else if (s == "AAB") {
-
- m_type = AABOX;
- Vector3 v[2];
- t.readSymbol("(");
- for (int i = 0; i < 2; ++i) {
- t.readSymbols("V3", "(");
- v[i].x = (float)t.readNumber();
- t.readSymbol(",");
- v[i].y = (float)t.readNumber();
- t.readSymbol(",");
- v[i].z = (float)t.readNumber();
- t.readSymbol(",");
- if (i == 0) {
- t.readSymbol(",");
- }
- }
- t.readSymbol(")");
- m_value = new AABox(v[0], v[1]);
-
- } else if (s == "V2") {
-
- t.readSymbol("(");
- Vector2 v;
- v.x = (float)t.readNumber();
- t.readSymbol(",");
- v.y = (float)t.readNumber();
- t.readSymbol(")");
- m_value = new Vector2(v);
- m_type = VECTOR2;
-
- } else if (s == "V3") {
-
- t.readSymbol("(");
- Vector3 v;
- v.x = (float)t.readNumber();
- t.readSymbol(",");
- v.y = (float)t.readNumber();
- t.readSymbol(",");
- v.z = (float)t.readNumber();
- t.readSymbol(")");
- m_value = new Vector3(v);
- m_type = VECTOR3;
-
- } else if (s == "V4") {
-
- t.readSymbol("(");
- Vector4 v;
- v.x = (float)t.readNumber();
- t.readSymbol(",");
- v.y = (float)t.readNumber();
- t.readSymbol(",");
- v.z = (float)t.readNumber();
- t.readSymbol(",");
- v.w = (float)t.readNumber();
- t.readSymbol(")");
- m_value = new Vector4(v);
- m_type = VECTOR4;
-
- } else if (s == "M2") {
-
- t.readSymbol("(");
- Matrix2 m;
- for (int r = 0; r < 2; ++r) {
- for (int c = 0; c < 2; ++c) {
- m[r][c] = (float)t.readNumber();
- if ((c != 1) || (r != 1)) {
- t.readSymbol(",");
- }
- }
- }
- t.readSymbol(")");
- m_value = new Matrix2(m);
- m_type = MATRIX2;
-
- } else if (s == "M3") {
-
- t.readSymbol("(");
- Matrix3 m;
- for (int r = 0; r < 3; ++r) {
- for (int c = 0; c < 3; ++c) {
- m[r][c] = (float)t.readNumber();
- if ((c != 2) || (r != 2)) {
- t.readSymbol(",");
- }
- }
- }
- t.readSymbol(")");
- m_value = new Matrix3(m);
- m_type = MATRIX3;
-
- } else if (s == "M4") {
-
- t.readSymbol("(");
- Matrix4 m;
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- m[r][c] = (float)t.readNumber();
- if ((c != 3) || (r != 3)) {
- t.readSymbol(",");
- }
- }
- }
- t.readSymbol(")");
- m_value = new Matrix4(m);
- m_type = MATRIX4;
-
- } else if (s == "Q") {
-
- t.readSymbol("(");
- Quat q;
- q.x = (float)t.readNumber();
- t.readSymbol(",");
- q.y = (float)t.readNumber();
- t.readSymbol(",");
- q.z = (float)t.readNumber();
- t.readSymbol(",");
- q.w = (float)t.readNumber();
- t.readSymbol(")");
- m_value = new Quat(q);
- m_type = QUAT;
-
- } else if (s == "CF") {
-
- t.readSymbol("(");
- CoordinateFrame m;
- if (t.peek().type() == Token::SYMBOL) {
- // Angle format
- float x, y, z, yaw, roll, pitch;
- t.readSymbols("V3", "(");
- x = (float)t.readNumber();
- t.readSymbol(",");
- y = (float)t.readNumber();
- t.readSymbol(",");
- z = (float)t.readNumber();
- t.readSymbols(")", ",");
- yaw = (float)t.readNumber();
- t.readSymbol(",");
- pitch = (float)t.readNumber();
- roll = 0;
- if (t.peek().string() == ",") {
- t.readSymbol(",");
- roll = (float)t.readNumber();
- }
- m = CoordinateFrame::fromXYZYPRDegrees(x, y, z, yaw, pitch, roll);
- } else {
- // Matrix format
- for (int r = 0; r < 3; ++r) {
- for (int c = 0; c < 3; ++c) {
- m.rotation[r][c] = (float)t.readNumber();
- }
- m.translation[r] = (float)t.readNumber();
- if (r != 2) {
- t.readSymbol(",");
- }
- }
- }
- t.readSymbol(")");
- m_value = new CoordinateFrame(m);
- m_type = COORDINATEFRAME;
-
- } else if (s == "C1") {
-
- t.readSymbol("(");
- float v = (float)t.readNumber();
- t.readSymbol(")");
- m_value = new Color1(v);
- m_type = COLOR1;
-
- } else if (s == "C3") {
-
- t.readSymbol("(");
- Color3 c;
- c.r = (float)t.readNumber();
- t.readSymbol(",");
- c.g = (float)t.readNumber();
- t.readSymbol(",");
- c.b = (float)t.readNumber();
- t.readSymbol(")");
- m_value = new Color3(c);
- m_type = COLOR3;
-
- } else if (s == "C4") {
-
- t.readSymbol("(");
- Color4 c;
- c.r = (float)t.readNumber();
- t.readSymbol(",");
- c.g = (float)t.readNumber();
- t.readSymbol(",");
- c.b = (float)t.readNumber();
- t.readSymbol(",");
- c.a = (float)t.readNumber();
- t.readSymbol(")");
- m_value = new Color4(c);
- m_type = COLOR4;
-
- } else if (s == "[") {
-
- // Array
- m_type = ARRAY;
- m_value = new Array<AnyVal>();
- m_referenceCount = new int(1);
- Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
-
- Token peek = t.peek();
- while ((peek.type() != Token::SYMBOL) || (peek.string() != "]")) {
- // Avoid copying large objects
- a.next().deserialize(t);
-
- peek = t.peek();
- if (peek.type() != Token::SYMBOL) {
- throw CorruptText("Expected ',' or ']'", peek);
- } else if (peek.string() == ",") {
- t.readSymbol(",");
- } else if (peek.string() != "]") {
- throw CorruptText("Missing ']'", peek);
- }
- }
- t.readSymbol("]");
-
- } else if (s == "{") {
-
- // Table
- m_type = TABLE;
- m_value = new Table<std::string, AnyVal>();
- m_referenceCount = new int(1);
- Table<std::string, AnyVal>& a = *(Table<std::string, AnyVal>*)m_value;
-
- Token peek = t.peek();
- while ((peek.type() != Token::SYMBOL) || (peek.string() != "}")) {
-
- std::string key;
- // Get the name
- if (peek.type() == Token::SYMBOL) {
- key = t.readSymbol();
- } else if (peek.extendedType() == Token::SINGLE_QUOTED_TYPE) {
- key = t.readString();
- } else {
- throw CorruptText("Expected name inside table", peek);
- }
-
- t.readSymbol("=");
-
- // Avoid copying large values
- a.set(key, AnyVal());
- a[key].deserialize(t);
-
- peek = t.peek();
- if ((peek.type() != Token::SYMBOL) && (peek.extendedType() == Token::SINGLE_QUOTED_TYPE)) {
- throw CorruptText("Missing expected name or '}'", peek);
- }
- }
- t.readSymbol("}");
-
- } else {
- throw CorruptText("Invalid value type.", t.peek());
- } // dispatch on symbol type
- } // scope
- break;
- }
-}
-
-/*
-void AnyVal::deserialize(G3D::BinaryInput& t) {
- alwaysAssertM(false, "TODO");
-}
-*/
-
-
-AnyVal& AnyVal::operator[](const char* key) {
- return this->operator[]((std::string)key);
-}
-
-
-const AnyVal& AnyVal::operator[](const char* key) const {
- return this->operator[]((std::string)key);
-}
-
-
-AnyVal& AnyVal::operator[](const std::string& key) {
- if (m_type != TABLE) {
- throw WrongType(TABLE, m_type);
- }
-
- makeMutable();
-
- Table<std::string, AnyVal>& t = *(Table<std::string, AnyVal>*)m_value;
-
- if (! t.containsKey(key)) {
- t.set(key, AnyVal());
- }
-
- return t[key];
-}
-
-
-const AnyVal& AnyVal::operator[](const std::string& key) const {
- if (m_type != TABLE) {
- throw WrongType(TABLE, m_type);
- }
-
- const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
-
- if (! t.containsKey(key)) {
- throw KeyNotFound(key);
- }
-
- return t[key];
-}
-
-
-void AnyVal::append(const AnyVal& v) {
- if (m_type != ARRAY) {
- throw WrongType(ARRAY, m_type);
- }
- makeMutable();
-
- Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
- a.append(v);
-}
-
-
-void AnyVal::getKeys(Array<std::string>& keys) const {
- if (m_type != TABLE) {
- throw WrongType(TABLE, m_type);
- }
-
- const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
- t.getKeys(keys);
-}
-
-
-int AnyVal::size() const {
- switch (m_type) {
- case TABLE:
- {
- const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
- return t.size();
- }
-
- case ARRAY:
- {
- const Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
- return a.size();
- }
-
- default:
- throw WrongType(ARRAY, m_type);
- }
-}
-
-
-AnyVal& AnyVal::operator[](int i) {
- if (m_type != ARRAY) {
- throw WrongType(ARRAY, m_type);
- }
- makeMutable();
-
- Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
-
- if (i < 0) {
- throw IndexOutOfBounds(i, a.size());
- }
-
- if (a.size() <= i) {
- a.resize(i + 1);
- }
-
- return a[i];
-}
-
-
-const AnyVal& AnyVal::operator[](int i) const {
- if (m_type != ARRAY) {
- throw WrongType(ARRAY, m_type);
- }
-
- const Array<AnyVal>& a = *(Array<AnyVal>*)m_value;
-
- if (a.size() <= i || i < 0) {
- throw IndexOutOfBounds(i, a.size());
- }
-
- return a[i];
-}
-
-
-void AnyVal::makeMutable() {
- if (*m_referenceCount > 1) {
- // This is a shared instance
- --(*m_referenceCount);
- m_referenceCount = new int(1);
- m_value = copyValue();
- }
-}
-
-bool AnyVal::boolean() const {
- if (m_type != BOOLEAN) {
- throw WrongType(BOOLEAN, m_type);
- }
-
- return *(bool*)m_value;
-}
-
-
-bool AnyVal::boolean(bool defaultVal) const {
- if (m_type != BOOLEAN) {
- return defaultVal;
- }
-
- return *(bool*)m_value;
-}
-
-
-const std::string& AnyVal::string() const {
- if (m_type != STRING) {
- throw WrongType(STRING, m_type);
- }
-
- return *(std::string*)m_value;
-}
-
-
-const std::string& AnyVal::string(const std::string& defaultVal) const {
- if (m_type != STRING) {
- return defaultVal;
- } else {
- return *(std::string*)m_value;
- }
-}
-
-
-double AnyVal::number() const {
- if (m_type != NUMBER) {
- throw WrongType(NUMBER, m_type);
- }
-
- return *(double*)m_value;
-}
-
-
-double AnyVal::number(double defaultVal) const {
- if (m_type != NUMBER) {
- return defaultVal;
- } else {
- return *(double*)m_value;
- }
-}
-
-
-const Rect2D& AnyVal::rect2D() const {
- if (m_type != RECT2D) {
- throw WrongType(RECT2D, m_type);
- }
-
- return *(Rect2D*)m_value;
-}
-
-
-const Rect2D& AnyVal::rect2D(const Rect2D& defaultVal) const {
- if (m_type != RECT2D) {
- return defaultVal;
- } else {
- return *(Rect2D*)m_value;
- }
-}
-
-
-const AABox& AnyVal::aabox() const {
- if (m_type != AABOX) {
- throw WrongType(AABOX, m_type);
- }
-
- return *(AABox*)m_value;
-}
-
-
-const AABox& AnyVal::aabox(const AABox& defaultVal) const {
- if (m_type != AABOX) {
- return defaultVal;
- } else {
- return *(AABox*)m_value;
- }
-}
-
-
-const Color1& AnyVal::color1() const {
- if (m_type != COLOR1) {
- throw WrongType(COLOR1, m_type);
- }
-
- return *(Color1*)m_value;
-}
-
-
-const Color1& AnyVal::color1(const Color1& defaultVal) const {
- if (m_type != COLOR1) {
- return defaultVal;
- } else {
- return *(Color1*)m_value;
- }
-}
-
-
-const Color3& AnyVal::color3() const {
- if (m_type != COLOR3) {
- throw WrongType(COLOR3, m_type);
- }
-
- return *(Color3*)m_value;
-}
-
-
-const Color3& AnyVal::color3(const Color3& defaultVal) const {
- if (m_type != COLOR3) {
- return defaultVal;
- } else {
- return *(Color3*)m_value;
- }
-}
-
-
-const Color4& AnyVal::color4() const {
- if (m_type != COLOR4) {
- throw WrongType(COLOR4, m_type);
- }
-
- return *(Color4*)m_value;
-}
-
-
-const Color4& AnyVal::color4(const Color4& defaultVal) const {
- if (m_type != COLOR4) {
- return defaultVal;
- } else {
- return *(Color4*)m_value;
- }
-}
-
-
-const Vector2& AnyVal::vector2() const {
- if (m_type != VECTOR2) {
- throw WrongType(VECTOR2, m_type);
- }
-
- return *(Vector2*)m_value;
-}
-
-
-const Vector2& AnyVal::vector2(const Vector2& defaultVal) const {
- if (m_type != VECTOR2) {
- return defaultVal;
- } else {
- return *(Vector2*)m_value;
- }
-}
-
-
-const Vector3& AnyVal::vector3() const {
- if (m_type != VECTOR3) {
- throw WrongType(VECTOR3, m_type);
- }
-
- return *(Vector3*)m_value;
-}
-
-
-const Vector3& AnyVal::vector3(const Vector3& defaultVal) const {
- if (m_type != VECTOR3) {
- return defaultVal;
- } else {
- return *(Vector3*)m_value;
- }
-}
-
-
-const Vector4& AnyVal::vector4() const {
- if (m_type != VECTOR4) {
- throw WrongType(VECTOR4, m_type);
- }
-
- return *(Vector4*)m_value;
-}
-
-
-const Vector4& AnyVal::vector4(const Vector4& defaultVal) const {
- if (m_type != VECTOR4) {
- return defaultVal;
- } else {
- return *(Vector4*)m_value;
- }
-}
-
-
-const CoordinateFrame& AnyVal::coordinateFrame() const {
- if (m_type != COORDINATEFRAME) {
- throw WrongType(COORDINATEFRAME, m_type);
- }
-
- return *(CoordinateFrame*)m_value;
-}
-
-
-const CoordinateFrame& AnyVal::coordinateFrame(const CoordinateFrame& defaultVal) const {
- if (m_type != COORDINATEFRAME) {
- return defaultVal;
- } else {
- return *(CoordinateFrame*)m_value;
- }
-}
-
-const Matrix2& AnyVal::matrix2(const Matrix2& defaultVal) const {
- if (m_type != MATRIX2) {
- return defaultVal;
- } else {
- return *(Matrix2*)m_value;
- }
-}
-
-
-const Matrix2& AnyVal::matrix2() const {
- if (m_type != MATRIX2) {
- throw WrongType(MATRIX2, m_type);
- }
-
- return *(Matrix2*)m_value;
-}
-
-
-const Matrix3& AnyVal::matrix3(const Matrix3& defaultVal) const {
- if (m_type != MATRIX3) {
- return defaultVal;
- } else {
- return *(Matrix3*)m_value;
- }
-}
-
-
-const Matrix3& AnyVal::matrix3() const {
- if (m_type != MATRIX3) {
- throw WrongType(MATRIX3, m_type);
- }
-
- return *(Matrix3*)m_value;
-}
-
-
-const Matrix4& AnyVal::matrix4(const Matrix4& defaultVal) const {
- if (m_type != MATRIX4) {
- return defaultVal;
- } else {
- return *(Matrix4*)m_value;
- }
-}
-
-
-const Matrix4& AnyVal::matrix4() const {
- if (m_type != MATRIX4) {
- throw WrongType(MATRIX4, m_type);
- }
-
- return *(Matrix4*)m_value;
-}
-
-
-const Quat& AnyVal::quat(const Quat& defaultVal) const {
- if (m_type != QUAT) {
- return defaultVal;
- } else {
- return *(Quat*)m_value;
- }
-}
-
-
-const Quat& AnyVal::quat() const {
- if (m_type != QUAT) {
- throw WrongType(QUAT, m_type);
- }
-
- return *(Quat*)m_value;
-}
-
-
-const AnyVal& AnyVal::get(const std::string& key, const AnyVal& defaultVal) const {
- if (m_type != TABLE) {
- return defaultVal;
- }
-
- const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
-
- if (t.containsKey(key)) {
- return t[key];
- } else {
- return defaultVal;
- }
-}
-
-
-const AnyVal& AnyVal::get(const std::string& key) const {
- if (m_type != TABLE) {
- throw WrongType(TABLE, m_type);
- }
-
- const Table<std::string, AnyVal>& t = *(const Table<std::string, AnyVal>*)m_value;
-
- if (t.containsKey(key)) {
- return t[key];
- } else {
- throw KeyNotFound(key);
- }
-}
-
-
-const AnyVal& AnyVal::get(int i, const AnyVal& defaultVal) const {
- if (m_type != ARRAY) {
- return defaultVal;
- }
-
- const Array<AnyVal>& a = *(const Array<AnyVal>*)m_value;
-
- if ((i >= 0) && (i < a.size())) {
- return a[i];
- } else {
- return defaultVal;
- }
-}
-
-
-const AnyVal& AnyVal::get(int i) const {
- if (m_type != ARRAY) {
- throw WrongType(ARRAY, m_type);
- }
-
- const Array<AnyVal>& a = *(const Array<AnyVal>*)m_value;
-
- if ((i >= 0) && (i < a.size())) {
- return a[i];
- } else {
- throw IndexOutOfBounds(i, a.size());
- }
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/BinaryFormat.cpp b/externals/g3dlite/G3D.lib/source/BinaryFormat.cpp
deleted file mode 100644
index a30ec0644ea..00000000000
--- a/externals/g3dlite/G3D.lib/source/BinaryFormat.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- @file BinaryFormat.cpp
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2005-06-10
- @edited 2005-06-10
- */
-
-#include "G3D/BinaryFormat.h"
-
-namespace G3D {
-
-int32 byteSize(BinaryFormat f) {
- switch (f) {
- case BOOL8_BINFMT:
- case UINT8_BINFMT:
- case INT8_BINFMT:
- return 1;
-
- case UINT16_BINFMT:
- case INT16_BINFMT:
- return 2;
-
- case FLOAT16_BINFMT:
- return 2;
-
- case UINT32_BINFMT:
- case INT32_BINFMT:
- case FLOAT32_BINFMT:
- return 4;
-
- case FLOAT64_BINFMT:
- case UINT64_BINFMT:
- case INT64_BINFMT:
- return 8;
-
- case INT128_BINFMT:
- case UINT128_BINFMT:
- return 16;
-
- case VECTOR2_BINFMT:
- return 2 * 4;
-
- case VECTOR2INT16_BINFMT:
- return 2 * 2;
-
- case VECTOR3_BINFMT:
- return 3 * 4;
-
- case VECTOR3INT16_BINFMT:
- return 3 * 2;
-
- case VECTOR4_BINFMT:
- return 4 * 4;
-
- case VECTOR4INT16_BINFMT:
- return 4 * 4;
-
- case COLOR3_BINFMT:
- return 3 * 4;
-
- case COLOR3UINT8_BINFMT:
- return 3 * 1;
-
- case COLOR3INT16_BINFMT:
- return 3 * 2;
-
- case COLOR4_BINFMT:
- return 4 * 4;
-
- case COLOR4UINT8_BINFMT:
- return 4 * 1;
-
- case COLOR4INT16_BINFMT:
- return 4 * 2;
-
- default:
- return -1;
- }
-}
-}
diff --git a/externals/g3dlite/G3D.lib/source/BinaryInput.cpp b/externals/g3dlite/G3D.lib/source/BinaryInput.cpp
deleted file mode 100644
index 65a9976fe04..00000000000
--- a/externals/g3dlite/G3D.lib/source/BinaryInput.cpp
+++ /dev/null
@@ -1,568 +0,0 @@
-/**
- @file BinaryInput.cpp
-
- @author Morgan McGuire, graphics3d.com
- Copyright 2001-2007, Morgan McGuire. All rights reserved.
-
- @created 2001-08-09
- @edited 2005-02-24
-
-
- <PRE>
- {
- BinaryOutput b("c:/tmp/test.b", BinaryOutput::LITTLE_ENDIAN);
-
- float f = 3.1415926;
- int i = 1027221;
- std::string s = "Hello World!";
-
- b.writeFloat32(f);
- b.writeInt32(i);
- b.writeString(s);
- b.commit();
-
-
- BinaryInput in("c:/tmp/test.b", BinaryInput::LITTLE_ENDIAN);
-
- debugAssert(f == in.readFloat32());
- int ii = in.readInt32();
- debugAssert(i == ii);
- debugAssert(s == in.readString());
- }
- </PRE>
- */
-
-#include "G3D/platform.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/Array.h"
-#include "G3D/fileutils.h"
-#include "G3D/Log.h"
-#include <zlib.h>
-
-#include <cstring>
-
-namespace G3D {
-
-void BinaryInput::readBool8(std::vector<bool>& out, int64 n) {
- out.resize((int)n);
- // std::vector optimizes bool in a way that prevents fast reading
- for (int64 i = 0; i < n ; ++i) {
- out[i] = readBool8();
- }
-}
-
-
-void BinaryInput::readBool8(Array<bool>& out, int64 n) {
- out.resize(n);
- readBool8(out.begin(), n);
-}
-
-
-#define IMPLEMENT_READER(ucase, lcase)\
-void BinaryInput::read##ucase(std::vector<lcase>& out, int64 n) {\
- out.resize(n);\
- read##ucase(&out[0], n);\
-}\
-\
-\
-void BinaryInput::read##ucase(Array<lcase>& out, int64 n) {\
- out.resize(n);\
- read##ucase(out.begin(), n);\
-}
-
-
-IMPLEMENT_READER(UInt8, uint8)
-IMPLEMENT_READER(Int8, int8)
-IMPLEMENT_READER(UInt16, uint16)
-IMPLEMENT_READER(Int16, int16)
-IMPLEMENT_READER(UInt32, uint32)
-IMPLEMENT_READER(Int32, int32)
-IMPLEMENT_READER(UInt64, uint64)
-IMPLEMENT_READER(Int64, int64)
-IMPLEMENT_READER(Float32, float32)
-IMPLEMENT_READER(Float64, float64)
-
-#undef IMPLEMENT_READER
-
-// Data structures that are one byte per element can be
-// directly copied, regardles of endian-ness.
-#define IMPLEMENT_READER(ucase, lcase)\
-void BinaryInput::read##ucase(lcase* out, int64 n) {\
- if (sizeof(lcase) == 1) {\
- readBytes(out, n);\
- } else {\
- for (int64 i = 0; i < n ; ++i) {\
- out[i] = read##ucase();\
- }\
- }\
-}
-
-IMPLEMENT_READER(Bool8, bool)
-IMPLEMENT_READER(UInt8, uint8)
-IMPLEMENT_READER(Int8, int8)
-
-#undef IMPLEMENT_READER
-
-
-#define IMPLEMENT_READER(ucase, lcase)\
-void BinaryInput::read##ucase(lcase* out, int64 n) {\
- if (m_swapBytes) {\
- for (int64 i = 0; i < n; ++i) {\
- out[i] = read##ucase();\
- }\
- } else {\
- readBytes(out, sizeof(lcase) * n);\
- }\
-}
-
-
-IMPLEMENT_READER(UInt16, uint16)
-IMPLEMENT_READER(Int16, int16)
-IMPLEMENT_READER(UInt32, uint32)
-IMPLEMENT_READER(Int32, int32)
-IMPLEMENT_READER(UInt64, uint64)
-IMPLEMENT_READER(Int64, int64)
-IMPLEMENT_READER(Float32, float32)
-IMPLEMENT_READER(Float64, float64)
-
-#undef IMPLEMENT_READER
-
-void BinaryInput::loadIntoMemory(int64 startPosition, int64 minLength) {
- // Load the next section of the file
- debugAssertM(m_filename != "<memory>", "Read past end of file.");
-
- int64 absPos = m_alreadyRead + m_pos;
-
- if (m_bufferLength < minLength) {
- // The current buffer isn't big enough to hold the chunk we want to read.
- // This happens if there was little memory available during the initial constructor
- // read but more memory has since been freed.
- m_bufferLength = minLength;
- debugAssert(m_freeBuffer);
- m_buffer = (uint8*)System::realloc(m_buffer, m_bufferLength);
- if (m_buffer == NULL) {
- throw "Tried to read a larger memory chunk than could fit in memory. (2)";
- }
- }
-
- m_alreadyRead = startPosition;
-
-# ifdef G3D_WIN32
- FILE* file = fopen(m_filename.c_str(), "rb");
- debugAssert(file);
- int ret = fseek(file, (off_t)m_alreadyRead, SEEK_SET);
- debugAssert(ret == 0);
- size_t toRead = (size_t)G3D::min(m_bufferLength, m_length - m_alreadyRead);
- ret = fread(m_buffer, 1, toRead, file);
- debugAssert(ret == toRead);
- fclose(file);
- file = NULL;
-
-# else
- FILE* file = fopen(m_filename.c_str(), "rb");
- debugAssert(file);
- int ret = fseeko(file, (off_t)m_alreadyRead, SEEK_SET);
- debugAssert(ret == 0);
- size_t toRead = (size_t)G3D::min<int64>(m_bufferLength, m_length - m_alreadyRead);
- ret = fread(m_buffer, 1, toRead, file);
- debugAssert((size_t)ret == (size_t)toRead);
- fclose(file);
- file = NULL;
-# endif
-
- m_pos = absPos - m_alreadyRead;
- debugAssert(m_pos >= 0);
-}
-
-
-
-const bool BinaryInput::NO_COPY = false;
-
-static bool needSwapBytes(G3DEndian fileEndian) {
- return (fileEndian != System::machineEndian());
-}
-
-
-/** Helper used by the constructors for decompression */
-static uint32 readUInt32(const uint8* data, bool swapBytes) {
- if (swapBytes) {
- uint8 out[4];
- out[0] = data[3];
- out[1] = data[2];
- out[2] = data[1];
- out[3] = data[0];
- return *((uint32*)out);
- } else {
- return *((uint32*)data);
- }
-}
-
-
-void BinaryInput::setEndian(G3DEndian e) {
- m_fileEndian = e;
- m_swapBytes = needSwapBytes(m_fileEndian);
-}
-
-
-BinaryInput::BinaryInput(
- const uint8* data,
- int64 dataLen,
- G3DEndian dataEndian,
- bool compressed,
- bool copyMemory) :
- m_filename("<memory>"),
- m_bitPos(0),
- m_bitString(0),
- m_beginEndBits(0),
- m_alreadyRead(0),
- m_bufferLength(0),
- m_pos(0) {
-
- m_freeBuffer = copyMemory || compressed;
-
- setEndian(dataEndian);
-
- if (compressed) {
- // Read the decompressed size from the first 4 bytes
- m_length = G3D::readUInt32(data, m_swapBytes);
-
- debugAssert(m_freeBuffer);
- m_buffer = (uint8*)System::alignedMalloc(m_length, 16);
-
- unsigned long L = m_length;
- // Decompress with zlib
- int64 result = uncompress(m_buffer, (unsigned long*)&L, data + 4, dataLen - 4);
- m_length = L;
- m_bufferLength = L;
- debugAssert(result == Z_OK); (void)result;
-
- } else {
- m_length = dataLen;
- m_bufferLength = m_length;
- if (! copyMemory) {
- debugAssert(!m_freeBuffer);
- m_buffer = const_cast<uint8*>(data);
- } else {
- debugAssert(m_freeBuffer);
- m_buffer = (uint8*)System::alignedMalloc(m_length, 16);
- System::memcpy(m_buffer, data, dataLen);
- }
- }
-}
-
-
-BinaryInput::BinaryInput(
- const std::string& filename,
- G3DEndian fileEndian,
- bool compressed) :
- m_filename(filename),
- m_bitPos(0),
- m_bitString(0),
- m_beginEndBits(0),
- m_alreadyRead(0),
- m_length(0),
- m_bufferLength(0),
- m_buffer(NULL),
- m_pos(0),
- m_freeBuffer(true) {
-
- setEndian(fileEndian);
-
- // Update global file tracker
- _internal::currentFilesUsed.insert(m_filename);
-
-
- if (! fileExists(m_filename, false)) {
- std::string zipfile;
- std::string internalfile;
- if (zipfileExists(m_filename, zipfile, internalfile)) {
- // Load from zipfile
- void* v;
- size_t s;
- zipRead(filename, v, s);
- m_buffer = reinterpret_cast<uint8*>(v);
- m_bufferLength = m_length = s;
- if (compressed) {
- decompress();
- }
- m_freeBuffer = true;
- } else {
- Log::common()->printf("Warning: File not found: %s\n", m_filename.c_str());
- }
- return;
- }
-
- // Figure out how big the file is and verify that it exists.
- m_length = fileLength(m_filename);
-
- // Read the file into memory
- FILE* file = fopen(m_filename.c_str(), "rb");
-
- if (! file || (m_length == -1)) {
- throw format("File not found: \"%s\"", m_filename.c_str());
- return;
- }
-
- if (! compressed && (m_length > INITIAL_BUFFER_LENGTH)) {
- // Read only a subset of the file so we don't consume
- // all available memory.
- m_bufferLength = INITIAL_BUFFER_LENGTH;
- } else {
- // Either the length is fine or the file is compressed
- // and requires us to read the whole thing for zlib.
- m_bufferLength = m_length;
- }
-
- debugAssert(m_freeBuffer);
- m_buffer = (uint8*)System::alignedMalloc(m_bufferLength, 16);
- if (m_buffer == NULL) {
- if (compressed) {
- throw "Not enough memory to load compressed file. (1)";
- }
-
- // Try to allocate a small array; not much memory is available.
- // Give up if we can't allocate even 1k.
- while ((m_buffer == NULL) && (m_bufferLength > 1024)) {
- m_bufferLength /= 2;
- m_buffer = (uint8*)System::alignedMalloc(m_bufferLength, 16);
- }
- }
- debugAssert(m_buffer);
-
- fread(m_buffer, m_bufferLength, sizeof(int8), file);
- fclose(file);
- file = NULL;
-
- if (compressed) {
- if (m_bufferLength != m_length) {
- throw "Not enough memory to load compressed file. (2)";
- }
-
- decompress();
- }
-}
-
-void BinaryInput::decompress() {
- // Decompress
- // Use the existing buffer as the source, allocate
- // a new buffer to use as the destination.
-
- int64 tempLength = m_length;
- m_length = G3D::readUInt32(m_buffer, m_swapBytes);
-
- // The file couldn't have better than 500:1 compression
- alwaysAssertM(m_length < m_bufferLength * 500, "Compressed file header is corrupted");
-
- uint8* tempBuffer = m_buffer;
- m_buffer = (uint8*)System::alignedMalloc(m_length, 16);
-
- debugAssert(m_buffer);
- debugAssert(isValidHeapPointer(tempBuffer));
- debugAssert(isValidHeapPointer(m_buffer));
-
- unsigned long L = m_length;
- int64 result = uncompress(m_buffer, &L, tempBuffer + 4, tempLength - 4);
- m_length = L;
- m_bufferLength = m_length;
-
- debugAssertM(result == Z_OK, "BinaryInput/zlib detected corruption in " + m_filename);
- (void)result;
-
- System::alignedFree(tempBuffer);
-}
-
-
-void BinaryInput::readBytes(void* bytes, int64 n) {
- prepareToRead(n);
- debugAssert(isValidPointer(bytes));
-
- memcpy(bytes, m_buffer + m_pos, n);
- m_pos += n;
-}
-
-
-BinaryInput::~BinaryInput() {
-
- if (m_freeBuffer) {
- System::alignedFree(m_buffer);
- }
- m_buffer = NULL;
-}
-
-
-uint64 BinaryInput::readUInt64() {
- prepareToRead(8);
- uint8 out[8];
-
- if (m_swapBytes) {
- out[0] = m_buffer[m_pos + 7];
- out[1] = m_buffer[m_pos + 6];
- out[2] = m_buffer[m_pos + 5];
- out[3] = m_buffer[m_pos + 4];
- out[4] = m_buffer[m_pos + 3];
- out[5] = m_buffer[m_pos + 2];
- out[6] = m_buffer[m_pos + 1];
- out[7] = m_buffer[m_pos + 0];
- } else {
- *(uint64*)out = *(uint64*)(m_buffer + m_pos);
- }
-
- m_pos += 8;
- return *(uint64*)out;
-}
-
-
-std::string BinaryInput::readString(int64 n) {
- prepareToRead(n);
- debugAssertM((m_pos + n) <= m_length, "Read past end of file");
-
- char *s = (char*)System::alignedMalloc(n + 1, 16);
- assert(s != NULL);
-
- memcpy(s, m_buffer + m_pos, n);
- // There may not be a null, so make sure
- // we add one.
- s[n] = '\0';
-
- std::string out = s;
- System::alignedFree(s);
- s = NULL;
-
- m_pos += n;
-
- return out;
-
-}
-
-
-std::string BinaryInput::readString() {
- int64 n = 0;
-
- if ((m_pos + m_alreadyRead + n) < (m_length - 1)) {
- prepareToRead(1);
- }
-
- if ( ((m_pos + m_alreadyRead + n) < (m_length - 1)) &&
- (m_buffer[m_pos + n] != '\0')) {
-
- ++n;
- while ( ((m_pos + m_alreadyRead + n) < (m_length - 1)) &&
- (m_buffer[m_pos + n] != '\0')) {
-
- prepareToRead(1);
- ++n;
- }
- }
-
- // Consume NULL
- ++n;
-
- return readString(n);
-}
-
-
-std::string BinaryInput::readStringEven() {
- std::string x = readString();
- if (hasMore() && (G3D::isOdd(x.length() + 1))) {
- skip(1);
- }
- return x;
-}
-
-
-std::string BinaryInput::readString32() {
- int len = readUInt32();
- return readString(len);
-}
-
-
-Vector4 BinaryInput::readVector4() {
- float x = readFloat32();
- float y = readFloat32();
- float z = readFloat32();
- float w = readFloat32();
- return Vector4(x, y, z, w);
-}
-
-
-Vector3 BinaryInput::readVector3() {
- float x = readFloat32();
- float y = readFloat32();
- float z = readFloat32();
- return Vector3(x, y, z);
-}
-
-
-Vector2 BinaryInput::readVector2() {
- float x = readFloat32();
- float y = readFloat32();
- return Vector2(x, y);
-}
-
-
-Color4 BinaryInput::readColor4() {
- float r = readFloat32();
- float g = readFloat32();
- float b = readFloat32();
- float a = readFloat32();
- return Color4(r, g, b, a);
-}
-
-
-Color3 BinaryInput::readColor3() {
- float r = readFloat32();
- float g = readFloat32();
- float b = readFloat32();
- return Color3(r, g, b);
-}
-
-
-void BinaryInput::beginBits() {
- debugAssert(m_beginEndBits == 0);
- m_beginEndBits = 1;
- m_bitPos = 0;
-
- debugAssertM(hasMore(), "Can't call beginBits when at the end of a file");
- m_bitString = readUInt8();
-}
-
-
-uint32 BinaryInput::readBits(int numBits) {
- debugAssert(m_beginEndBits == 1);
-
- uint32 out = 0;
-
- const int total = numBits;
- while (numBits > 0) {
- if (m_bitPos > 7) {
- // Consume a new byte for reading. We do this at the beginning
- // of the loop so that we don't try to read past the end of the file.
- m_bitPos = 0;
- m_bitString = readUInt8();
- }
-
- // Slide the lowest bit of the bitString into
- // the correct position.
- out |= (m_bitString & 1) << (total - numBits);
-
- // Shift over to the next bit
- m_bitString = m_bitString >> 1;
- ++m_bitPos;
- --numBits;
- }
-
- return out;
-}
-
-
-void BinaryInput::endBits() {
- debugAssert(m_beginEndBits == 1);
- if (m_bitPos == 0) {
- // Put back the last byte we read
- --m_pos;
- }
- m_beginEndBits = 0;
- m_bitPos = 0;
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/BinaryOutput.cpp b/externals/g3dlite/G3D.lib/source/BinaryOutput.cpp
deleted file mode 100644
index 8fcc30e548f..00000000000
--- a/externals/g3dlite/G3D.lib/source/BinaryOutput.cpp
+++ /dev/null
@@ -1,518 +0,0 @@
-/**
- @file BinaryOutput.cpp
-
- @author Morgan McGuire, graphics3d.com
- Copyright 2002-2007, Morgan McGuire, All rights reserved.
-
- @created 2002-02-20
- @edited 2008-01-07
- */
-
-#include "G3D/platform.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/fileutils.h"
-#include "G3D/stringutils.h"
-#include "G3D/Array.h"
-#include <zlib.h>
-
-#include <cstring>
-
-// Largest memory buffer that the system will use for writing to
-// disk. After this (or if the system runs out of memory)
-// chunks of the file will be dumped to disk.
-//
-// Currently 400 MB
-#define MAX_BINARYOUTPUT_BUFFER_SIZE 400000000
-
-namespace G3D {
-
-void BinaryOutput::writeBool8(const std::vector<bool>& out, int n) {
- for (int i = 0; i < n; ++i) {
- writeBool8(out[i]);
- }
-}
-
-
-void BinaryOutput::writeBool8(const Array<bool>& out, int n) {
- writeBool8(out.getCArray(), n);
-}
-
-#define IMPLEMENT_WRITER(ucase, lcase)\
-void BinaryOutput::write##ucase(const std::vector<lcase>& out, int n) {\
- write##ucase(&out[0], n);\
-}\
-\
-\
-void BinaryOutput::write##ucase(const Array<lcase>& out, int n) {\
- write##ucase(out.getCArray(), n);\
-}
-
-
-IMPLEMENT_WRITER(UInt8, uint8)
-IMPLEMENT_WRITER(Int8, int8)
-IMPLEMENT_WRITER(UInt16, uint16)
-IMPLEMENT_WRITER(Int16, int16)
-IMPLEMENT_WRITER(UInt32, uint32)
-IMPLEMENT_WRITER(Int32, int32)
-IMPLEMENT_WRITER(UInt64, uint64)
-IMPLEMENT_WRITER(Int64, int64)
-IMPLEMENT_WRITER(Float32, float32)
-IMPLEMENT_WRITER(Float64, float64)
-
-#undef IMPLEMENT_WRITER
-
-// Data structures that are one byte per element can be
-// directly copied, regardles of endian-ness.
-#define IMPLEMENT_WRITER(ucase, lcase)\
-void BinaryOutput::write##ucase(const lcase* out, int n) {\
- if (sizeof(lcase) == 1) {\
- writeBytes((void*)out, n);\
- } else {\
- for (int i = 0; i < n ; ++i) {\
- write##ucase(out[i]);\
- }\
- }\
-}
-
-IMPLEMENT_WRITER(Bool8, bool)
-IMPLEMENT_WRITER(UInt8, uint8)
-IMPLEMENT_WRITER(Int8, int8)
-
-#undef IMPLEMENT_WRITER
-
-
-#define IMPLEMENT_WRITER(ucase, lcase)\
-void BinaryOutput::write##ucase(const lcase* out, int n) {\
- if (m_swapBytes) {\
- for (int i = 0; i < n; ++i) {\
- write##ucase(out[i]);\
- }\
- } else {\
- writeBytes((const void*)out, sizeof(lcase) * n);\
- }\
-}
-
-
-IMPLEMENT_WRITER(UInt16, uint16)
-IMPLEMENT_WRITER(Int16, int16)
-IMPLEMENT_WRITER(UInt32, uint32)
-IMPLEMENT_WRITER(Int32, int32)
-IMPLEMENT_WRITER(UInt64, uint64)
-IMPLEMENT_WRITER(Int64, int64)
-IMPLEMENT_WRITER(Float32, float32)
-IMPLEMENT_WRITER(Float64, float64)
-
-#undef IMPLEMENT_WRITER
-
-
-void BinaryOutput::reallocBuffer(size_t bytes, size_t oldBufferLen) {
- //debugPrintf("reallocBuffer(%d, %d)\n", bytes, oldBufferLen);
-
- size_t newBufferLen = (int)(m_bufferLen * 1.5) + 100;
- uint8* newBuffer = NULL;
-
- if ((m_filename == "<memory>") || (newBufferLen < MAX_BINARYOUTPUT_BUFFER_SIZE)) {
- // We're either writing to memory (in which case we *have* to try and allocate)
- // or we've been asked to allocate a reasonable size buffer.
-
- //debugPrintf(" realloc(%d)\n", newBufferLen);
- newBuffer = (uint8*)System::realloc(m_buffer, newBufferLen);
- if (newBuffer != NULL) {
- m_maxBufferLen = newBufferLen;
- }
- }
-
- if ((newBuffer == NULL) && (bytes > 0)) {
- // Realloc failed; we're probably out of memory. Back out
- // the entire call and try to dump some data to disk.
- m_bufferLen = oldBufferLen;
- reserveBytesWhenOutOfMemory(bytes);
- } else {
- m_buffer = newBuffer;
- debugAssert(isValidHeapPointer(m_buffer));
- }
-}
-
-
-void BinaryOutput::reserveBytesWhenOutOfMemory(size_t bytes) {
- if (m_filename == "<memory>") {
- throw "Out of memory while writing to memory in BinaryOutput (no RAM left).";
- } else if ((int)bytes > (int)m_maxBufferLen) {
- throw "Out of memory while writing to disk in BinaryOutput (could not create a large enough buffer).";
- } else {
-
- // Dump the contents to disk. In order to enable seeking backwards,
- // we keep the last 10 MB in memory.
- int writeBytes = m_bufferLen - 10 * 1024 * 1024;
-
- if (writeBytes < m_bufferLen / 3) {
- // We're going to write less than 1/3 of the file;
- // give up and just write the whole thing.
- writeBytes = m_bufferLen;
- }
- debugAssert(writeBytes > 0);
-
- //debugPrintf("Writing %d bytes to disk\n", writeBytes);
-
- const char* mode = (m_alreadyWritten > 0) ? "ab" : "wb";
- FILE* file = fopen(m_filename.c_str(), mode);
- debugAssert(file);
-
- size_t count = fwrite(m_buffer, 1, writeBytes, file);
- debugAssert((int)count == writeBytes); (void)count;
-
- fclose(file);
- file = NULL;
-
- // Record that we saved this data.
- m_alreadyWritten += writeBytes;
- m_bufferLen -= writeBytes;
- m_pos -= writeBytes;
-
- debugAssert(m_bufferLen < m_maxBufferLen);
- debugAssert(m_bufferLen >= 0);
- debugAssert(m_pos >= 0);
- debugAssert(m_pos <= m_bufferLen);
-
- // Shift the unwritten data back appropriately in the buffer.
- debugAssert(isValidHeapPointer(m_buffer));
- System::memcpy(m_buffer, m_buffer + writeBytes, m_bufferLen);
- debugAssert(isValidHeapPointer(m_buffer));
-
- // *now* we allocate bytes (there should presumably be enough
- // space in the buffer; if not, we'll come back through this
- // code and dump the last 10MB to disk as well. Note that the
- // bytes > maxBufferLen case above would already have triggered
- // if this call couldn't succeed.
- reserveBytes(bytes);
- }
-}
-
-
-BinaryOutput::BinaryOutput() {
- m_alreadyWritten = 0;
- m_swapBytes = false;
- m_pos = 0;
- m_filename = "<memory>";
- m_buffer = NULL;
- m_bufferLen = 0;
- m_maxBufferLen = 0;
- m_beginEndBits = 0;
- m_bitString = 0;
- m_bitPos = 0;
- m_ok = true;
- m_committed = false;
-}
-
-
-BinaryOutput::BinaryOutput(
- const std::string& filename,
- G3DEndian fileEndian) {
-
- m_pos = 0;
- m_alreadyWritten = 0;
- setEndian(fileEndian);
- m_filename = filename;
- m_buffer = NULL;
- m_bufferLen = 0;
- m_maxBufferLen = 0;
- m_beginEndBits = 0;
- m_bitString = 0;
- m_bitPos = 0;
- m_committed = false;
-
- m_ok = true;
- /** Verify ability to write to disk */
- commit(false);
- m_committed = false;
-}
-
-
-void BinaryOutput::reset() {
- debugAssert(m_beginEndBits == 0);
- alwaysAssertM(m_filename == "<memory>",
- "Can only reset a BinaryOutput that writes to memory.");
-
- // Do not reallocate, just clear the size of the buffer.
- m_pos = 0;
- m_alreadyWritten = 0;
- m_bufferLen = 0;
- m_beginEndBits = 0;
- m_bitString = 0;
- m_bitPos = 0;
- m_committed = false;
-}
-
-
-BinaryOutput::~BinaryOutput() {
- debugAssert((m_buffer == NULL) || isValidHeapPointer(m_buffer));
- System::free(m_buffer);
- m_buffer = NULL;
- m_bufferLen = 0;
- m_maxBufferLen = 0;
-}
-
-
-void BinaryOutput::setEndian(G3DEndian fileEndian) {
- m_fileEndian = fileEndian;
- m_swapBytes = (fileEndian != System::machineEndian());
-}
-
-
-bool BinaryOutput::ok() const {
- return m_ok;
-}
-
-
-void BinaryOutput::compress() {
- if (m_alreadyWritten > 0) {
- throw "Cannot compress huge files (part of this file has already been written to disk).";
- }
-
- // Old buffer size
- int L = m_bufferLen;
- uint8* convert = (uint8*)&L;
-
- // Zlib requires the output buffer to be this big
- unsigned long newSize = iCeil(m_bufferLen * 1.01) + 12;
- uint8* temp = (uint8*)System::malloc(newSize);
- int result = compress2(temp, &newSize, m_buffer, m_bufferLen, 9);
-
- debugAssert(result == Z_OK); (void)result;
-
- // Write the header
- if (m_swapBytes) {
- m_buffer[0] = convert[3];
- m_buffer[1] = convert[2];
- m_buffer[2] = convert[1];
- m_buffer[3] = convert[0];
- } else {
- m_buffer[0] = convert[0];
- m_buffer[1] = convert[1];
- m_buffer[2] = convert[2];
- m_buffer[3] = convert[3];
- }
-
- // Write the data
- if ((int64)newSize + 4 > (int64)m_maxBufferLen) {
- m_maxBufferLen = newSize + 4;
- m_buffer = (uint8*)System::realloc(m_buffer, m_maxBufferLen);
- }
- m_bufferLen = newSize + 4;
- System::memcpy(m_buffer + 4, temp, newSize);
- m_pos = m_bufferLen;
-
- System::free(temp);
-}
-
-
-void BinaryOutput::commit(bool flush) {
- debugAssertM(! m_committed, "Cannot commit twice");
- m_committed = true;
- debugAssertM(m_beginEndBits == 0, "Missing endBits before commit");
-
- // Make sure the directory exists.
- std::string root, base, ext, path;
- Array<std::string> pathArray;
- parseFilename(m_filename, root, pathArray, base, ext);
-
- path = root + stringJoin(pathArray, '/');
- if (! fileExists(path, false)) {
- createDirectory(path);
- }
-
- const char* mode = (m_alreadyWritten > 0) ? "ab" : "wb";
-
- FILE* file = fopen(m_filename.c_str(), mode);
-
- m_ok = (file != NULL) && m_ok;
-
- if (m_ok) {
- debugAssertM(file, std::string("Could not open '") + m_filename + "'");
-
- m_alreadyWritten += m_bufferLen;
-
- fwrite(m_buffer, m_bufferLen, 1, file);
- if (flush) {
- fflush(file);
- }
- fclose(file);
- file = NULL;
- }
-}
-
-
-void BinaryOutput::commit(
- uint8* out) {
- debugAssertM(! m_committed, "Cannot commit twice");
- m_committed = true;
-
- System::memcpy(out, m_buffer, m_bufferLen);
-}
-
-
-void BinaryOutput::writeUInt16(uint16 u) {
- reserveBytes(2);
-
- uint8* convert = (uint8*)&u;
-
- if (m_swapBytes) {
- m_buffer[m_pos] = convert[1];
- m_buffer[m_pos + 1] = convert[0];
- } else {
- *(uint16*)(m_buffer + m_pos) = u;
- }
-
- m_pos += 2;
-}
-
-
-void BinaryOutput::writeUInt32(uint32 u) {
- reserveBytes(4);
-
- uint8* convert = (uint8*)&u;
-
- debugAssert(m_beginEndBits == 0);
-
- if (m_swapBytes) {
- m_buffer[m_pos] = convert[3];
- m_buffer[m_pos + 1] = convert[2];
- m_buffer[m_pos + 2] = convert[1];
- m_buffer[m_pos + 3] = convert[0];
- } else {
- *(uint32*)(m_buffer + m_pos) = u;
- }
-
- m_pos += 4;
-}
-
-
-void BinaryOutput::writeUInt64(uint64 u) {
- reserveBytes(8);
-
- uint8* convert = (uint8*)&u;
-
- if (m_swapBytes) {
- m_buffer[m_pos] = convert[7];
- m_buffer[m_pos + 1] = convert[6];
- m_buffer[m_pos + 2] = convert[5];
- m_buffer[m_pos + 3] = convert[4];
- m_buffer[m_pos + 4] = convert[3];
- m_buffer[m_pos + 5] = convert[2];
- m_buffer[m_pos + 6] = convert[1];
- m_buffer[m_pos + 7] = convert[0];
- } else {
- *(uint64*)(m_buffer + m_pos) = u;
- }
-
- m_pos += 8;
-}
-
-
-void BinaryOutput::writeString(const char* s) {
- // +1 is because strlen doesn't count the null
- int len = strlen(s) + 1;
-
- debugAssert(m_beginEndBits == 0);
- reserveBytes(len);
- System::memcpy(m_buffer + m_pos, s, len);
- m_pos += len;
-}
-
-
-void BinaryOutput::writeStringEven(const char* s) {
- // +1 is because strlen doesn't count the null
- int len = strlen(s) + 1;
-
- reserveBytes(len);
- System::memcpy(m_buffer + m_pos, s, len);
- m_pos += len;
-
- // Pad with another NULL
- if ((len % 2) == 1) {
- writeUInt8(0);
- }
-}
-
-
-void BinaryOutput::writeString32(const char* s) {
- writeUInt32(strlen(s) + 1);
- writeString(s);
-}
-
-
-void BinaryOutput::writeVector4(const Vector4& v) {
- writeFloat32(v.x);
- writeFloat32(v.y);
- writeFloat32(v.z);
- writeFloat32(v.w);
-}
-
-
-void BinaryOutput::writeVector3(const Vector3& v) {
- writeFloat32(v.x);
- writeFloat32(v.y);
- writeFloat32(v.z);
-}
-
-
-void BinaryOutput::writeVector2(const Vector2& v) {
- writeFloat32(v.x);
- writeFloat32(v.y);
-}
-
-
-void BinaryOutput::writeColor4(const Color4& v) {
- writeFloat32(v.r);
- writeFloat32(v.g);
- writeFloat32(v.b);
- writeFloat32(v.a);
-}
-
-
-void BinaryOutput::writeColor3(const Color3& v) {
- writeFloat32(v.r);
- writeFloat32(v.g);
- writeFloat32(v.b);
-}
-
-
-void BinaryOutput::beginBits() {
- debugAssertM(m_beginEndBits == 0, "Already in beginBits...endBits");
- m_bitString = 0x00;
- m_bitPos = 0;
- m_beginEndBits = 1;
-}
-
-
-void BinaryOutput::writeBits(uint32 value, int numBits) {
-
- while (numBits > 0) {
- // Extract the current bit of value and
- // insert it into the current byte
- m_bitString |= (value & 1) << m_bitPos;
- ++m_bitPos;
- value = value >> 1;
- --numBits;
-
- if (m_bitPos > 7) {
- // We've reached the end of this byte
- writeUInt8(m_bitString);
- m_bitString = 0x00;
- m_bitPos = 0;
- }
- }
-}
-
-
-void BinaryOutput::endBits() {
- debugAssertM(m_beginEndBits == 1, "Not in beginBits...endBits");
- if (m_bitPos > 0) {
- writeUInt8(m_bitString);
- }
- m_bitString = 0;
- m_bitPos = 0;
- m_beginEndBits = 0;
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Box.cpp b/externals/g3dlite/G3D.lib/source/Box.cpp
deleted file mode 100644
index 4b6c56388ec..00000000000
--- a/externals/g3dlite/G3D.lib/source/Box.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-/**
- @file Box.cpp
- Box class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2001-06-02
- @edited 2006-02-05
-*/
-
-#include "G3D/Box.h"
-#include "G3D/debug.h"
-#include "G3D/Plane.h"
-#include "G3D/AABox.h"
-#include "G3D/CoordinateFrame.h"
-
-namespace G3D {
-
-/**
- Sets a field on four vertices. Used by the constructor.
- */
-#define setMany(i0, i1, i2, i3, field, extreme) \
- _corner[i0].field = _corner[i1].field = \
- _corner[i2].field = _corner[i3].field = \
- (extreme).field
-
-Box::Box() {
-}
-
-
-Box::Box(const AABox& b) {
- init(b.low(), b.high());
-}
-
-Box::Box(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-void Box::serialize(class BinaryOutput& b) const {
- int i;
- for (i = 0; i < 8; ++i) {
- _corner[i].serialize(b);
- }
-
- // Other state can be reconstructed
-}
-
-
-void Box::deserialize(class BinaryInput& b) {
- int i;
-
- _center = Vector3::zero();
- for (i = 0; i < 8; ++i) {
- _corner[i].deserialize(b);
- _center += _corner[i];
- }
-
- _center = _center / 8;
-
- // Reconstruct other state from the corners
- _axis[0] = _corner[5] - _corner[4];
- _axis[1] = _corner[7] - _corner[4];
- _axis[2] = _corner[0] - _corner[4];
-
- for (i = 0; i < 3; ++i) {
- _extent[i] = _axis[i].magnitude();
- _axis[i] /= _extent[i];
- }
-
- _volume = _extent.x * _extent.y * _extent.z;
-
- _area = 2 *
- (_extent.x * _extent.y +
- _extent.y * _extent.z +
- _extent.z * _extent.x);
-}
-
-
-Box::Box(
- const Vector3& min,
- const Vector3& max) {
-
- init(min.min(max), min.max(max));
-
-}
-
-void Box::init(
- const Vector3& min,
- const Vector3& max) {
-
- debugAssert(
- (min.x <= max.x) &&
- (min.y <= max.y) &&
- (min.z <= max.z));
-
- setMany(0, 1, 2, 3, z, max);
- setMany(4, 5, 6, 7, z, min);
-
- setMany(1, 2, 5, 6, x, max);
- setMany(0, 3, 4, 7, x, min);
-
- setMany(3, 2, 6, 7, y, max);
- setMany(0, 1, 5, 4, y, min);
-
- _extent = max - min;
-
- _axis[0] = Vector3::unitX();
- _axis[1] = Vector3::unitY();
- _axis[2] = Vector3::unitZ();
-
- if (_extent.isFinite()) {
- _volume = _extent.x * _extent.y * _extent.z;
- } else {
- _volume = G3D::inf();
- }
-
- debugAssert(! isNaN(_extent.x));
-
- _area = 2 *
- (_extent.x * _extent.y +
- _extent.y * _extent.z +
- _extent.z * _extent.x);
-
- _center = (max + min) / 2;
-
- // If the extent is infinite along an axis, make the center zero to avoid NaNs
- for (int i = 0; i < 3; ++i) {
- if (! G3D::isFinite(_extent[i])) {
- _center[i] = 0.0f;
- }
- }
-}
-
-
-float Box::volume() const {
- return _volume;
-}
-
-
-float Box::area() const {
- return _area;
-}
-
-
-void Box::getLocalFrame(CoordinateFrame& frame) const {
-
- frame.rotation = Matrix3(
- _axis[0][0], _axis[1][0], _axis[2][0],
- _axis[0][1], _axis[1][1], _axis[2][1],
- _axis[0][2], _axis[1][2], _axis[2][2]);
-
- frame.translation = _center;
-}
-
-
-CoordinateFrame Box::localFrame() const {
- CoordinateFrame out;
- getLocalFrame(out);
- return out;
-}
-
-
-void Box::getFaceCorners(int f, Vector3& v0, Vector3& v1, Vector3& v2, Vector3& v3) const {
- switch (f) {
- case 0:
- v0 = _corner[0]; v1 = _corner[1]; v2 = _corner[2]; v3 = _corner[3];
- break;
-
- case 1:
- v0 = _corner[1]; v1 = _corner[5]; v2 = _corner[6]; v3 = _corner[2];
- break;
-
- case 2:
- v0 = _corner[7]; v1 = _corner[6]; v2 = _corner[5]; v3 = _corner[4];
- break;
-
- case 3:
- v0 = _corner[2]; v1 = _corner[6]; v2 = _corner[7]; v3 = _corner[3];
- break;
-
- case 4:
- v0 = _corner[3]; v1 = _corner[7]; v2 = _corner[4]; v3 = _corner[0];
- break;
-
- case 5:
- v0 = _corner[1]; v1 = _corner[0]; v2 = _corner[4]; v3 = _corner[5];
- break;
-
- default:
- debugAssert((f >= 0) && (f < 6));
- }
-}
-
-
-
-int Box::dummy = 0;
-
-bool Box::culledBy(
- const Array<Plane>& plane,
- int& cullingPlane,
- const uint32 _inMask,
- uint32& childMask) const {
-
- uint32 inMask = _inMask;
- assert(plane.size() < 31);
-
- childMask = 0;
-
- // See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < plane.size(); ++p) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
-
- Vector3 corner;
-
- int numContained = 0;
- int v = 0;
-
- // We can early-out only if we have found one point on each
- // side of the plane (i.e. if we are straddling). That
- // occurs when (numContained < v) && (numContained > 0)
- for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) {
- if (plane[p].halfSpaceContains(_corner[v])) {
- ++numContained;
- }
- }
-
- if (numContained == 0) {
- // Plane p culled the box
- cullingPlane = p;
-
- // The caller should not recurse into the children,
- // since the parent is culled. If they do recurse,
- // make them only test against this one plane, which
- // will immediately cull the volume.
- childMask = 1 << p;
- return true;
-
- } else if (numContained < v) {
- // The bounding volume straddled the plane; we have
- // to keep testing against this plane
- childMask |= (1 << p);
- }
- }
-
- // Move on to the next bit.
- inMask = inMask >> 1;
- }
-
- // None of the planes could cull this box
- cullingPlane = -1;
- return false;
-}
-
-
-bool Box::culledBy(
- const Array<Plane>& plane,
- int& cullingPlane,
- const uint32 _inMask) const {
-
- uint32 inMask = _inMask;
- assert(plane.size() < 31);
-
- // See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < plane.size(); ++p) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
-
- bool culled = true;
-
- int v;
-
- // Assume this plane culls all points. See if there is a point
- // not culled by the plane... early out when at least one point
- // is in the positive half space.
- for (v = 0; (v < 8) && culled; ++v) {
- culled = ! plane[p].halfSpaceContains(corner(v));
- }
-
- if (culled) {
- // Plane p culled the box
- cullingPlane = p;
-
- return true;
- }
- }
-
- // Move on to the next bit.
- inMask = inMask >> 1;
- }
-
- // None of the planes could cull this box
- cullingPlane = -1;
- return false;
-}
-
-
-bool Box::contains(
- const Vector3& point) const {
-
- // Form axes from three edges, transform the point into that
- // space, and perform 3 interval tests
-
- Vector3 u = _corner[4] - _corner[0];
- Vector3 v = _corner[3] - _corner[0];
- Vector3 w = _corner[1] - _corner[0];
-
- Matrix3 M = Matrix3(u.x, v.x, w.x,
- u.y, v.y, w.y,
- u.z, v.z, w.z);
-
- // M^-1 * (point - _corner[0]) = point in unit cube's object space
- // compute the inverse of M
- Vector3 osPoint = M.inverse() * (point - _corner[0]);
-
- return
- (osPoint.x >= 0) &&
- (osPoint.y >= 0) &&
- (osPoint.z >= 0) &&
- (osPoint.x <= 1) &&
- (osPoint.y <= 1) &&
- (osPoint.z <= 1);
-}
-
-#undef setMany
-
-
-void Box::getRandomSurfacePoint(Vector3& P, Vector3& N) const {
- float aXY = _extent.x * _extent.y;
- float aYZ = _extent.y * _extent.z;
- float aZX = _extent.z * _extent.x;
-
- float r = (float)uniformRandom(0, aXY + aYZ + aZX);
-
- // Choose evenly between positive and negative face planes
- float d = (uniformRandom(0, 1) < 0.5f) ? -1.0f : 1.0f;
-
- // The probability of choosing a given face is proportional to
- // its area.
- if (r < aXY) {
- P = _axis[0] * (float)uniformRandom(-0.5, 0.5) * _extent.x +
- _axis[1] * (float)uniformRandom(-0.5, 0.5) * _extent.y +
- _center + _axis[2] * d * _extent.z * 0.5f;
- N = _axis[2] * d;
- } else if (r < aYZ) {
- P = _axis[1] * (float)uniformRandom(-0.5, 0.5) * _extent.y +
- _axis[2] * (float)uniformRandom(-0.5, 0.5) * _extent.z +
- _center + _axis[0] * d * _extent.x * 0.5f;
- N = _axis[0] * d;
- } else {
- P = _axis[2] * (float)uniformRandom(-0.5, 0.5) * _extent.z +
- _axis[0] *(float) uniformRandom(-0.5, 0.5) * _extent.x +
- _center + _axis[1] * d * _extent.y * 0.5f;
- N = _axis[1] * d;
- }
-}
-
-
-Vector3 Box::randomInteriorPoint() const {
- Vector3 sum = _center;
-
- for (int a = 0; a < 3; ++a) {
- sum += _axis[a] * (float)uniformRandom(-0.5, 0.5) * _extent[a];
- }
-
- return sum;
-}
-
-Box Box::inf() {
- return Box(-Vector3::inf(), Vector3::inf());
-}
-
-void Box::getBounds(class AABox& aabb) const {
-
- Vector3 lo = _corner[0];
- Vector3 hi = lo;
-
- for (int v = 1; v < 8; ++v) {
- const Vector3& C = _corner[v];
- lo = lo.min(C);
- hi = hi.max(C);
- }
-
- aabb = AABox(lo, hi);
-}
-
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/Capsule.cpp b/externals/g3dlite/G3D.lib/source/Capsule.cpp
deleted file mode 100644
index fbcb56fe97b..00000000000
--- a/externals/g3dlite/G3D.lib/source/Capsule.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- @file Capsule.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-02-07
- @edited 2005-08-18
-
- Copyright 2000-2005, Morgan McGuire.
- All rights reserved.
- */
-
-#include "G3D/Capsule.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/LineSegment.h"
-#include "G3D/Sphere.h"
-#include "G3D/CoordinateFrame.h"
-#include "G3D/Line.h"
-#include "G3D/AABox.h"
-
-namespace G3D {
-
-Capsule::Capsule(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-Capsule::Capsule() {
-}
-
-
-Capsule::Capsule(const Vector3& _p1, const Vector3& _p2, float _r)
- : p1(_p1), p2(_p2), _radius(_r) {
-}
-
-
-void Capsule::serialize(class BinaryOutput& b) const {
- p1.serialize(b);
- p2.serialize(b);
- b.writeFloat64(_radius);
-}
-
-
-void Capsule::deserialize(class BinaryInput& b) {
- p1.deserialize(b);
- p2.deserialize(b);
- _radius = b.readFloat64();
-}
-
-
-Line Capsule::axis() const {
- return Line::fromTwoPoints(p1, p2);
-}
-
-
-float Capsule::volume() const {
- return
- // Sphere volume
- pow(_radius, 3) * pi() * 4 / 3 +
-
- // Cylinder volume
- pow(_radius, 2) * (p1 - p2).magnitude();
-}
-
-
-float Capsule::area() const {
-
- return
- // Sphere area
- pow(_radius, 2) * 4 * pi() +
-
- // Cylinder area
- twoPi() * _radius * (p1 - p2).magnitude();
-}
-
-
-void Capsule::getBounds(AABox& out) const {
- Vector3 min = p1.min(p2) - (Vector3(1, 1, 1) * _radius);
- Vector3 max = p1.max(p2) + (Vector3(1, 1, 1) * _radius);
-
- out = AABox(min, max);
-}
-
-
-bool Capsule::contains(const Vector3& p) const {
- return LineSegment::fromTwoPoints(p1, p2).distanceSquared(p) <= square(radius());
-}
-
-
-void Capsule::getRandomSurfacePoint(Vector3& p, Vector3& N) const {
- float h = height();
- float r = radius();
-
- // Create a random point on a standard capsule and then rotate to the global frame.
-
- // Relative areas
- float capRelArea = sqrt(r) / 2.0f;
- float sideRelArea = r * h;
-
- float r1 = uniformRandom(0, capRelArea * 2 + sideRelArea);
-
- if (r1 < capRelArea * 2) {
-
- // Select a point uniformly at random on a sphere
- N = Sphere(Vector3::zero(), 1).randomSurfacePoint();
- p = N * r;
- p.y += sign(p.y) * h / 2.0f;
- } else {
- // Side
- float a = uniformRandom(0, (float)twoPi());
- N.x = cos(a);
- N.y = 0;
- N.z = sin(a);
- p.x = N.x * r;
- p.z = N.y * r;
- p.y = uniformRandom(-h / 2.0f, h / 2.0f);
- }
-
- // Transform to world space
- CoordinateFrame cframe;
- getReferenceFrame(cframe);
-
- p = cframe.pointToWorldSpace(p);
- N = cframe.normalToWorldSpace(N);
-}
-
-
-void Capsule::getReferenceFrame(CoordinateFrame& cframe) const {
- cframe.translation = center();
-
- Vector3 Y = (p1 - p2).direction();
- Vector3 X = (abs(Y.dot(Vector3::unitX())) > 0.9) ? Vector3::unitY() : Vector3::unitX();
- Vector3 Z = X.cross(Y).direction();
- X = Y.cross(Z);
- cframe.rotation.setColumn(0, X);
- cframe.rotation.setColumn(1, Y);
- cframe.rotation.setColumn(2, Z);
-}
-
-
-Vector3 Capsule::randomInteriorPoint() const {
- float h = height();
- float r = radius();
-
- // Create a random point in a standard capsule and then rotate to the global frame.
-
- Vector3 p;
-
- float hemiVolume = pi() * (r*r*r) * 4 / 6.0;
- float cylVolume = pi() * square(r) * h;
-
- float r1 = uniformRandom(0, 2.0 * hemiVolume + cylVolume);
-
- if (r1 < 2.0 * hemiVolume) {
-
- p = Sphere(Vector3::zero(), r).randomInteriorPoint();
-
- p.y += sign(p.y) * h / 2.0f;
-
- } else {
-
- // Select a point uniformly at random on a disk
- float a = uniformRandom(0, (float)twoPi());
- float r2 = sqrt(uniformRandom(0, 1)) * r;
-
- p = Vector3(cos(a) * r2,
- uniformRandom(-h / 2.0f, h / 2.0f),
- sin(a) * r2);
- }
-
- // Transform to world space
- CoordinateFrame cframe;
- getReferenceFrame(cframe);
-
- return cframe.pointToWorldSpace(p);
-}
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/CollisionDetection.cpp b/externals/g3dlite/G3D.lib/source/CollisionDetection.cpp
deleted file mode 100644
index 16650bc1a96..00000000000
--- a/externals/g3dlite/G3D.lib/source/CollisionDetection.cpp
+++ /dev/null
@@ -1,2152 +0,0 @@
-/**
- @file CollisionDetection.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @cite Bounce direction based on Paul Nettle's ftp://ftp.3dmaileffects.com/pub/FluidStudios/CollisionDetection/Fluid_Studios_Generic_Collision_Detection_for_Games_Using_Ellipsoids.pdf and comments by Max McGuire. Ray-sphere code by Eric Haines.
-
- @created 2001-11-24
- @edited 2008-10-10
- */
-
-#include "G3D/CoordinateFrame.h"
-#include "G3D/platform.h"
-#include "G3D/CollisionDetection.h"
-#include "G3D/debugAssert.h"
-#include "G3D/vectorMath.h"
-#include "G3D/Capsule.h"
-#include "G3D/Plane.h"
-#include "G3D/Line.h"
-#include "G3D/LineSegment.h"
-#include "G3D/Sphere.h"
-#include "G3D/Box.h"
-#include "G3D/Triangle.h"
-#include "G3D/Vector3.h"
-#include "G3D/AABox.h"
-
-namespace G3D {
-
-bool CollisionDetection::ignoreBool;
-Vector3 CollisionDetection::ignore;
-Array<Vector3> CollisionDetection::ignoreArray;
-
-
-
-Vector3 CollisionDetection::separatingAxisForSolidBoxSolidBox(
- const int separatingAxisIndex,
- const Box & box1,
- const Box & box2) {
- debugAssert(separatingAxisIndex >= 0);
- debugAssert(separatingAxisIndex < 15);
- Vector3 axis;
- if (separatingAxisIndex < 3) {
- axis = box1.axis(separatingAxisIndex);
- } else if (separatingAxisIndex < 6) {
- axis = box2.axis(separatingAxisIndex - 3);
- } else {
- int box1Index = (separatingAxisIndex - 6) / 3;
- int box2Index = (separatingAxisIndex - 6) % 3;
- axis = cross(box1.axis(box1Index), box2.axis(box2Index));
- }
- return axis;
-}
-
-#ifdef _MSC_VER
-# pragma warning (push)
-# pragma warning (disable : 4244)
-#endif
-
-float CollisionDetection::projectedDistanceForSolidBoxSolidBox(
- const int separatingAxisIndex,
- const Vector3 & a,
- const Vector3 & b,
- const Vector3 & D,
- const double* c,
- const double* ca,
- const double* ad,
- const double* bd)
-{
- (void)D;
-
- float R0 = 0.0f;
- float R1 = 0.0f;
- float R = 0.0f;
- switch (separatingAxisIndex) {
- case 0:
- // A0
- R0 = a[0];
- R1 = b[0] * ca[0] + b[1] * ca[1] + b[2] * ca[2];
- R = fabs(ad[0]);
- break;
- case 1:
- // A1
- R0 = a[1];
- R1 = b[0] * ca[3] + b[1] * ca[4] + b[2] * ca[5];
- R = fabs(ad[1]);
- break;
- case 2:
- // A2
- R0 = a[2];
- R1 = b[0] * ca[6] + b[1] * ca[7] + b[2] * ca[8];
- R = fabs(ad[2]);
- break;
- case 3:
- // B0
- R0 = a[0] * ca[0] + a[1] * ca[3] + a[2] * ca[6];
- R1 = b[0];
- R = fabs(bd[0]);
- break;
- case 4:
- // B1
- R0 = a[0] * ca[1] + a[1] * ca[4] + a[2] * ca[7];
- R1 = b[1];
- R = fabs(bd[1]);
- break;
- case 5:
- // B2
- R0 = a[0] * ca[2] + a[1] * ca[5] + a[2] * ca[8];
- R1 = b[2];
- R = fabs(bd[2]);
- break;
- case 6:
- // A0 x B0
- R0 = a[1] * ca[6] + a[2] * ca[3];
- R1 = b[1] * ca[2] + b[2] * ca[1];
- R = fabs(c[3] * ad[2] - c[6] * ad[1]);
- break;
- case 7:
- // A0 x B1
- R0 = a[1] * ca[7] + a[2] * ca[4];
- R1 = b[0] * ca[2] + b[2] * ca[0];
- R = fabs(c[4] * ad[2] - c[7] * ad[1]);
- break;
- case 8:
- // A0 x B2
- R0 = a[1] * ca[8] + a[2] * ca[5];
- R1 = b[0] * ca[1] + b[1] * ca[0];
- R = fabs(c[5] * ad[2] - c[8] * ad[1]);
- break;
- case 9:
- // A1 x B0
- R0 = a[0] * ca[6] + a[2] * ca[0];
- R1 = b[1] * ca[5] + b[2] * ca[4];
- R = fabs(c[6] * ad[0] - c[0] * ad[2]);
- break;
- case 10:
- // A1 x B1
- R0 = a[0] * ca[7] + a[2] * ca[1];
- R1 = b[0] * ca[5] + b[2] * ca[3];
- R = fabs(c[7] * ad[0] - c[1] * ad[2]);
- break;
- case 11:
- // A1 x B2
- R0 = a[0] * ca[8] + a[2] * ca[2];
- R1 = b[0] * ca[4] + b[1] * ca[3];
- R = fabs(c[8] * ad[0] - c[2] * ad[2]);
- break;
- case 12:
- // A2 x B0
- R0 = a[0] * ca[3] + a[1] * ca[0];
- R1 = b[1] * ca[8] + b[2] * ca[7];
- R = fabs(c[0] * ad[1] - c[3] * ad[0]);
- break;
- case 13:
- // A2 x B1
- R0 = a[0] * ca[4] + a[1] * ca[1];
- R1 = b[0] * ca[8] + b[2] * ca[6];
- R = fabs(c[1] * ad[1] - c[4] * ad[0]);
- break;
- case 14:
- // A2 x B2
- R0 = a[0] * ca[5] + a[1] * ca[2];
- R1 = b[0] * ca[7] + b[1] * ca[6];
- R = fabs(c[2] * ad[1] - c[5] * ad[0]);
- break;
- default:
- debugAssertM(false, "fell through switch statement");
- }
-
- return (R - (R0 + R1));
-}
-
-
-bool CollisionDetection::parallelAxisForSolidBoxSolidBox(
- const double* ca,
- const double epsilon,
- int & axis1,
- int & axis2) {
- const double parallelDot = 1.0 - epsilon;
- for (int i = 0; i < 9; i++) {
- if (ca[i] >= parallelDot) {
- axis1 = i / 3;
- axis2 = i % 3;
- return true;
- }
- }
- return false;
-}
-
-
-
-
-void CollisionDetection::fillSolidBoxSolidBoxInfo(
- const Box & box1,
- const Box & box2,
- Vector3 & a,
- Vector3 & b,
- Vector3 & D,
- double* c,
- double* ca,
- double* ad,
- double* bd) {
- // length between center and each side of box1 and box2
- a = box1.extent() * 0.5;
- b = box2.extent() * 0.5;
-
- // difference between centers of box1 and box2
- D = box2.center() - box1.center();
-
- // store the value of all possible dot products between the
- // axes of box1 and box2, c_{row, col} in the Eberly paper
- // corresponds to c[row * 3 + col] for this 9 element array.
- //
- // c[] holds signed values, ca[] hold absolute values
- for (int i = 0; i < 9; i++) {
- c[i] = dot(box1.axis(i / 3), box2.axis(i % 3));
- ca[i] = fabs(c[i]);
- }
-
- // store all possible dot products between the axes of box1 and D,
- // as well as the axes of box2 and D
- for (int i = 0; i < 3; i++) {
- ad[i] = dot(box1.axis(i), D);
- bd[i] = dot(box2.axis(i), D);
- }
-}
-
-
-
-bool CollisionDetection::conservativeBoxBoxTest(
- const Vector3 & a, const Vector3 & b, const Vector3 & D) {
- // do a quick bounding sphere test because it is relatively
- // cheap, (three dot products, two sqrts, and a few others)
- double boxRadius1 = a.magnitude();
- double boxRadius2 = b.magnitude();
- return (D.squaredMagnitude() < square(boxRadius1 + boxRadius2));
-}
-
-
-
-
-bool CollisionDetection::fixedSolidBoxIntersectsFixedSolidBox(
- const Box& box1,
- const Box& box2,
- const int lastSeparatingAxis) {
- // for explanations of the variable please refer to the
- // paper and fillSolidBoxSolidBoxInfo()
- Vector3 a;
- Vector3 b;
- Vector3 D;
- double c[9];
- double ca[9];
- double ad[3];
- double bd[3];
-
- fillSolidBoxSolidBoxInfo(box1, box2, a, b, D, c, ca, ad, bd);
-
- int dummy1, dummy2;
- bool parallelAxes = parallelAxisForSolidBoxSolidBox(ca, 0.00001,
- dummy1, dummy2);
-
- // check the separating axis from the last time step
- if (lastSeparatingAxis != -1 &&
- (lastSeparatingAxis < 6 || !parallelAxes)) {
- double projectedDistance = projectedDistanceForSolidBoxSolidBox(
- lastSeparatingAxis, a, b, D, c, ca, ad, bd);
-
- // the separating axis from the last time step is still
- // valid, the boxes do not intersect
- if (projectedDistance > 0.0) {
- return false;
- }
- }
-
- // test if the boxes can be separated by a plane normal to
- // any of the three axes of box1, any of the three axes of box2,
- // or any of the 9 possible cross products of axes from box1
- // and box2
- for (int i = 0; i < 15; i++) {
- // do not need to check edge-edge cases if any two of
- // the axes are parallel
- if (parallelAxes && i == 6) {
- return true;
- }
-
- double projectedDistance =
- projectedDistanceForSolidBoxSolidBox(i, a, b, D, c, ca, ad, bd);
-
- // found a separating axis, the boxes do not intersect
- if (projectedDistance > 0.0) {
- return false;
- }
- }
-
- return true;
-}
-
-
-
-void CollisionDetection::closestPointsBetweenLineAndLine(
- const Line & line1,
- const Line & line2,
- Vector3 & closest1,
- Vector3 & closest2) {
- // TODO make accessors for Line that don't make a copy of data
- Vector3 P0 = line1.point();
- Vector3 u = line1.direction();
- Vector3 Q0 = line2.point();
- Vector3 v = line2.direction();
- Vector3 w0 = P0 - Q0;
-
- // a = 1.0, c = 1.0
- double b = dot(u, v);
- double d = dot(u, w0);
- double e = dot(v, w0);
- double D = 1.0 - b * b;
- double sc, tc;
-
- static const double epsilon = 0.00001;
-
- if (D < epsilon) {
- // lines are parallel, choose P0 as one point, find the point
- // on line2 that is closest to P0
- sc = 0.0;
- tc = (b > 1.0) ? (d / b) : (e / 1.0);
- } else {
- // lines are not parallel
- sc = (b * e - 1.0 * d) / D;
- tc = (1.0 * e - b * d) / D;
- }
-
- closest1 = P0 + (sc * u);
- closest2 = Q0 + (tc * v);
-}
-
-
-
-float CollisionDetection::penetrationDepthForFixedBoxFixedBox(
- const Box& box1,
- const Box& box2,
- Array<Vector3>& contactPoints,
- Array<Vector3>& contactNormals,
- const int lastSeparatingAxis) {
-
- contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
- contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
-
- Vector3 a;
- Vector3 b;
- Vector3 D;
- double c[9];
- double ca[9];
- double ad[3];
- double bd[3];
-
- debugAssert(lastSeparatingAxis >= -1);
- debugAssert(lastSeparatingAxis < 15);
-
- fillSolidBoxSolidBoxInfo(box1, box2, a, b, D, c, ca, ad, bd);
-
- int axis1, axis2;
- bool parallelAxes = parallelAxisForSolidBoxSolidBox(ca, 0.00001,
- axis1, axis2);
-
-
- // check the separating axis from the last time step
- if (lastSeparatingAxis != -1 &&
- (lastSeparatingAxis < 6 || !parallelAxes)) {
- float projectedDistance = projectedDistanceForSolidBoxSolidBox(
- lastSeparatingAxis, a, b, D, c, ca, ad, bd);
-
- // the separating axis from the last time step is still
- // valid, the boxes do not intersect
- if (projectedDistance > 0.0) {
- return -projectedDistance;
- }
- }
-
- // test if the boxes can be separated by a plane normal to
- // any of the three axes of box1, any of the three axes of box2,
- // (test 9 possible cross products later)
- float penetration = -(float)G3D::inf();
- int penetrationAxisIndex = -1;
-
- for (int i = 0; i < 6; i++) {
- float projectedDistance =
- projectedDistanceForSolidBoxSolidBox(i, a, b, D, c, ca, ad, bd);
-
- // found a separating axis, the boxes do not intersect
- if (projectedDistance > 0.0) {
- return -projectedDistance;
- }
-
- // keep track of the axis that is least violated
- if (projectedDistance > penetration) {
- penetration = projectedDistance;
- penetrationAxisIndex = i;
- }
- }
-
-
- // for each edge-edge case we have to adjust the magnitude of
- // penetration since we did not include the dot(L, L) denominator
- // that can be smaller than 1.0 for the edge-edge cases.
- if (!parallelAxes) {
- double edgeDistances[9];
-
- // run through edge-edge cases to see if we can find a separating axis
- for (int i = 6; i < 15; i++) {
- float projectedDistance =
- projectedDistanceForSolidBoxSolidBox(i, a, b, D, c, ca, ad, bd);
-
- // found a separating axis, the boxes do not intersect,
- // correct magnitude and return projected distance
- if (projectedDistance > 0.0) {
- Vector3 L = separatingAxisForSolidBoxSolidBox(i, box1, box2);
- projectedDistance /= dot(L, L);
- return -projectedDistance;
- }
-
- edgeDistances[i - 6] = projectedDistance;
- }
-
- // no separating axis found, the boxes do intersect,
- // correct the magnitudes of the projectedDistance values
- for (int i = 6; i < 15; i++) {
- // find the negative penetration value with the smallest magnitude,
- // the adjustment done for the edge-edge cases only increases
- // magnitude by dividing by a number smaller than 1 and greater than 0
- float projectedDistance = (float)edgeDistances[i - 6];
- if (projectedDistance > penetration) {
- Vector3 L = separatingAxisForSolidBoxSolidBox(i, box1, box2);
- projectedDistance /= dot(L, L);
- if (projectedDistance > penetration) {
- penetration = projectedDistance;
- penetrationAxisIndex = i;
- }
- }
- }
- }
-
- // get final separating axis vector
- Vector3 L = separatingAxisForSolidBoxSolidBox(penetrationAxisIndex,
- box1, box2);
-
- // set L to be the normal that faces away from box1
- if (dot(L, D) < 0) {
- L = -L;
- }
-
- Vector3 contactPoint;
-
- if (penetrationAxisIndex < 6) {
- // vertex to face collision, find deepest colliding vertex
- const Box* vertexBox;
- const Box* faceBox;
- Vector3 faceNormal = L;
-
- // L will be the outward facing normal for the faceBox
- if (penetrationAxisIndex < 3) {
- faceBox = & box1;
- vertexBox = & box2;
- if (dot(L, D) < 0) {
- faceNormal = -L;
- }
- } else {
- faceBox = & box2;
- vertexBox = & box1;
- if (dot(L, D) > 0) {
- faceNormal = -L;
- }
- }
-
- // find the vertex that is farthest away in the direction
- // face normal direction
- int deepestPointIndex = 0;
- float deepestPointDot = dot(faceNormal, vertexBox->corner(0));
- for (int i = 1; i < 8; i++) {
- float dotProduct = dot(faceNormal, vertexBox->corner(i));
- if (dotProduct < deepestPointDot) {
- deepestPointDot = dotProduct;
- deepestPointIndex = i;
- }
- }
-
- // return the point half way between the deepest point and the
- // contacting face
- contactPoint = vertexBox->corner(deepestPointIndex) +
- (-penetration * 0.5 * faceNormal);
- } else {
- // edge-edge case, find the two ege lines
- int edge1 = (penetrationAxisIndex - 6) / 3;
- int edge2 = (penetrationAxisIndex - 6) % 3;
- Vector3 linePoint1 = box1.center();
- Vector3 linePoint2 = box2.center();
- Vector3 lineDir1;
- Vector3 lineDir2;
-
- // find edge line by finding the edge axis, and the
- // other two axes that are closest to the other box
- for (int i = 0; i < 3; i++ ) {
- if (i == edge1) {
- lineDir1 = box1.axis(i);
- } else {
- Vector3 axis = box1.axis(i);
- if (dot(axis, L) < 0) {
- axis = -axis;
- }
- linePoint1 += axis * a[i];
- }
-
- if (i == edge2) {
- lineDir2 = box2.axis(i);
- } else {
- Vector3 axis = box2.axis(i);
- if (dot(axis, L) > 0) {
- axis = -axis;
- }
- linePoint2 += axis * b[i];
- }
- }
-
- // make lines from the two closest edges, and find
- // the points that on each line that are closest to the other
- Line line1 = Line::fromPointAndDirection(linePoint1, lineDir1);
- Line line2 = Line::fromPointAndDirection(linePoint2, lineDir2);
- Vector3 closest1;
- Vector3 closest2;
-
- closestPointsBetweenLineAndLine(line1, line2, closest1, closest2);
-
- // take the average of the two closest edge points for the final
- // contact point
- contactPoint = (closest1 + closest2) * 0.5;
- }
-
- contactPoints.push(contactPoint);
- contactNormals.push(L);
-
- return -penetration;
-
-}
-
-
-
-
-float CollisionDetection::penetrationDepthForFixedSphereFixedBox(
- const Sphere& sphere,
- const Box& box,
- Array<Vector3>& contactPoints,
- Array<Vector3>& contactNormals) {
-
- contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
- contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
-
- // In its local coordinate frame, the box measures
- // 2 * halfExtent[a] along dimesion a.
- Vector3 halfExtent(box.extent(0), box.extent(1), box.extent(2));
- halfExtent *= 0.5f;
-
- CoordinateFrame boxFrame;
- box.getLocalFrame(boxFrame);
-
- // Transform the sphere to the box's coordinate frame.
- Vector3 center = boxFrame.pointToObjectSpace(sphere.center);
-
- // Find the square of the distance from the sphere to the box
-
-
- // Distance along each axis from the closest side of the box
- // to the sphere center. Negative values are *inside* the box.
- Vector3 distOutsideBox;
-
- // Divide space up into the 27 regions corresponding
- // to {+|-|0}X, {+|-|0}Y, {+|-|0}Z and classify the
- // sphere center into one of them.
- Vector3 centerRegion;
-
- // In the edge collision case, the edge is between vertices
- // (constant + variable) and (constant - variable).
- Vector3 constant, variable;
-
- int numNonZero = 0;
-
- // Iterate over axes
- for (int a = 0; a < 3; ++a) {
- // For each (box side), see which direction the sphere
- // is outside the box (positive or negative). Add the
- // square of that distance to the total distance from
- // the box.
-
- float distanceFromLow = -halfExtent[a] - center[a];
- float distanceFromHigh = center[a] - halfExtent[a];
-
- if (fabsf(distanceFromLow) < fabsf(distanceFromHigh)) {
- distOutsideBox[a] = distanceFromLow;
- } else {
- distOutsideBox[a] = distanceFromHigh;
- }
-
- if (distanceFromLow < 0.0) {
- if (distanceFromHigh < 0.0) {
- // Inside the box
- centerRegion[a] = 0.0;
- variable[a] = 1.0;
- } else {
- // Off the high side
- centerRegion[a] = 1.0;
- constant[a] = halfExtent[a];
- ++numNonZero;
- }
- } else if (distanceFromHigh < 0.0) {
- // Off the low side
- centerRegion[a] = -1.0;
- constant[a] = -halfExtent[a];
- ++numNonZero;
- } else {
- debugAssertM(false,
- "distanceFromLow and distanceFromHigh cannot both be positive");
- }
- }
-
- // Squared distance between the outside of the box and the
- // sphere center.
- float d2 = Vector3::zero().max(distOutsideBox).squaredMagnitude();
-
- if (d2 > square(sphere.radius)) {
- // There is no penetration because the distance is greater
- // than the radius of the sphere. This is the common case
- // and we quickly exit.
- return -1;
- }
-
- // We know there is some penetration but need to classify it.
- //
- // Examine the region that contains the center of the sphere. If
- // there is exactly one non-zero axis, the collision is with a
- // plane. If there are exactly two non-zero axes, the collision
- // is with an edge. If all three axes are non-zero, the collision is
- // with a vertex. If there are no non-zero axes, the center is inside
- // the box.
-
- double depth = -1;
- switch (numNonZero) {
- case 3: // Vertex collision
- // The collision point is the vertex at constant, the normal
- // is the vector from there to the sphere center.
- contactNormals.append(boxFrame.normalToWorldSpace(constant - center));
- contactPoints.append(boxFrame.pointToWorldSpace(constant));
- depth = sphere.radius - sqrt(d2);
- break;
-
- case 2: // Edge collision
- {
- // TODO: unwrapping the edge constructor and closest point
- // code will probably make it faster.
-
- // Determine the edge
- Line line = Line::fromPointAndDirection(constant, variable);
-
- // Penetration depth:
- depth = sphere.radius - sqrt(d2);
-
- // The contact point is the closes point to the sphere on the line
- Vector3 X = line.closestPoint(center);
- contactNormals.append(boxFrame.normalToWorldSpace(X - center).direction());
- contactPoints.append(boxFrame.pointToWorldSpace(X));
- }
- break;
-
- case 1: // Plane collision
- {
- // The plane normal is the centerRegion vector,
- // so the sphere normal is the negative. Take
- // it to world space from box-space.
-
- // Center region doesn't need to be normalized because
- // it is known to contain only one non-zero value
- // and that value is +/- 1.
- Vector3 N = boxFrame.normalToWorldSpace(-centerRegion);
- contactNormals.append(N);
-
- // Penetration depth:
- depth = sphere.radius - sqrtf(d2);
-
- // Compute the contact point from the penetration depth
- contactPoints.append(sphere.center + N * (sphere.radius - depth));
- }
- break;
-
- case 0: // Volume collision
-
- // The sphere center is inside the box. This is an easy case
- // to handle. Note that all axes of distOutsideBox must
- // be negative.
-
- // Arbitratily choose the sphere center as a contact point
- contactPoints.append(sphere.center);
-
- // Find the least-negative penetration axis.
- //
- // We could have computed this during the loop over the axes,
- // but since volume collisions are rare (they only occur with
- // large time steps), this case will seldom be executed and
- // should not be optimized at the expense of the others.
- if (distOutsideBox.x > distOutsideBox.y) {
- if (distOutsideBox.x > distOutsideBox.z) {
- // Smallest penetration on x-axis
- // Chose normal based on which side we're closest to.
- // Keep in mind that this is a normal to the sphere,
- // so it is the inverse of the box normal.
- if (center.x > 0) {
- contactNormals.append(boxFrame.normalToWorldSpace(-Vector3::unitX()));
- } else {
- contactNormals.append(boxFrame.normalToWorldSpace(Vector3::unitX()));
- }
- depth = -distOutsideBox.x;
- } else {
- // Smallest penetration on z-axis
- goto ZAXIS;
- }
- } else if (distOutsideBox.y > distOutsideBox.z) {
- // Smallest penetration on y-axis
- // Chose normal based on which side we're closest to.
- // Keep in mind that this is a normal to the sphere,
- // so it is the inverse of the box normal.
- if (center.y > 0) {
- contactNormals.append(boxFrame.normalToWorldSpace(-Vector3::unitY()));
- } else {
- contactNormals.append(boxFrame.normalToWorldSpace(Vector3::unitY()));
- }
- depth = -distOutsideBox.y;
- } else {
- // Smallest on z-axis
-ZAXIS:
- // Chose normal based on which side we're closest to.
- // Keep in mind that this is a normal to the sphere,
- // so it is the inverse of the box normal.
- if (center.z > 0) {
- contactNormals.append(boxFrame.normalToWorldSpace(-Vector3::unitZ()));
- } else {
- contactNormals.append(boxFrame.normalToWorldSpace(Vector3::unitZ()));
- }
- depth = -distOutsideBox.z;
- }
- break;
-
- default:
- debugAssertM(false, "Fell through switch");
- break;
- }
-
- return depth;
-}
-
-
-float CollisionDetection::penetrationDepthForFixedSphereFixedSphere(
- const Sphere& sphereA,
- const Sphere& sphereB,
- Array<Vector3>& contactPoints,
- Array<Vector3>& contactNormals) {
-
- Vector3 axis = sphereB.center - sphereA.center;
- double radius = sphereA.radius + sphereB.radius;
- double mag = axis.magnitude();
- axis /= mag;
- double depth = -(mag - radius);
-
- contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
- contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
-
- if (depth >= 0) {
- contactPoints.append(sphereA.center + axis * (sphereA.radius - depth / 2));
- contactNormals.append(axis);
- }
-
- return depth;
-}
-
-
-float CollisionDetection::penetrationDepthForFixedSphereFixedPlane(
- const Sphere& sphereA,
- const Plane& planeB,
- Array<Vector3>& contactPoints,
- Array<Vector3>& contactNormals) {
-
- Vector3 N;
- double d;
-
- planeB.getEquation(N, d);
-
- double depth = -(sphereA.center.dot(N) + d - sphereA.radius);
-
- contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
- contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
-
- if (depth >= 0) {
- contactPoints.append(N * (depth - sphereA.radius) + sphereA.center);
- contactNormals.append(N);
- }
-
- return depth;
-}
-
-
-float CollisionDetection::penetrationDepthForFixedBoxFixedPlane(
- const Box& box,
- const Plane& plane,
- Array<Vector3>& contactPoints,
- Array<Vector3>& contactNormals) {
-
- Vector3 N;
- double d;
-
- plane.getEquation(N, d);
-
- contactPoints.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
- contactNormals.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
-
- float lowest = (float)inf();
- for (int i = 0; i < 8; ++i) {
- const Vector3 vertex = box.corner(i);
-
- float x = vertex.dot(N) + (float)d;
-
- if (x <= 0) {
- // All vertices below the plane should be contact points.
- contactPoints.append(vertex);
- contactNormals.append(-N);
- }
-
- lowest = min(lowest, x);
- }
-
- // Depth should be a positive number
- return -lowest;
-}
-
-
-float CollisionDetection::collisionTimeForMovingPointFixedPlane(
- const Vector3& point,
- const Vector3& velocity,
- const Plane& plane,
- Vector3& location,
- Vector3& outNormal) {
-
- // Solve for the time at which normal.dot(point + velocity) + d == 0.
- double d;
- Vector3 normal;
- plane.getEquation(normal, d);
-
- float vdotN = velocity.dot(normal);
- float pdotN = point.dot(normal);
-
- if (fuzzyEq(pdotN + d, 0)) {
- // The point is *in* the plane.
- location = point;
- outNormal = normal;
- return 0;
- }
-
- if (vdotN >= 0) {
- // no collision will occur
- location = Vector3::inf();
- return (float)inf();
- }
-
- float t = -(pdotN + d) / vdotN;
- if (t < 0) {
- location = Vector3::inf();
- return (float)inf();
- } else {
- location = point + velocity * t;
- outNormal = normal;
- return t;
- }
-}
-
-
-float CollisionDetection::collisionTimeForMovingPointFixedSphere(
- const Vector3& point,
- const Vector3& velocity,
- const Sphere& sphere,
- Vector3& location,
- Vector3& outNormal) {
-
- double speed = velocity.magnitude();
- Vector3 direction = velocity / speed;
-
- Vector3 L = sphere.center - point;
- double d = L.dot(direction);
-
- double L2 = L.dot(L);
- double R2 = sphere.radius * sphere.radius;
- double D2 = d * d;
-
- if ((d < 0) && (L2 > R2)) {
- location = Vector3::inf();
- return inf();
- }
-
- double M2 = L2 - D2;
-
- if (M2 > R2) {
- location = Vector3::inf();
- return inf();
- }
-
- double q = sqrt(R2 - M2);
- double time;
-
- if (L2 > R2) {
- time = d - q;
- } else {
- time = d + q;
- }
-
- time /= speed;
-
- location = point + velocity * time;
- outNormal = (location - sphere.center).direction();
-
- return time;
-}
-
-
-float CollisionDetection::collisionTimeForMovingSphereFixedSphere(
- const Sphere& movingSphere,
- const Vector3& velocity,
- const Sphere& fixedSphere,
- Vector3& location,
- Vector3& outNormal) {
-
- double time = collisionTimeForMovingPointFixedSphere(movingSphere.center, velocity, Sphere(fixedSphere.center, fixedSphere.radius + movingSphere.radius), location, outNormal);
-
- if (time < inf()) {
- // Location is now the center of the moving sphere at the collision time.
- // Adjust for the size of the moving sphere. Two spheres always collide
- // along a line between their centers.
- location += (location - fixedSphere.center) * movingSphere.radius / fixedSphere.radius;
- }
-
- return time;
-}
-
-
-/*
-float CollisionDetection::collisionTimeForMovingPointFixedTriangle(
- const Vector3& point,
- const Vector3& velocity,
- const Triangle& triangle,
- Vector3& outLocation,
- Vector3& outNormal) {
-
- double time = collisionTimeForMovingPointFixedPlane(point, velocity, triangle.plane(), outLocation, outNormal);
-
- if (time == inf()) {
- // No collision with the plane of the triangle.
- return inf();
- }
-
- if (isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(), outLocation, triangle.primaryAxis())) {
- // Collision occured inside the triangle
- return time;
- } else {
- // Missed the triangle
- outLocation = Vector3::inf();
- return inf();
- }
-}*/
-
-/*
-float CollisionDetection::collisionTimeForMovingPointFixedTriangle(
- const Vector3& orig,
- const Vector3& dir,
- const Vector3& vert0,
- const Vector3& vert1,
- const Vector3& vert2) {
-
- // Barycenteric coords
- double u, v;
- #define EPSILON 0.000001
- #define CROSS(dest,v1,v2) \
- dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
- dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \
- dest[2]=v1[0]*v2[1]-v1[1]*v2[0];
-
- #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
-
- #define SUB(dest,v1,v2) \
- dest[0]=v1[0]-v2[0]; \
- dest[1]=v1[1]-v2[1]; \
- dest[2]=v1[2]-v2[2];
-
- double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
-
- // find vectors for two edges sharing vert0
- SUB(edge1, vert1, vert0);
- SUB(edge2, vert2, vert0);
-
- // begin calculating determinant - also used to calculate U parameter
- CROSS(pvec, dir, edge2);
-
- // if determinant is near zero, ray lies in plane of triangle
- const double det = DOT(edge1, pvec);
-
- if (det < EPSILON) {
- return inf();
- }
-
- // calculate distance from vert0 to ray origin
- SUB(tvec, orig, vert0);
-
- // calculate U parameter and test bounds
- u = DOT(tvec, pvec);
- if ((u < 0.0) || (u > det)) {
- // Hit the plane outside the triangle
- return inf();
- }
-
- // prepare to test V parameter
- CROSS(qvec, tvec, edge1);
-
- // calculate V parameter and test bounds
- v = DOT(dir, qvec);
- if ((v < 0.0) || (u + v > det)) {
- // Hit the plane outside the triangle
- return inf();
- }
-
- // calculate t, scale parameters, ray intersects triangle
- // If we want u,v, we can compute this
- // double t = DOT(edge2, qvec);
- //const double inv_det = 1.0 / det;
- //t *= inv_det;
- //u *= inv_det;
- //v *= inv_det;
- // return t;
-
- // Case where we don't need correct (u, v):
-
- const double t = DOT(edge2, qvec);
-
- if (t >= 0) {
- // Note that det must be positive
- return t / det;
- } else {
- // We had to travel backwards in time to intersect
- return inf();
- }
-
- #undef EPSILON
- #undef CROSS
- #undef DOT
- #undef SUB
-}
-*/
-
-float CollisionDetection::collisionTimeForMovingPointFixedBox(
- const Vector3& point,
- const Vector3& velocity,
- const Box& box,
- Vector3& location,
- Vector3& outNormal) {
-
- double bestTime;
-
- Vector3 normal;
- Vector3 v[4];
-
- // Prime the loop
- int f = 0;
- box.getFaceCorners(f, v[0], v[1], v[2], v[3]);
- bestTime = collisionTimeForMovingPointFixedRectangle(point, velocity, v[0], v[1], v[2], v[3], location, normal);
- outNormal = normal;
-
- // Check other faces
- for (f = 1; f < 6; ++f) {
- Vector3 pos;
- box.getFaceCorners(f, v[0], v[1], v[2], v[3]);
- float time = collisionTimeForMovingPointFixedRectangle(point, velocity, v[0], v[1], v[2], v[3], pos, normal);
- if (time < bestTime) {
- bestTime = time;
- outNormal = normal;
- location = pos;
- }
- }
-
- return bestTime;
-}
-
-
-float CollisionDetection::collisionTimeForMovingPointFixedAABox(
- const Vector3& origin,
- const Vector3& dir,
- const AABox& box,
- Vector3& location,
- bool& Inside,
- Vector3& normal) {
-
- if (collisionLocationForMovingPointFixedAABox(origin, dir, box, location, Inside, normal)) {
- return (location - origin).magnitude();
- } else {
- return (float)inf();
- }
-}
-
-
-bool CollisionDetection::collisionLocationForMovingPointFixedAABox(
- const Vector3& origin,
- const Vector3& dir,
- const AABox& box,
- Vector3& location,
- bool& Inside,
- Vector3& normal) {
-
- // Integer representation of a floating-point value.
- #define IR(x) ((uint32&)x)
-
- Inside = true;
- const Vector3& MinB = box.low();
- const Vector3& MaxB = box.high();
- Vector3 MaxT(-1.0f, -1.0f, -1.0f);
-
- // Find candidate planes.
- for (int i = 0; i < 3; ++i) {
- if (origin[i] < MinB[i]) {
- location[i] = MinB[i];
- Inside = false;
-
- // Calculate T distances to candidate planes
- if (IR(dir[i])) {
- MaxT[i] = (MinB[i] - origin[i]) / dir[i];
- }
- } else if (origin[i] > MaxB[i]) {
- location[i] = MaxB[i];
- Inside = false;
-
- // Calculate T distances to candidate planes
- if (IR(dir[i])) {
- MaxT[i] = (MaxB[i] - origin[i]) / dir[i];
- }
- }
- }
-
- if (Inside) {
- // Ray origin inside bounding box
- location = origin;
- return false;
- }
-
- // Get largest of the maxT's for final choice of intersection
- int WhichPlane = 0;
- if (MaxT[1] > MaxT[WhichPlane]) {
- WhichPlane = 1;
- }
-
- if (MaxT[2] > MaxT[WhichPlane]) {
- WhichPlane = 2;
- }
-
- // Check final candidate actually inside box
- if (IR(MaxT[WhichPlane]) & 0x80000000) {
- // Miss the box
- return false;
- }
-
- for (int i = 0; i < 3; ++i) {
- if (i != WhichPlane) {
- location[i] = origin[i] + MaxT[WhichPlane] * dir[i];
- if ((location[i] < MinB[i]) ||
- (location[i] > MaxB[i])) {
- // On this plane we're outside the box extents, so
- // we miss the box
- return false;
- }
- }
- }
-
- // Choose the normal to be the plane normal facing into the ray
- normal = Vector3::zero();
- normal[WhichPlane] = (dir[WhichPlane] > 0) ? -1.0 : 1.0;
-
- return true;
-
- #undef IR
-}
-
-
-
-float CollisionDetection::collisionTimeForMovingPointFixedRectangle(
- const Vector3& point,
- const Vector3& velocity,
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- Vector3& location,
- Vector3& outNormal) {
-
- Plane plane = Plane(v0, v1, v2);
-
- float time = collisionTimeForMovingPointFixedPlane(point, velocity, plane, location, outNormal);
-
- if (time == inf()) {
- // No collision is ever going to happen
- return time;
- }
-
- if (isPointInsideRectangle(v0, v1, v2, v3, plane.normal(), location)) {
- // The intersection point is inside the rectangle; that is the location where
- // the point hits the rectangle.
- return time;
- } else {
- return inf();
- }
-}
-
-/** Used by findRayCapsuleIntersection.
- @cite From magic software http://www.magic-software.com/Source/Intersection3D/MgcIntr3DLinCap.cpp */
-static int findRayCapsuleIntersectionAux(
- const Vector3& rkOrigin,
- const Vector3& rkDirection,
- const Capsule& rkCapsule,
- double afT[2]) {
-
- Vector3 capsuleDirection = rkCapsule.point(1) - rkCapsule.point(0);
-
- // set up quadratic Q(t) = a*t^2 + 2*b*t + c
- Vector3 kU, kV, kW = capsuleDirection;
- float fWLength = kW.unitize();
- Vector3::generateOrthonormalBasis(kU, kV, kW);
- Vector3 kD(kU.dot(rkDirection), kV.dot(rkDirection), kW.dot(rkDirection));
- float fDLength = kD.unitize();
-
- float fEpsilon = 1e-6f;
-
- float fInvDLength = 1.0f/fDLength;
- Vector3 kDiff = rkOrigin - rkCapsule.point(0);
- Vector3 kP(kU.dot(kDiff),kV.dot(kDiff),kW.dot(kDiff));
- float fRadiusSqr = square(rkCapsule.radius());
-
- float fInv, fA, fB, fC, fDiscr, fRoot, fT, fTmp;
-
- // Is the velocity parallel to the capsule direction? (or zero)
- if ((abs(kD.z) >= 1.0f - fEpsilon) || (fDLength < fEpsilon)) {
-
- float fAxisDir = rkDirection.dot(capsuleDirection);
-
- fDiscr = fRadiusSqr - kP.x*kP.x - kP.y*kP.y;
- if ((fAxisDir < 0) && (fDiscr >= 0.0f)) {
- // Velocity anti-parallel to the capsule direction
- fRoot = sqrt(fDiscr);
- afT[0] = (kP.z + fRoot)*fInvDLength;
- afT[1] = -(fWLength - kP.z + fRoot)*fInvDLength;
- return 2;
- } else if ((fAxisDir > 0) && (fDiscr >= 0.0f)) {
- // Velocity parallel to the capsule direction
- fRoot = sqrt(fDiscr);
- afT[0] = -(kP.z + fRoot)*fInvDLength;
- afT[1] = (fWLength - kP.z + fRoot)*fInvDLength;
- return 2;
- } else {
- // sphere heading wrong direction, or no velocity at all
- return 0;
- }
- }
-
- // test intersection with infinite cylinder
- fA = kD.x*kD.x + kD.y*kD.y;
- fB = kP.x*kD.x + kP.y*kD.y;
- fC = kP.x*kP.x + kP.y*kP.y - fRadiusSqr;
- fDiscr = fB*fB - fA*fC;
- if (fDiscr < 0.0f) {
- // line does not intersect infinite cylinder
- return 0;
- }
-
- int iQuantity = 0;
-
- if (fDiscr > 0.0f) {
- // line intersects infinite cylinder in two places
- fRoot = sqrt(fDiscr);
- fInv = 1.0f/fA;
- fT = (-fB - fRoot)*fInv;
- fTmp = kP.z + fT*kD.z;
- if ((0.0f <= fTmp) && (fTmp <= fWLength)) {
- afT[iQuantity] = fT * fInvDLength;
- iQuantity++;
- }
-
- fT = (-fB + fRoot)*fInv;
- fTmp = kP.z + fT*kD.z;
-
- if ((0.0f <= fTmp) && (fTmp <= fWLength)) {
- afT[iQuantity++] = fT*fInvDLength;
- }
-
- if (iQuantity == 2) {
- // line intersects capsule wall in two places
- return 2;
- }
- } else {
- // line is tangent to infinite cylinder
- fT = -fB/fA;
- fTmp = kP.z + fT*kD.z;
- if ((0.0f <= fTmp) && (fTmp <= fWLength)) {
- afT[0] = fT*fInvDLength;
- return 1;
- }
- }
-
- // test intersection with bottom hemisphere
- // fA = 1
- fB += kP.z*kD.z;
- fC += kP.z*kP.z;
- fDiscr = fB*fB - fC;
- if (fDiscr > 0.0f) {
- fRoot = sqrt(fDiscr);
- fT = -fB - fRoot;
- fTmp = kP.z + fT*kD.z;
- if (fTmp <= 0.0f) {
- afT[iQuantity++] = fT*fInvDLength;
- if (iQuantity == 2) {
- return 2;
- }
- }
-
- fT = -fB + fRoot;
- fTmp = kP.z + fT*kD.z;
- if (fTmp <= 0.0f) {
- afT[iQuantity++] = fT*fInvDLength;
- if (iQuantity == 2) {
- return 2;
- }
- }
- } else if (fDiscr == 0.0f) {
- fT = -fB;
- fTmp = kP.z + fT*kD.z;
- if (fTmp <= 0.0f) {
- afT[iQuantity++] = fT*fInvDLength;
- if (iQuantity == 2) {
- return 2;
- }
- }
- }
-
- // test intersection with top hemisphere
- // fA = 1
- fB -= kD.z*fWLength;
- fC += fWLength*(fWLength - 2.0f*kP.z);
-
- fDiscr = fB*fB - fC;
- if (fDiscr > 0.0f) {
- fRoot = sqrt(fDiscr);
- fT = -fB - fRoot;
- fTmp = kP.z + fT*kD.z;
- if (fTmp >= fWLength) {
- afT[iQuantity++] = fT*fInvDLength;
- if (iQuantity == 2) {
- return 2;
- }
- }
-
- fT = -fB + fRoot;
- fTmp = kP.z + fT*kD.z;
- if (fTmp >= fWLength) {
- afT[iQuantity++] = fT*fInvDLength;
- if (iQuantity == 2) {
- return 2;
- }
- }
- } else if (fDiscr == 0.0f) {
- fT = -fB;
- fTmp = kP.z + fT*kD.z;
- if (fTmp >= fWLength) {
- afT[iQuantity++] = fT*fInvDLength;
- if (iQuantity == 2) {
- return 2;
- }
- }
- }
-
- return iQuantity;
-}
-
-
-/** Used by collisionTimeForMovingPointFixedCapsule.
- @cite From magic software http://www.magic-software.com/Source/Intersection3D/MgcIntr3DLinCap.cpp
-
- @param rkRay The ray
- @param rkCapsule The capsule
- @param riQuantity The number of intersections found
- @param akPoint The intersections found
- @return True if there is at least one intersection
- */
-static bool findRayCapsuleIntersection(
- const Ray& rkRay,
- const Capsule& rkCapsule,
- int& riQuantity,
- Vector3 akPoint[2]) {
-
- double afT[2];
- riQuantity = findRayCapsuleIntersectionAux(rkRay.origin, rkRay.direction, rkCapsule, afT);
-
- // Only return intersections that occur in the future
- int iClipQuantity = 0;
- int i;
- for (i = 0; i < riQuantity; i++) {
- if (afT[i] >= 0.0f) {
- akPoint[iClipQuantity] = rkRay.origin + afT[i] * rkRay.direction;
- iClipQuantity++;
- }
- }
-
- riQuantity = iClipQuantity;
- return (riQuantity > 0);
-}
-
-float CollisionDetection::collisionTimeForMovingPointFixedCapsule(
- const Vector3& _point,
- const Vector3& velocity,
- const Capsule& capsule,
- Vector3& location,
- Vector3& outNormal) {
-
- float timeScale = velocity.magnitude();
-
- if (timeScale == 0.0f) {
- timeScale = 1;
- }
-
- Vector3 direction = velocity / timeScale;
- int numIntersections;
- Vector3 intersection[2];
- findRayCapsuleIntersection(Ray::fromOriginAndDirection(_point, direction), capsule, numIntersections, intersection);
-
- if (numIntersections == 2) {
- // A collision can only occur if there are two intersections. If there is one
- // intersection, that one is exiting the capsule.
-
- // Find the entering intersection (the first one that occurs).
- float d0 = (intersection[0] - _point).squaredMagnitude();
- float d1 = (intersection[1] - _point).squaredMagnitude();
-
- // Compute the surface normal (if we aren't ignoring the result)
- if (&outNormal != &ignore) {
- Vector3 p2 = LineSegment::fromTwoPoints(capsule.point(0), capsule.point(1)).closestPoint(_point);
- outNormal = (_point - p2).direction();
- }
-
- if (d0 > d1) {
- location = intersection[1];
- return sqrt(d1) / timeScale;
- } else {
- location = intersection[0];
- return sqrt(d0) / timeScale;
- }
- } else {
- // No entering intersection discovered; return no intersection.
- location = Vector3::inf();
- return inf();
- }
-}
-
-
-float CollisionDetection::collisionTimeForMovingSphereFixedPlane(
- const Sphere& sphere,
- const Vector3& velocity,
- const Plane& plane,
- Vector3& location,
- Vector3& outNormal) {
-
- if (sphere.radius == 0) {
- // Optimization for zero radius sphere
- return collisionTimeForMovingPointFixedPlane(sphere.center, velocity, plane, location, outNormal);
- }
-
- // The collision point on the sphere will be the point at
- // center - (radius * normal). Collisions only occur when
- // the sphere is travelling into the plane.
-
- double d;
- plane.getEquation(outNormal, d);
-
- double vdotN = velocity.dot(outNormal);
-
- if (fuzzyGt(vdotN, 0)) {
- // No collision when the sphere is moving towards a backface.
- location = Vector3::inf();
- return (float)inf();
- }
-
- float cdotN = sphere.center.dot(outNormal);
-
- // Distance from the center to the plane
- float distance = cdotN + (float)d;
-
- // Where is the collision on the sphere?
- Vector3 point = sphere.center - (sphere.radius * outNormal);
-
- if (fuzzyLe(G3D::abs(distance), sphere.radius)) {
- // Already interpenetrating
- location = sphere.center - distance * outNormal;
- return 0;
- } else {
- return collisionTimeForMovingPointFixedPlane(point, velocity, plane, location, outNormal);
- }
-
-}
-
-
-float CollisionDetection::collisionTimeForMovingSphereFixedTriangle(
- const class Sphere& sphere,
- const Vector3& velocity,
- const Triangle& triangle,
- Vector3& outLocation,
- float b[3]) {
-
- Vector3 dummy;
- float time = collisionTimeForMovingSphereFixedPlane(sphere, velocity, triangle.plane(),
- outLocation, dummy);
-
- if (time == inf()) {
- // No collision is ever going to happen
- return time;
- }
-
- // We will hit the plane of the triangle at *time*. See if
- // the intersection point actually is within the triangle.
-
- if (isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(),
- outLocation, b, triangle.primaryAxis())) {
-
- // The intersection point is inside the triangle; that is the location where
- // the sphere hits the triangle.
-
-# ifdef G3D_DEBUG
- {
- // Internal consistency checks
- debugAssertM(b[0] >= 0.0 && b[0] <= 1.0f, "Intersection is outside triangle.");
- debugAssertM(b[1] >= 0.0 && b[1] <= 1.0f, "Intersection is outside triangle.");
- debugAssertM(b[2] >= 0.0 && b[2] <= 1.0f, "Intersection is outside triangle.");
- Vector3 blend =
- b[0] * triangle.vertex(0) +
- b[1] * triangle.vertex(1) +
- b[2] * triangle.vertex(2);
- debugAssertM(blend.fuzzyEq(outLocation), "Barycentric coords don't match intersection.");
- // Call again so that we can debug the problem
- // isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(),
- // outLocation, b, triangle.primaryAxis());
- }
-# endif
-
- return time;
- }
-
- // The collision (if it exists) is with a point on the triangle perimeter.
- // Switch over to moving the triangle towards a fixed sphere and see at what time
- // they will hit.
-
- // Closest point on the triangle to the sphere intersection with the plane.
- int edgeIndex;
- const Vector3& point = closestPointOnTrianglePerimeter(triangle._vertex, triangle.edgeDirection,
- triangle.edgeMagnitude, outLocation, edgeIndex);
-
- float t = 0;
- if (! sphere.contains(point)) {
- // The point is outside the sphere--see when it will hit
- t = collisionTimeForMovingPointFixedSphere(point, -velocity, sphere, dummy, dummy);
- }
-
- if (t < inf()) {
- outLocation = point;
- // Compute Barycentric coords
-
- // Index of the next vertex
- static const int next[] = {1, 2, 0};
-
- // Project along the edge in question.
- // Avoid sqrt by taking advantage of the existing edgeDirection unit vector.
- b[next[edgeIndex]] = (outLocation - triangle._vertex[edgeIndex]).dot
- (triangle.edgeDirection[edgeIndex]) / triangle.edgeMagnitude[edgeIndex];
-
- b[edgeIndex] = 1.0f - b[next[edgeIndex]];
-
- b[next[next[edgeIndex]]] = 0.0f;
-
-# ifdef G3D_DEBUG
- {
- // Internal consistency checks
- for (int i = 0; i < 3; ++i) {
- debugAssertM(fuzzyGe(b[i], 0.0f) && fuzzyLe(b[i], 1.0f), "Intersection is outside triangle.");
- }
- Vector3 blend =
- b[0] * triangle.vertex(0) +
- b[1] * triangle.vertex(1) +
- b[2] * triangle.vertex(2);
- debugAssertM(blend.fuzzyEq(outLocation),
- format("Barycentric coords don't match intersection. %s != %s",
- blend.toString().c_str(),
- outLocation.toString().c_str()));
-
- // Call again so that we can debug the problem
- collisionTimeForMovingPointFixedSphere(point, -velocity, sphere, dummy, dummy);
- }
-# endif
-
- // Due to tiny roundoffs, these values might be slightly out of bounds.
- // Ensure that they are legal. Note that the above debugging code
- // verifies that we are not clamping truly illegal values.
- for (int i = 0; i < 3; ++i) {
- b[i] = clamp(b[i], 0.0f, 1.0f);
- }
- }
-
- // The collision occured at the point, if it occured. The normal
- // was the plane normal, computed above.
-
- return t;
-}
-
-
-float CollisionDetection::collisionTimeForMovingSphereFixedRectangle(
- const Sphere& sphere,
- const Vector3& velocity,
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- Vector3& location,
- Vector3& outNormal) {
-
- Plane plane(v0, v1, v2);
-
- float time = collisionTimeForMovingSphereFixedPlane(sphere, velocity, plane, location, outNormal);
-
- if (time == inf()) {
- // No collision is ever going to happen
- return time;
- }
-
- if (isPointInsideRectangle(v0, v1, v2, v3, plane.normal(), location)) {
- // The intersection point is inside the rectangle; that is the location where
- // the sphere hits the rectangle.
- return time;
- }
-
- // Switch over to moving the rectangle towards a fixed sphere and see at what time
- // they will hit.
-
- Vector3 point = closestPointToRectanglePerimeter(v0, v1, v2, v3, sphere.center);
-
- Vector3 dummy;
- double t = collisionTimeForMovingPointFixedSphere(point, -velocity, sphere, location, dummy);
-
- // Normal is the plane normal, location is the original location of the point.
- location = point;
-
- return t;
-}
-
-
-float CollisionDetection::collisionTimeForMovingSphereFixedBox(
- const Sphere& sphere,
- const Vector3& velocity,
- const Box& box,
- Vector3& location,
- Vector3& outNormal) {
-
- if (fixedSolidSphereIntersectsFixedSolidBox(sphere, box)) {
- // TODO: Compute more useful location and normal?
- location = sphere.center;
- outNormal = Vector3::zero();
- return 0;
- }
-
- float bestTime;
-
- Vector3 v[4];
- int f = 0;
- box.getFaceCorners(f, v[0], v[1], v[2], v[3]);
- bestTime = collisionTimeForMovingSphereFixedRectangle(sphere, velocity, v[0], v[1], v[2], v[3], location, outNormal);
-
- for (f = 1; f < 6; ++f) {
- Vector3 pos, normal;
- box.getFaceCorners(f, v[0], v[1], v[2], v[3]);
- float time = collisionTimeForMovingSphereFixedRectangle(sphere, velocity, v[0], v[1], v[2], v[3], pos, normal);
- if (time < bestTime) {
- bestTime = time;
- location = pos;
- outNormal = normal;
- }
- }
-
- return bestTime;
-}
-
-
-float CollisionDetection::collisionTimeForMovingSphereFixedCapsule(
- const Sphere& sphere,
- const Vector3& velocity,
- const Capsule& capsule,
- Vector3& location,
- Vector3& outNormal) {
-
- (void)outNormal;
-
- Capsule _capsule(capsule.point(0), capsule.point(1), capsule.radius() + sphere.radius);
-
- Vector3 normal;
- double time = collisionTimeForMovingPointFixedCapsule(sphere.center, velocity, _capsule, location, normal);
-
- if (time < inf()) {
- // Location is now the position of the center of the sphere at the time of collision.
- // We have to adjust the collision location for the size of the sphere.
- location -= sphere.radius * normal;
- }
-
- return time;
-}
-
-
-Vector3 CollisionDetection::bounceDirection(
- const Sphere& sphere,
- const Vector3& velocity,
- const float collisionTime,
- const Vector3& collisionLocation,
- const Vector3& collisionNormal) {
-
- // Location when the collision occurs
- Vector3 sphereLocation = sphere.center + velocity * collisionTime;
-
- Vector3 normal = (sphereLocation - collisionLocation);
- if (fuzzyEq(normal.squaredMagnitude(), 0)) {
- normal = collisionNormal;
- } else {
- normal.unitize();
- }
-
- Vector3 direction = velocity.direction();
-
- // Reflect direction about the normal
- return direction - 2.0 * normal * normal.dot(direction);
-}
-
-
-Vector3 CollisionDetection::slideDirection(
- const Sphere& sphere,
- const Vector3& velocity,
- const float collisionTime,
- const Vector3& collisionLocation) {
-
- Vector3 sphereLocation = sphere.center + velocity * collisionTime;
- Vector3 normal = (sphereLocation - collisionLocation).direction();
- Vector3 direction = velocity.direction();
-
- // subtract off the part in the direction away from the normal.
- return direction - normal * normal.dot(direction);
-}
-
-
-Vector3 CollisionDetection::closestPointOnLineSegment(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& point) {
-
- const Vector3& edge = (v1 - v0);
- float edgeLength = edge.magnitude();
-
- if (edgeLength == 0) {
- // The line segment is a point
- return v0;
- }
-
- return closestPointOnLineSegment(v0, v1, edge / edgeLength, edgeLength, point);
-}
-
-
-Vector3 CollisionDetection::closestPointOnLineSegment(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& edgeDirection,
- const float edgeLength,
- const Vector3& point) {
-
- debugAssert((v1 - v0).direction().fuzzyEq(edgeDirection));
- debugAssert(fuzzyEq((v1 - v0).magnitude(), edgeLength));
-
- // Vector towards the point
- const Vector3& c = point - v0;
-
- // Projected onto the edge itself
- float t = edgeDirection.dot(c);
-
- if (t <= 0) {
- // Before the start
- return v0;
- } else if (t >= edgeLength) {
- // After the end
- return v1;
- } else {
- // At distance t along the edge
- return v0 + edgeDirection * t;
- }
-}
-
-
-Vector3 CollisionDetection::closestPointOnTrianglePerimeter(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& point) {
-
- Vector3 v[3] = {v0, v1, v2};
- Vector3 edgeDirection[3] = {(v1 - v0), (v2 - v1), (v0 - v2)};
- float edgeLength[3];
-
- for (int i = 0; i < 3; ++i) {
- edgeLength[i] = edgeDirection[i].magnitude();
- edgeDirection[i] /= edgeLength[i];
- }
-
- int edgeIndex;
- return closestPointOnTrianglePerimeter(v, edgeDirection, edgeLength, point, edgeIndex);
-}
-
-
-Vector3 CollisionDetection::closestPointOnTrianglePerimeter(
- const Vector3 v[3],
- const Vector3 edgeDirection[3],
- const float edgeLength[3],
- const Vector3& point,
- int& edgeIndex) {
-
- // Closest point on segment from v[i] to v[i + 1]
- Vector3 r[3];
-
- // Distance squared from r[i] to point
- float d[3];
-
- // Index of the next point
- static const int next[] = {1, 2, 0};
-
- for (int i = 0; i < 3; ++i) {
- r[i] = closestPointOnLineSegment(v[i], v[next[i]], edgeDirection[i], edgeLength[i], point);
- d[i] = (r[i] - point).squaredMagnitude();
- }
-
- if (d[0] < d[1]) {
- if (d[0] < d[2]) {
- // Between v0 and v1
- edgeIndex = 0;
- } else {
- // Between v2 and v0
- edgeIndex = 2;
- }
- } else {
- if (d[1] < d[2]) {
- // Between v1 and v2
- edgeIndex = 1;
- } else {
- // Between v2 and v0
- edgeIndex = 2;
- }
- }
-
-# ifdef G3D_DEBUG
- {
- Vector3 diff = r[edgeIndex] - v[edgeIndex];
- debugAssertM(fuzzyEq(diff.direction().dot(edgeDirection[edgeIndex]), 1.0f) ||
- diff.fuzzyEq(Vector3::zero()), "Point not on correct triangle edge");
- float frac = diff.dot(edgeDirection[edgeIndex])/edgeLength[edgeIndex];
- debugAssertM(frac >= -0.000001, "Point off low side of edge.");
- debugAssertM(frac <= 1.000001, "Point off high side of edge.");
- }
-# endif
-
- return r[edgeIndex];
-}
-
-
-bool CollisionDetection::isPointInsideTriangle(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& normal,
- const Vector3& point,
- float b[3],
- Vector3::Axis primaryAxis) {
-
- if (primaryAxis == Vector3::DETECT_AXIS) {
- primaryAxis = normal.primaryAxis();
- }
-
- // Check that the point is within the triangle using a Barycentric
- // coordinate test on a two dimensional plane.
- int i, j;
-
- switch (primaryAxis) {
- case Vector3::X_AXIS:
- i = Vector3::Y_AXIS;
- j = Vector3::Z_AXIS;
- break;
-
- case Vector3::Y_AXIS:
- i = Vector3::Z_AXIS;
- j = Vector3::X_AXIS;
- break;
-
- case Vector3::Z_AXIS:
- i = Vector3::X_AXIS;
- j = Vector3::Y_AXIS;
- break;
-
- default:
- // This case is here to supress a warning on Linux
- i = j = 0;
- debugAssertM(false, "Should not get here.");
- break;
- }
-
- // See if all barycentric coordinates are non-negative
-
- // 2D area via cross product
-# define AREA2(d, e, f) (((e)[i] - (d)[i]) * ((f)[j] - (d)[j]) - ((f)[i] - (d)[i]) * ((e)[j] - (d)[j]))
-
- // Area of the polygon
- float area = AREA2(v0, v1, v2);
- if (area == 0) {
- // This triangle has zero area, so the point must not
- // be in it unless the triangle point is the test point.
- return (v0 == point);
- }
-
- debugAssert(area != 0);
-
- float invArea = 1.0f / area;
-
- // (avoid normalization until absolutely necessary)
- b[0] = AREA2(point, v1, v2) * invArea;
-
- if ((b[0] < 0.0f) || (b[0] > 1.0f)) {
- return false;
- }
-
- b[1] = AREA2(v0, point, v2) * invArea;
- if ((b[1] < 0.0f) || (b[1] > 1.0f)) {
- return false;
- }
-
- b[2] = 1.0f - b[0] - b[1];
-
-# undef AREA2
-
- return (b[2] >= 0.0f) && (b[2] <= 1.0f);
-}
-
-
-bool CollisionDetection::isPointInsideRectangle(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- const Vector3& normal,
- const Vector3& point) {
-
- return isPointInsideTriangle(v0, v1, v2, normal, point) ||
- isPointInsideTriangle(v2, v3, v0, normal, point);
-}
-
-
-Vector3 CollisionDetection::closestPointToRectanglePerimeter(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- const Vector3& point) {
-
- Vector3 r0 = closestPointOnLineSegment(v0, v1, point);
- Vector3 r1 = closestPointOnLineSegment(v1, v2, point);
- Vector3 r2 = closestPointOnLineSegment(v2, v3, point);
- Vector3 r3 = closestPointOnLineSegment(v3, v0, point);
-
- double d0 = (r0 - point).squaredMagnitude();
- double d1 = (r1 - point).squaredMagnitude();
- double d2 = (r2 - point).squaredMagnitude();
- double d3 = (r3 - point).squaredMagnitude();
-
- if (d0 < d1) {
- if (d0 < d2) {
- if (d0 < d3) {
- return r0;
- } else {
- return r3;
- }
- } else {
- if (d2 < d3) {
- return r2;
- } else {
- return r3;
- }
- }
- } else {
- if (d1 < d2) {
- if (d1 < d3) {
- return r1;
- } else {
- return r3;
- }
- } else {
- if (d2 < d3) {
- return r2;
- } else {
- return r3;
- }
- }
- }
-}
-
-
-Vector3 CollisionDetection::closestPointToRectangle(
- const Vector3& v0,
- const Vector3& v1,
- const Vector3& v2,
- const Vector3& v3,
- const Vector3& point) {
-
- Plane plane(v0, v1, v2);
-
- // Project the point into the plane
- double a, b, c, d;
- plane.getEquation(a, b, c, d);
-
- double distance = a*point.x + b*point.y + c*point.z + d;
- Vector3 planePoint = point - distance * plane.normal();
-
- if (isPointInsideRectangle(v0, v1, v2, v3, plane.normal(), planePoint)) {
- return planePoint;
- } else {
- return closestPointToRectanglePerimeter(v0, v1, v2, v3, planePoint);
- }
-}
-
-
-bool CollisionDetection::fixedSolidSphereIntersectsFixedSolidSphere(
- const Sphere& sphere1,
- const Sphere& sphere2) {
-
- return (sphere1.center - sphere2.center).squaredMagnitude() < square(sphere1.radius + sphere2.radius);
-}
-
-
-bool CollisionDetection::fixedSolidSphereIntersectsFixedSolidBox(
- const Sphere& sphere,
- const Box& box) {
-
- // If the center of the sphere is within the box, the whole
- // sphere is within the box.
- if (box.contains(sphere.center)) {
- return true;
- }
-
- float r2 = square(sphere.radius);
-
- // Find the closest point on the surface of the box to the sphere. If
- // this point is within the sphere's radius, they intersect.
- int f;
- for (f = 0; f < 6; ++f) {
- Vector3 v0, v1, v2, v3;
- box.getFaceCorners(f, v0, v1, v2, v3);
- if ((closestPointToRectangle(v0, v1, v2, v3, sphere.center) - sphere.center).squaredMagnitude() <= r2) {
- return true;
- }
- }
-
- return false;
-}
-
-
-bool CollisionDetection::movingSpherePassesThroughFixedBox(
- const Sphere& sphere,
- const Vector3& velocity,
- const Box& box,
- double timeLimit) {
-
- // If they intersect originally, they definitely pass through each other.
- if (fixedSolidSphereIntersectsFixedSolidBox(sphere, box)) {
- return true;
- }
-
- // See if the sphere hits the box during the time period.
- Vector3 dummy1, dummy2;
-
- return (collisionTimeForMovingSphereFixedBox(sphere, velocity, box, dummy1, dummy2) < timeLimit);
-}
-
-
-bool CollisionDetection::movingSpherePassesThroughFixedSphere(
- const Sphere& sphere,
- const Vector3& velocity,
- const Sphere& fixedSphere,
- double timeLimit) {
-
- if (fixedSolidSphereIntersectsFixedSolidSphere(sphere, fixedSphere)) {
- return true;
- }
-
- // Extend the fixed sphere by the radius of the moving sphere
- Sphere bigFixed(fixedSphere.center, fixedSphere.radius + sphere.radius);
- Vector3 dummy1, dummy2;
-
- // If the sphere collides with the other sphere during the time limit, it passes through
- return (collisionTimeForMovingPointFixedSphere(sphere.center, velocity, bigFixed, dummy1, dummy2) < timeLimit);
-}
-
-
-
-bool CollisionDetection::fixedSolidSphereIntersectsFixedTriangle(
- const Sphere& sphere,
- const Triangle& triangle) {
-
- // How far is the sphere from the plane of the triangle
- const Plane& plane = triangle.plane();
-
- // Does the closest point to the sphere center lie within the triangle?
- Vector3 v = plane.closestPoint(sphere.center);
-
- // Is the closest point to the plane within the sphere?
- if ((v - sphere.center).squaredLength() <= square(sphere.radius)) {
- // Is it also within the triangle?
- float b[3];
- if (isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(),
- v, b, triangle.primaryAxis())){
- // The closest point is inside the triangle
- return true;
- }
- }
-
- // ignored
- int edgeIndex;
-
- v = closestPointOnTrianglePerimeter(triangle._vertex, triangle.edgeDirection, triangle.edgeMagnitude, sphere.center, edgeIndex);
-
- // Is the closest point within the sphere?
- return ((v - sphere.center).squaredLength() <= square(sphere.radius));
-}
-
-
-} // namespace
-#ifdef _MSC_VER
-#pragma warning (pop)
-#endif
diff --git a/externals/g3dlite/G3D.lib/source/Color1.cpp b/externals/g3dlite/G3D.lib/source/Color1.cpp
deleted file mode 100644
index 7e058a27d1a..00000000000
--- a/externals/g3dlite/G3D.lib/source/Color1.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- @file Color1.cpp
-
- Color class.
-
- @author Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-01-30
- @edited 2007-01-30
- */
-
-#include "G3D/platform.h"
-#include "G3D/Color1.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-Color1::Color1(BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Color1::deserialize(BinaryInput& bi) {
- value = bi.readFloat32();
-}
-
-
-void Color1::serialize(BinaryOutput& bo) const {
- bo.writeFloat32(value);
-}
-
-
-Color1::Color1(const class Color1uint8& other) {
- value = other.value / 255.0f;
-}
-
-} // namespace G3D
-
diff --git a/externals/g3dlite/G3D.lib/source/Color1uint8.cpp b/externals/g3dlite/G3D.lib/source/Color1uint8.cpp
deleted file mode 100644
index 0fd00693d4c..00000000000
--- a/externals/g3dlite/G3D.lib/source/Color1uint8.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- @file Color1uint8.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-01-30
- @edited 2007-01-30
- */
-
-#include "G3D/platform.h"
-#include "G3D/g3dmath.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/Color1.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-Color1uint8::Color1uint8(const class Color1& c) : value(iClamp(iFloor(c.value * 256), 0, 255)) {
-}
-
-
-Color1uint8::Color1uint8(class BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Color1uint8::serialize(class BinaryOutput& bo) const {
- bo.writeUInt8(value);
-}
-
-
-void Color1uint8::deserialize(class BinaryInput& bi) {
- value = bi.readUInt8();
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Color3.cpp b/externals/g3dlite/G3D.lib/source/Color3.cpp
deleted file mode 100644
index 8183d8a0f62..00000000000
--- a/externals/g3dlite/G3D.lib/source/Color3.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/**
- @file Color3.cpp
-
- Color class.
-
- @author Morgan McGuire, matrix@graphics3d.com
- @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
-
-
- @created 2001-06-02
- @edited 2006-01-13
- */
-
-#include "G3D/platform.h"
-#include <stdlib.h>
-#include "G3D/Color3.h"
-#include "G3D/Vector3.h"
-#include "G3D/format.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Color3uint8.h"
-
-namespace G3D {
-
-const Color3& Color3::red() {
- static Color3 c(1.0f, 0.0f, 0.0f);
- return c;
-}
-
-
-const Color3& Color3::green() {
- static Color3 c(0.0f, 1.0f, 0.0f);
- return c;
-}
-
-
-const Color3& Color3::blue() {
- static Color3 c(0.0f, 0.0f, 1.0f);
- return c;
-}
-
-
-const Color3& Color3::purple() {
- static Color3 c(0.7f, 0.0f, 1.0f);
- return c;
-}
-
-
-const Color3& Color3::cyan() {
- static Color3 c(0.0f, 0.7f, 1.0f);
- return c;
-}
-
-
-const Color3& Color3::yellow() {
- static Color3 c(1.0f, 1.0f, 0.0f);
- return c;
-}
-
-
-const Color3& Color3::brown() {
- static Color3 c(0.5f, 0.5f, 0.0f);
- return c;
-}
-
-
-const Color3& Color3::orange() {
- static Color3 c(1.0f, 0.5f, 0.0f);
- return c;
-}
-
-
-const Color3& Color3::black() {
- static Color3 c(0.0f, 0.0f, 0.0f);
- return c;
-}
-
-const Color3& Color3::zero() {
- static Color3 c(0.0f, 0.0f, 0.0f);
- return c;
-}
-
-
-const Color3& Color3::one() {
- static Color3 c(1.0f, 1.0f, 1.0f);
- return c;
-}
-
-
-const Color3& Color3::gray() {
- static Color3 c(0.7f, 0.7f, 0.7f);
- return c;
-}
-
-
-const Color3& Color3::white() {
- static Color3 c(1, 1, 1);
- return c;
-}
-
-
-Color3::Color3(BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Color3::deserialize(BinaryInput& bi) {
- r = bi.readFloat32();
- g = bi.readFloat32();
- b = bi.readFloat32();
-}
-
-
-void Color3::serialize(BinaryOutput& bo) const {
- bo.writeFloat32(r);
- bo.writeFloat32(g);
- bo.writeFloat32(b);
-}
-
-
-const Color3& Color3::wheelRandom() {
- static const Color3 colorArray[8] =
- {Color3::blue(), Color3::red(), Color3::green(),
- Color3::orange(), Color3::yellow(),
- Color3::cyan(), Color3::purple(), Color3::brown()};
-
- return colorArray[iRandom(0, 7)];
-}
-
-
-size_t Color3::hashCode() const {
- unsigned int rhash = (*(int*)(void*)(&r));
- unsigned int ghash = (*(int*)(void*)(&g));
- unsigned int bhash = (*(int*)(void*)(&b));
-
- return rhash + (ghash * 37) + (bhash * 101);
-}
-
-
-Color3::Color3(const Vector3& v) {
- r = v.x;
- g = v.y;
- b = v.z;
-}
-
-
-Color3::Color3(const class Color3uint8& other) {
- r = other.r / 255.0f;
- g = other.g / 255.0f;
- b = other.b / 255.0f;
-}
-
-
-Color3 Color3::fromARGB(uint32 x) {
- return Color3((float)((x >> 16) & 0xFF), (float)((x >> 8) & 0xFF), (float)(x & 0xFF)) / 255.0f;
-}
-
-//----------------------------------------------------------------------------
-
-
-Color3 Color3::random() {
- return Color3(uniformRandom(),
- uniformRandom(),
- uniformRandom()).direction();
-}
-
-//----------------------------------------------------------------------------
-Color3 Color3::operator/ (float fScalar) const {
- Color3 kQuot;
-
- if (fScalar != 0.0f) {
- float fInvScalar = 1.0f / fScalar;
- kQuot.r = fInvScalar * r;
- kQuot.g = fInvScalar * g;
- kQuot.b = fInvScalar * b;
- return kQuot;
-
- } else {
-
- return Color3((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf());
- }
-}
-
-//----------------------------------------------------------------------------
-Color3& Color3::operator/= (float fScalar) {
- if (fScalar != 0.0f) {
- float fInvScalar = 1.0f / fScalar;
- r *= fInvScalar;
- g *= fInvScalar;
- b *= fInvScalar;
- } else {
- r = (float)G3D::inf();
- g = (float)G3D::inf();
- b = (float)G3D::inf();
- }
-
- return *this;
-}
-
-//----------------------------------------------------------------------------
-float Color3::unitize (float fTolerance) {
- float fLength = length();
-
- if ( fLength > fTolerance ) {
- float fInvLength = 1.0f / fLength;
- r *= fInvLength;
- g *= fInvLength;
- b *= fInvLength;
- } else {
- fLength = 0.0f;
- }
-
- return fLength;
-}
-
-//----------------------------------------------------------------------------
-Color3 Color3::fromHSV(const Vector3& _hsv) {
- debugAssertM((_hsv.x <= 1.0f && _hsv.x >= 0.0f)
- && (_hsv.y <= 1.0f && _hsv.y >= 0.0f)
- && ( _hsv.z <= 1.0f && _hsv.z >= 0.0f), "H,S,V must be between [0,1]");
- const int i = G3D::iFloor(6.0*_hsv.x);
- const float f = 6.0f * _hsv.x - i;
- const float m = _hsv.z * (1.0f - (_hsv.y));
- const float n = _hsv.z * (1.0f - (_hsv.y * f));
- const float k = _hsv.z * (1.0f - (_hsv.y * (1 - f)));
- switch(i) {
- case 0:
- return Color3(_hsv.z, k, m);
-
- case 1:
- return Color3(n, _hsv.z, m);
-
- case 2:
- return Color3(m, _hsv.z, k);
-
- case 3:
- return Color3(m, n, _hsv.z);
-
- case 4:
- return Color3(k, m, _hsv.z);
-
- case 5:
- return Color3(_hsv.z, m, n);
-
- default:
- debugAssertM(false, "fell through switch..");
- }
- return Color3::black();
-}
-
-
-Vector3 Color3::toHSV(const Color3& _rgb) {
- debugAssertM((_rgb.r <= 1.0f && _rgb.r >= 0.0f)
- && (_rgb.g <= 1.0f && _rgb.g >= 0.0f)
- && (_rgb.b <= 1.0f && _rgb.b >= 0.0f), "R,G,B must be between [0,1]");
- Vector3 hsv = Vector3::zero();
- hsv.z = G3D::max(G3D::max(_rgb.r, _rgb.g), _rgb.b);
- if (G3D::fuzzyEq(hsv.z, 0.0f)) {
- return hsv;
- }
-
- const float x = G3D::min(G3D::min(_rgb.r, _rgb.g), _rgb.b);
- hsv.y = (hsv.z - x) / hsv.z;
-
- if (G3D::fuzzyEq(hsv.y, 0.0f)) {
- return hsv;
- }
-
- Vector3 rgbN;
- rgbN.x = (hsv.z - _rgb.r) / (hsv.z - x);
- rgbN.y = (hsv.z - _rgb.g) / (hsv.z - x);
- rgbN.z = (hsv.z - _rgb.b) / (hsv.z - x);
-
- if (_rgb.r == hsv.z) { // note from the max we know that it exactly equals one of the three.
- hsv.x = (_rgb.g == x)? 5.0f + rgbN.z : 1.0f - rgbN.y;
- } else if (_rgb.g == hsv.z) {
- hsv.x = (_rgb.b == x)? 1.0f + rgbN.x : 3.0f - rgbN.z;
- } else {
- hsv.x = (_rgb.r == x)? 3.0f + rgbN.y : 5.0f - rgbN.x;
- }
-
- hsv.x /= 6.0f;
-
- return hsv;
-}
-
-Color3 Color3::jetColorMap(const float& val) {
- debugAssertM(val <= 1.0f && val >= 0.0f , "value should be in [0,1]");
-
- //truncated triangles where sides have slope 4
- Color3 jet;
-
- jet.r = G3D::min(4.0f * val - 1.5f,-4.0f * val + 4.5f) ;
- jet.g = G3D::min(4.0f * val - 0.5f,-4.0f * val + 3.5f) ;
- jet.b = G3D::min(4.0f * val + 0.5f,-4.0f * val + 2.5f) ;
-
-
- jet.r = G3D::clamp(jet.r, 0.0f, 1.0f);
- jet.g = G3D::clamp(jet.g, 0.0f, 1.0f);
- jet.b = G3D::clamp(jet.b, 0.0f, 1.0f);
-
- return jet;
-}
-
-
-
-
-
-std::string Color3::toString() const {
- return G3D::format("(%g, %g, %g)", r, g, b);
-}
-
-//----------------------------------------------------------------------------
-
-Color3 Color3::rainbowColorMap(float hue) {
- return fromHSV(Vector3(hue, 1.0f, 1.0f));
-}
-
-
-}; // namespace
-
diff --git a/externals/g3dlite/G3D.lib/source/Color3uint8.cpp b/externals/g3dlite/G3D.lib/source/Color3uint8.cpp
deleted file mode 100644
index 837bf1b2c8b..00000000000
--- a/externals/g3dlite/G3D.lib/source/Color3uint8.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- @file Color3uint8.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-04-07
- @edited 2006-01-07
- */
-
-#include "G3D/platform.h"
-#include "G3D/g3dmath.h"
-#include "G3D/Color3uint8.h"
-#include "G3D/Color3.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-Color3uint8::Color3uint8(const class Color3& c) {
- r = iMin(255, iFloor(c.r * 256));
- g = iMin(255, iFloor(c.g * 256));
- b = iMin(255, iFloor(c.b * 256));
-}
-
-
-Color3uint8::Color3uint8(class BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Color3uint8::serialize(class BinaryOutput& bo) const {
- bo.writeUInt8(r);
- bo.writeUInt8(g);
- bo.writeUInt8(b);
-}
-
-
-void Color3uint8::deserialize(class BinaryInput& bi) {
- r = bi.readUInt8();
- g = bi.readUInt8();
- b = bi.readUInt8();
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Color4.cpp b/externals/g3dlite/G3D.lib/source/Color4.cpp
deleted file mode 100644
index ed2e91291a1..00000000000
--- a/externals/g3dlite/G3D.lib/source/Color4.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- @file Color4.cpp
-
- Color class.
-
- @author Morgan McGuire, matrix@graphics3d.com
- @cite Portions by Laura Wollstadt, graphics3d.com
- @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
-
-
- @created 2002-06-25
- @edited 2006-01-10
- */
-
-#include <stdlib.h>
-#include "G3D/Color4.h"
-#include "G3D/Color4uint8.h"
-#include "G3D/Vector4.h"
-#include "G3D/format.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-const Color4& Color4::zero() {
- static Color4 c(0.0f, 0.0f, 0.0f, 0.0f);
- return c;
-}
-
-
-const Color4& Color4::inf() {
- static Color4 c((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf());
- return c;
-}
-
-
-const Color4& Color4::clear() {
- return Color4::zero();
-}
-
-
-Color4::Color4(const Vector4& v) {
- r = v.x;
- g = v.y;
- b = v.z;
- a = v.w;
-}
-
-
-Color4::Color4(const Color4uint8& c) : r(c.r), g(c.g), b(c.b), a(c.a) {
- *this /= 255.0f;
-}
-
-size_t Color4::hashCode() const {
- unsigned int rhash = (*(int*)(void*)(&r));
- unsigned int ghash = (*(int*)(void*)(&g));
- unsigned int bhash = (*(int*)(void*)(&b));
- unsigned int ahash = (*(int*)(void*)(&a));
-
- return rhash + (ghash * 37) + (bhash * 101) + (ahash * 241);
-}
-
-Color4 Color4::fromARGB(uint32 x) {
- return Color4(
- (float)((x >> 16) & 0xFF),
- (float)((x >> 8) & 0xFF),
- (float)(x & 0xFF),
- (float)((x >> 24) & 0xFF)) / 255.0;
-}
-
-
-Color4::Color4(BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Color4::deserialize(BinaryInput& bi) {
- r = bi.readFloat32();
- g = bi.readFloat32();
- b = bi.readFloat32();
- a = bi.readFloat32();
-}
-
-
-void Color4::serialize(BinaryOutput& bo) const {
- bo.writeFloat32(r);
- bo.writeFloat32(g);
- bo.writeFloat32(b);
- bo.writeFloat32(a);
-}
-
-
-//----------------------------------------------------------------------------
-
-Color4 Color4::operator/ (float fScalar) const {
- Color4 kQuot;
-
- if (fScalar != 0.0f) {
- float fInvScalar = 1.0f / fScalar;
- kQuot.r = fInvScalar * r;
- kQuot.g = fInvScalar * g;
- kQuot.b = fInvScalar * b;
- kQuot.a = fInvScalar * a;
- return kQuot;
-
- } else {
-
- return Color4::inf();
- }
-}
-
-//----------------------------------------------------------------------------
-
-Color4& Color4::operator/= (float fScalar) {
- if (fScalar != 0.0f) {
- float fInvScalar = 1.0f / fScalar;
- r *= fInvScalar;
- g *= fInvScalar;
- b *= fInvScalar;
- a *= fInvScalar;
- } else {
- r = (float)G3D::inf();
- g = (float)G3D::inf();
- b = (float)G3D::inf();
- a = (float)G3D::inf();
- }
-
- return *this;
-}
-
-//----------------------------------------------------------------------------
-
-std::string Color4::toString() const {
- return G3D::format("(%g, %g, %g, %g)", r, g, b, a);
-}
-
-//----------------------------------------------------------------------------
-
-}; // namespace
-
diff --git a/externals/g3dlite/G3D.lib/source/Color4uint8.cpp b/externals/g3dlite/G3D.lib/source/Color4uint8.cpp
deleted file mode 100644
index 8c8636a742e..00000000000
--- a/externals/g3dlite/G3D.lib/source/Color4uint8.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- @file Color4uint8.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-04-07
- @edited 2006-01-07
- */
-#include "G3D/platform.h"
-#include "G3D/g3dmath.h"
-#include "G3D/Color4uint8.h"
-#include "G3D/Color4.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-Color4uint8::Color4uint8(const class Color4& c) {
- r = iMin(255, iFloor(c.r * 256));
- g = iMin(255, iFloor(c.g * 256));
- b = iMin(255, iFloor(c.b * 256));
- a = iMin(255, iFloor(c.a * 256));
-}
-
-
-Color4uint8::Color4uint8(class BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Color4uint8::serialize(class BinaryOutput& bo) const {
- bo.writeUInt8(r);
- bo.writeUInt8(g);
- bo.writeUInt8(b);
- bo.writeUInt8(a);
-}
-
-
-void Color4uint8::deserialize(class BinaryInput& bi) {
- r = bi.readUInt8();
- g = bi.readUInt8();
- b = bi.readUInt8();
- a = bi.readUInt8();
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Cone.cpp b/externals/g3dlite/G3D.lib/source/Cone.cpp
deleted file mode 100644
index 99b29b5b0af..00000000000
--- a/externals/g3dlite/G3D.lib/source/Cone.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- @file Cone.cpp
-
- Cone class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2001-07-09
- @edited 2006-01-29
-*/
-
-#include "G3D/platform.h"
-#include "G3D/Cone.h"
-#include "G3D/Line.h"
-#include "G3D/Sphere.h"
-#include "G3D/Box.h"
-
-namespace G3D {
-
-Cone::Cone(const Vector3 &tip, const Vector3 &direction, float angle) {
- this->tip = tip;
- this->direction = direction.direction();
- this->angle = angle;
-
- debugAssert(angle >= 0);
- debugAssert(angle <= pi());
-}
-
-/**
- Forms the smallest cone that contains the box. Undefined if
- the tip is inside or on the box.
- */
-Cone::Cone(const Vector3& tip, const Box& box) {
- this->tip = tip;
- this->direction = (box.center() - tip).direction();
-
- // Find the biggest angle
- float smallestDotProduct = direction.dot((box.corner(0) - tip).direction());
-
- for (int i = 1; i < 8; ++i) {
- float dp = direction.dot((box.corner(i) - tip).direction());
-
- debugAssert(dp > 0);
-
- if (dp < smallestDotProduct) {
- smallestDotProduct = dp;
- }
- }
-
- angle = acosf(smallestDotProduct);
-}
-
-
-bool Cone::intersects(const Sphere& b) const {
- // If the bounding sphere contains the tip, then
- // they definitely touch.
- if (b.contains(this->tip)) {
- return true;
- }
-
- // Move the tip backwards, effectively making the cone bigger
- // to account for the radius of the sphere.
-
- Vector3 tip = this->tip - direction * b.radius / sinf(angle);
-
- return Cone(tip, direction, angle).contains(b.center);
-}
-
-
-bool Cone::contains(const Vector3& v) const {
-
- Vector3 d = (v - tip).direction();
-
- float x = d.dot(direction);
-
- return (x > 0) && (x >= cosf(angle));
-}
-
-}; // namespace
diff --git a/externals/g3dlite/G3D.lib/source/ConvexPolyhedron.cpp b/externals/g3dlite/G3D.lib/source/ConvexPolyhedron.cpp
deleted file mode 100644
index 76dbe21a7c4..00000000000
--- a/externals/g3dlite/G3D.lib/source/ConvexPolyhedron.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-/**
- @file ConvexPolyhedron.cpp
-
- @author Morgan McGuire, morgan@graphics3d.com
-
- @created 2001-11-11
- @edited 2006-01-10
-
- Copyright 2000-2006, Morgan McGuire.
- All rights reserved.
- */
-
-#include "G3D/platform.h"
-#include "G3D/ConvexPolyhedron.h"
-#include "G3D/debug.h"
-
-namespace G3D {
-
-ConvexPolygon::ConvexPolygon(const Array<Vector3>& __vertex) : _vertex(__vertex) {
- // Intentionally empty
-}
-
-
-bool ConvexPolygon::isEmpty() const {
- return (_vertex.length() == 0) || (getArea() <= fuzzyEpsilon);
-}
-
-
-float ConvexPolygon::getArea() const {
-
- if (_vertex.length() < 3) {
- return 0;
- }
-
- float sum = 0;
-
- int length = _vertex.length();
- // Split into triangle fan, compute individual area
- for (int v = 2; v < length; v++) {
- int i0 = 0;
- int i1 = v - 1;
- int i2 = v;
-
- sum += (_vertex[i1] - _vertex[i0]).cross(_vertex[i2] - _vertex[i0]).magnitude() / 2;
- }
-
- return sum;
-}
-
-void ConvexPolygon::cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below) {
- DirectedEdge edge;
- cut(plane, above, below, edge);
-}
-
-void ConvexPolygon::cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below, DirectedEdge &newEdge) {
- above._vertex.resize(0);
- below._vertex.resize(0);
-
- if (isEmpty()) {
- //debugPrintf("Empty\n");
- return;
- }
-
- int v = 0;
- int length = _vertex.length();
-
-
- Vector3 polyNormal = normal();
- Vector3 planeNormal= plane.normal();
-
- // See if the polygon is *in* the plane.
- if (planeNormal.fuzzyEq(polyNormal) || planeNormal.fuzzyEq(-polyNormal)) {
- // Polygon is parallel to the plane. It must be either above,
- // below, or in the plane.
-
- double a, b, c, d;
- Vector3 pt = _vertex[0];
-
- plane.getEquation(a,b,c,d);
- float r = (float)(a * pt.x + b * pt.y + c * pt.z + d);
-
- if (fuzzyGe(r, 0)) {
- // The polygon is entirely in the plane.
- //debugPrintf("Entirely above\n");
- above = *this;
- return;
- } else {
- //debugPrintf("Entirely below (1)\n");
- below = *this;
- return;
- }
- }
-
-
- // Number of edges crossing the plane. Used for
- // debug assertions.
- int count = 0;
-
- // True when the last _vertex we looked at was above the plane
- bool lastAbove = plane.halfSpaceContains(_vertex[v]);
-
- if (lastAbove) {
- above._vertex.append(_vertex[v]);
- } else {
- below._vertex.append(_vertex[v]);
- }
-
- for (v = 1; v < length; v++) {
- bool isAbove = plane.halfSpaceContains(_vertex[v]);
-
- if (lastAbove ^ isAbove) {
- // Switched sides.
- // Create an interpolated point that lies
- // in the plane, between the two points.
- Line line = Line::fromTwoPoints(_vertex[v - 1], _vertex[v]);
- Vector3 interp = line.intersection(plane);
-
- if (! interp.isFinite()) {
-
- // Since the polygon is not in the plane (we checked above),
- // it must be the case that this edge (and only this edge)
- // is in the plane. This only happens when the polygon is
- // entirely below the plane except for one edge. This edge
- // forms a degenerate polygon, so just treat the whole polygon
- // as below the plane.
- below = *this;
- above._vertex.resize(0);
- //debugPrintf("Entirely below\n");
- return;
- }
-
- above._vertex.append(interp);
- below._vertex.append(interp);
- if (lastAbove) {
- newEdge.stop = interp;
- } else {
- newEdge.start = interp;
- }
- count++;
- }
-
- lastAbove = isAbove;
- if (lastAbove) {
- above._vertex.append(_vertex[v]);
- } else {
- below._vertex.append(_vertex[v]);
- }
- }
-
- // Loop back to the first point, seeing if an interpolated point is
- // needed.
- bool isAbove = plane.halfSpaceContains(_vertex[0]);
- if (lastAbove ^ isAbove) {
- Line line = Line::fromTwoPoints(_vertex[length - 1], _vertex[0]);
- Vector3 interp = line.intersection(plane);
- if (! interp.isFinite()) {
- // Since the polygon is not in the plane (we checked above),
- // it must be the case that this edge (and only this edge)
- // is in the plane. This only happens when the polygon is
- // entirely below the plane except for one edge. This edge
- // forms a degenerate polygon, so just treat the whole polygon
- // as below the plane.
- below = *this;
- above._vertex.resize(0);
- //debugPrintf("Entirely below\n");
- return;
- }
-
- above._vertex.append(interp);
- below._vertex.append(interp);
- debugAssertM(count < 2, "Convex polygons may only intersect planes at two edges.");
- if (lastAbove) {
- newEdge.stop = interp;
- } else {
- newEdge.start = interp;
- }
- count++;
- }
-
- debugAssertM((count == 2) || (count == 0), "Convex polygons may only intersect planes at two edges.");
-}
-
-ConvexPolygon ConvexPolygon::inverse() const {
- ConvexPolygon result;
- int length = _vertex.length();
- result._vertex.resize(length);
-
- for (int v = 0; v < length; v++) {
- result._vertex[v] = _vertex[length - v - 1];
- }
-
- return result;
-}
-
-void ConvexPolygon::removeDuplicateVertices(){
- // Any valid polygon should have 3 or more vertices, but why take chances?
- if(_vertex.size() >= 2){
-
- // Remove duplicate vertices.
- for(int i=0;i<_vertex.size()-1;++i){
- if(_vertex[i].fuzzyEq(_vertex[i+1])){
- _vertex.remove(i+1);
- --i; // Don't move forward.
- }
- }
-
- // Check the last vertex against the first.
- if(_vertex[_vertex.size()-1].fuzzyEq(_vertex[0])){
- _vertex.pop();
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-ConvexPolyhedron::ConvexPolyhedron(const Array<ConvexPolygon>& _face) : face(_face) {
- // Intentionally empty
-}
-
-float ConvexPolyhedron::getVolume() const {
-
- if (face.length() < 4) {
- return 0;
- }
-
- // The volume of any pyramid is 1/3 * h * base area.
- // Discussion at: http://nrich.maths.org/mathsf/journalf/oct01/art1/
-
- float sum = 0;
-
- // Choose the first _vertex of the first face as the origin.
- // This lets us skip one face, too, and avoids negative heights.
- Vector3 v0 = face[0]._vertex[0];
- for (int f = 1; f < face.length(); f++) {
- const ConvexPolygon& poly = face[f];
-
- float height = (poly._vertex[0] - v0).dot(poly.normal());
- float base = poly.getArea();
-
- sum += height * base;
- }
-
- return sum / 3;
-}
-
-bool ConvexPolyhedron::isEmpty() const {
- return (face.length() == 0) || (getVolume() <= fuzzyEpsilon);
-}
-
-void ConvexPolyhedron::cut(const Plane& plane, ConvexPolyhedron &above, ConvexPolyhedron &below) {
- above.face.resize(0);
- below.face.resize(0);
-
- Array<DirectedEdge> edge;
-
- int f;
-
- // See if the plane cuts this polyhedron at all. Detect when
- // the polyhedron is entirely to one side or the other.
- //{
- int numAbove = 0, numIn = 0, numBelow = 0;
- bool ruledOut = false;
- double d;
- Vector3 abc;
- plane.getEquation(abc, d);
-
- // This number has to be fairly large to prevent precision problems down
- // the road.
- const float eps = 0.005f;
- for (f = face.length() - 1; (f >= 0) && (!ruledOut); f--) {
- const ConvexPolygon& poly = face[f];
- for (int v = poly._vertex.length() - 1; (v >= 0) && (!ruledOut); v--) {
- double r = abc.dot(poly._vertex[v]) + d;
- if (r > eps) {
- numAbove++;
- } else if (r < -eps) {
- numBelow++;
- } else {
- numIn++;
- }
-
- ruledOut = (numAbove != 0) && (numBelow !=0);
- }
- }
-
- if (numBelow == 0) {
- above = *this;
- return;
- } else if (numAbove == 0) {
- below = *this;
- return;
- }
- //}
-
- // Clip each polygon, collecting split edges.
- for (f = face.length() - 1; f >= 0; f--) {
- ConvexPolygon a, b;
- DirectedEdge e;
- face[f].cut(plane, a, b, e);
-
- bool aEmpty = a.isEmpty();
- bool bEmpty = b.isEmpty();
-
- //debugPrintf("\n");
- if (! aEmpty) {
- //debugPrintf(" Above %f\n", a.getArea());
- above.face.append(a);
- }
-
- if (! bEmpty) {
- //debugPrintf(" Below %f\n", b.getArea());
- below.face.append(b);
- }
-
- if (! aEmpty && ! bEmpty) {
- //debugPrintf(" == Split\n");
- edge.append(e);
- } else {
- // Might be the case that the polygon is entirely on
- // one side of the plane yet there is an edge we need
- // because it touches the plane.
- //
- // Extract the non-empty _vertex list and examine it.
- // If we find exactly one edge in the plane, add that edge.
- const Array<Vector3>& _vertex = (aEmpty ? b._vertex : a._vertex);
- int L = _vertex.length();
- int count = 0;
- for (int v = 0; v < L; v++) {
- if (plane.fuzzyContains(_vertex[v]) && plane.fuzzyContains(_vertex[(v + 1) % L])) {
- e.start = _vertex[v];
- e.stop = _vertex[(v + 1) % L];
- count++;
- }
- }
-
- if (count == 1) {
- edge.append(e);
- }
- }
- }
-
- if (above.face.length() == 1) {
- // Only one face above means that this entire
- // polyhedron is below the plane. Move that face over.
- below.face.append(above.face[0]);
- above.face.resize(0);
- } else if (below.face.length() == 1) {
- // This shouldn't happen, but it arises in practice
- // from numerical imprecision.
- above.face.append(below.face[0]);
- below.face.resize(0);
- }
-
- if ((above.face.length() > 0) && (below.face.length() > 0)) {
- // The polyhedron was actually cut; create a cap polygon
- ConvexPolygon cap;
-
- // Collect the final polgyon by sorting the edges
- int numVertices = edge.length();
-/*debugPrintf("\n");
-for (int xx=0; xx < numVertices; xx++) {
- std::string s1 = edge[xx].start.toString();
- std::string s2 = edge[xx].stop.toString();
- debugPrintf("%s -> %s\n", s1.c_str(), s2.c_str());
-}
-*/
-
- // Need at least three points to make a polygon
- debugAssert(numVertices >= 3);
-
- Vector3 last_vertex = edge.last().stop;
- cap._vertex.append(last_vertex);
-
- // Search for the next _vertex. Because of accumulating
- // numerical error, we have to find the closest match, not
- // just the one we expect.
- for (int v = numVertices - 1; v >= 0; v--) {
- // matching edge index
- int index = 0;
- int num = edge.length();
- double distance = (edge[index].start - last_vertex).squaredMagnitude();
- for (int e = 1; e < num; e++) {
- double d = (edge[e].start - last_vertex).squaredMagnitude();
-
- if (d < distance) {
- // This is the new closest one
- index = e;
- distance = d;
- }
- }
-
- // Don't tolerate ridiculous error.
- debugAssertM(distance < 0.02, "Edge missing while closing polygon.");
-
- last_vertex = edge[index].stop;
- cap._vertex.append(last_vertex);
- }
-
- //debugPrintf("\n");
- //debugPrintf("Cap (both) %f\n", cap.getArea());
- above.face.append(cap);
- below.face.append(cap.inverse());
- }
-
- // Make sure we put enough faces on each polyhedra
- debugAssert((above.face.length() == 0) || (above.face.length() >= 4));
- debugAssert((below.face.length() == 0) || (below.face.length() >= 4));
-}
-
-///////////////////////////////////////////////
-
-ConvexPolygon2D::ConvexPolygon2D(const Array<Vector2>& pts, bool reverse) : m_vertex(pts) {
- if (reverse) {
- m_vertex.reverse();
- }
-}
-
-
-bool ConvexPolygon2D::contains(const Vector2& p, bool reverse) const {
- // Compute the signed area of each polygon from p to an edge.
- // If the area is non-negative for all polygons then p is inside
- // the polygon. (To adapt this algorithm for a concave polygon,
- // the *sum* of the areas must be non-negative).
-
- float r = reverse ? -1 : 1;
-
- for (int i0 = 0; i0 < m_vertex.size(); ++i0) {
- int i1 = (i0 + 1) % m_vertex.size();
- const Vector2& v0 = m_vertex[i0];
- const Vector2& v1 = m_vertex[i1];
-
- Vector2 e0 = v0 - p;
- Vector2 e1 = v1 - p;
-
- // Area = (1/2) cross product, negated to be ccw in
- // a 2D space; we neglect the 1/2
- float area = -(e0.x * e1.y - e0.y * e1.x);
-
- if (area * r < 0) {
- return false;
- }
- }
-
- return true;
-}
-
-
-}
-
diff --git a/externals/g3dlite/G3D.lib/source/CoordinateFrame.cpp b/externals/g3dlite/G3D.lib/source/CoordinateFrame.cpp
deleted file mode 100644
index b6e94fe5857..00000000000
--- a/externals/g3dlite/G3D.lib/source/CoordinateFrame.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/**
- @file CoordinateFrame.cpp
-
- Coordinate frame class
-
- @maintainer Morgan McGuire, morgan@cs.williams.edu
-
- @created 2001-06-02
- @edited 2008-07-13
-*/
-
-#include "G3D/platform.h"
-#include "G3D/CoordinateFrame.h"
-#include "G3D/Quat.h"
-#include "G3D/Matrix4.h"
-#include "G3D/Box.h"
-#include "G3D/AABox.h"
-#include "G3D/Sphere.h"
-#include "G3D/Triangle.h"
-#include "G3D/Ray.h"
-#include "G3D/Capsule.h"
-#include "G3D/Cylinder.h"
-#include "G3D/UprightFrame.h"
-
-namespace G3D {
-
-CoordinateFrame::CoordinateFrame(const class UprightFrame& f) {
- *this = f.toCoordinateFrame();
-}
-
-
-CoordinateFrame CoordinateFrame::fromXYZYPRRadians(float x, float y, float z, float yaw,
- float pitch, float roll) {
- Matrix3 rotation = Matrix3::fromAxisAngle(Vector3::unitY(), yaw);
-
- rotation = Matrix3::fromAxisAngle(rotation.column(0), pitch) * rotation;
- rotation = Matrix3::fromAxisAngle(rotation.column(2), roll) * rotation;
-
- const Vector3 translation(x, y, z);
-
- return CoordinateFrame(rotation, translation);
-}
-
-
-void CoordinateFrame::getXYZYPRRadians(float& x, float& y, float& z,
- float& yaw, float& pitch, float& roll) const {
- x = translation.x;
- y = translation.y;
- z = translation.z;
-
- const Vector3& look = lookVector();
-
- if (abs(look.y) > 0.99f) {
- // Looking nearly straight up or down
-
- yaw = G3D::pi() + atan2(look.x, look.z);
- pitch = asin(look.y);
- roll = 0.0f;
-
- } else {
-
- // Yaw cannot be affected by others, so pull it first
- yaw = G3D::pi() + atan2(look.x, look.z);
-
- // Pitch is the elevation of the yaw vector
- pitch = asin(look.y);
-
- Vector3 actualRight = rightVector();
- Vector3 expectedRight = look.cross(Vector3::unitY());
-
- roll = 0;//acos(actualRight.dot(expectedRight)); TODO
- }
-}
-
-
-void CoordinateFrame::getXYZYPRDegrees(float& x, float& y, float& z,
- float& yaw, float& pitch, float& roll) const {
- getXYZYPRRadians(x, y, z, yaw, pitch, roll);
- yaw = toDegrees(yaw);
- pitch = toDegrees(pitch);
- roll = toDegrees(roll);
-}
-
-
-CoordinateFrame CoordinateFrame::fromXYZYPRDegrees(float x, float y, float z,
- float yaw, float pitch, float roll) {
- return fromXYZYPRRadians(x, y, z, toRadians(yaw), toRadians(pitch), toRadians(roll));
-}
-
-
-Ray CoordinateFrame::lookRay() const {
- return Ray::fromOriginAndDirection(translation, lookVector());
-}
-
-
-bool CoordinateFrame::fuzzyEq(const CoordinateFrame& other) const {
-
- for (int c = 0; c < 3; ++c) {
- for (int r = 0; r < 3; ++r) {
- if (! G3D::fuzzyEq(other.rotation[r][c], rotation[r][c])) {
- return false;
- }
- }
- if (! G3D::fuzzyEq(translation[c], other.translation[c])) {
- return false;
- }
- }
-
- return true;
-}
-
-
-bool CoordinateFrame::fuzzyIsIdentity() const {
- const Matrix3& I = Matrix3::identity();
-
- for (int c = 0; c < 3; ++c) {
- for (int r = 0; r < 3; ++r) {
- if (fuzzyNe(I[r][c], rotation[r][c])) {
- return false;
- }
- }
- if (fuzzyNe(translation[c], 0)) {
- return false;
- }
- }
-
- return true;
-}
-
-
-bool CoordinateFrame::isIdentity() const {
- return
- (translation == Vector3::zero()) &&
- (rotation == Matrix3::identity());
-}
-
-
-Matrix4 CoordinateFrame::toMatrix4() const {
- return Matrix4(*this);
-}
-
-
-std::string CoordinateFrame::toXML() const {
- return G3D::format(
- "<COORDINATEFRAME>\n %lf,%lf,%lf,%lf,\n %lf,%lf,%lf,%lf,\n %lf,%lf,%lf,%lf,\n %lf,%lf,%lf,%lf\n</COORDINATEFRAME>\n",
- rotation[0][0], rotation[0][1], rotation[0][2], translation.x,
- rotation[1][0], rotation[1][1], rotation[1][2], translation.y,
- rotation[2][0], rotation[2][1], rotation[2][2], translation.z,
- 0.0, 0.0, 0.0, 1.0);
-}
-
-
-Plane CoordinateFrame::toObjectSpace(const Plane& p) const {
- Vector3 N, P;
- double d;
- p.getEquation(N, d);
- P = N * (float)d;
- P = pointToObjectSpace(P);
- N = normalToObjectSpace(N);
- return Plane(N, P);
-}
-
-
-Plane CoordinateFrame::toWorldSpace(const Plane& p) const {
- Vector3 N, P;
- double d;
- p.getEquation(N, d);
- P = N * (float)d;
- P = pointToWorldSpace(P);
- N = normalToWorldSpace(N);
- return Plane(N, P);
-}
-
-
-Triangle CoordinateFrame::toObjectSpace(const Triangle& t) const {
- return Triangle(pointToObjectSpace(t.vertex(0)),
- pointToObjectSpace(t.vertex(1)),
- pointToObjectSpace(t.vertex(2)));
-}
-
-
-Triangle CoordinateFrame::toWorldSpace(const Triangle& t) const {
- return Triangle(pointToWorldSpace(t.vertex(0)),
- pointToWorldSpace(t.vertex(1)),
- pointToWorldSpace(t.vertex(2)));
-}
-
-
-Cylinder CoordinateFrame::toWorldSpace(const Cylinder& c) const {
- return Cylinder(
- pointToWorldSpace(c.point(0)),
- pointToWorldSpace(c.point(1)),
- c.radius());
-}
-
-
-Capsule CoordinateFrame::toWorldSpace(const Capsule& c) const {
- return Capsule(
- pointToWorldSpace(c.point(0)),
- pointToWorldSpace(c.point(1)),
- c.radius());
-}
-
-
-Box CoordinateFrame::toWorldSpace(const AABox& b) const {
- return toWorldSpace(Box(b));
-}
-
-
-Box CoordinateFrame::toWorldSpace(const Box& b) const {
- Box out(b);
-
- for (int i = 0; i < 8; ++i) {
- out._corner[i] = pointToWorldSpace(out._corner[i]);
- debugAssert(! isNaN(out._corner[i].x));
- }
-
- for (int i = 0; i < 3; ++i) {
- out._axis[i] = vectorToWorldSpace(out._axis[i]);
- }
-
- out._center = pointToWorldSpace(out._center);
-
- return out;
-}
-
-
-Box CoordinateFrame::toObjectSpace(const Box &b) const {
- return inverse().toWorldSpace(b);
-}
-
-
-Box CoordinateFrame::toObjectSpace(const AABox& b) const {
- return toObjectSpace(Box(b));
-}
-
-
-CoordinateFrame::CoordinateFrame(class BinaryInput& b) : rotation(Matrix3::zero()) {
- deserialize(b);
-}
-
-
-void CoordinateFrame::deserialize(class BinaryInput& b) {
- rotation.deserialize(b);
- translation.deserialize(b);
-}
-
-
-void CoordinateFrame::serialize(class BinaryOutput& b) const {
- rotation.serialize(b);
- translation.serialize(b);
-}
-
-
-Sphere CoordinateFrame::toWorldSpace(const Sphere &b) const {
- return Sphere(pointToWorldSpace(b.center), b.radius);
-}
-
-
-Sphere CoordinateFrame::toObjectSpace(const Sphere &b) const {
- return Sphere(pointToObjectSpace(b.center), b.radius);
-}
-
-
-Ray CoordinateFrame::toWorldSpace(const Ray& r) const {
- return Ray::fromOriginAndDirection(pointToWorldSpace(r.origin), vectorToWorldSpace(r.direction));
-}
-
-
-Ray CoordinateFrame::toObjectSpace(const Ray& r) const {
- return Ray::fromOriginAndDirection(pointToObjectSpace(r.origin), vectorToObjectSpace(r.direction));
-}
-
-
-void CoordinateFrame::lookAt(const Vector3 &target) {
- lookAt(target, Vector3::unitY());
-}
-
-
-void CoordinateFrame::lookAt(
- const Vector3& target,
- Vector3 up) {
-
- up = up.direction();
-
- Vector3 look = (target - translation).direction();
- if (fabs(look.dot(up)) > .99f) {
- up = Vector3::unitX();
- if (fabs(look.dot(up)) > .99f) {
- up = Vector3::unitY();
- }
- }
-
- up -= look * look.dot(up);
- up.unitize();
-
- Vector3 z = -look;
- Vector3 x = -z.cross(up);
- x.unitize();
-
- Vector3 y = z.cross(x);
-
- rotation.setColumn(0, x);
- rotation.setColumn(1, y);
- rotation.setColumn(2, z);
-}
-
-
-CoordinateFrame CoordinateFrame::lerp(
- const CoordinateFrame& other,
- float alpha) const {
-
- if (alpha == 1.0f) {
- return other;
- } else if (alpha == 0.0f) {
- return *this;
- } else {
- Quat q1 = Quat(this->rotation);
- Quat q2 = Quat(other.rotation);
-
- return CoordinateFrame(
- q1.slerp(q2, alpha).toRotationMatrix(),
- this->translation * (1 - alpha) + other.translation * alpha);
- }
-}
-
-
-void CoordinateFrame::pointToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
- vout.resize(v.size());
-
- for (int i = v.size() - 1; i >= 0; --i) {
- vout[i] = pointToWorldSpace(v[i]);
- }
-}
-
-
-void CoordinateFrame::normalToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
- vout.resize(v.size());
-
- for (int i = v.size() - 1; i >= 0; --i) {
- vout[i] = normalToWorldSpace(v[i]);
- }
-}
-
-
-void CoordinateFrame::vectorToWorldSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
- vout.resize(v.size());
-
- for (int i = v.size() - 1; i >= 0; --i) {
- vout[i] = vectorToWorldSpace(v[i]);
- }
-}
-
-
-void CoordinateFrame::pointToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
- vout.resize(v.size());
-
- for (int i = v.size() - 1; i >= 0; --i) {
- vout[i] = pointToObjectSpace(v[i]);
- }
-}
-
-
-void CoordinateFrame::normalToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
- vout.resize(v.size());
-
- for (int i = v.size() - 1; i >= 0; --i) {
- vout[i] = normalToObjectSpace(v[i]);
- }
-}
-
-
-void CoordinateFrame::vectorToObjectSpace(const Array<Vector3>& v, Array<Vector3>& vout) const {
- vout.resize(v.size());
-
- for (int i = v.size() - 1; i >= 0; --i) {
- vout[i] = vectorToObjectSpace(v[i]);
- }
-}
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/Crypto.cpp b/externals/g3dlite/G3D.lib/source/Crypto.cpp
deleted file mode 100644
index 09aee2c265d..00000000000
--- a/externals/g3dlite/G3D.lib/source/Crypto.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- @file Crypto.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
-
-
- @created 2006-03-28
- @edited 2006-04-06
- */
-
-#include "G3D/platform.h"
-#include "G3D/Crypto.h"
-#include "G3D/g3dmath.h"
-#include <zlib.h>
-
-namespace G3D {
-
-
-int Crypto::smallPrime(int n) {
- debugAssert(n < numSmallPrimes() && n >= 0);
-
- // From:
- // http://primes.utm.edu/lists/small/1000.txt
-
- static const int table[] = {
- 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
- 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
- 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
- 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
- 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
- 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
- 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
- 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
- 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
- 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
- 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
- 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
- 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
- 739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
- 811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
- 877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
- 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
- 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
- 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
- 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
- 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
- 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
- 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
- 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
- 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
- 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,
- 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
- 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
- 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,
- 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
- 1993, 1997, 1999};
-
- return table[n];
-}
-
-
-int Crypto::numSmallPrimes() {
- return 303;
-}
-
-uint32 Crypto::crc32(const void* byte, size_t numBytes) {
- return ::crc32(::crc32(0, Z_NULL, 0), static_cast<const Bytef *>(byte), numBytes);
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/Crypto_md5.cpp b/externals/g3dlite/G3D.lib/source/Crypto_md5.cpp
deleted file mode 100644
index 4aa24c39f9c..00000000000
--- a/externals/g3dlite/G3D.lib/source/Crypto_md5.cpp
+++ /dev/null
@@ -1,471 +0,0 @@
-/**
- @file Crypto_md5.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
- Copyright 2006-2007, Morgan McGuire. All rights reserved.
-
- @created 2006-03-28
- @edited 2006-04-06
- */
-
-#include "G3D/platform.h"
-#include "G3D/Crypto.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-#include <cstring>
-
-namespace G3D {
-
-
-MD5Hash::MD5Hash(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-void MD5Hash::deserialize(class BinaryInput& b) {
- b.readBytes(value, 16);
-}
-
-
-void MD5Hash::serialize(class BinaryOutput& b) const {
- b.writeBytes(value, 16);
-}
-
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
- md5_word_t count[2]; /* message length in bits, lsw first */
- md5_word_t abcd[4]; /* digest buffer */
- md5_byte_t buf[64]; /* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* Initialize the algorithm. */
-static void md5_init(md5_state_t *pms);
-
-/* Append a string to the message. */
-static void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-
-/* Finish the message and return the digest. */
-void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-#ifdef __cplusplus
-}
-#endif
-
-
-
-MD5Hash Crypto::md5(const void* data, size_t n) {
- md5_state_t state;
- md5_init(&state);
- md5_append(&state, (const uint8*)data, (int)n);
-
- MD5Hash h;
- md5_finish(&state, &(h[0]));
- return h;
-}
-
-/*
- Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.c is L. Peter Deutsch
- <ghost@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
- either statically or dynamically; added missing #include <string.h>
- in library.
- 2002-03-11 lpd Corrected argument list for main(), and added int return
- type, in test program and T value program.
- 2002-02-21 lpd Added missing #include <stdio.h> in test program.
- 2000-07-03 lpd Patched to eliminate warnings about "constant is
- unsigned in ANSI C, signed in traditional"; made test program
- self-checking.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
- 1999-05-03 lpd Original version.
- */
-
-/*
- * This package supports both compile-time and run-time determination of CPU
- * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
- * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
- * defined as non-zero, the code will be compiled to run only on big-endian
- * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
- * run on either big- or little-endian CPUs, but will run slightly less
- * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
- */
-
-
-#if defined(G3D_LINUX) || defined(G3D_OSX)
-# if defined(G3D_OSX_PPC)
-# include <ppc/endian.h>
-# elif defined(G3D_OSX_INTEL)
-# include <i386/endian.h>
-# elif defined(__linux__)
-# include <endian.h>
-# elif defined(__FreeBSD__)
-# include <sys/endian.h>
-# endif
-#else
-# define BYTE_ORDER 0
-#endif
-
-#define T_MASK ((md5_word_t)~0)
-#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
-#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
-#define T3 0x242070db
-#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
-#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
-#define T6 0x4787c62a
-#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
-#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
-#define T9 0x698098d8
-#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
-#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
-#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
-#define T13 0x6b901122
-#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
-#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
-#define T16 0x49b40821
-#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
-#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
-#define T19 0x265e5a51
-#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
-#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
-#define T22 0x02441453
-#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
-#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
-#define T25 0x21e1cde6
-#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
-#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
-#define T28 0x455a14ed
-#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
-#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
-#define T31 0x676f02d9
-#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
-#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
-#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
-#define T35 0x6d9d6122
-#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
-#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
-#define T38 0x4bdecfa9
-#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
-#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
-#define T41 0x289b7ec6
-#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
-#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
-#define T44 0x04881d05
-#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
-#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
-#define T47 0x1fa27cf8
-#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
-#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
-#define T50 0x432aff97
-#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
-#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
-#define T53 0x655b59c3
-#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
-#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
-#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
-#define T57 0x6fa87e4f
-#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
-#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
-#define T60 0x4e0811a1
-#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
-#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
-#define T63 0x2ad7d2bb
-#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
-
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
- md5_word_t
- a = pms->abcd[0], b = pms->abcd[1],
- c = pms->abcd[2], d = pms->abcd[3];
- md5_word_t t;
-#if BYTE_ORDER > 0
- /* Define storage only for big-endian CPUs. */
- md5_word_t X[16];
-#else
- /* Define storage for little-endian or both types of CPUs. */
- md5_word_t xbuf[16];
- const md5_word_t *X;
-#endif
-
- {
-#if BYTE_ORDER == 0
- /*
- * Determine dynamically whether this is a big-endian or
- * little-endian machine, since we can use a more efficient
- * algorithm on the latter.
- */
- static const int w = 1;
-
- if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
-#endif
-#if BYTE_ORDER <= 0 /* little-endian */
- {
- /*
- * On little-endian machines, we can process properly aligned
- * data without copying it.
- */
- if (!((data - (const md5_byte_t *)0) & 3)) {
- /* data are properly aligned */
- X = (const md5_word_t *)data;
- } else {
- /* not aligned */
- memcpy(xbuf, data, 64);
- X = xbuf;
- }
- }
-#endif
-#if BYTE_ORDER == 0
- else /* dynamic big-endian */
-#endif
-#if BYTE_ORDER >= 0 /* big-endian */
- {
- /*
- * On big-endian machines, we must arrange the bytes in the
- * right order.
- */
- const md5_byte_t *xp = data;
- int i;
-
-# if BYTE_ORDER == 0
- X = xbuf; /* (dynamic only) */
-# else
-# define xbuf X /* (static only) */
-# endif
- for (i = 0; i < 16; ++i, xp += 4)
- xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
- }
-#endif
- }
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
- /* Round 1. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + F(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 7, T1);
- SET(d, a, b, c, 1, 12, T2);
- SET(c, d, a, b, 2, 17, T3);
- SET(b, c, d, a, 3, 22, T4);
- SET(a, b, c, d, 4, 7, T5);
- SET(d, a, b, c, 5, 12, T6);
- SET(c, d, a, b, 6, 17, T7);
- SET(b, c, d, a, 7, 22, T8);
- SET(a, b, c, d, 8, 7, T9);
- SET(d, a, b, c, 9, 12, T10);
- SET(c, d, a, b, 10, 17, T11);
- SET(b, c, d, a, 11, 22, T12);
- SET(a, b, c, d, 12, 7, T13);
- SET(d, a, b, c, 13, 12, T14);
- SET(c, d, a, b, 14, 17, T15);
- SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
- /* Round 2. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + G(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 1, 5, T17);
- SET(d, a, b, c, 6, 9, T18);
- SET(c, d, a, b, 11, 14, T19);
- SET(b, c, d, a, 0, 20, T20);
- SET(a, b, c, d, 5, 5, T21);
- SET(d, a, b, c, 10, 9, T22);
- SET(c, d, a, b, 15, 14, T23);
- SET(b, c, d, a, 4, 20, T24);
- SET(a, b, c, d, 9, 5, T25);
- SET(d, a, b, c, 14, 9, T26);
- SET(c, d, a, b, 3, 14, T27);
- SET(b, c, d, a, 8, 20, T28);
- SET(a, b, c, d, 13, 5, T29);
- SET(d, a, b, c, 2, 9, T30);
- SET(c, d, a, b, 7, 14, T31);
- SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
- /* Round 3. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + H(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 5, 4, T33);
- SET(d, a, b, c, 8, 11, T34);
- SET(c, d, a, b, 11, 16, T35);
- SET(b, c, d, a, 14, 23, T36);
- SET(a, b, c, d, 1, 4, T37);
- SET(d, a, b, c, 4, 11, T38);
- SET(c, d, a, b, 7, 16, T39);
- SET(b, c, d, a, 10, 23, T40);
- SET(a, b, c, d, 13, 4, T41);
- SET(d, a, b, c, 0, 11, T42);
- SET(c, d, a, b, 3, 16, T43);
- SET(b, c, d, a, 6, 23, T44);
- SET(a, b, c, d, 9, 4, T45);
- SET(d, a, b, c, 12, 11, T46);
- SET(c, d, a, b, 15, 16, T47);
- SET(b, c, d, a, 2, 23, T48);
-#undef SET
-
- /* Round 4. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + I(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 6, T49);
- SET(d, a, b, c, 7, 10, T50);
- SET(c, d, a, b, 14, 15, T51);
- SET(b, c, d, a, 5, 21, T52);
- SET(a, b, c, d, 12, 6, T53);
- SET(d, a, b, c, 3, 10, T54);
- SET(c, d, a, b, 10, 15, T55);
- SET(b, c, d, a, 1, 21, T56);
- SET(a, b, c, d, 8, 6, T57);
- SET(d, a, b, c, 15, 10, T58);
- SET(c, d, a, b, 6, 15, T59);
- SET(b, c, d, a, 13, 21, T60);
- SET(a, b, c, d, 4, 6, T61);
- SET(d, a, b, c, 11, 10, T62);
- SET(c, d, a, b, 2, 15, T63);
- SET(b, c, d, a, 9, 21, T64);
-#undef SET
-
- /* Then perform the following additions. (That is increment each
- of the four registers by the value it had before this block
- was started.) */
- pms->abcd[0] += a;
- pms->abcd[1] += b;
- pms->abcd[2] += c;
- pms->abcd[3] += d;
-}
-
-void
-md5_init(md5_state_t *pms)
-{
- pms->count[0] = pms->count[1] = 0;
- pms->abcd[0] = 0x67452301;
- pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
- pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
- pms->abcd[3] = 0x10325476;
-}
-
-void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
- const md5_byte_t *p = data;
- int left = nbytes;
- int offset = (pms->count[0] >> 3) & 63;
- md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
- if (nbytes <= 0)
- return;
-
- /* Update the message length. */
- pms->count[1] += nbytes >> 29;
- pms->count[0] += nbits;
- if (pms->count[0] < nbits)
- pms->count[1]++;
-
- /* Process an initial partial block. */
- if (offset) {
- int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
- memcpy(pms->buf + offset, p, copy);
- if (offset + copy < 64)
- return;
- p += copy;
- left -= copy;
- md5_process(pms, pms->buf);
- }
-
- /* Process full blocks. */
- for (; left >= 64; p += 64, left -= 64)
- md5_process(pms, p);
-
- /* Process a final partial block. */
- if (left)
- memcpy(pms->buf, p, left);
-}
-
-void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
- static const md5_byte_t pad[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- md5_byte_t data[8];
- int i;
-
- /* Save the length before padding. */
- for (i = 0; i < 8; ++i)
- data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
- /* Pad to 56 bytes mod 64. */
- md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
- /* Append the length. */
- md5_append(pms, data, 8);
- for (i = 0; i < 16; ++i)
- digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Cylinder.cpp b/externals/g3dlite/G3D.lib/source/Cylinder.cpp
deleted file mode 100644
index bdc7d56be23..00000000000
--- a/externals/g3dlite/G3D.lib/source/Cylinder.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- @file Cylinder.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-02-07
- @edited 2006-02-18
-
- Copyright 2000-2006, Morgan McGuire.
- All rights reserved.
- */
-
-#include "G3D/platform.h"
-#include "G3D/Cylinder.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/LineSegment.h"
-#include "G3D/CoordinateFrame.h"
-#include "G3D/Line.h"
-#include "G3D/AABox.h"
-
-namespace G3D {
-
-Cylinder::Cylinder(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-Cylinder::Cylinder() {
-}
-
-
-Cylinder::Cylinder(const Vector3& _p1, const Vector3& _p2, float _r)
- : p1(_p1), p2(_p2), mRadius(_r) {
-}
-
-
-void Cylinder::serialize(class BinaryOutput& b) const {
- p1.serialize(b);
- p2.serialize(b);
- b.writeFloat64(mRadius);
-}
-
-
-void Cylinder::deserialize(class BinaryInput& b) {
- p1.deserialize(b);
- p2.deserialize(b);
- mRadius = b.readFloat64();
-}
-
-
-Line Cylinder::axis() const {
- return Line::fromTwoPoints(p1, p2);
-}
-
-
-
-float Cylinder::radius() const {
- return mRadius;
-}
-
-
-float Cylinder::volume() const {
- return
- (float)pi() * square(mRadius) * (p1 - p2).magnitude();
-}
-
-
-float Cylinder::area() const {
- return
- // Sides
- (twoPi() * mRadius) * height() +
-
- // Caps
- twoPi() * square(mRadius);
-}
-
-void Cylinder::getBounds(AABox& out) const {
- Vector3 min = p1.min(p2) - (Vector3(1, 1, 1) * mRadius);
- Vector3 max = p1.max(p2) + (Vector3(1, 1, 1) * mRadius);
- out = AABox(min, max);
-}
-
-bool Cylinder::contains(const Vector3& p) const {
- return LineSegment::fromTwoPoints(p1, p2).distanceSquared(p) <= square(mRadius);
-}
-
-
-void Cylinder::getReferenceFrame(CoordinateFrame& cframe) const {
- cframe.translation = center();
-
- Vector3 Y = (p1 - p2).direction();
- Vector3 X = (abs(Y.dot(Vector3::unitX())) > 0.9) ? Vector3::unitY() : Vector3::unitX();
- Vector3 Z = X.cross(Y).direction();
- X = Y.cross(Z);
- cframe.rotation.setColumn(0, X);
- cframe.rotation.setColumn(1, Y);
- cframe.rotation.setColumn(2, Z);
-}
-
-
-void Cylinder::getRandomSurfacePoint(Vector3& p, Vector3& N) const {
- float h = height();
- float r = radius();
-
- // Create a random point on a standard cylinder and then rotate to the global frame.
-
- // Relative areas (factor of 2PI already taken out)
- float capRelArea = square(r) / 2.0f;
- float sideRelArea = r * h;
-
- float r1 = uniformRandom(0, capRelArea * 2 + sideRelArea);
-
- if (r1 < capRelArea * 2) {
-
- // Select a point uniformly at random on a disk
- // @cite http://mathworld.wolfram.com/DiskPointPicking.html
- float a = uniformRandom(0, (float)twoPi());
- float r2 = sqrt(uniformRandom(0, 1)) * r;
- p.x = cos(a) * r2;
- p.z = sin(a) * r2;
-
- N.x = 0;
- N.z = 0;
- if (r1 < capRelArea) {
- // Top
- p.y = h / 2.0f;
- N.y = 1;
- } else {
- // Bottom
- p.y = -h / 2.0f;
- N.y = -1;
- }
- } else {
- // Side
- float a = uniformRandom(0, (float)twoPi());
- N.x = cos(a);
- N.y = 0;
- N.z = sin(a);
- p.x = N.x * r;
- p.z = N.y * r;
- p.y = uniformRandom(-h / 2.0f, h / 2.0f);
- }
-
- // Transform to world space
- CoordinateFrame cframe;
- getReferenceFrame(cframe);
-
- p = cframe.pointToWorldSpace(p);
- N = cframe.normalToWorldSpace(N);
-}
-
-
-Vector3 Cylinder::randomInteriorPoint() const {
- float h = height();
- float r = radius();
-
- // Create a random point in a standard cylinder and then rotate to the global frame.
-
- // Select a point uniformly at random on a disk
- // @cite http://mathworld.wolfram.com/DiskPointPicking.html
- float a = uniformRandom(0, (float)twoPi());
- float r2 = sqrt(uniformRandom(0, 1)) * r;
-
- Vector3 p( cos(a) * r2,
- uniformRandom(-h / 2.0f, h / 2.0f),
- sin(a) * r2);
-
- // Transform to world space
- CoordinateFrame cframe;
- getReferenceFrame(cframe);
-
- return cframe.pointToWorldSpace(p);
-}
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/Discovery.cpp b/externals/g3dlite/G3D.lib/source/Discovery.cpp
deleted file mode 100644
index 2c27c5bf2b9..00000000000
--- a/externals/g3dlite/G3D.lib/source/Discovery.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- @file Discovery.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-06-26
- @edited 2005-02-24
- */
-
-#include "G3D/Discovery.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-#include <cstring>
-
-namespace G3D {
-
-///////////////////////////////////////////////////////////////////////////////////////////
-
-void DiscoveryAdvertisement::serialize(BinaryOutput& b) const {
- address.serialize(b);
-}
-
-void DiscoveryAdvertisement::deserialize(BinaryInput& b) {
- address.deserialize(b);
- lastUpdateTime = System::time();
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////
-
-void DiscoveryServerAddressMessage::serialize(BinaryOutput& b) const {
- b.writeString(G3D_DISCOVERY_PROTOCOL_NAME);
- b.writeInt32(G3D_DISCOVERY_PROTOCOL_VERSION);
- b.writeString(settings->appProtocolName);
- b.writeInt32(settings->appProtocolVersion);
-
- // Send addresses
- b.writeInt32(address.size());
- for (int i = 0; i < address.size(); ++i) {
- address[i].serialize(b);
- }
-}
-
-
-void DiscoveryServerAddressMessage::deserialize(BinaryInput& b) {
- address.clear();
- correctProtocol = false;
- serverProtocolVersion[0] = 0;
- serverProtocolVersion[1] = 0;
-
- // Verify that we are on the same protocol
- if (b.readString(strlen(G3D_DISCOVERY_PROTOCOL_NAME) + 1) != G3D_DISCOVERY_PROTOCOL_NAME) {
- return;
- }
-
- serverProtocolVersion[0] = b.readInt32();
- if (serverProtocolVersion[0] != G3D_DISCOVERY_PROTOCOL_VERSION) {
- return;
- }
-
- if (b.readString() != settings->appProtocolName) {
- return;
- }
-
- serverProtocolVersion[1] = b.readInt32();
- if (serverProtocolVersion[1] != settings->appProtocolVersion) {
- return;
- }
-
- correctProtocol = true;
-
- address.resize(b.readInt32());
- for (int i = 0; i < address.size(); ++i) {
- address[i].deserialize(b);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////
-
-void DiscoveryServer::sendAnnouncement() const {
- NetAddress broadcast(NetworkDevice::instance()->broadcastAddressArray()[0], settings->serverBroadcastPort);
-
- net->send(broadcast, SERVER_BROADCAST_MESSAGE, addressMessage);
-
- const_cast<DiscoveryServer*>(this)->lastBroadcast = System::time();
-}
-
-
-void DiscoveryServer::sendShutDown() const {
- NetAddress broadcast(NetworkDevice::instance()->broadcastAddressArray()[0], settings->serverBroadcastPort);
- ShutdownMessage s;
- net->send(broadcast, SERVER_SHUTDOWN_MESSAGE, s);
-}
-
-
-bool DiscoveryServer::ok() const {
- return listener->ok() && net->ok();
-}
-
-
-void DiscoveryServer::init(
- const DiscoverySettings* _settings,
- DiscoveryAdvertisement* _advertisement) {
-
- Discovery::init(_settings);
-
- advertisement = _advertisement;
- addressMessage.settings = settings;
- NetworkDevice::instance()->localHostAddresses(addressMessage.address);
-
- // Set the port number
- for (int i = 0; i < addressMessage.address.size(); ++i) {
- addressMessage.address[i] =
- NetAddress(addressMessage.address[i].ip(),
- settings->serverAdvertisementPort);
- }
-
- net = LightweightConduit::create(settings->clientBroadcastPort, true, true);
-
- listener = NetListener::create(settings->serverAdvertisementPort);
-
- // Send initial announcement
- sendAnnouncement();
-}
-
-
-void DiscoveryServer::doNetwork() {
- const RealTime UNSOLICITED_BROADCAST_PERIOD = 60;
-
- // Check for client broadcast requests
-
- if (net->messageWaiting()) {
- // Some client broadcast that it is looking for servers.
- // Respond by sending out our announcement to everyone
- // (avoids having to figure out if the message return address
- // is correct).
- NetAddress dummy;
- net->receive(dummy);
- sendAnnouncement();
- } else if (System::time() > lastBroadcast + UNSOLICITED_BROADCAST_PERIOD) {
- sendAnnouncement();
- }
-
- // Handle incoming connections
-
- if (listener->clientWaiting()) {
- // Respond to this client
- ReliableConduitRef client = listener->waitForConnection();
- client->send(SERVER_BROADCAST_MESSAGE, *advertisement);
- }
-}
-
-
-void DiscoveryServer::cleanup() {
- sendShutDown();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-
-std::string IncompatibleServerDescription::toString() const {
- return std::string("Incompatible server at ") + address.toString() +
- format(", version %d.%d", protocolVersion[0], protocolVersion[1]);
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-
-
-}
-
diff --git a/externals/g3dlite/G3D.lib/source/GCamera.cpp b/externals/g3dlite/G3D.lib/source/GCamera.cpp
deleted file mode 100644
index e70188377e6..00000000000
--- a/externals/g3dlite/G3D.lib/source/GCamera.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/**
- @file GCamera.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
- @author Jeff Marsceill, 08jcm@williams.edu
-
- @created 2005-07-20
- @edited 2007-07-24
-*/
-#include "G3D/GCamera.h"
-#include "G3D/platform.h"
-#include "G3D/Rect2D.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Ray.h"
-#include "G3D/Matrix4.h"
-
-namespace G3D {
-
-GCamera::GCamera() {
- setNearPlaneZ(-0.1f);
- setFarPlaneZ(-(float)inf());
- setFieldOfView((float)toRadians(55.0f), VERTICAL);
-}
-
-
-GCamera::~GCamera() {
-}
-
-void GCamera::getCoordinateFrame(CoordinateFrame& c) const {
- c = m_cframe;
-}
-
-void GCamera::setCoordinateFrame(const CoordinateFrame& c) {
- m_cframe = c;
-}
-
-void GCamera::setFieldOfView(float angle, FOVDirection dir) {
- debugAssert((angle < pi()) && (angle > 0));
-
- m_fieldOfView = angle;
- m_direction = dir;
-}
-
-float GCamera::imagePlaneDepth() const{
- return -m_nearPlaneZ;
-}
-
-float GCamera::viewportWidth(const Rect2D& viewport) const {
- // Compute the side of a square at the near plane based on our field of view
- float s = 2.0f * -m_nearPlaneZ * tan(m_fieldOfView * 0.5f);
-
- if (m_direction == VERTICAL) {
- s *= viewport.width() / viewport.height();
- }
-
- return s;
-}
-
-float GCamera::viewportHeight(const Rect2D& viewport) const {
- // Compute the side of a square at the near plane based on our field of view
- float s = 2.0f * -m_nearPlaneZ * tan(m_fieldOfView * 0.5f);
-
- if (m_direction == HORIZONTAL) {
- s *= viewport.height() / viewport.width();
- }
-
- return s;
-}
-
-Ray GCamera::worldRay(float x, float y, const Rect2D& viewport) const {
-
- int screenWidth = iFloor(viewport.width());
- int screenHeight = iFloor(viewport.height());
-
- Ray out;
- out.origin = m_cframe.translation;
-
- float cx = screenWidth / 2.0f;
- float cy = screenHeight / 2.0f;
-
- out.direction = Vector3( (x - cx) * viewportWidth(viewport) / screenWidth,
- -(y - cy) * viewportHeight(viewport) / screenHeight,
- (m_nearPlaneZ) );
-
- out.direction = m_cframe.vectorToWorldSpace(out.direction);
-
- // Normalize the direction (we didn't do it before)
- out.direction = out.direction.direction();
-
- return out;
-}
-
-/**
-This is the matrix that a RenderDevice (or OpenGL) uses as the projection matrix.
-@sa RenderDevice::setProjectionAndCameraMatrix, RenderDevice::setProjectionMatrix, Matrix4::perspectiveProjection
-*/
-void GCamera::getProjectUnitMatrix(const Rect2D& viewport, Matrix4& P) const{
-
- float screenWidth = viewport.width();
- float screenHeight = viewport.height();
-
- float r, l, t, b, n, f, x, y;
-
- if(m_direction == VERTICAL){
- y = -m_nearPlaneZ * tan(m_fieldOfView / 2);
- x = y * (screenWidth / screenHeight);
- }
- else{ //m_direction == HORIZONTAL
- x = -m_nearPlaneZ * tan(m_fieldOfView / 2);
- y = x * (screenHeight / screenWidth);
- }
-
- n = -m_nearPlaneZ;
- f = -m_farPlaneZ;
- r = x;
- l = -x;
- t = y;
- b = -y;
-
- P = Matrix4::perspectiveProjection(l, r, b, t, n, f);
-}
-
-Vector3 GCamera::projectUnit(const Vector3& point, const Rect2D& viewport) const {
- Matrix4 M;
- getProjectUnitMatrix(viewport, M);
-
- Vector4 cameraSpacePoint(coordinateFrame().pointToObjectSpace(point), 1.0f);
- const Vector4& screenSpacePoint = M * cameraSpacePoint;
-
- return Vector3(screenSpacePoint.xyz() / screenSpacePoint.w);
-}
-
-Vector3 GCamera::project(const Vector3& point,
- const Rect2D& viewport) const {
-
- // Find the point in the homogeneous cube
- const Vector3& cube = projectUnit(point, viewport);
-
- return convertFromUnitToNormal(cube, viewport);
-}
-
-Vector3 GCamera::unprojectUnit(const Vector3& v, const Rect2D& viewport) const {
-
- const Vector3& projectedPoint = convertFromUnitToNormal(v, viewport);
-
- return unproject(projectedPoint, viewport);
-}
-
-
-Vector3 GCamera::unproject(const Vector3& v, const Rect2D& viewport) const {
-
- const float n = m_nearPlaneZ;
- const float f = m_farPlaneZ;
-
- float z;
-
- if (-f >= inf()) {
- // Infinite far plane
- z = 1.0f / (((-1.0f / n) * v.z) + 1.0f / n);
- } else {
- z = 1.0f / ((((1.0f / f) - (1.0f / n)) * v.z) + 1.0f / n);
- }
-
- const Ray& ray = worldRay(v.x, v.y, viewport);
-
- // Find out where the ray reaches the specified depth.
- const Vector3& out = ray.origin + ray.direction * -z / (ray.direction.dot(m_cframe.lookVector()));
-
- return out;
-}
-
-float GCamera::worldToScreenSpaceArea(float area, float z, const Rect2D& viewport) const {
- if (z >= 0) {
- return (float)inf();
- }
- return area * (float)square(imagePlaneDepth() / z);
-}
-
-
-void GCamera::getClipPlanes(
- const Rect2D& viewport,
- Array<Plane>& clip) const {
-
- Frustum fr;
- frustum(viewport, fr);
- clip.resize(fr.faceArray.size(), DONT_SHRINK_UNDERLYING_ARRAY);
- for (int f = 0; f < clip.size(); ++f) {
- clip[f] = fr.faceArray[f].plane;
- }
-}
-
-GCamera::Frustum GCamera::frustum(const Rect2D& viewport) const {
- Frustum f;
- frustum(viewport, f);
- return f;
-}
-
-void GCamera::frustum(const Rect2D& viewport, Frustum& fr) const {
-
- // The volume is the convex hull of the vertices definining the view
- // frustum and the light source point at infinity.
-
- const float x = viewportWidth(viewport) / 2;
- const float y = viewportHeight(viewport) / 2;
- const float z = m_nearPlaneZ;
- const float w = z / -m_farPlaneZ;
- float fovx;
-
- fovx = m_fieldOfView;
- if (m_direction == VERTICAL) {
- fovx *= x / y;
- }
-
- // Near face (ccw from UR)
- fr.vertexPos.append(
- Vector4( x, y, z, 1),
- Vector4(-x, y, z, 1),
- Vector4(-x, -y, z, 1),
- Vector4( x, -y, z, 1));
-
- // Far face (ccw from UR, from origin)
- fr.vertexPos.append(
- Vector4( x, y, z, w),
- Vector4(-x, y, z, w),
- Vector4(-x, -y, z, w),
- Vector4( x, -y, z, w));
-
- Frustum::Face face;
-
- // Near plane (wind backwards so normal faces into frustum)
- // Recall that nearPlane, farPlane are positive numbers, so
- // we need to negate them to produce actual z values.
- face.plane = Plane(Vector3(0,0,-1), Vector3(0,0,m_nearPlaneZ));
- face.vertexIndex[0] = 3;
- face.vertexIndex[1] = 2;
- face.vertexIndex[2] = 1;
- face.vertexIndex[3] = 0;
- fr.faceArray.append(face);
-
- // Right plane
- face.plane = Plane(Vector3(-cosf(fovx/2), 0, -sinf(fovx/2)), Vector3::zero());
- face.vertexIndex[0] = 0;
- face.vertexIndex[1] = 4;
- face.vertexIndex[2] = 7;
- face.vertexIndex[3] = 3;
- fr.faceArray.append(face);
-
- // Left plane
- face.plane = Plane(Vector3(-fr.faceArray.last().plane.normal().x, 0, fr.faceArray.last().plane.normal().z), Vector3::zero());
- face.vertexIndex[0] = 5;
- face.vertexIndex[1] = 1;
- face.vertexIndex[2] = 2;
- face.vertexIndex[3] = 6;
- fr.faceArray.append(face);
-
- // Top plane
- face.plane = Plane(Vector3(0, -cosf(m_fieldOfView/2.0f), -sinf(m_fieldOfView/2.0f)), Vector3::zero());
- face.vertexIndex[0] = 1;
- face.vertexIndex[1] = 5;
- face.vertexIndex[2] = 4;
- face.vertexIndex[3] = 0;
- fr.faceArray.append(face);
-
- // Bottom plane
- face.plane = Plane(Vector3(0, -fr.faceArray.last().plane.normal().y, fr.faceArray.last().plane.normal().z), Vector3::zero());
- face.vertexIndex[0] = 2;
- face.vertexIndex[1] = 3;
- face.vertexIndex[2] = 7;
- face.vertexIndex[3] = 6;
- fr.faceArray.append(face);
-
- // Far plane
- if (-m_farPlaneZ < inf()) {
- face.plane = Plane(Vector3(0, 0, 1), Vector3(0, 0, m_farPlaneZ));
- face.vertexIndex[0] = 4;
- face.vertexIndex[1] = 5;
- face.vertexIndex[2] = 6;
- face.vertexIndex[3] = 7;
- fr.faceArray.append(face);
- }
-
- // Transform vertices to world space
- for (int v = 0; v < fr.vertexPos.size(); ++v) {
- fr.vertexPos[v] = m_cframe.toWorldSpace(fr.vertexPos[v]);
- }
-
- // Transform planes to world space
- for (int p = 0; p < fr.faceArray.size(); ++p) {
- // Since there is no scale factor, we don't have to
- // worry about the inverse transpose of the normal.
- Vector3 normal;
- float d;
-
- fr.faceArray[p].plane.getEquation(normal, d);
-
- Vector3 newNormal = m_cframe.rotation * normal;
-
- if (isFinite(d)) {
- d = (newNormal * -d + m_cframe.translation).dot(newNormal);
- fr.faceArray[p].plane = Plane(newNormal, newNormal * d);
- } else {
- // When d is infinite, we can't multiply 0's by it without
- // generating NaNs.
- fr.faceArray[p].plane = Plane::fromEquation(newNormal.x, newNormal.y, newNormal.z, d);
- }
- }
-}
-
-void GCamera::getNearViewportCorners(
- const Rect2D& viewport,
- Vector3& outUR,
- Vector3& outUL,
- Vector3& outLL,
- Vector3& outLR) const {
-
- // Must be kept in sync with getFrustum()
- const float w = viewportWidth(viewport) / 2.0f;
- const float h = viewportHeight(viewport) / 2.0f;
- const float z = nearPlaneZ();
-
- // Compute the points
- outUR = Vector3( w, h, z);
- outUL = Vector3(-w, h, z);
- outLL = Vector3(-w, -h, z);
- outLR = Vector3( w, -h, z);
-
- // Take to world space
- outUR = m_cframe.pointToWorldSpace(outUR);
- outUL = m_cframe.pointToWorldSpace(outUL);
- outLR = m_cframe.pointToWorldSpace(outLR);
- outLL = m_cframe.pointToWorldSpace(outLL);
-}
-
-void GCamera::getFarViewportCorners(
- const Rect2D& viewport,
- Vector3& outUR,
- Vector3& outUL,
- Vector3& outLL,
- Vector3& outLR) const {
-
- // Must be kept in sync with getFrustum()
- const float w = viewportWidth(viewport) * m_farPlaneZ / m_nearPlaneZ;
- const float h = viewportHeight(viewport) * m_farPlaneZ / m_nearPlaneZ;
- const float z = m_farPlaneZ;
-
- // Compute the points
- outUR = Vector3( w, h, z);
- outUL = Vector3(-w, h, z);
- outLL = Vector3(-w, -h, z);
- outLR = Vector3( w, -h, z);
-
- // Take to world space
- outUR = m_cframe.pointToWorldSpace(outUR);
- outUL = m_cframe.pointToWorldSpace(outUL);
- outLR = m_cframe.pointToWorldSpace(outLR);
- outLL = m_cframe.pointToWorldSpace(outLL);
-}
-
-
-
-void GCamera::setPosition(const Vector3& t) {
- m_cframe.translation = t;
-}
-
-
-void GCamera::lookAt(const Vector3& position, const Vector3& up) {
- m_cframe.lookAt(position, up);
-}
-
-
-void GCamera::serialize(BinaryOutput& bo) const {
- bo.writeFloat32(m_fieldOfView);
- bo.writeFloat32(imagePlaneDepth());
- debugAssert(nearPlaneZ() < 0.0f);
- bo.writeFloat32(nearPlaneZ());
- debugAssert(farPlaneZ() < 0.0f);
- bo.writeFloat32(farPlaneZ());
- m_cframe.serialize(bo);
- bo.writeInt8(m_direction);
-}
-
-
-void GCamera::deserialize(BinaryInput& bi) {
- m_fieldOfView = bi.readFloat32();
- m_nearPlaneZ = bi.readFloat32();
- debugAssert(m_nearPlaneZ < 0.0f);
- m_farPlaneZ = bi.readFloat32();
- debugAssert(m_farPlaneZ < 0.0f);
- m_cframe.deserialize(bi);
- m_direction = (FOVDirection)bi.readInt8();
-}
-
-
-Vector3 GCamera::convertFromUnitToNormal(const Vector3& in, const Rect2D& viewport) const{
- return (in + Vector3(1,1,1)) * 0.5 * Vector3(viewport.width(), -viewport.height(), 1) +
- Vector3(viewport.x0(), viewport.y1(), 0);
-}
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/GImage.cpp b/externals/g3dlite/G3D.lib/source/GImage.cpp
deleted file mode 100644
index c7abf982553..00000000000
--- a/externals/g3dlite/G3D.lib/source/GImage.cpp
+++ /dev/null
@@ -1,1065 +0,0 @@
-/**
- @file GImage.cpp
- @author Morgan McGuire, morgan@graphics3d.com
- Copyright 2002-2007, Morgan McGuire
-
- @created 2002-05-27
- @edited 2006-10-10
- */
-#include "G3D/platform.h"
-#include "G3D/GImage.h"
-#include "G3D/debug.h"
-#include "G3D/stringutils.h"
-#include "G3D/TextInput.h"
-#include "G3D/TextOutput.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Log.h"
-#include <png.h>
-#include <sys/stat.h>
-#include <assert.h>
-#include <sys/types.h>
-
-//////////////////////////////////////////////////////////////////////////////////////////////
-
-namespace G3D {
-
-void GImage::RGBtoRGBA(
- const uint8* in,
- uint8* out,
- int numPixels) {
-
- for (int i = 0; i < numPixels; ++i) {
- int i3 = i * 3;
- int i4 = i3 + i;
-
- out[i4 + 0] = in[i3 + 0];
- out[i4 + 1] = in[i3 + 1];
- out[i4 + 2] = in[i3 + 2];
- out[i4 + 3] = 255;
- }
-}
-
-
-void GImage::RGBAtoRGB(
- const uint8* in,
- uint8* out,
- int numPixels) {
-
- for (int i = 0; i < numPixels; ++i) {
- int i3 = i * 3;
- int i4 = i3 + i;
-
- out[i3 + 0] = in[i4 + 0];
- out[i3 + 1] = in[i4 + 1];
- out[i3 + 2] = in[i4 + 2];
- }
-}
-
-
-void GImage::RGBtoBGRA(
- const uint8* in,
- uint8* out,
- int numPixels) {
-
- for (int i = 0; i < numPixels; ++i) {
- int i3 = i * 3;
- int i4 = i3 + i;
-
- out[i4 + 2] = in[i3 + 0];
- out[i4 + 1] = in[i3 + 1];
- out[i4 + 0] = in[i3 + 2];
- out[i4 + 3] = 255;
- }
-}
-
-
-
-void GImage::RGBtoBGR(
- const uint8* in,
- uint8* out,
- int numPixels) {
-
- for (int i = 0; i < numPixels; ++i) {
- int i3 = i * 3;
-
- int r = in[i3 + 0];
- int g = in[i3 + 1];
- int b = in[i3 + 2];
-
- out[i3 + 2] = r;
- out[i3 + 1] = g;
- out[i3 + 0] = b;
- }
-}
-
-
-void GImage::RGBxRGBtoRGBA(
- const uint8* colorRGB,
- const uint8* alphaRGB,
- uint8* out,
- int numPixels) {
-
- for (int i = numPixels - 1; i >= 0; --i) {
- int i3 = i * 3;
- int i4 = i3 + i;
-
- out[i4 + 0] = colorRGB[i3 + 0];
- out[i4 + 1] = colorRGB[i3 + 1];
- out[i4 + 2] = colorRGB[i3 + 2];
- out[i4 + 3] = alphaRGB[i3 + 0];
- }
-}
-
-
-void GImage::RGBtoARGB(
- const uint8* in,
- uint8* out,
- int numPixels) {
-
- for (int i = 0; i < numPixels; ++i) {
- int i3 = i * 3;
- int i4 = i3 + i;
-
- out[i4 + 0] = 255;
- out[i4 + 1] = in[i3 + 0];
- out[i4 + 2] = in[i3 + 1];
- out[i4 + 3] = in[i3 + 2];
- }
-}
-
-
-void GImage::flipRGBVertical(
- const uint8* in,
- uint8* out,
- int width,
- int height) {
-
-
- // Allocate a temp row so the operation
- // is still safe if in == out
- uint8* temp = (uint8*)System::malloc(width * 3);
- alwaysAssertM(temp != NULL, "Out of memory");
-
- int oneRow = width * 3;
- int N = height / 2;
-
- // if height is an odd value, don't swap odd middle row
- for (int i = 0; i < N; ++i) {
- int topOff = i * oneRow;
- int botOff = (height - i - 1) * oneRow;
- System::memcpy(temp, in + topOff, oneRow);
- System::memcpy(out + topOff, in + botOff, oneRow);
- System::memcpy(out + botOff, temp, oneRow);
- }
-
- System::free(temp);
-}
-
-
-void GImage::flipRGBAVertical(
- const uint8* in,
- uint8* out,
- int width,
- int height) {
-
-
- // Allocate a temp row so the operation
- // is still safe if in == out
- uint8* temp = (uint8*)System::malloc(width * 4);
- alwaysAssertM(temp != NULL, "Out of memory");
-
- int oneRow = width * 4;
-
- // if height is an odd value, don't swap odd middle row
- for (int i = 0; i < height / 2; ++i) {
- int topOff = i * oneRow;
- int botOff = (height - i - 1) * oneRow;
- System::memcpy(temp, in + topOff, oneRow);
- System::memcpy(out + topOff, in + botOff, oneRow);
- System::memcpy(out + botOff, temp, oneRow);
- }
-
- System::free(temp);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-
-void GImage::decode(
- BinaryInput& input,
- Format format) {
-
- switch (format) {
- case PPM_ASCII:
- decodePPMASCII(input);
- break;
-
- case PPM:
- decodePPM(input);
- break;
-
- case PNG:
- decodePNG(input);
- break;
-
- case JPEG:
- decodeJPEG(input);
- break;
-
- case TGA:
- decodeTGA(input);
- break;
-
- case BMP:
- decodeBMP(input);
- break;
-
- case ICO:
- decodeICO(input);
- break;
-
- case PCX:
- decodePCX(input);
- break;
-
- default:
- debugAssert(false);
- }
-
- debugAssert(width >= 0);
- debugAssert(height >= 0);
- debugAssert(channels == 1 || channels == 3 || channels == 4);
- debugAssert(_byte != NULL);
-}
-
-
-void GImage::decodePCX(
- BinaryInput& input) {
-
- uint8 manufacturer = input.readUInt8();
- uint8 version = input.readUInt8();
- uint8 encoding = input.readUInt8();
- uint8 bitsPerPixel = input.readUInt8();
-
- uint16 xmin = input.readUInt16();
- uint16 ymin = input.readUInt16();
- uint16 xmax = input.readUInt16();
- uint16 ymax = input.readUInt16();
-
- uint16 horizDPI = input.readUInt16();
- uint16 vertDPI = input.readUInt16();
-
- Color3uint8 colorMap[16];
- input.readBytes(colorMap, 48);
-
- input.skip(1);
-
- uint8 planes = input.readUInt8();
- uint16 bytesPerLine = input.readUInt16();
- uint16 paletteType = input.readUInt16();
- input.skip(4 + 54);
-
- (void)bytesPerLine;
-
- width = xmax - xmin + 1;
- height = ymax - ymin + 1;
- channels = 3;
-
- if ((manufacturer != 0x0A) || (encoding != 0x01)) {
- throw GImage::Error("PCX file is corrupted", input.getFilename());
- }
-
- (void)version;
- (void)vertDPI;
- (void)horizDPI;
-
- if ((bitsPerPixel != 8) || ((planes != 1) && (planes != 3))) {
- throw GImage::Error("Only 8-bit paletted and 24-bit PCX files supported.", input.getFilename());
- }
-
- // Prepare the pointer object for the pixel data
- _byte = (uint8*)System::malloc(width * height * 3);
-
- if ((paletteType == 1) && (planes == 3)) {
-
- Color3uint8* pixel = pixel3();
-
- // Iterate over each scan line
- for (int row = 0; row < height; ++row) {
- // Read each scan line once per plane
- for (int plane = 0; plane < planes; ++plane) {
- int p = row * width;
- int p1 = p + width;
- while (p < p1) {
- uint8 value = input.readUInt8();
- int length = 1;
-
- if (value >= 192) {
- // This is the length, not the value. Mask off
- // the two high bits and read the true index.
- length = value & 0x3F;
- value = input.readUInt8();
- }
-
- // Set the whole run
- for (int i = length - 1; i >= 0; --i, ++p) {
- debugAssert(p < width * height);
- pixel[p][plane] = value;
- }
- }
- }
- }
-
- } else if (planes == 1) {
-
- Color3uint8 palette[256];
-
- int imageBeginning = input.getPosition();
- int paletteBeginning = input.getLength() - 769;
-
- input.setPosition(paletteBeginning);
-
- uint8 dummy = input.readUInt8();
-
- if (dummy != 12) {
- Log::common()->println("\n*********************");
- Log::common()->printf("Warning: Corrupted PCX file (palette marker byte was missing) \"%s\"\nLoading anyway\n\n", input.getFilename().c_str());
- }
-
- input.readBytes(palette, sizeof(palette));
- input.setPosition(imageBeginning);
-
- Color3uint8* pixel = pixel3();
-
- // The palette indices are run length encoded.
- int p = 0;
- while (p < width * height) {
- uint8 index = input.readUInt8();
- uint8 length = 1;
-
- if (index >= 192) {
- // This is the length, not the index. Mask off
- // the two high bits and read the true index.
- length = index & 0x3F;
- index = input.readUInt8();
- }
-
- Color3uint8 color = palette[index];
-
- // Set the whole run
- for (int i = length - 1; i >= 0; --i, ++p) {
- if (p > width * height) {
- break;
- }
- pixel[p] = color;
- }
-
- }
-
- } else {
- throw GImage::Error("Unsupported PCX file type.", input.getFilename());
- }
-}
-
-
-GImage::Format GImage::resolveFormat(const std::string& filename) {
- BinaryInput b(filename, G3D_LITTLE_ENDIAN);
- if (b.size() <= 0) {
- throw Error("File not found.", filename);
- }
-
- return resolveFormat(filename, b.getCArray(), b.size(), AUTODETECT);
-}
-
-
-GImage::Format GImage::resolveFormat(
- const std::string& filename,
- const uint8* data,
- int dataLen,
- Format maybeFormat) {
-
- // Return the provided format if it is specified.
- if (maybeFormat != AUTODETECT) {
- return maybeFormat;
- }
-
- std::string extension;
-
- // Try to detect from the filename's extension
- if (filename.size() >= 5) {
- int n = iMax(filename.size() - 1, 5);
- // Search backwards for the "."
- for (int i = 1; i <= n; ++i) {
- if (filename[filename.size() - i] == '.') {
- // Upper case
- extension = toUpper(filename.substr(filename.size() - i + 1));
- break;
- }
- }
- }
-
- if (extension == "PPM") {
- // There are two PPM formats; we handle them differently
- if (dataLen > 3) {
- if (!memcmp(data, "P6", 2)) {
- return PPM;
- } else {
- return PPM_ASCII;
- }
- }
- }
-
- Format tmp = stringToFormat(extension);
- if ((tmp != AUTODETECT) && (tmp != UNKNOWN)) {
- return tmp;
- }
-
- // Try and autodetect from the file itself by looking at the first
- // character.
-
- // We can't look at the character if it is null.
- debugAssert(data != NULL);
-
- if ((dataLen > 3) && (!memcmp(data, "P3", 2) || !memcmp(data, "P2", 2) || !memcmp(data, "P1", 2))) {
- return PPM_ASCII;
- }
-
- if ((dataLen > 3) && !memcmp(data, "P6", 2)) {
- return PPM;
- }
-
- if (dataLen > 8) {
- if (!png_sig_cmp((png_bytep)data, 0, 8))
- return PNG;
- }
-
- if ((dataLen > 0) && (data[0] == 'B')) {
- return BMP;
- }
-
- if (dataLen > 10) {
- if ((dataLen > 11) && (data[0] == 0xFF) &&
- (memcmp(&data[6], "JFIF", 4) == 0)) {
- return JPEG;
- }
- }
-
- if (dataLen > 40) {
- if (memcmp(&data[dataLen - 18], "TRUEVISION-XFILE", 16) == 0) {
- return TGA;
- }
- }
-
- if ((dataLen > 4) && (data[0] == 0) && (data[1] == 0) && (data[2] == 0) && (data[3] == 1)) {
- return ICO;
- }
-
- if ((dataLen > 0) && (data[0] == 10)) {
- return PCX;
- }
-
- return UNKNOWN;
-}
-
-
-GImage::GImage(
- const std::string& filename,
- Format format) :
- _byte(NULL),
- width(0),
- height(0),
- channels(0){
-
- load(filename, format);
-}
-
-
-void GImage::load(
- const std::string& filename,
- Format format) {
-
- clear();
-
- try {
- BinaryInput b(filename, G3D_LITTLE_ENDIAN);
- if (b.size() <= 0) {
- throw Error("File not found.", filename);
- }
-
- alwaysAssertM(this != NULL, "Corrupt GImage");
- decode(b, resolveFormat(filename, b.getCArray(), b.size(), format));
- } catch (const std::string& error) {
- throw Error(error, filename);
- }
-}
-
-
-GImage::GImage(
- const uint8* data,
- int length,
- Format format) {
-
- BinaryInput b(data, length, G3D_LITTLE_ENDIAN);
- // It is safe to cast away the const because we
- // know we don't corrupt the data.
-
- decode(b, resolveFormat("", data, length, format));
-}
-
-
-GImage::GImage(
- int width,
- int height,
- int channels) {
-
- _byte = NULL;
- resize(width, height, channels);
-}
-
-
-void GImage::resize(
- int width,
- int height,
- int channels) {
- debugAssert(width >= 0);
- debugAssert(height >= 0);
- debugAssert(channels >= 1);
-
- clear();
-
- this->width = width;
- this->height = height;
- this->channels = channels;
- size_t sz = width * height * channels;
-
- _byte = (uint8*)System::calloc(sz, sizeof(uint8));
- debugAssert(isValidHeapPointer(_byte));
-}
-
-
-void GImage::_copy(
- const GImage& other) {
-
- clear();
-
- width = other.width;
- height = other.height;
- channels = other.channels;
- int s = width * height * channels * sizeof(uint8);
- _byte = (uint8*)System::malloc(s);
- debugAssert(isValidHeapPointer(_byte));
- memcpy(_byte, other._byte, s);
-}
-
-
-GImage::GImage(
- const GImage& other) : _byte(NULL) {
-
- _copy(other);
-}
-
-
-GImage::~GImage() {
- clear();
-}
-
-
-void GImage::clear() {
- width = 0;
- height = 0;
- System::free(_byte);
- _byte = NULL;
-}
-
-
-GImage& GImage::operator=(const GImage& other) {
- _copy(other);
- return *this;
-}
-
-
-bool GImage::copySubImage(
- GImage & dest, const GImage & src,
- int srcX, int srcY, int srcWidth, int srcHeight) {
- if ((src.width < srcX + srcWidth) ||
- (src.height < srcY + srcHeight) ||
- (srcY < 0) ||
- (srcX < 0)) {
-
- return false;
- }
-
- dest.resize(srcWidth, srcHeight, src.channels);
-
- bool ret;
- ret = pasteSubImage(dest, src, 0, 0, srcX, srcY, srcWidth, srcHeight);
- debugAssert(ret);
-
- return true;
-}
-
-
-bool GImage::pasteSubImage(
- GImage & dest, const GImage & src,
- int destX, int destY,
- int srcX, int srcY, int srcWidth, int srcHeight) {
- if ((src.width < srcX + srcWidth) ||
- (src.height < srcY + srcHeight) ||
- (dest.width < destX + srcWidth) ||
- (dest.height < destY + srcHeight) ||
- (srcY < 0) ||
- (srcX < 0) ||
- (destY < 0) ||
- (destX < 0) ||
- (src.channels != dest.channels)) {
-
- return false;
- }
-
- for (int i = 0; i < srcHeight; i++) {
- const uint8* srcRow = src.byte() +
- ((i + srcY) * src.width + srcX) * src.channels;
- uint8* destRow = dest.byte() +
- ((i + destY) * dest.width + destX) * dest.channels;
- memcpy(destRow, srcRow, srcWidth * src.channels);
- }
-
- return true;
-}
-
-
-bool GImage::supportedFormat(
- const std::string& format) {
-
- return (stringToFormat(format) != UNKNOWN);
-}
-
-
-GImage::Format GImage::stringToFormat(
- const std::string& format) {
-
- std::string extension = toUpper(format);
-
- if ((extension == "JPG") || (extension == "JPEG")) {
- return JPEG;
- } else if (extension == "TGA") {
- return TGA;
- } else if (extension == "BMP") {
- return BMP;
- } else if (extension == "PCX") {
- return PCX;
- } else if (extension == "ICO") {
- return ICO;
- } else if (extension == "PNG") {
- return PNG;
- } else if (extension == "PPM") {
- return PPM;
- } else {
- return UNKNOWN;
- }
-}
-
-
-void GImage::save(
- const std::string& filename,
- Format format) const {
-
- BinaryOutput b(filename, G3D_LITTLE_ENDIAN);
- encode(resolveFormat(filename, NULL, 0, format), b);
- b.commit(false);
-}
-
-
-void GImage::encode(
- Format format,
- uint8*& outData,
- int& outLength) const {
-
- BinaryOutput out;
-
- encode(format, out);
-
- outData = (uint8*)System::malloc(out.size());
- debugAssert(outData);
- outLength = out.size();
-
- out.commit(outData);
-}
-
-
-void GImage::encode(
- Format format,
- BinaryOutput& out) const {
-
- switch (format) {
- case PPM_ASCII:
- encodePPMASCII(out);
- break;
-
- case PPM:
- encodePPM(out);
- break;
-
- case PNG:
- encodePNG(out);
- break;
-
- case JPEG:
- encodeJPEG(out);
- break;
-
- case BMP:
- encodeBMP(out);
- break;
-
- case TGA:
- encodeTGA(out);
- break;
-
- default:
- debugAssert(false);
- }
-}
-
-void GImage::insertRedAsAlpha(const GImage& alpha, GImage& output) const {
- debugAssert(alpha.width == width);
- debugAssert(alpha.height == height);
-
- // make sure output GImage is valid
- if (output.width != width || output.height != height || output.channels != 4) {
- output.resize(width, height, 4);
- }
-
- for (int i = 0; i < width * height; ++i) {
- output.byte()[i * 4 + 0] = byte()[i * channels + 0];
- output.byte()[i * 4 + 1] = byte()[i * channels + 1];
- output.byte()[i * 4 + 2] = byte()[i * channels + 2];
- output.byte()[i * 4 + 3] = alpha.byte()[i * alpha.channels];
- }
-}
-
-GImage GImage::insertRedAsAlpha(const GImage& alpha) const {
- debugAssert(alpha.width == width);
- debugAssert(alpha.height == height);
-
- GImage out(width, height, 4);
-
- insertRedAsAlpha(alpha, out);
-
- return out;
-}
-
-
-void GImage::stripAlpha(GImage& output) const {
-
- if (output.width != width || output.height != height || output.channels != 3)
- {
- output.resize(width, height, 3);
- }
-
- for (int i = 0; i < width * height; ++i) {
- output.byte()[i * 3 + 0] = byte()[i * channels + 0];
- output.byte()[i * 3 + 1] = byte()[i * channels + 1];
- output.byte()[i * 3 + 2] = byte()[i * channels + 2];
- }
-}
-
-GImage GImage::stripAlpha() const {
- GImage out(width, height, 3);
-
- stripAlpha(out);
-
- return out;
-}
-
-
-int GImage::sizeInMemory() const {
- return sizeof(GImage) + width * height * channels;
-}
-
-
-void GImage::computeNormalMap(
- const GImage& bump,
- GImage& normal,
- float whiteHeightInPixels,
- bool lowPassBump,
- bool scaleHeightByNz) {
- computeNormalMap(bump.width, bump.height, bump.channels, bump.byte(), normal, whiteHeightInPixels, lowPassBump, scaleHeightByNz);
-}
-
-void GImage::computeNormalMap(
- int width,
- int height,
- int channels,
- const uint8* src,
- GImage& normal,
- float whiteHeightInPixels,
- bool lowPassBump,
- bool scaleHeightByNz) {
-
- if (whiteHeightInPixels == -1.0f) {
- // Default setting scales so that a gradient ramp
- // over the whole image becomes a 45-degree angle
-
- // Account for potentially non-square aspect ratios
- whiteHeightInPixels = max(width, height);
- }
-
- debugAssert(whiteHeightInPixels >= 0);
-
- const int w = width;
- const int h = height;
- const int stride = channels;
-
- normal.resize(w, h, 4);
-
- const uint8* const B = src;
- Color4uint8* const N = normal.pixel4();
-
- for (int y = 0; y < h; ++y) {
- for (int x = 0; x < w; ++x) {
- // Index into normal map pixel
- int i = x + y * w;
-
- // Index into bump map *byte*
- int j = stride * i;
-
- Vector3 delta;
-
- // Get a value from B (with wrapping lookup) relative to (x, y)
- // and divide by 255
- #define height(DX, DY) ((int)B[(((DX + x + w) % w) + \
- ((DY + y + h) % h) * w) * stride])
-
-
- // Sobel filter to compute the normal.
- //
- // Y Filter (X filter is the transpose)
- // [ -1 -2 -1 ]
- // [ 0 0 0 ]
- // [ 1 2 1 ]
-
- // Write the Y value directly into the x-component so we don't have
- // to explicitly compute a cross product at the end.
- delta.y = -(height(-1, -1) * 1 + height( 0, -1) * 2 + height( 1, -1) * 1 +
- height(-1, 1) * -1 + height( 0, 1) * -2 + height( 1, 1) * -1);
-
- delta.x = -(height(-1, -1) * -1 + height( 1, -1) * 1 +
- height(-1, 0) * -2 + height( 1, 0) * 2 +
- height(-1, 1) * -1 + height( 1, 1) * 1);
-
- // The scale of each filter row is 4, the filter width is two pixels,
- // and the "normal" range is 0-255.
- delta.z = 4 * 2 * (whiteHeightInPixels / 255.0f);
-
- // Delta is now scaled in pixels; normalize
- delta = delta.direction();
-
- // Copy over the bump value into the alpha channel.
- float H = B[j] / 255.0;
-
- if (lowPassBump) {
- H = (height(-1, -1) + height( 0, -1) + height(1, -1) +
- height(-1, 0) + height( 0, 0) + height(1, 0) +
- height(-1, 1) + height( 0, 1) + height(1, 1)) / (255.0f * 9.0f);
- }
- #undef height
-
- if (scaleHeightByNz) {
- // delta.z can't possibly be negative, so we avoid actually
- // computing the absolute value.
- H *= delta.z;
- }
-
- N[i].a = iRound(H * 255.0);
-
- // Pack into byte range
- delta = delta * 127.5 + Vector3(127.5, 127.5, 127.5);
- N[i].r = iClamp(iRound(delta.x), 0, 255);
- N[i].g = iClamp(iRound(delta.y), 0, 255);
- N[i].b = iClamp(iRound(delta.z), 0, 255);
- }
- }
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-void GImage::convertToL8() {
- switch(channels) {
- case 1:
- return;
-
- case 3:
- {
- // Average
- Color3uint8* src = (Color3uint8*)_byte;
- _byte = NULL;
- resize(width, height, 1);
- for (int i = width * height - 1; i >= 0; --i) {
- const Color3uint8 s = src[i];
- uint8& d = _byte[i];
- d = ((int)s.r + (int)s.g + (int)s.b) / 3;
- }
- System::free(src);
- }
- break;
-
- case 4:
- {
- // Average
- Color4uint8* src = (Color4uint8*)_byte;
- _byte = NULL;
- resize(width, height, 1);
- for (int i = width * height - 1; i >= 0; --i) {
- const Color4uint8 s = src[i];
- uint8& d = _byte[i];
- d = ((int)s.r + (int)s.g + (int)s.b) / 3;
- }
- System::free(src);
- }
- return;
-
- default:
- alwaysAssertM(false, "Bad number of channels in input image");
- }
-}
-
-
-void GImage::convertToRGBA() {
- switch(channels) {
- case 1:
- {
- // Spread
- uint8* old = _byte;
- _byte = NULL;
- resize(width, height, 4);
- for (int i = width * height - 1; i >= 0; --i) {
- const uint8 s = old[i];
- Color4uint8& d = ((Color4uint8*)_byte)[i];
- d.r = d.g = d.b = s;
- d.a = 255;
- }
- System::free(_byte);
- }
- break;
-
- case 3:
- {
- // Add alpha
- Color3uint8* old = (Color3uint8*)_byte;
- _byte = NULL;
- resize(width, height, 4);
- for (int i = width * height - 1; i >= 0; --i) {
- const Color3uint8 s = old[i];
- Color4uint8& d = ((Color4uint8*)_byte)[i];
- d.r = s.r;
- d.g = s.g;
- d.b = s.b;
- d.a = 255;
- }
- System::free(old);
- }
- break;
-
- case 4:
- // Already RGBA
- return;
-
- default:
- alwaysAssertM(false, "Bad number of channels in input image");
- }
-}
-
-
-void GImage::convertToRGB() {
- switch(channels) {
- case 1:
- {
- // Spread
- uint8* old = _byte;
- _byte = NULL;
- resize(width, height, 3);
- for (int i = width * height - 1; i >= 0; --i) {
- const uint8 s = old[i];
- Color3uint8& d = ((Color3uint8*)_byte)[i];
- d.r = d.g = d.b = s;
- }
- System::free(old);
- }
- break;
-
- case 3:
- return;
-
- case 4:
- // Strip alpha
- {
- Color4uint8* old = (Color4uint8*)_byte;
- _byte = NULL;
- resize(width, height, 3);
- for (int i = width * height - 1; i >= 0; --i) {
- const Color4uint8 s = old[i];
- Color3uint8& d = ((Color3uint8*)_byte)[i];
- d.r = s.r;
- d.g = s.g;
- d.b = s.b;
- }
- System::free(old);
- }
- break;
-
- default:
- alwaysAssertM(false, "Bad number of channels in input image");
- }
-}
-
-
-void GImage::R8G8B8_to_Y8U8V8(int width, int height, const uint8* _in, uint8* _out) {
- const Color3uint8* in = reinterpret_cast<const Color3uint8*>(_in);
- Color3uint8* out = reinterpret_cast<Color3uint8*>(_out);
-
- Color3uint8 p;
- for (int i = width * height - 1; i >= 0; --i) {
- p.r = iClamp(iRound(in->r * 0.229 + in->g * 0.587 + in->b * 0.114), 0, 255);
- p.g = iClamp(iRound(in->r * -0.147 + in->g * -0.289 + in->b * 0.436) + 127, 0, 255);
- p.b = iClamp(iRound(in->r * 0.615 + in->g * -0.515 + in->b * -0.100) + 127, 0, 255);
- *out = p;
- ++in;
- ++out;
- }
-}
-
-
-
-void GImage::Y8U8V8_to_R8G8B8(int width, int height, const uint8* _in, uint8* _out) {
- const Color3uint8* in = reinterpret_cast<const Color3uint8*>(_in);
- Color3uint8* out = reinterpret_cast<Color3uint8*>(_out);
-
- Color3uint8 p;
- for (int i = width * height - 1; i >= 0; --i) {
- p.r = iClamp(iRound(in->r * 1.0753 + (in->b - 127) * 1.2256), 0, 255);
- p.g = iClamp(iRound(in->r * 1.0753 + (in->g - 127) * -0.3946 + (in->b - 127) * -0.4947), 0, 255);
- p.b = iClamp(iRound(in->r * 1.0753 + (in->g - 127) * 2.0320 + (in->b - 127) * 0.0853), 0, 255);
- *out = p;
- ++in;
- ++out;
- }
-}
-
-
-void GImage::makeCheckerboard(GImage& im, int checkerSize, const Color4uint8& A, const Color4uint8& B) {
- for (int y = 0; y < im.height; ++y) {
- for (int x = 0; x < im.width; ++x) {
- bool checker = isOdd((x / checkerSize) + (y / checkerSize));
- const Color4uint8& color = checker ? A : B;
- for (int c = 0; c < im.channels; ++c) {
- uint8* v = im.byte() + (x + y * im.width) * im.channels + c;
- *v = color[c];
- }
- }
- }
-}
-
-}
-
diff --git a/externals/g3dlite/G3D.lib/source/GImage_bayer.cpp b/externals/g3dlite/G3D.lib/source/GImage_bayer.cpp
deleted file mode 100644
index 16499af15f6..00000000000
--- a/externals/g3dlite/G3D.lib/source/GImage_bayer.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-/**
- @file GImage_bayer.cpp
- @author Morgan McGuire, morgan@graphics3d.com
- @created 2002-05-27
- @edited 2006-05-10
- */
-#include "G3D/platform.h"
-#include "G3D/GImage.h"
-
-namespace G3D {
-
-void GImage::BAYER_G8B8_R8G8_to_Quarter_R8G8B8(int width, int height, const uint8* in, uint8* out) {
- debugAssert(in != out);
-
- int halfHeight = height / 2;
- int halfWidth = width / 2;
-
- int dst_off = 0;
- for (int y = 0; y < halfHeight; ++y) {
- for (int x = 0; x < halfWidth; ++x) {
- // GBRG
- int src_off = x*2 + y*2*width;
- out[dst_off] = in[src_off+width]; // red
- out[dst_off+1] = ((int)in[src_off] + (int)in[src_off+width+1])/2; // green
- out[dst_off+2] = in[src_off+1]; // blue
-
- dst_off = dst_off + 3;
- }
- }
-}
-
-
-void GImage::Quarter_R8G8B8_to_BAYER_G8B8_R8G8(int inWidth, int inHeight, const uint8* in, uint8* out) {
- // Undo quarter-size Bayer as best we can. This code isn't very efficient, but it
- // also isn't used very frequently.
-
- debugAssert(out != in);
-
- int outWidth = 2 * inWidth;
- int outHeight = 2 * inHeight;
-
- for (int y = 0; y < outHeight; ++y) {
- for (int x = 0; x < outWidth; ++x) {
- const Color3uint8* inp = ((const Color3uint8*)in) + ((x/2) + (y/2)* inWidth);
- uint8* outp = out + x + y * outWidth;
-
- if (isEven(y)) {
- // GB row
- if (isEven(x)) {
- // Green
- *outp = inp->g;
- } else {
- // Blue
- *outp = inp->b;
- }
- } else {
- // RG row
- if (isEven(x)) {
- // Red
- *outp = inp->r;
- } else {
- // Green
- *outp = inp->g;
- }
- }
- }
- }
-}
-
-
-/** Applies a 5x5 filter to monochrome image I (wrapping at the boundaries) */
-static uint8 applyFilter(
- const uint8* I,
- int x,
- int y,
- int w,
- int h,
- const float filter[5][5]) {
-
- debugAssert(isEven(w));
- debugAssert(isEven(h));
-
- float sum = 0.0f;
- float denom = 0.0f;
-
- for (int dy = 0; dy < 5; ++dy) {
- int offset = ((y + dy + h - 2) % h) * w;
-
- for (int dx = 0; dx < 5; ++dx) {
- float f = filter[dy][dx];
- sum += f * I[((x + dx + w - 2) % w) + offset];
- denom += f;
- }
- }
-
- return (uint8)iClamp(iRound(sum / denom), 0, 255);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// Bayer conversions
-//
-
-// There are two kinds of rows (GR and BG).
-// In each row, there are two kinds of pixels (G/R, B/G).
-// We express the four kinds of INPUT pixels as:
-// GRG, GRG, BGB, BGG
-//
-// There are three kinds of OUTPUT pixels: R, G, B.
-// Thus there are nominally 12 different I/O combinations,
-// but several are impulses because needed output at that
-// location *is* the input (e.g., G_GRG and G_BGG).
-//
-// The following 5x5 row-major filters are named as output_input.
-
-// Green
-static const float G_GRR[5][5] =
-{{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
-{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
-{ -1.0f, 2.0f, 4.0f, 2.0f, -1.0f},
-{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
-{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
-
-static const float G_BGB[5][5] =
-{{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
-{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
-{ -1.0f, 2.0f, 4.0f, 2.0f, -1.0f},
-{ 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
-{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
-
-// Red
-//(the caption in the paper is wrong for this case:
-// "R row B column really means R row G column"
-static const float R_GRG[5][5] =
-{{ 0.0f, 0.0f, 0.5f, 0.0f, 0.0f},
-{ 0.0f, -1.0f, 0.0f, -1.0f, 0.0f},
-{ -1.0f, 4.0f, 5.0f, 4.0f, -1.0f},
-{ 0.0f, -1.0f, 0.0f, -1.0f, 0.0f},
-{ 0.0f, 0.0f, 0.5f, 0.0f, 0.0f}};
-
-static const float R_BGG[5][5] =
-{{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
-{ 0.0f, -1.0f, 4.0f, -1.0f, 0.0f},
-{ 0.5f, 0.0f, 5.0f, 0.0f, 0.5f},
-{ 0.0f, -1.0f, 4.0f, -1.0f, 0.0f},
-{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
-
-static const float R_BGB[5][5] =
-{{ 0.0f, 0.0f, -3.0f/2.0f, 0.0f, 0.0f},
-{ 0.0f, 2.0f, 0.0f, 2.0f, 0.0f},
-{-3.0f/2.0f, 0.0f, 6.0f, 0.0f, -3.0f/2.0f},
-{ 0.0f, 2.0f, 0.0f, 2.0f, 0.0f},
-{ 0.0f, 0.0f, -3.0f/2.0f, 0.0f, 0.0f}};
-
-
-// Blue
-//(the caption in the paper is wrong for this case:
-// "B row R column really means B row G column")
-#define B_BGG R_GRG
-#define B_GRG R_BGG
-#define B_GRR R_BGB
-
-
-void GImage::BAYER_R8G8_G8B8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) {
- debugAssert(in != _out);
-
- Color3uint8* out = (Color3uint8*)_out;
-
- for (int y = 0; y < h; ++y) {
-
- // Row beginning in the input array.
- int offset = y * w;
-
- // RG row
- for (int x = 0; x < w; ++x, ++out) {
- // R pixel
- {
- out->r = in[x + offset];
- out->g = applyFilter(in, x, y, w, h, G_GRR);
- out->b = applyFilter(in, x, y, w, h, B_GRR);
- }
- ++x; ++out;
-
- // G pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_GRG);
- out->g = in[x + offset];
- out->b = applyFilter(in, x, y, w, h, B_GRG);
- }
- }
-
- ++y;
- offset += w;
-
- // GB row
- for (int x = 0; x < w; ++x, ++out) {
- // G pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_BGG);
- out->g = in[x + offset];
- out->b = applyFilter(in, x, y, w, h, B_BGG);
- }
- ++x; ++out;
-
- // B pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_BGB);
- out->g = applyFilter(in, x, y, w, h, G_BGB);
- out->b = in[x + offset];
- }
- }
- }
-}
-
-static void swapRedAndBlue(int N, Color3uint8* out) {
- for (int i = N - 1; i >= 0; --i) {
- uint8 tmp = out[i].r;
- out[i].r = out[i].b;
- out[i].b = tmp;
- }
-}
-
-void GImage::BAYER_G8R8_B8G8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) {
- // Run the equivalent function for red
- BAYER_G8B8_R8G8_to_R8G8B8_MHC(w, h, in, _out);
-
- // Now swap red and blue
- swapRedAndBlue(w * h, (Color3uint8*)_out);
-}
-
-
-void GImage::BAYER_B8G8_G8R8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) {
- // Run the equivalent function for red
- BAYER_R8G8_G8B8_to_R8G8B8_MHC(w, h, in, _out);
-
- // Now swap red and blue
- swapRedAndBlue(w * h, (Color3uint8*)_out);
-}
-
-
-void GImage::BAYER_G8B8_R8G8_to_R8G8B8_MHC(int w, int h, const uint8* in, uint8* _out) {
-
- debugAssert(in != _out);
-
- Color3uint8* out = (Color3uint8*)_out;
-
- for (int y = 0; y < h; ++y) {
-
- // Row beginning in the input array.
- int offset = y * w;
-
- // GB row
- for (int x = 0; x < w; ++x, ++out) {
- // G pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_BGG);
- out->g = in[x + offset];
- out->b = applyFilter(in, x, y, w, h, B_BGG);
- }
- ++x; ++out;
-
- // B pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_BGB);
- out->g = applyFilter(in, x, y, w, h, G_BGB);
- out->b = in[x + offset];
- }
- }
-
- ++y;
- offset += w;
-
- // RG row
- for (int x = 0; x < w; ++x, ++out) {
- // R pixel
- {
- out->r = in[x + offset];
- out->g = applyFilter(in, x, y, w, h, G_GRR);
- out->b = applyFilter(in, x, y, w, h, B_GRR);
- }
- ++x; ++out;
-
- // G pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_GRG);
- out->g = in[x + offset];
- out->b = applyFilter(in, x, y, w, h, B_GRG);
- }
- }
- }
-
-}
-
-#undef B_BGG
-#undef B_GRG
-#undef B_GRR
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/GImage_bmp.cpp b/externals/g3dlite/G3D.lib/source/GImage_bmp.cpp
deleted file mode 100644
index 598ba730d0b..00000000000
--- a/externals/g3dlite/G3D.lib/source/GImage_bmp.cpp
+++ /dev/null
@@ -1,716 +0,0 @@
-/**
- @file GImage_bmp.cpp
- @author Morgan McGuire, morgan@graphics3d.com
- @created 2002-05-27
- @edited 2006-05-10
- */
-#include "G3D/platform.h"
-#include "G3D/GImage.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Log.h"
-
-namespace G3D {
-
-#ifndef G3D_WIN32
-/**
- This is used by the Windows bitmap I/O.
- */
-static const int BI_RGB = 0;
-#endif
-
-void GImage::encodeBMP(
- BinaryOutput& out) const {
-
- debugAssert(channels == 1 || channels == 3);
- out.setEndian(G3D_LITTLE_ENDIAN);
-
- uint8 red;
- uint8 green;
- uint8 blue;
- int pixelBufferSize = width * height * 3;
- int fileHeaderSize = 14;
- int infoHeaderSize = 40;
- int BMScanWidth;
- int BMPadding;
-
- // First write the BITMAPFILEHEADER
- //
- // WORD bfType;
- // DWORD bfSize;
- // WORD bfReserved1;
- // WORD bfReserved2;
- // DWORD bfOffBits;
-
- // Type
- out.writeUInt8('B');
- out.writeUInt8('M');
-
- // File size
- out.writeUInt32(fileHeaderSize + infoHeaderSize + pixelBufferSize);
-
- // Two reserved fields set to zero
- out.writeUInt16(0);
- out.writeUInt16(0);
-
- // The offset, in bytes, from the BITMAPFILEHEADER structure
- // to the bitmap bits.
- out.writeUInt32(infoHeaderSize + fileHeaderSize);
-
- // Now the BITMAPINFOHEADER
- //
- // DWORD biSize;
- // LONG biWidth;
- // LONG biHeight;
- // WORD biPlanes;
- // WORD biBitCount
- // DWORD biCompression;
- // DWORD biSizeImage;
- // LONG biXPelsPerMeter;
- // LONG biYPelsPerMeter;
- // DWORD biClrUsed;
- // DWORD biClrImportant;
-
- // Size of the info header
- out.writeUInt32(infoHeaderSize);
-
- // Width and height of the image
- out.writeUInt32(width);
- out.writeUInt32(height);
-
- // Planes ("must be set to 1")
- out.writeUInt16(1);
-
- // BitCount and CompressionType
- out.writeUInt16(24);
- out.writeUInt32(BI_RGB);
-
- // Image size ("may be zero for BI_RGB bitmaps")
- out.writeUInt32(0);
-
- // biXPelsPerMeter
- out.writeUInt32(0);
- // biYPelsPerMeter
- out.writeUInt32(0);
-
- // biClrUsed
- out.writeUInt32(0);
-
- // biClrImportant
- out.writeUInt32(0);
-
- BMScanWidth = width * 3;
-
- if (BMScanWidth & 3) {
- BMPadding = 4 - (BMScanWidth & 3);
- } else {
- BMPadding = 0;
- }
-
- int hStart = height - 1;
- int hEnd = -1;
- int hDir = -1;
- int dest;
-
- // Write the pixel data
- for (int h = hStart; h != hEnd; h += hDir) {
- dest = channels * h * width;
- for (int w = 0; w < width; ++w) {
-
- if (channels == 3) {
- red = _byte[dest];
- green = _byte[dest + 1];
- blue = _byte[dest + 2];
- } else {
- red = _byte[dest];
- green = _byte[dest];
- blue = _byte[dest];
- }
-
- out.writeUInt8(blue);
- out.writeUInt8(green);
- out.writeUInt8(red);
-
- dest += channels;
- }
-
- if (BMPadding > 0) {
- out.skip(BMPadding);
- }
- }
-}
-
-
-void GImage::decodeBMP(
- BinaryInput& input) {
-
- // The BMP decoding uses these flags.
- static const uint16 PICTURE_NONE = 0x0000;
- static const uint16 PICTURE_BITMAP = 0x1000;
-
- // Compression Flags
- static const uint16 PICTURE_UNCOMPRESSED = 0x0100;
- static const uint16 PICTURE_MONOCHROME = 0x0001;
- static const uint16 PICTURE_4BIT = 0x0002;
- static const uint16 PICTURE_8BIT = 0x0004;
- static const uint16 PICTURE_16BIT = 0x0008;
- static const uint16 PICTURE_24BIT = 0x0010;
- static const uint16 PICTURE_32BIT = 0x0020;
-
- (void)PICTURE_16BIT;
- (void)PICTURE_32BIT;
-
- // This is a simple BMP loader that can handle uncompressed BMP files.
- // Verify this is a BMP file by looking for the BM tag.
- input.reset();
- std::string tag = input.readString(2);
- if (tag != "BM") {
- throw Error("Not a BMP file", input.getFilename());
- }
-
- channels = 3;
- // Skip to the BITMAPINFOHEADER's width and height
- input.skip(16);
-
- width = input.readUInt32();
- height = input.readUInt32();
-
- // Skip to the bit count and compression type
- input.skip(2);
-
- uint16 bitCount = input.readUInt16();
- uint32 compressionType = input.readUInt32();
-
- uint8 red;
- uint8 green;
- uint8 blue;
- uint8 blank;
-
- // Only uncompressed bitmaps are supported by this code
- if ((int32)compressionType != BI_RGB) {
- throw Error("BMP images must be uncompressed", input.getFilename());
- }
-
- uint8* palette = NULL;
-
- // Create the palette if needed
- if (bitCount <= 8) {
-
- // Skip to the palette color count in the header
- input.skip(12);
-
- int numColors = input.readUInt32();
-
- palette = (uint8*)System::malloc(numColors * 3);
- debugAssert(palette);
-
- // Skip past the end of the header to the palette info
- input.skip(4);
-
- int c;
- for(c = 0; c < numColors * 3; c += 3) {
- // Palette information in bitmaps is stored in BGR_ format.
- // That means it's blue-green-red-blank, for each entry.
- blue = input.readUInt8();
- green = input.readUInt8();
- red = input.readUInt8();
- blank = input.readUInt8();
-
- palette[c] = red;
- palette[c + 1] = green;
- palette[c + 2] = blue;
- }
- }
-
- int hStart = 0;
- int hEnd = 0;
- int hDir = 0;
-
- if (height < 0) {
- height = -height;
- hStart = 0;
- hEnd = height;
- hDir = 1;
- } else {
- //height = height;
- hStart = height - 1;
- hEnd = -1;
- hDir = -1;
- }
-
- _byte = (uint8*)System::malloc(width * height * 3);
- debugAssert(_byte);
-
- int BMScanWidth;
- int BMPadding;
- uint8 BMGroup;
- uint8 BMPixel8;
- int currPixel;
- int dest;
- int flags = PICTURE_NONE;
-
- if (bitCount == 1) {
- // Note that this file is not necessarily grayscale, since it's possible
- // the palette is blue-and-white, or whatever. But of course most image
- // programs only write 1-bit images if they're black-and-white.
- flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_MONOCHROME;
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = (width + 7) >> 3;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- // Powers of 2
- int pow2[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
- dest = 3 * h * width;
-
- for (int w = 0; w < BMScanWidth; ++w) {
-
- BMGroup = input.readUInt8();
-
- // Now we read the pixels. Usually there are eight pixels per byte,
- // since each pixel is represented by one bit, but if the width
- // is not a multiple of eight, the last byte will have some bits
- // set, with the others just being extra. Plus there's the
- // dword-alignment padding. So we keep checking to see if we've
- // already read "width" number of pixels.
- for (int i = 7; i >= 0; --i) {
- if (currPixel < width) {
- int src = 3 * ((BMGroup & pow2[i]) >> i);
-
- _byte[dest] = palette[src];
- _byte[dest + 1] = palette[src + 1];
- _byte[dest + 2] = palette[src + 2];
-
- ++currPixel;
- dest += 3;
- }
- }
- }
- }
-
- } else if (bitCount == 4) {
-
- flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_4BIT;
-
- // For bitmaps, each scanline is dword-aligned.
- int BMScanWidth = (width+1) >> 1;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
- dest = 3 * h * width;
-
- for (int w = 0; w < BMScanWidth; w++) {
-
- BMGroup = input.readUInt8();
- int src[2];
- src[0] = 3 * ((BMGroup & 0xF0) >> 4);
- src[1] = 3 * (BMGroup & 0x0F);
-
- // Now we read the pixels. Usually there are two pixels per byte,
- // since each pixel is represented by four bits, but if the width
- // is not a multiple of two, the last byte will have only four bits
- // set, with the others just being extra. Plus there's the
- // dword-alignment padding. So we keep checking to see if we've
- // already read "Width" number of pixels.
-
- for (int i = 0; i < 2; ++i) {
- if (currPixel < width) {
- int tsrc = src[i];
-
- _byte[dest] = palette[tsrc];
- _byte[dest + 1] = palette[tsrc + 1];
- _byte[dest + 2] = palette[tsrc + 2];
-
- ++currPixel;
- dest += 3;
- }
- }
- }
- }
-
- } else if (bitCount == 8) {
-
- flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_8BIT;
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = width;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
-
- for (int w = 0; w < BMScanWidth; ++w) {
-
- BMPixel8 = input.readUInt8();
-
- if (currPixel < width) {
- dest = 3 * ((h * width) + currPixel);
- int src = 3 * BMPixel8;
-
- _byte[dest] = palette[src];
- _byte[dest + 1] = palette[src + 1];
- _byte[dest + 2] = palette[src + 2];
-
- ++currPixel;
- }
- }
- }
-
- } else if (bitCount == 16) {
-
- System::free(_byte);
- _byte = NULL;
- System::free(palette);
- palette = NULL;
- throw Error("16-bit bitmaps not supported", input.getFilename());
-
- } else if (bitCount == 24) {
- input.skip(20);
-
- flags = PICTURE_BITMAP | PICTURE_UNCOMPRESSED | PICTURE_24BIT;
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = width * 3;
-
- if (BMScanWidth & 3) {
- BMPadding = 4 - (BMScanWidth & 3);
- } else {
- BMPadding = 0;
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
- dest = 3 * h * width;
- for (int w = 0; w < width; ++w) {
-
- blue = input.readUInt8();
- green = input.readUInt8();
- red = input.readUInt8();
-
- _byte[dest] = red;
- _byte[dest + 1] = green;
- _byte[dest + 2] = blue;
-
- dest += 3;
- }
-
- if (BMPadding) {
- input.skip(2);
- }
- }
-
- } else if (bitCount == 32) {
-
- System::free(_byte);
- _byte = NULL;
- System::free(palette);
- palette = NULL;
- throw Error("32 bit bitmaps not supported", input.getFilename());
-
- } else {
- // We support all possible bit depths, so if the
- // code gets here, it's not even a real bitmap.
- System::free(_byte);
- _byte = NULL;
- throw Error("Not a bitmap!", input.getFilename());
- }
-
- System::free(palette);
- palette = NULL;
-}
-
-
-void GImage::decodeICO(
- BinaryInput& input) {
-
- // Header
- uint16 r = input.readUInt16();
- debugAssert(r == 0);
- r = input.readUInt16();
- debugAssert(r == 1);
-
- // Read the number of icons, although we'll only load the
- // first one.
- int count = input.readUInt16();
-
- channels = 4;
-
- debugAssert(count > 0);
-
- const uint8* headerBuffer = input.getCArray() + input.getPosition();
- int maxWidth = 0, maxHeight = 0;
- int maxHeaderNum = 0;
- for (int currentHeader = 0; currentHeader < count; ++currentHeader) {
-
- const uint8* curHeaderBuffer = headerBuffer + (currentHeader * 16);
- int tmpWidth = curHeaderBuffer[0];
- int tmpHeight = curHeaderBuffer[1];
- // Just in case there is a non-square icon, checking area
- if ((tmpWidth * tmpHeight) > (maxWidth * maxHeight)) {
- maxWidth = tmpWidth;
- maxHeight = tmpHeight;
- maxHeaderNum = currentHeader;
- }
- }
-
- input.skip(maxHeaderNum * 16);
-
- width = input.readUInt8();
- height = input.readUInt8();
- int numColors = input.readUInt8();
-
- _byte = (uint8*)System::malloc(width * height * channels);
- debugAssert(_byte);
-
- // Bit mask for packed bits
- int mask = 0;
-
- int bitsPerPixel = 8;
-
- switch (numColors) {
- case 2:
- mask = 0x01;
- bitsPerPixel = 1;
- break;
-
- case 16:
- mask = 0x0F;
- bitsPerPixel = 4;
- break;
-
- case 0:
- numColors = 256;
- mask = 0xFF;
- bitsPerPixel = 8;
- break;
- default:
- throw Error("Unsupported ICO color count.", input.getFilename());
- }
-
- input.skip(5);
- // Skip 'size' unused
- input.skip(4);
-
- int offset = input.readUInt32();
-
- // Skip over any other icon descriptions
- input.setPosition(offset);
-
- // Skip over bitmap header; it is redundant
- input.skip(40);
-
- Array<Color4uint8> palette;
- palette.resize(numColors, true);
- for (int c = 0; c < numColors; ++c) {
- palette[c].b = input.readUInt8();
- palette[c].g = input.readUInt8();
- palette[c].r = input.readUInt8();
- palette[c].a = input.readUInt8();
- }
-
- // The actual image and mask follow
-
- // The XOR Bitmap is stored as 1-bit, 4-bit or 8-bit uncompressed Bitmap
- // using the same encoding as BMP files. The AND Bitmap is stored in as
- // 1-bit uncompressed Bitmap.
- //
- // Pixels are stored bottom-up, left-to-right. Pixel lines are padded
- // with zeros to end on a 32bit (4byte) boundary. Every line will have the
- // same number of bytes. Color indices are zero based, meaning a pixel color
- // of 0 represents the first color table entry, a pixel color of 255 (if there
- // are that many) represents the 256th entry.
-/*
- int bitsPerRow = width * bitsPerPixel;
- int bytesPerRow = iCeil((double)bitsPerRow / 8);
- // Rows are padded to 32-bit boundaries
- bytesPerRow += bytesPerRow % 4;
-
- // Read the XOR values into the color channel
- for (int y = height - 1; y >= 0; --y) {
- int x = 0;
- // Read the row
- for (int i = 0; i < bytesPerRow; ++i) {
- uint8 byte = input.readUInt8();
- for (int j = 0; (j < 8) && (x < width); ++x, j += bitsPerPixel) {
- int bit = ((byte << j) >> (8 - bitsPerPixel)) & mask;
- pixel4(x, y) = colorTable[bit];
- }
- }
- }
-*/
- int hStart = 0;
- int hEnd = 0;
- int hDir = 0;
-
- if (height < 0) {
- height = -height;
- hStart = 0;
- hEnd = height;
- hDir = 1;
- } else {
- //height = height;
- hStart = height - 1;
- hEnd = -1;
- hDir = -1;
- }
-
- int BMScanWidth;
- uint8 BMGroup;
- uint8 BMPixel8;
- int currPixel;
- int dest;
-
- if (bitsPerPixel == 1) {
- // Note that this file is not necessarily grayscale, since it's possible
- // the palette is blue-and-white, or whatever. But of course most image
- // programs only write 1-bit images if they're black-and-white.
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = (width + 7) >> 3;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- // Powers of 2
- int pow2[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
- dest = 3 * h * width;
-
- for (int w = 0; w < BMScanWidth; ++w) {
-
- BMGroup = input.readUInt8();
-
- // Now we read the pixels. Usually there are eight pixels per byte,
- // since each pixel is represented by one bit, but if the width
- // is not a multiple of eight, the last byte will have some bits
- // set, with the others just being extra. Plus there's the
- // dword-alignment padding. So we keep checking to see if we've
- // already read "width" number of pixels.
- for (int i = 7; i >= 0; --i) {
- if (currPixel < width) {
- int src = ((BMGroup & pow2[i]) >> i);
-
- _byte[dest] = palette[src].r;
- _byte[dest + 1] = palette[src].g;
- _byte[dest + 2] = palette[src].b;
-
- ++currPixel;
- dest += 4;
- }
- }
- }
- }
-
- } else if (bitsPerPixel == 4) {
-
- // For bitmaps, each scanline is dword-aligned.
- int BMScanWidth = (width+1) >> 1;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
- dest = 4 * h * width;
-
- for (int w = 0; w < BMScanWidth; w++) {
-
- BMGroup = input.readUInt8();
- int src[2];
- src[0] = ((BMGroup & 0xF0) >> 4);
- src[1] = (BMGroup & 0x0F);
-
- // Now we read the pixels. Usually there are two pixels per byte,
- // since each pixel is represented by four bits, but if the width
- // is not a multiple of two, the last byte will have only four bits
- // set, with the others just being extra. Plus there's the
- // dword-alignment padding. So we keep checking to see if we've
- // already read "Width" number of pixels.
-
- for (int i = 0; i < 2; ++i) {
- if (currPixel < width) {
- int tsrc = src[i];
-
- _byte[dest] = palette[tsrc].r;
- _byte[dest + 1] = palette[tsrc].g;
- _byte[dest + 2] = palette[tsrc].b;
-
- ++currPixel;
- dest += 4;
- }
- }
- }
- }
-
- } else if (bitsPerPixel == 8) {
-
- // For bitmaps, each scanline is dword-aligned.
- BMScanWidth = width;
- if (BMScanWidth & 3) {
- BMScanWidth += 4 - (BMScanWidth & 3);
- }
-
- for (int h = hStart; h != hEnd; h += hDir) {
-
- currPixel = 0;
-
- for (int w = 0; w < BMScanWidth; ++w) {
-
- BMPixel8 = input.readUInt8();
-
- if (currPixel < width) {
- dest = 4 * ((h * width) + currPixel);
- int src = BMPixel8;
-
- _byte[dest] = palette[src].r;
- _byte[dest + 1] = palette[src].g;
- _byte[dest + 2] = palette[src].b;
-
- ++currPixel;
- }
- }
- }
- }
-
- // Read the mask into the alpha channel
- int bitsPerRow = width;
- int bytesPerRow = iCeil((double)bitsPerRow / 8);
-
- // For bitmaps, each scanline is dword-aligned.
- //BMScanWidth = (width + 1) >> 1;
- if (bytesPerRow & 3) {
- bytesPerRow += 4 - (bytesPerRow & 3);
- }
-
- for (int y = height - 1; y >= 0; --y) {
- int x = 0;
- // Read the row
- for (int i = 0; i < bytesPerRow; ++i) {
- uint8 byte = input.readUInt8();
- for (int j = 0; (j < 8) && (x < width); ++x, ++j) {
- int bit = (byte >> (7 - j)) & 0x01;
- pixel4(x, y).a = (1 - bit) * 0xFF;
- }
- }
- }
-
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/GImage_jpeg.cpp b/externals/g3dlite/G3D.lib/source/GImage_jpeg.cpp
deleted file mode 100644
index fe2812cf3b2..00000000000
--- a/externals/g3dlite/G3D.lib/source/GImage_jpeg.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-/**
- @file GImage_jpeg.cpp
- @author Morgan McGuire, morgan@graphics3d.com
- @created 2002-05-27
- @edited 2006-10-10
- */
-#include "G3D/platform.h"
-#include "G3D/GImage.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-#include <cstring>
-
-/**
- Pick up libjpeg headers locally on Windows, but from the system on all other platforms.
-*/
-extern "C" {
-#include <jconfig.h>
-#include <jpeglib.h>
-}
-
-namespace G3D {
-
-
-const int jpegQuality = 96;
-
-/**
- The IJG library needs special setup for compress/decompressing
- from memory. These classes provide them.
-
- The format of this class is defined by the IJG library; do not
- change it.
- */
-class memory_destination_mgr {
-public:
- struct jpeg_destination_mgr pub;
- JOCTET* buffer;
- int size;
- int count;
-};
-
-typedef memory_destination_mgr* mem_dest_ptr;
-
-/**
- Signature dictated by IJG.
- */
-static void init_destination (
- j_compress_ptr cinfo) {
-
- mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
-
- dest->pub.next_output_byte = dest->buffer;
- dest->pub.free_in_buffer = dest->size;
- dest->count=0;
-}
-
-/**
- Signature dictated by IJG.
- */
-static boolean empty_output_buffer (
- j_compress_ptr cinfo) {
-
- mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
-
- dest->pub.next_output_byte = dest->buffer;
- dest->pub.free_in_buffer = dest->size;
-
- return TRUE;
-}
-
-/**
- Signature dictated by IJG.
- */
-static void term_destination (
- j_compress_ptr cinfo) {
-
- mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
- dest->count = dest->size - dest->pub.free_in_buffer;
-}
-
-/**
- Signature dictated by IJG.
- */
-static void jpeg_memory_dest (
- j_compress_ptr cinfo,
- JOCTET* buffer,
- int size) {
-
- mem_dest_ptr dest;
-
- if (cinfo->dest == NULL) {
- // First time for this JPEG object; call the
- // IJG allocator to get space.
- cinfo->dest = (struct jpeg_destination_mgr*)
- (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
- JPOOL_PERMANENT,
- sizeof(memory_destination_mgr));
- }
-
- dest = (mem_dest_ptr) cinfo->dest;
- dest->size = size;
- dest->buffer = buffer;
- dest->pub.init_destination = init_destination;
- dest->pub.empty_output_buffer = empty_output_buffer;
- dest->pub.term_destination = term_destination;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
-
-#define INPUT_BUF_SIZE 4096
-
-/**
- Structure dictated by IJG.
- */
-class memory_source_mgr {
-public:
- struct jpeg_source_mgr pub;
- int source_size;
- unsigned char* source_data;
- boolean start_of_data;
- JOCTET* buffer;
-};
-
-
-typedef memory_source_mgr* mem_src_ptr;
-
-
-/**
- Signature dictated by IJG.
- */
-static void init_source(
- j_decompress_ptr cinfo) {
-
- mem_src_ptr src = (mem_src_ptr) cinfo->src;
-
- src->start_of_data = TRUE;
-}
-
-
-/**
- Signature dictated by IJG.
- */
-static boolean fill_input_buffer(
- j_decompress_ptr cinfo) {
-
- mem_src_ptr src = (mem_src_ptr) cinfo->src;
-
- size_t bytes_read = 0;
-
- if (src->source_size > INPUT_BUF_SIZE)
- bytes_read = INPUT_BUF_SIZE;
- else
- bytes_read = src->source_size;
-
- memcpy (src->buffer, src->source_data, bytes_read);
-
- src->source_data += bytes_read;
- src->source_size -= bytes_read;
-
- src->pub.next_input_byte = src->buffer;
- src->pub.bytes_in_buffer = bytes_read;
- src->start_of_data = FALSE;
-
-
- return TRUE;
-}
-
-
-/**
- Signature dictated by IJG.
- */
-static void skip_input_data(
- j_decompress_ptr cinfo,
- long num_bytes) {
-
- mem_src_ptr src = (mem_src_ptr)cinfo->src;
-
- if (num_bytes > 0) {
- while (num_bytes > (long) src->pub.bytes_in_buffer) {
- num_bytes -= (long) src->pub.bytes_in_buffer;
- boolean s = fill_input_buffer(cinfo);
- debugAssert(s); (void)s;
- }
-
- src->pub.next_input_byte += (size_t) num_bytes;
- src->pub.bytes_in_buffer -= (size_t) num_bytes;
- }
-}
-
-
-/**
- Signature dictated by IJG.
- */
-static void term_source (
- j_decompress_ptr cinfo) {
- (void)cinfo;
- // Intentionally empty
-}
-
-
-/**
- Signature dictated by IJG.
- */
-static void jpeg_memory_src (
- j_decompress_ptr cinfo,
- JOCTET* buffer,
- int size) {
-
- mem_src_ptr src;
-
- if (cinfo->src == NULL) {
- // First time for this JPEG object
- cinfo->src = (struct jpeg_source_mgr*)
- (*cinfo->mem->alloc_small)(
- (j_common_ptr) cinfo,
- JPOOL_PERMANENT,
- sizeof(memory_source_mgr));
-
- src = (mem_src_ptr)cinfo->src;
-
- src->buffer = (JOCTET*)
- (*cinfo->mem->alloc_small)(
- (j_common_ptr) cinfo,
- JPOOL_PERMANENT,
- INPUT_BUF_SIZE * sizeof(JOCTET));
- }
-
- src = (mem_src_ptr)cinfo->src;
- src->pub.init_source = init_source;
- src->pub.fill_input_buffer = fill_input_buffer;
- src->pub.skip_input_data = skip_input_data;
-
- // use default method
- src->pub.resync_to_restart = jpeg_resync_to_restart;
- src->pub.term_source = term_source;
- src->source_data = buffer;
- src->source_size = size;
-
- // forces fill_input_buffer on first read
- src->pub.bytes_in_buffer = 0;
-
- // until buffer loaded
- src->pub.next_input_byte = NULL;
-}
-
-
-void GImage::encodeJPEG(
- BinaryOutput& out) const {
-
- if (channels != 3) {
- // Convert to three channel
- GImage tmp = *this;
- tmp.convertToRGB();
- tmp.encodeJPEG(out);
- return;
- }
-
- debugAssert(channels == 3);
- out.setEndian(G3D_LITTLE_ENDIAN);
-
- // Allocate and initialize a compression object
- jpeg_compress_struct cinfo;
- jpeg_error_mgr jerr;
-
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_compress(&cinfo);
-
- // Specify the destination for the compressed data.
- // (Overestimate the size)
- int buffer_size = width * height * 3 + 200;
- JOCTET* compressed_data = (JOCTET*)System::malloc(buffer_size);
- jpeg_memory_dest(&cinfo, compressed_data, buffer_size);
-
-
- cinfo.image_width = width;
- cinfo.image_height = height;
-
- // # of color components per pixel
- cinfo.input_components = 3;
-
- // colorspace of input image
- cinfo.in_color_space = JCS_RGB;
- cinfo.input_gamma = 1.0;
-
- // Set parameters for compression, including image size & colorspace
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, jpegQuality, false);
- cinfo.smoothing_factor = 0;
- cinfo.optimize_coding = TRUE;
-// cinfo.dct_method = JDCT_FLOAT;
- cinfo.dct_method = JDCT_ISLOW;
- cinfo.jpeg_color_space = JCS_YCbCr;
-
- // Initialize the compressor
- jpeg_start_compress(&cinfo, TRUE);
-
- // Iterate over all scanlines from top to bottom
- // pointer to a single row
- JSAMPROW row_pointer[1];
-
- // JSAMPLEs per row in image_buffer
- int row_stride = cinfo.image_width * 3;
- while (cinfo.next_scanline < cinfo.image_height) {
- row_pointer[0] = &(_byte[cinfo.next_scanline * row_stride]);
- jpeg_write_scanlines(&cinfo, row_pointer, 1);
- }
-
- // Shut down the compressor
- jpeg_finish_compress(&cinfo);
-
- // Figure out how big the result was.
- int outLength = ((mem_dest_ptr)cinfo.dest)->count;
-
- // Release the JPEG compression object
- jpeg_destroy_compress(&cinfo);
-
- // Copy into an appropriately sized output buffer.
- out.writeBytes(compressed_data, outLength);
-
- // Free the conservative buffer.
- System::free(compressed_data);
- compressed_data = NULL;
-}
-
-
-
-void GImage::decodeJPEG(
- BinaryInput& input) {
-
- struct jpeg_decompress_struct cinfo;
- struct jpeg_error_mgr jerr;
- int loc = 0;
-
- channels = 3;
- // We have to set up the error handler, in case initialization fails.
- cinfo.err = jpeg_std_error(&jerr);
-
- // Initialize the JPEG decompression object.
- jpeg_create_decompress(&cinfo);
-
- // Specify data source (eg, a file, for us, memory)
- jpeg_memory_src(&cinfo, const_cast<uint8*>(input.getCArray()), input.size());
-
- // Read the parameters with jpeg_read_header()
- jpeg_read_header(&cinfo, TRUE);
-
- // Set parameters for decompression
- // (We do nothing here since the defaults are fine)
-
- // Start decompressor
- jpeg_start_decompress(&cinfo);
-
- // Get and set the values of interest to this object
- this->width = cinfo.output_width;
- this->height = cinfo.output_height;
-
- // Prepare the pointer object for the pixel data
- _byte = (uint8*)System::malloc(width * height * 3);
-
- // JSAMPLEs per row in output buffer
- int bpp = cinfo.output_components;
- int row_stride = cinfo.output_width * bpp;
-
- // Make a one-row-high sample array that will go away when done with image
- JSAMPARRAY temp = (*cinfo.mem->alloc_sarray)
- ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
-
- // Read data on a scanline by scanline basis
- while (cinfo.output_scanline < cinfo.output_height) {
-
- // We may need to adjust the output based on the
- // number of channels it has.
- switch (bpp) {
- case 1:
- // Grayscale; decompress to temp.
- jpeg_read_scanlines(&cinfo, temp, 1);
-
- // Expand to three channels
- {
- uint8* scan = &(_byte[loc * 3]);
- uint8* endScan = scan + (width * 3);
- uint8* t = *temp;
-
- while (scan < endScan) {
- uint8 value = t[0];
-
- // Spread the value 3x.
- scan[0] = value;
- scan[1] = value;
- scan[2] = value;
-
- scan += 3;
- t += 1;
- }
- }
- break;
-
- case 3:
- // Read directly into the array
- {
- // Need one extra level of indirection.
- uint8* scan = _byte + loc;
- JSAMPARRAY ptr = &scan;
- jpeg_read_scanlines(&cinfo, ptr, 1);
- }
- break;
-
- case 4:
- // RGBA; decompress to temp.
- jpeg_read_scanlines(&cinfo, temp, 1);
-
- // Drop the 3rd channel
- {
- uint8* scan = &(_byte[loc * 3]);
- uint8* endScan = scan + width * 3;
- uint8* t = *temp;
-
- while (scan < endScan) {
- scan[0] = t[0];
- scan[1] = t[1];
- scan[2] = t[2];
-
- scan += 3;
- t += 4;
- }
- }
- break;
-
- default:
- throw Error("Unexpected number of channels.", input.getFilename());
- }
-
- loc += row_stride;
- }
-
- // Finish decompression
- jpeg_finish_decompress(&cinfo);
-
- alwaysAssertM(this, "Corrupt GImage");
- // Release JPEG decompression object
- jpeg_destroy_decompress(&cinfo);
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/GImage_png.cpp b/externals/g3dlite/G3D.lib/source/GImage_png.cpp
deleted file mode 100644
index 9fd6a743e8e..00000000000
--- a/externals/g3dlite/G3D.lib/source/GImage_png.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- @file GImage_png.cpp
- @author Morgan McGuire, morgan@graphics3d.com
- @created 2002-05-27
- @edited 2006-05-10
- */
-#include "G3D/platform.h"
-#include "G3D/GImage.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Log.h"
-#include <png.h>
-
-namespace G3D {
-
-
-//libpng required function signature
-static void png_read_data(
- png_structp png_ptr,
- png_bytep data,
- png_size_t length) {
-
-
- debugAssert( png_ptr->io_ptr != NULL );
- debugAssert( length >= 0 );
- debugAssert( data != NULL );
-
- ((BinaryInput*)png_ptr->io_ptr)->readBytes(data, length);
-}
-
-//libpng required function signature
-static void png_write_data(png_structp png_ptr,
- png_bytep data,
- png_size_t length) {
-
- debugAssert( png_ptr->io_ptr != NULL );
- debugAssert( data != NULL );
-
- ((BinaryOutput*)png_ptr->io_ptr)->writeBytes(data, length);
-}
-
-//libpng required function signature
-static void png_flush_data(
- png_structp png_ptr) {
- (void)png_ptr;
- //Do nothing.
-}
-
-//libpng required function signature
-static void png_error(
- png_structp png_ptr,
- png_const_charp error_msg) {
-
- (void)png_ptr;
- debugAssert( error_msg != NULL );
- throw GImage::Error(error_msg, "PNG");
-}
-
-//libpng required function signature
-void png_warning(
- png_structp png_ptr,
- png_const_charp warning_msg) {
-
- (void)png_ptr;
- debugAssert( warning_msg != NULL );
- Log::common()->println(warning_msg);
-}
-
-void GImage::encodePNG(
- BinaryOutput& out) const {
-
- debugAssert( channels == 1 || channels == 3 || channels == 4 );
-
- if (this->height > (int)(PNG_UINT_32_MAX/png_sizeof(png_bytep)))
- throw GImage::Error("Unsupported PNG height.", out.getFilename());
-
- out.setEndian(G3D_LITTLE_ENDIAN);
-
- png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error, png_warning);
- if (!png_ptr)
- throw GImage::Error("Unable to initialize PNG encoder.", out.getFilename());
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- throw GImage::Error("Unable to initialize PNG encoder.", out.getFilename());
- }
-
- //setup libpng write handler so can use BinaryOutput
- png_set_write_fn(png_ptr, (void*)&out, png_write_data, png_flush_data);
-
- if (channels == 3) {
- png_set_IHDR(png_ptr, info_ptr, this->width, this->height, 8, PNG_COLOR_TYPE_RGB,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
- }
- else if (channels == 4) {
- png_set_IHDR(png_ptr, info_ptr, this->width, this->height, 8, PNG_COLOR_TYPE_RGBA,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
- }
- else if (channels == 1) {
- png_set_IHDR(png_ptr, info_ptr, this->width, this->height, 8, PNG_COLOR_TYPE_GRAY,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
- }
- else {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- throw GImage::Error("Unsupported number of channels for PNG.", out.getFilename());
- }
-
- png_color_8_struct sig_bit;
- sig_bit.red = 8;
- sig_bit.green = 8;
- sig_bit.blue = 8;
- if (channels == 4)
- sig_bit.alpha = 8;
- else
- sig_bit.alpha = 0;
- png_set_sBIT(png_ptr, info_ptr, &sig_bit);
-
- //write the png header
- png_write_info(png_ptr, info_ptr);
-
- png_bytepp row_pointers = new png_bytep[this->height];
-
- for (int i=0; i < this->height; ++i) {
- row_pointers[i] = (png_bytep)&this->_byte[(this->width * this->channels * i)];
- }
-
- png_write_image(png_ptr, row_pointers);
-
- png_write_end(png_ptr, info_ptr);
-
- delete[] row_pointers;
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
-}
-
-
-void GImage::decodePNG(
- BinaryInput& input) {
-
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, png_error, png_warning);
- if (!png_ptr)
- throw GImage::Error("Unable to initialize PNG decoder.", input.getFilename());
-
- png_infop info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
- throw GImage::Error("Unable to initialize PNG decoder.", input.getFilename());
- }
-
- png_infop end_info = png_create_info_struct(png_ptr);
- if (!end_info) {
- png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
- throw GImage::Error("Unable to initialize PNG decoder.", input.getFilename());
- }
-
- //now that the libpng structures are setup, change the error handlers and read routines
- //to use G3D functions so that BinaryInput can be used.
-
- png_set_read_fn(png_ptr, (png_voidp)&input, png_read_data);
-
- //read in sequentially so that three copies of the file are not in memory at once
- png_read_info(png_ptr, info_ptr);
-
- png_uint_32 png_width, png_height;
- int bit_depth, color_type, interlace_type;
- //this will validate the data it extracts from info_ptr
- png_get_IHDR(png_ptr, info_ptr, &png_width, &png_height, &bit_depth, &color_type,
- &interlace_type, int_p_NULL, int_p_NULL);
-
- if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
- throw GImage::Error("Unsupported PNG color type - PNG_COLOR_TYPE_GRAY_ALPHA.", input.getFilename());
- }
-
- this->width = static_cast<uint32>(png_width);
- this->height = static_cast<uint32>(png_height);
-
- //swap bytes of 16 bit files to least significant byte first
- png_set_swap(png_ptr);
-
- png_set_strip_16(png_ptr);
-
- //Expand paletted colors into true RGB triplets
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- png_set_palette_to_rgb(png_ptr);
- }
-
- //Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel
- if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
- png_set_gray_1_2_4_to_8(png_ptr);
- }
-
- //Expand paletted or RGB images with transparency to full alpha channels
- //so the data will be available as RGBA quartets.
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
- png_set_tRNS_to_alpha(png_ptr);
- }
-
- // Fix sub-8 bit_depth to 8bit
- if (bit_depth < 8) {
- png_set_packing(png_ptr);
- }
-
- if ((color_type == PNG_COLOR_TYPE_RGBA) ||
- ((color_type == PNG_COLOR_TYPE_PALETTE) && (png_ptr->num_trans > 0)) ) {
-
- this->channels = 4;
- this->_byte = (uint8*)System::malloc(width * height * 4);
-
- } else if ((color_type == PNG_COLOR_TYPE_RGB) ||
- (color_type == PNG_COLOR_TYPE_PALETTE)) {
-
- this->channels = 3;
- this->_byte = (uint8*)System::malloc(width * height * 3);
-
- } else if (color_type == PNG_COLOR_TYPE_GRAY) {
-
- this->channels = 1;
- this->_byte = (uint8*)System::malloc(width * height);
-
- } else {
- throw GImage::Error("Unsupported PNG bit-depth or type.", input.getFilename());
- }
-
- //since we are reading row by row, required to handle interlacing
- uint32 number_passes = png_set_interlace_handling(png_ptr);
-
- png_read_update_info(png_ptr, info_ptr);
-
- for (uint32 pass = 0; pass < number_passes; ++pass) {
- for (uint32 y = 0; y < (uint32)height; ++y) {
- png_bytep rowPointer = &this->_byte[width * this->channels * y];
- png_read_rows(png_ptr, &rowPointer, png_bytepp_NULL, 1);
- }
- }
-
-// png_read_image(png_ptr, &_byte);
- png_read_end(png_ptr, info_ptr);
-
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/GImage_ppm.cpp b/externals/g3dlite/G3D.lib/source/GImage_ppm.cpp
deleted file mode 100644
index bfe5c8305e8..00000000000
--- a/externals/g3dlite/G3D.lib/source/GImage_ppm.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- @file GImage_ppm.cpp
- @author Morgan McGuire, morgan@graphics3d.com
- @created 2002-05-27
- @edited 2006-05-10
- */
-#include "G3D/platform.h"
-#include "G3D/GImage.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/TextInput.h"
-#include "G3D/TextOutput.h"
-#include "G3D/Log.h"
-
-namespace G3D {
-
-void GImage::encodePPMASCII(
- BinaryOutput& out) const {
-
- debugAssert(channels == 3);
-
- TextOutput::Settings ppmOptions;
- ppmOptions.convertNewlines = false;
- ppmOptions.numColumns = 70;
- ppmOptions.wordWrap = TextOutput::Settings::WRAP_WITHOUT_BREAKING;
- TextOutput ppm(ppmOptions);
- // Always write out a full-color ppm
- ppm.printf("P3\n%d %d\n255\n", width, height);
-
- const Color3uint8* c = this->pixel3();
- for (uint32 i = 0; i < (uint32)(width * height); ++i) {
- ppm.printf("%d %d %d%c", c[i].r, c[i].g, c[i].b,
- ((i % ((width * 3) - 1)) == 0) ?
- '\n' : ' ');
- }
-
- out.writeString(ppm.commitString());
-}
-
-
-void GImage::encodePPM(
- BinaryOutput& out) const {
-
- // http://netpbm.sourceforge.net/doc/ppm.html
- debugAssert(channels == 3);
-
- std::string header = format("P6 %d %d 255 ", width, height);
-
- out.writeBytes(header.c_str(), header.size());
-
- out.writeBytes(this->pixel3(), width * height * 3);
-}
-
-void GImage::decodePPMASCII(
- BinaryInput& input) {
-
- int ppmWidth;
- int ppmHeight;
-
- double maxColor;
-
- // Create a TextInput object to parse ascii format
- // Mixed binary/ascii formats will require more
-
- const std::string inputStr = input.readString();
-
- TextInput::Settings ppmOptions;
- ppmOptions.cppComments = false;
- ppmOptions.otherCommentCharacter = '#';
- ppmOptions.signedNumbers = true;
- ppmOptions.singleQuotedStrings = false;
-
- TextInput ppmInput(TextInput::FROM_STRING, inputStr, ppmOptions);
-
- //Skip first line in header P#
- std::string ppmType = ppmInput.readSymbol();
-
- ppmWidth = (int)ppmInput.readNumber();
- ppmHeight = (int)ppmInput.readNumber();
-
- // Everything but a PBM will have a max color value
- if (ppmType != "P2") {
- maxColor = ppmInput.readNumber();
- } else {
- maxColor = 255;
- }
-
- if ((ppmWidth < 0) ||
- (ppmHeight < 0) ||
- (maxColor <= 0)) {
- throw GImage::Error("Invalid PPM Header.", input.getFilename());
- }
-
- // I don't think it's proper to scale values less than 255
- if (maxColor <= 255.0) {
- maxColor = 255.0;
- }
-
- this->width = ppmWidth;
- this->height = ppmHeight;
- this->channels = 3;
- // always scale down to 1 byte per channel
- this->_byte = (uint8*)System::malloc(width * height * 3);
-
- // Read in the image data. I am not validating if the values match the maxColor
- // requirements. I only scale if needed to fit within the byte available.
- for (uint32 i = 0; i < (uint32)(width * height); ++i) {
- // read in color and scale to max pixel defined in header
- // A max color less than 255 might need to be left alone and not scaled.
- Color3uint8& curPixel = *(this->pixel3() + i);
-
- if (ppmType == "P3") {
- curPixel.r = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
- curPixel.g = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
- curPixel.b = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
- } else if (ppmType == "P2") {
- uint8 pixel = (uint8)(ppmInput.readNumber() * (255.0 / maxColor));
- curPixel.r = pixel;
- curPixel.g = pixel;
- curPixel.b = pixel;
- } else if (ppmType == "P1") {
- int pixel = (uint8)(ppmInput.readNumber() * maxColor);
- curPixel.r = pixel;
- curPixel.g = pixel;
- curPixel.b = pixel;
- }
- }
-}
-
-/** Consumes whitespace up to and including a number, but not the following character */
-static int scanUInt(BinaryInput& input) {
- char c = input.readUInt8();
- while (isWhiteSpace(c)) {
- c = input.readUInt8();
- }
-
- std::string s;
- s += c;
- c = input.readUInt8();
- while (!isWhiteSpace(c)) {
- s += c;
- c = input.readUInt8();
- }
-
- // Back up one to avoid consuming the last character
- input.setPosition(input.getPosition() - 1);
-
- int x;
- sscanf(s.c_str(), "%d", &x);
- return x;
-}
-
-void GImage::decodePPM(
- BinaryInput& input) {
-
- char head[2];
- int w, h;
-
- input.readBytes(head, 2);
- if (head[0] != 'P' || head[1] != '6') {
- throw GImage::Error("Invalid PPM Header.", input.getFilename());
- }
-
- w = scanUInt(input);
- h = scanUInt(input);
-
- // Skip the max color specifier
- scanUInt(input);
-
- if ((w < 0) ||
- (h < 0) ||
- (w > 100000) ||
- (h > 100000)) {
- throw GImage::Error("Invalid PPM size in header.", input.getFilename());
- }
-
- // Trailing whitespace
- input.readUInt8();
-
- resize(w, h, 3);
-
- input.readBytes(_byte, width * height * 3);
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/GImage_tga.cpp b/externals/g3dlite/G3D.lib/source/GImage_tga.cpp
deleted file mode 100644
index d84feedecc9..00000000000
--- a/externals/g3dlite/G3D.lib/source/GImage_tga.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- @file GImage_tga.cpp
- @author Morgan McGuire, morgan@graphics3d.com
- @created 2002-05-27
- @edited 2006-05-10
- */
-#include "G3D/platform.h"
-#include "G3D/GImage.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Log.h"
-
-namespace G3D {
-
-void GImage::encodeTGA(
- BinaryOutput& out) const {
-
- out.setEndian(G3D_LITTLE_ENDIAN);
-
- // ID length
- out.writeUInt8(0);
-
- // Color map Type
- out.writeUInt8(0);
-
- // Type
- out.writeUInt8(2);
-
- // Color map
- out.skip(5);
-
- // x, y offsets
- out.writeUInt16(0);
- out.writeUInt16(0);
-
- // Width & height
- out.writeUInt16(width);
- out.writeUInt16(height);
-
- // Color depth
- out.writeUInt8(8 * channels);
-
- // Image descriptor
- if (channels == 3) {
- // 0 alpha bits
- out.writeUInt8(0);
- }
- else {
- // 8 alpha bits
- out.writeUInt8(8);
- }
-
- // Image ID (zero length)
-
- if (channels == 3) {
- // Pixels are upside down in BGR format.
- for (int y = height - 1; y >= 0; y--) {
- for (int x = 0; x < width; x++) {
- uint8* p = &(_byte[3 * (y * width + x)]);
- out.writeUInt8(p[2]);
- out.writeUInt8(p[1]);
- out.writeUInt8(p[0]);
- }
- }
- } else {
- // Pixels are upside down in BGRA format.
- for (int y = height - 1; y >= 0; y--) {
- for (int x = 0; x < width; x++) {
- uint8* p = &(_byte[4 * (y * width + x)]);
- out.writeUInt8(p[2]);
- out.writeUInt8(p[1]);
- out.writeUInt8(p[0]);
- out.writeUInt8(p[3]);
- }
- }
- }
-
- // Write "TRUEVISION-XFILE " 18 bytes from the end
- // (with null termination)
- out.writeString("TRUEVISION-XFILE ");
-}
-
-
-void GImage::decodeTGA(
- BinaryInput& input) {
-
- // This is a simple TGA loader that can handle uncompressed
- // truecolor TGA files (TGA type 2).
- // Verify this is a TGA file by looking for the TRUEVISION tag.
- int pos = input.getPosition();
- input.setPosition(input.size() - 18);
- std::string tag = input.readString(16);
- if (tag != "TRUEVISION-XFILE") {
- throw Error("Not a TGA file", input.getFilename());
- }
-
- input.setPosition(pos);
-
- int IDLength = input.readUInt8();
- int colorMapType = input.readUInt8();
- int imageType = input.readUInt8();
-
- (void)colorMapType;
-
- // 2 is the type supported by this routine.
- if (imageType != 2) {
- throw Error("TGA images must be type 2 (Uncompressed truecolor)", input.getFilename());
- }
-
- // Color map specification
- input.skip(5);
-
- // Image specification
-
- // Skip x and y offsets
- input.skip(4);
-
- width = input.readInt16();
- height = input.readInt16();
-
- int colorDepth = input.readUInt8();
-
- if ((colorDepth != 24) && (colorDepth != 32)) {
- throw Error("TGA files must be 24 or 32 bit.", input.getFilename());
- }
-
- if (colorDepth == 32) {
- channels = 4;
- } else {
- channels = 3;
- }
-
- // Image descriptor contains overlay data as well
- // as data indicating where the origin is
- int imageDescriptor = input.readUInt8();
- (void)imageDescriptor;
-
- // Image ID
- input.skip(IDLength);
-
- _byte = (uint8*)System::malloc(width * height * channels);
- debugAssert(_byte);
-
- // Pixel data
- int x;
- int y;
-
- if (channels == 3) {
- for (y = height - 1; y >= 0; y--) {
- for (x = 0; x < width; x++) {
- int b = input.readUInt8();
- int g = input.readUInt8();
- int r = input.readUInt8();
-
- int i = (x + y * width) * 3;
- _byte[i + 0] = r;
- _byte[i + 1] = g;
- _byte[i + 2] = b;
- }
- }
- } else {
- for (y = height - 1; y >= 0; y--) {
- for (x = 0; x < width; x++) {
- int b = input.readUInt8();
- int g = input.readUInt8();
- int r = input.readUInt8();
- int a = input.readUInt8();
-
- int i = (x + y * width) * 4;
- _byte[i + 0] = r;
- _byte[i + 1] = g;
- _byte[i + 2] = b;
- _byte[i + 3] = a;
- }
- }
- }
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/GLight.cpp b/externals/g3dlite/G3D.lib/source/GLight.cpp
deleted file mode 100644
index 8acb066ef54..00000000000
--- a/externals/g3dlite/G3D.lib/source/GLight.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/**
- @file GLight.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-11-12
- @edited 2007-10-22
-*/
-
-#include "G3D/GLight.h"
-#include "G3D/Sphere.h"
-
-namespace G3D {
-
-GLight::GLight() {
- position = Vector4(0, 0, 0, 0);
- color = Color3::white();
- spotDirection = Vector3(0, 0, -1);
- spotCutoff = 180;
- enabled = false;
- attenuation[0] = 1.0;
- attenuation[1] = 0.0;
- attenuation[2] = 0.0;
- specular = true;
- diffuse = true;
-}
-
-
-GLight GLight::directional(const Vector3& toLight, const Color3& color, bool s, bool d) {
- GLight L;
- L.position = Vector4(toLight.direction(), 0);
- L.color = color;
- L.specular = s;
- L.diffuse = d;
- return L;
-}
-
-
-GLight GLight::point(const Vector3& pos, const Color3& color, float constAtt, float linAtt, float quadAtt, bool s, bool d) {
- GLight L;
- L.position = Vector4(pos, 1);
- L.color = color;
- L.attenuation[0] = constAtt;
- L.attenuation[1] = linAtt;
- L.attenuation[2] = quadAtt;
- L.specular = s;
- L.diffuse = d;
- return L;
-}
-
-
-GLight GLight::spot(const Vector3& pos, const Vector3& pointDirection, float cutOffAngleDegrees, const Color3& color, float constAtt, float linAtt, float quadAtt, bool s, bool d) {
- GLight L;
- L.position = Vector4(pos, 1.0f);
- L.spotDirection = pointDirection.direction();
- debugAssert(cutOffAngleDegrees <= 90);
- L.spotCutoff = cutOffAngleDegrees;
- L.color = color;
- L.attenuation[0] = constAtt;
- L.attenuation[1] = linAtt;
- L.attenuation[2] = quadAtt;
- L.specular = s;
- L.diffuse = d;
- return L;
-}
-
-
-bool GLight::operator==(const GLight& other) const {
- return (position == other.position) &&
- (spotDirection == other.spotDirection) &&
- (spotCutoff == other.spotCutoff) &&
- (attenuation[0] == other.attenuation[0]) &&
- (attenuation[1] == other.attenuation[1]) &&
- (attenuation[2] == other.attenuation[2]) &&
- (color == other.color) &&
- (enabled == other.enabled) &&
- (specular == other.specular) &&
- (diffuse == other.diffuse);
-}
-
-bool GLight::operator!=(const GLight& other) const {
- return !(*this == other);
-}
-
-
-Sphere GLight::effectSphere(float cutoff) const {
- if (position.w == 0) {
- // Directional light
- return Sphere(Vector3::zero(), (float)inf());
- } else {
- // Avoid divide by zero
- cutoff = max(cutoff, 0.0001f);
- float maxIntensity = max(color.r, max(color.g, color.b));
-
- float radius = (float)inf();
-
- if (attenuation[2] != 0) {
-
- // Solve I / attenuation.dot(1, r, r^2) < cutoff for r
- //
- // a[0] + a[1] r + a[2] r^2 > I/cutoff
- //
-
- float a = attenuation[2];
- float b = attenuation[1];
- float c = attenuation[0] - maxIntensity / cutoff;
-
- float discrim = square(b) - 4 * a * c;
-
- if (discrim >= 0) {
- discrim = sqrt(discrim);
-
- float r1 = (-b + discrim) / (2 * a);
- float r2 = (-b - discrim) / (2 * a);
-
- if (r1 < 0) {
- if (r2 > 0) {
- radius = r2;
- }
- } else if (r2 > 0) {
- radius = min(r1, r2);
- } else {
- radius = r1;
- }
- }
-
- } else if (attenuation[1] != 0) {
-
- // Solve I / attenuation.dot(1, r) < cutoff for r
- //
- // r * a[1] + a[0] = I / cutoff
- // r = (I / cutoff - a[0]) / a[1]
-
- float radius = (maxIntensity / cutoff - attenuation[0]) / attenuation[1];
- radius = max(radius, 0.0f);
- }
-
- return Sphere(position.xyz(), radius);
-
- }
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/GThread.cpp b/externals/g3dlite/G3D.lib/source/GThread.cpp
deleted file mode 100644
index 090370436c4..00000000000
--- a/externals/g3dlite/G3D.lib/source/GThread.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/**
- @file GThread.cpp
-
- GThread class.
-
- @created 2005-09-24
- @edited 2005-10-22
- */
-
-#include "G3D/GThread.h"
-#include "G3D/System.h"
-#include "G3D/debugAssert.h"
-
-
-namespace G3D {
-
-namespace _internal {
-
-class BasicThread: public GThread {
-public:
- BasicThread(const std::string& name, void (*proc)(void*), void* param):
- GThread(name), m_wrapperProc(proc), m_param(param) { }
-protected:
- virtual void threadMain() {
- m_wrapperProc(m_param);
- }
-
-private:
- void (*m_wrapperProc)(void*);
-
- void* m_param;
-};
-
-} // namespace _internal
-
-
-GThread::GThread(const std::string& name):
- m_status(STATUS_CREATED),
- m_name(name) {
-
-#ifdef G3D_WIN32
- m_event = NULL;
-#endif
-
- // system-independent clear of handle
- System::memset(&m_handle, 0, sizeof(m_handle));
-}
-
-GThread::~GThread() {
-#ifdef _MSC_VER
-# pragma warning( push )
-# pragma warning( disable : 4127 )
-#endif
- alwaysAssertM(m_status != STATUS_RUNNING, "Deleting thread while running.");
-#ifdef _MSC_VER
-# pragma warning( pop )
-#endif
-
-#ifdef G3D_WIN32
- if (m_event) {
- ::CloseHandle(m_event);
- }
-#endif
-}
-
-GThreadRef GThread::create(const std::string& name, void (*proc)(void*), void* param) {
- return new _internal::BasicThread(name, proc, param);
-}
-
-
-bool GThread::started() const {
- return m_status != STATUS_CREATED;
-}
-
-bool GThread::start() {
-
- debugAssertM(! started(), "Thread has already executed.");
- if (started()) {
- return false;
- }
-
- m_status = STATUS_STARTED;
-
-# ifdef G3D_WIN32
- DWORD threadId;
-
- m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- debugAssert(m_event);
-
- m_handle = ::CreateThread(NULL, 0, &internalThreadProc, this, 0, &threadId);
-
- if (m_handle == NULL) {
- ::CloseHandle(m_event);
- m_event = NULL;
- }
-
- return (m_handle != NULL);
-# else
- if (!pthread_create(&m_handle, NULL, &internalThreadProc, this)) {
- return true;
- } else {
- // system-independent clear of handle
- System::memset(&m_handle, 0, sizeof(m_handle));
-
- return false;
- }
-# endif
-}
-
-void GThread::terminate() {
- if (m_handle) {
-# ifdef G3D_WIN32
- ::TerminateThread(m_handle, 0);
-# else
- pthread_kill(m_handle, SIGSTOP);
-# endif
- // system-independent clear of handle
- System::memset(&m_handle, 0, sizeof(m_handle));
- }
-}
-
-bool GThread::running() const{
- return (m_status == STATUS_RUNNING);
-}
-
-bool GThread::completed() const {
- return (m_status == STATUS_COMPLETED);
-}
-
-void GThread::waitForCompletion() {
-# ifdef G3D_WIN32
- debugAssert(m_event);
- ::WaitForSingleObject(m_event, INFINITE);
-# else
- debugAssert(m_handle);
- pthread_join(m_handle, NULL);
-# endif
-}
-
-#ifdef G3D_WIN32
-DWORD WINAPI GThread::internalThreadProc(LPVOID param) {
- GThread* current = reinterpret_cast<GThread*>(param);
- debugAssert(current->m_event);
- current->m_status = STATUS_RUNNING;
- current->threadMain();
- current->m_status = STATUS_COMPLETED;
- ::SetEvent(current->m_event);
- return 0;
-}
-#else
-void* GThread::internalThreadProc(void* param) {
- GThread* current = reinterpret_cast<GThread*>(param);
- current->m_status = STATUS_RUNNING;
- current->threadMain();
- current->m_status = STATUS_COMPLETED;
- return (void*)NULL;
-}
-#endif
-
-
-
-GMutex::GMutex() {
-# ifdef G3D_WIN32
- ::InitializeCriticalSection(&m_handle);
-# else
- pthread_mutex_init(&m_handle, NULL);
-# endif
-}
-
-GMutex::~GMutex() {
- //TODO: Debug check for locked
-# ifdef G3D_WIN32
- ::DeleteCriticalSection(&m_handle);
-# else
- pthread_mutex_destroy(&m_handle);
-# endif
-}
-
-//bool GMutex::tryLock() {
-//# ifdef G3D_WIN32
-// return ::TryEnterCriticalSection(&m_handle);
-//# else
-// return pthread_mutex_trylock(&m_handle);
-//# endif
-//}
-
-void GMutex::lock() {
-# ifdef G3D_WIN32
- ::EnterCriticalSection(&m_handle);
-# else
- pthread_mutex_lock(&m_handle);
-# endif
-}
-
-void GMutex::unlock() {
-# ifdef G3D_WIN32
- ::LeaveCriticalSection(&m_handle);
-# else
- pthread_mutex_unlock(&m_handle);
-# endif
-}
-
-} // namespace G3D
diff --git a/externals/g3dlite/G3D.lib/source/GUniqueID.cpp b/externals/g3dlite/G3D.lib/source/GUniqueID.cpp
deleted file mode 100644
index 25c757b70e4..00000000000
--- a/externals/g3dlite/G3D.lib/source/GUniqueID.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- @file GUniqueID.cpp
- @author Morgan McGuire, morgan@cs.williams.edu
- */
-#include "G3D/GUniqueID.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/TextInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/TextOutput.h"
-#include "G3D/NetworkDevice.h"
-
-namespace G3D {
-
-void GUniqueID::serialize(BinaryOutput& b) const {
- b.writeUInt64(id);
-}
-
-
-void GUniqueID::deserialize(BinaryInput& b) {
- id = b.readUInt64();
-}
-
-void GUniqueID::serialize(TextOutput& t) const {
- t.writeSymbol("(");
- t.writeNumber((double)(id >> 32));
- t.writeNumber((double)(id & 0xFFFFFFFF));
- t.writeSymbol(")");
-}
-
-void GUniqueID::deserialize(TextInput& t) {
- t.readSymbol("(");
- id = (((uint64)t.readNumber()) << 32) + (uint64)t.readNumber();
- t.readSymbol(")");
-}
-
-
-GUniqueID GUniqueID::create(uint16 tag) {
- static uint64 counter = 0;
- static uint64 systemID = 0;
-
- if (systemID == 0) {
- // Create a unique ID for this machine/program instance
-
- // TODO: see ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr)
- Array<NetAddress> addr;
- NetworkDevice::instance()->localHostAddresses(addr);
- if (addr.size() > 0) {
- systemID |= addr[0].ip();
- }
-
- union {
- float64 ft;
- uint64 ut;
- };
- ft = System::time();
- systemID = ut << 22;
- systemID ^= ((uint64)iRandom(0, 32768)) << 8;
-
- systemID &= ~((uint64)1023 << 54);
-
- // Ensure that the systemID is non-zero (vanishingly small probability)
- if (systemID == 0) {
- systemID = 1;
- }
- }
-
- // No need for modulo; we'll all be dead before this counter
- // overflows 54 bits
- ++counter;
-
- GUniqueID i;
-
- i.id = (((uint64)(tag & 1023)) << 54) | (counter ^ systemID);
-
- return i;
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/Image1.cpp b/externals/g3dlite/G3D.lib/source/Image1.cpp
deleted file mode 100644
index 30841d01c6b..00000000000
--- a/externals/g3dlite/G3D.lib/source/Image1.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- @file Image1.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-01-31
- @edited 2007-01-31
-*/
-
-
-#include "G3D/Image1.h"
-#include "G3D/Image1uint8.h"
-#include "G3D/GImage.h"
-#include "G3D/Color4.h"
-#include "G3D/Color4uint8.h"
-#include "G3D/Color1.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/ImageFormat.h"
-
-namespace G3D {
-
-Image1::Image1(int w, int h, WrapMode wrap) : Map2D<Color1, Color1>(w, h, wrap) {
- setAll(Color1(0.0f));
-}
-
-
-Image1::Ref Image1::fromGImage(const GImage& im, WrapMode wrap) {
- switch (im.channels) {
- case 1:
- return fromArray(im.pixel1(), im.width, im.height, wrap);
-
- case 3:
- return fromArray(im.pixel3(), im.width, im.height, wrap);
-
- case 4:
- return fromArray(im.pixel4(), im.width, im.height, wrap);
-
- default:
- debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
- return NULL;
- }
-}
-
-
-Image1::Ref Image1::fromImage1uint8(const ReferenceCountedPointer<Image1uint8>& im) {
- Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
- out->resize(im->width(), im->height());
-
- int N = im->width() * im->height();
- const Color1uint8* src = reinterpret_cast<Color1uint8*>(im->getCArray());
- for (int i = 0; i < N; ++i) {
- out->data[i] = Color1(src[i]);
- }
-
- return out;
-}
-
-
-Image1::Ref Image1::createEmpty(int width, int height, WrapMode wrap) {
- return new Type(width, height, wrap);
-}
-
-
-Image1::Ref Image1::createEmpty(WrapMode wrap) {
- return createEmpty(0, 0, wrap);
-}
-
-
-Image1::Ref Image1::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
- Ref out = createEmpty(wrap);
- out->load(filename);
- return out;
-}
-
-
-void Image1::load(const std::string& filename, GImage::Format fmt) {
- copyGImage(GImage(filename, fmt));
- setChanged(true);
-}
-
-
-Image1::Ref Image1::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1::Ref Image1::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1::Ref Image1::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1::Ref Image1::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1::Ref Image1::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1::Ref Image1::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-void Image1::copyGImage(const GImage& im) {
- switch (im.channels) {
- case 1:
- copyArray(im.pixel1(), im.width, im.height);
- break;
-
- case 3:
- copyArray(im.pixel3(), im.width, im.height);
- break;
-
- case 4:
- copyArray(im.pixel4(), im.width, im.height);
- break;
- }
-}
-
-
-void Image1::copyArray(const Color3uint8* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color1* dst = data.getCArray();
- // Convert int8 -> float
- for (int i = 0; i < N; ++i) {
- dst[i] = Color1(Color3(src[i]).average());
- }
-}
-
-
-void Image1::copyArray(const Color4uint8* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color1* dst = data.getCArray();
-
- // Strip alpha and convert
- for (int i = 0; i < N; ++i) {
- dst[i] = Color1(Color3(src[i].rgb()).average());
- }
-}
-
-
-void Image1::copyArray(const Color1* src, int w, int h) {
- resize(w, h);
- System::memcpy(getCArray(), src, w * h * sizeof(Color1));
-}
-
-
-void Image1::copyArray(const Color4* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color1* dst = data.getCArray();
-
- // Strip alpha
- for (int i = 0; i < N; ++i) {
- dst[i] = Color1(src[i].rgb().average());
- }
-}
-
-
-void Image1::copyArray(const Color1uint8* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color1* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i]= Color1(src[i]);
- }
-}
-
-
-void Image1::copyArray(const Color3* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color1* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color1(src[i].average());
- }
-}
-
-
-/** Saves in any of the formats supported by G3D::GImage. */
-void Image1::save(const std::string& filename, GImage::Format fmt) {
- GImage im(width(), height(), 1);
-
- int N = im.width * im.height;
- Color1uint8* dst = im.pixel1();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color1uint8(data[i]);
- }
-
- im.save(filename, fmt);
-}
-
-
-const ImageFormat* Image1::format() const {
- return ImageFormat::L32F();
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/Image1uint8.cpp b/externals/g3dlite/G3D.lib/source/Image1uint8.cpp
deleted file mode 100644
index c43e7194d7d..00000000000
--- a/externals/g3dlite/G3D.lib/source/Image1uint8.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- @file Image1uint8.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-01-31
- @edited 2008-01-13
-*/
-
-#include "G3D/Image1uint8.h"
-#include "G3D/Image3uint8.h"
-#include "G3D/Image1.h"
-#include "G3D/GImage.h"
-#include "G3D/Color1.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/Color4.h"
-#include "G3D/Color4uint8.h"
-#include "G3D/ImageFormat.h"
-
-namespace G3D {
-
-Image1uint8::Image1uint8(int w, int h, WrapMode wrap) : Map2D<Color1uint8, Color1>(w, h, wrap) {
- setAll(Color1uint8(0));
-}
-
-
-Image1uint8::Ref Image1uint8::fromImage3uint8(const ReferenceCountedPointer<class Image3uint8>& im) {
- return fromArray(im->getCArray(), im->width(), im->height(), im->wrapMode());
-}
-
-
-Image1uint8::Ref Image1uint8::fromGImage(const GImage& im, WrapMode wrap) {
- switch (im.channels) {
- case 1:
- return fromArray(im.pixel1(), im.width, im.height, wrap);
-
- case 3:
- return fromArray(im.pixel3(), im.width, im.height, wrap);
-
- case 4:
- return fromArray(im.pixel4(), im.width, im.height, wrap);
-
- default:
- debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
- return NULL;
- }
-}
-
-
-Image1uint8::Ref Image1uint8::fromImage1(const ReferenceCountedPointer<Image1>& im) {
- Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
- out->copyArray(im->getCArray(), im->width(), im->height());
-
- return out;
-}
-
-
-Image1uint8::Ref Image1uint8::createEmpty(int width, int height, WrapMode wrap) {
- return new Type(width, height, wrap);
-}
-
-
-Image1uint8::Ref Image1uint8::createEmpty(WrapMode wrap) {
- return createEmpty(0, 0, wrap);
-}
-
-
-Image1uint8::Ref Image1uint8::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
- Ref out = createEmpty(wrap);
- out->load(filename);
- return out;
-}
-
-
-Image1uint8::Ref Image1uint8::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1uint8::Ref Image1uint8::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1uint8::Ref Image1uint8::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1uint8::Ref Image1uint8::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1uint8::Ref Image1uint8::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image1uint8::Ref Image1uint8::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-void Image1uint8::load(const std::string& filename, GImage::Format fmt) {
- copyGImage(GImage(filename, fmt));
- setChanged(true);
-}
-
-
-void Image1uint8::copyGImage(const GImage& im) {
- switch (im.channels) {
- case 1:
- copyArray(im.pixel1(), im.width, im.height);
- break;
-
- case 3:
- copyArray(im.pixel3(), im.width, im.height);
- break;
-
- case 4:
- copyArray(im.pixel4(), im.width, im.height);
- break;
- }
-}
-
-
-void Image1uint8::copyArray(const Color3uint8* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color1uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].value = (src[i].r + src[i].g + src[i].b) / 3;
- }
-}
-
-void Image1uint8::copyArray(const Color3* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color1uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color1uint8(Color1(src[i].average()));
- }
-}
-
-
-void Image1uint8::copyArray(const Color1uint8* ptr, int w, int h) {
- resize(w, h);
- System::memcpy(getCArray(), ptr, w * h);
-}
-
-
-void Image1uint8::copyArray(const Color1* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color1uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color1uint8(src[i]);
- }
-}
-
-
-void Image1uint8::copyArray(const Color4uint8* ptr, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color1uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].value = (ptr[i].r + ptr[i].g + ptr[i].b) / 3;
- }
-}
-
-
-void Image1uint8::copyArray(const Color4* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color1uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color1uint8(Color1(src[i].rgb().average()));
- }
-}
-
-
-/** Saves in any of the formats supported by G3D::GImage. */
-void Image1uint8::save(const std::string& filename, GImage::Format fmt) {
- GImage im(width(), height(), 1);
- System::memcpy(im.byte(), getCArray(), width() * height());
- im.save(filename, fmt);
-}
-
-
-const ImageFormat* Image1uint8::format() const {
- return ImageFormat::L8();
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/Image3.cpp b/externals/g3dlite/G3D.lib/source/Image3.cpp
deleted file mode 100644
index aa2ac6098dc..00000000000
--- a/externals/g3dlite/G3D.lib/source/Image3.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- @file Image3.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-01-31
- @edited 2007-01-31
-*/
-
-
-#include "G3D/Image3.h"
-#include "G3D/Image3uint8.h"
-#include "G3D/GImage.h"
-#include "G3D/Color4.h"
-#include "G3D/Color4uint8.h"
-#include "G3D/Color1.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/ImageFormat.h"
-
-namespace G3D {
-
-Image3::Image3(int w, int h, WrapMode wrap) : Map2D<Color3, Color3>(w, h, wrap) {
- setAll(Color3::black());
-}
-
-
-Image3::Ref Image3::fromGImage(const GImage& im, WrapMode wrap) {
- switch (im.channels) {
- case 1:
- return fromArray(im.pixel1(), im.width, im.height, wrap);
-
- case 3:
- return fromArray(im.pixel3(), im.width, im.height, wrap);
-
- case 4:
- return fromArray(im.pixel4(), im.width, im.height, wrap);
-
- default:
- debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
- return NULL;
- }
-}
-
-
-Image3::Ref Image3::fromImage3uint8(const ReferenceCountedPointer<Image3uint8>& im) {
- Ref out = createEmpty(im->wrapMode());
- out->resize(im->width(), im->height());
-
- int N = im->width() * im->height();
- const Color3uint8* src = reinterpret_cast<Color3uint8*>(im->getCArray());
- for (int i = 0; i < N; ++i) {
- out->data[i] = Color3(src[i]);
- }
-
- return out;
-}
-
-
-Image3::Ref Image3::createEmpty(int width, int height, WrapMode wrap) {
- return new Image3(width, height, wrap);
-}
-
-
-Image3::Ref Image3::createEmpty(WrapMode wrap) {
- return createEmpty(0, 0, wrap);
-}
-
-
-Image3::Ref Image3::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
- Ref out = createEmpty(wrap);
- out->load(filename);
- return out;
-}
-
-
-void Image3::load(const std::string& filename, GImage::Format fmt) {
- copyGImage(GImage(filename, fmt));
- setChanged(true);
-}
-
-
-Image3::Ref Image3::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3::Ref Image3::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3::Ref Image3::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3::Ref Image3::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3::Ref Image3::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3::Ref Image3::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-void Image3::copyGImage(const GImage& im) {
- switch (im.channels) {
- case 1:
- copyArray(im.pixel1(), im.width, im.height);
- break;
-
- case 3:
- copyArray(im.pixel3(), im.width, im.height);
- break;
-
- case 4:
- copyArray(im.pixel4(), im.width, im.height);
- break;
- }
-}
-
-
-void Image3::copyArray(const Color3uint8* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color3* dst = data.getCArray();
- // Convert int8 -> float
- for (int i = 0; i < N; ++i) {
- dst[i] = Color3(src[i]);
- }
-}
-
-
-void Image3::copyArray(const Color4uint8* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color3* dst = data.getCArray();
-
- // Strip alpha and convert
- for (int i = 0; i < N; ++i) {
- dst[i] = Color3(src[i].rgb());
- }
-}
-
-
-void Image3::copyArray(const Color3* src, int w, int h) {
- resize(w, h);
- System::memcpy(getCArray(), src, w * h * sizeof(Color3));
-}
-
-
-void Image3::copyArray(const Color4* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color3* dst = data.getCArray();
-
- // Strip alpha
- for (int i = 0; i < N; ++i) {
- dst[i] = src[i].rgb();
- }
-}
-
-
-void Image3::copyArray(const Color1uint8* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color3* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].r = dst[i].g = dst[i].b = Color1(src[i]).value;
- }
-}
-
-
-void Image3::copyArray(const Color1* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color3* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].r = dst[i].g = dst[i].b = src[i].value;
- }
-}
-
-
-/** Saves in any of the formats supported by G3D::GImage. */
-void Image3::save(const std::string& filename, GImage::Format fmt) {
- GImage im(width(), height(), 3);
-
- int N = im.width * im.height;
- Color3uint8* dst = im.pixel3();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color3uint8(data[i]);
- }
-
- im.save(filename, fmt);
-}
-
-
-const ImageFormat* Image3::format() const {
- return ImageFormat::RGB32F();
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/Image3uint8.cpp b/externals/g3dlite/G3D.lib/source/Image3uint8.cpp
deleted file mode 100644
index 2de32b6009e..00000000000
--- a/externals/g3dlite/G3D.lib/source/Image3uint8.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/**
- @file Image3uint8.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-01-31
- @edited 2008-01-08
-*/
-
-#include "G3D/Image1uint8.h"
-#include "G3D/Image3uint8.h"
-#include "G3D/Image3.h"
-#include "G3D/GImage.h"
-#include "G3D/Color1.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/Color4.h"
-#include "G3D/Color4uint8.h"
-#include "G3D/ImageFormat.h"
-
-namespace G3D {
-
-Image3uint8::Ref Image3uint8::fromImage1uint8(const ReferenceCountedPointer<class Image1uint8>& im) {
- return fromArray(im->getCArray(), im->width(), im->height(), im->wrapMode());
-}
-
-
-Image3uint8::Image3uint8(int w, int h, WrapMode wrap) : Map2D<Color3uint8>(w, h, wrap) {
- setAll(Color3::black());
-}
-
-
-Image3uint8::Ref Image3uint8::fromGImage(const GImage& im, WrapMode wrap) {
- switch (im.channels) {
- case 1:
- return fromArray(im.pixel1(), im.width, im.height, wrap);
-
- case 3:
- return fromArray(im.pixel3(), im.width, im.height, wrap);
-
- case 4:
- return fromArray(im.pixel4(), im.width, im.height, wrap);
-
- default:
- debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
- return NULL;
- }
-}
-
-
-Image3uint8::Ref Image3uint8::fromImage3(const ReferenceCountedPointer<Image3>& im) {
- Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
- out->copyArray(im->getCArray(), im->width(), im->height());
-
- return out;
-}
-
-
-Image3uint8::Ref Image3uint8::createEmpty(int width, int height, WrapMode wrap) {
- return new Type(width, height, wrap);
-}
-
-
-Image3uint8::Ref Image3uint8::createEmpty(WrapMode wrap) {
- return createEmpty(0, 0, wrap);
-}
-
-
-Image3uint8::Ref Image3uint8::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
- Ref out = createEmpty(wrap);
- out->load(filename);
- return out;
-}
-
-
-Image3uint8::Ref Image3uint8::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3uint8::Ref Image3uint8::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3uint8::Ref Image3uint8::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3uint8::Ref Image3uint8::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3uint8::Ref Image3uint8::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image3uint8::Ref Image3uint8::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-void Image3uint8::load(const std::string& filename, GImage::Format fmt) {
- copyGImage(GImage(filename, fmt));
- setChanged(true);
-}
-
-
-void Image3uint8::copyGImage(const GImage& im) {
- switch (im.channels) {
- case 1:
- copyArray(im.pixel1(), im.width, im.height);
- break;
-
- case 3:
- copyArray(im.pixel3(), im.width, im.height);
- break;
-
- case 4:
- copyArray(im.pixel4(), im.width, im.height);
- break;
- }
-}
-
-
-void Image3uint8::copyArray(const Color1uint8* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color3uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].r = dst[i].g = dst[i].b = src[i].value;
- }
-}
-
-void Image3uint8::copyArray(const Color1* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color3uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].r = dst[i].g = dst[i].b = Color1uint8(src[i]).value;
- }
-}
-
-
-void Image3uint8::copyArray(const Color3uint8* ptr, int w, int h) {
- resize(w, h);
- System::memcpy(getCArray(), ptr, w * h * 3);
-}
-
-
-void Image3uint8::copyArray(const Color3* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color3uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color3uint8(src[i]);
- }
-}
-
-
-void Image3uint8::copyArray(const Color4uint8* ptr, int w, int h) {
- resize(w, h);
-
- // Copy 3/4 bytes
- GImage::RGBAtoRGB((const uint8*)ptr, (uint8*)getCArray(), w * h);
-}
-
-
-void Image3uint8::copyArray(const Color4* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color3uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color3uint8(src[i].rgb());
- }
-}
-
-
-/** Saves in any of the formats supported by G3D::GImage. */
-void Image3uint8::save(const std::string& filename, GImage::Format fmt) {
- GImage im(width(), height(), 3);
- System::memcpy(im.byte(), getCArray(), width() * height() * 3);
- im.save(filename, fmt);
-}
-
-
-ReferenceCountedPointer<class Image1uint8> Image3uint8::getChannel(int c) const {
- debugAssert(c >= 0 && c <= 2);
-
- Image1uint8Ref dst = Image1uint8::createEmpty(width(), height(), wrapMode());
- const Color3uint8* srcArray = getCArray();
- Color1uint8* dstArray = dst->getCArray();
-
- const int N = width() * height();
- for (int i = 0; i < N; ++i) {
- dstArray[i] = Color1uint8(srcArray[i][c]);
- }
-
- return dst;
-}
-
-
-const ImageFormat* Image3uint8::format() const {
- return ImageFormat::RGB8();
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/Image4.cpp b/externals/g3dlite/G3D.lib/source/Image4.cpp
deleted file mode 100644
index 84a1cd650b6..00000000000
--- a/externals/g3dlite/G3D.lib/source/Image4.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/**
- @file Image4.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-01-31
- @edited 2008-07-27
-*/
-
-
-#include "G3D/Image4.h"
-#include "G3D/Image4uint8.h"
-#include "G3D/GImage.h"
-#include "G3D/Color3.h"
-#include "G3D/Color3uint8.h"
-#include "G3D/Color1.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/ImageFormat.h"
-
-namespace G3D {
-
-Image4::Image4(int w, int h, WrapMode wrap) : Map2D<Color4, Color4>(w, h, wrap) {
- setAll(Color4::zero());
-}
-
-
-Image4::Ref Image4::fromGImage(const GImage& im, WrapMode wrap) {
- switch (im.channels) {
- case 1:
- return fromArray(im.pixel1(), im.width, im.height, wrap);
-
- case 3:
- return fromArray(im.pixel3(), im.width, im.height, wrap);
-
- case 4:
- return fromArray(im.pixel4(), im.width, im.height, wrap);
-
- default:
- debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
- return NULL;
- }
-}
-
-
-Image4::Ref Image4::fromImage4uint8(const ReferenceCountedPointer<Image4uint8>& im) {
- Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
- out->resize(im->width(), im->height());
-
- int N = im->width() * im->height();
- const Color4uint8* src = reinterpret_cast<Color4uint8*>(im->getCArray());
- for (int i = 0; i < N; ++i) {
- out->data[i] = Color4(src[i]);
- }
-
- return out;
-}
-
-
-Image4::Ref Image4::createEmpty(int width, int height, WrapMode wrap) {
- return new Type(width, height, WrapMode::ERROR);
-}
-
-
-Image4::Ref Image4::createEmpty(WrapMode wrap) {
- return createEmpty(0, 0, wrap);
-}
-
-
-Image4::Ref Image4::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
- Ref out = createEmpty(wrap);
- out->load(filename);
- return out;
-}
-
-
-void Image4::load(const std::string& filename, GImage::Format fmt) {
- copyGImage(GImage(filename, fmt));
- setChanged(true);
-}
-
-
-Image4::Ref Image4::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4::Ref Image4::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4::Ref Image4::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4::Ref Image4::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4::Ref Image4::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4::Ref Image4::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-void Image4::copyGImage(const GImage& im) {
- switch (im.channels) {
- case 1:
- copyArray(im.pixel1(), im.width, im.height);
- break;
-
- case 3:
- copyArray(im.pixel3(), im.width, im.height);
- break;
-
- case 4:
- copyArray(im.pixel4(), im.width, im.height);
- break;
- }
-}
-
-
-void Image4::copyArray(const Color4uint8* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color4* dst = data.getCArray();
- // Convert int8 -> float
- for (int i = 0; i < N; ++i) {
- dst[i] = Color4(src[i]);
- }
-}
-
-
-void Image4::copyArray(const Color3uint8* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color4* dst = data.getCArray();
-
- // Add alpha and convert
- for (int i = 0; i < N; ++i) {
- dst[i] = Color4(Color3(src[i]), 1.0f);
- }
-}
-
-
-void Image4::copyArray(const Color4* src, int w, int h) {
- resize(w, h);
- System::memcpy(getCArray(), src, w * h * sizeof(Color4));
-}
-
-
-void Image4::copyArray(const Color3* src, int w, int h) {
- resize(w, h);
-
- int N = w * h;
- Color4* dst = data.getCArray();
-
- // Add alpha
- for (int i = 0; i < N; ++i) {
- dst[i] = Color4(src[i], 1.0f);
- }
-}
-
-
-void Image4::copyArray(const Color1uint8* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color4* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].r = dst[i].g = dst[i].b = Color1(src[i]).value;
- dst[i].a = 1.0f;
- }
-}
-
-
-void Image4::copyArray(const Color1* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color4* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].r = dst[i].g = dst[i].b = src[i].value;
- dst[i].a = 1.0f;
- }
-}
-
-
-/** Saves in any of the formats supported by G3D::GImage. */
-void Image4::save(const std::string& filename, GImage::Format fmt) {
- GImage im(width(), height(), 4);
-
- int N = im.width * im.height;
- Color4uint8* dst = im.pixel4();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color4uint8(data[i]);
- }
-
- im.save(filename, fmt);
-}
-
-const ImageFormat* Image4::format() const {
- return ImageFormat::RGBA32F();
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/Image4uint8.cpp b/externals/g3dlite/G3D.lib/source/Image4uint8.cpp
deleted file mode 100644
index dee1cba14ba..00000000000
--- a/externals/g3dlite/G3D.lib/source/Image4uint8.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- @file Image4uint8.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-01-31
- @edited 2008-07-31
-*/
-
-#include "G3D/Image4uint8.h"
-#include "G3D/Image4.h"
-#include "G3D/Image3uint8.h"
-#include "G3D/Image3.h"
-#include "G3D/GImage.h"
-#include "G3D/Color1.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/Color4.h"
-#include "G3D/Color4uint8.h"
-#include "G3D/ImageFormat.h"
-
-namespace G3D {
-
-Image4uint8::Image4uint8(int w, int h, WrapMode wrap) : Map2D<Color4uint8, Color4>(w, h, wrap) {
- setAll(Color4::zero());
-}
-
-
-Image4uint8::Ref Image4uint8::fromGImage(const GImage& im, WrapMode wrap) {
- switch (im.channels) {
- case 1:
- return fromArray(im.pixel1(), im.width, im.height, wrap);
-
- case 3:
- return fromArray(im.pixel3(), im.width, im.height, wrap);
-
- case 4:
- return fromArray(im.pixel4(), im.width, im.height, wrap);
-
- default:
- debugAssertM(false, "Input GImage must have 1, 3, or 4 channels.");
- return NULL;
- }
-}
-
-
-Image4uint8::Ref Image4uint8::fromImage4(const ReferenceCountedPointer<Image4>& im) {
- Ref out = createEmpty(static_cast<WrapMode>(im->wrapMode()));
- out->copyArray(im->getCArray(), im->width(), im->height());
-
- return out;
-}
-
-
-Image4uint8::Ref Image4uint8::createEmpty(int width, int height, WrapMode wrap) {
- return new Type(width, height, wrap);
-}
-
-
-Image4uint8::Ref Image4uint8::createEmpty(WrapMode wrap) {
- return createEmpty(0, 0, wrap);
-}
-
-
-Image4uint8::Ref Image4uint8::fromFile(const std::string& filename, WrapMode wrap, GImage::Format fmt) {
- Ref out = createEmpty(wrap);
- out->load(filename);
- return out;
-}
-
-
-Image4uint8::Ref Image4uint8::fromArray(const class Color3uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4uint8::Ref Image4uint8::fromArray(const class Color1* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4uint8::Ref Image4uint8::fromArray(const class Color1uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4uint8::Ref Image4uint8::fromArray(const class Color3* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4uint8::Ref Image4uint8::fromArray(const class Color4uint8* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-Image4uint8::Ref Image4uint8::fromArray(const class Color4* ptr, int w, int h, WrapMode wrap) {
- Ref out = createEmpty(wrap);
- out->copyArray(ptr, w, h);
- return out;
-}
-
-
-void Image4uint8::load(const std::string& filename, GImage::Format fmt) {
- copyGImage(GImage(filename, fmt));
- setChanged(true);
-}
-
-
-void Image4uint8::copyGImage(const GImage& im) {
- switch (im.channels) {
- case 1:
- copyArray(im.pixel1(), im.width, im.height);
- break;
-
- case 3:
- copyArray(im.pixel3(), im.width, im.height);
- break;
-
- case 4:
- copyArray(im.pixel4(), im.width, im.height);
- break;
- }
-}
-
-
-void Image4uint8::copyArray(const Color1uint8* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color4uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].r = dst[i].g = dst[i].b = src[i].value;
- dst[i].a = 255;
- }
-}
-
-void Image4uint8::copyArray(const Color1* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color4uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i].r = dst[i].g = dst[i].b = Color1uint8(src[i]).value;
- dst[i].a = 255;
- }
-}
-
-
-void Image4uint8::copyArray(const Color4uint8* ptr, int w, int h) {
- resize(w, h);
- System::memcpy(getCArray(), ptr, w * h * 4);
-}
-
-
-void Image4uint8::copyArray(const Color4* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color4uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color4uint8(src[i]);
- }
-}
-
-
-void Image4uint8::copyArray(const Color3uint8* ptr, int w, int h) {
- resize(w, h);
-
- GImage::RGBtoRGBA((const uint8*)ptr, (uint8*)getCArray(), w * h);
-}
-
-
-void Image4uint8::copyArray(const Color3* src, int w, int h) {
- resize(w, h);
- int N = w * h;
-
- Color4uint8* dst = getCArray();
- for (int i = 0; i < N; ++i) {
- dst[i] = Color4uint8(Color4(src[i], 1.0f));
- }
-}
-
-
-/** Saves in any of the formats supported by G3D::GImage. */
-void Image4uint8::save(const std::string& filename, GImage::Format fmt) {
- GImage im(width(), height(), 4);
- System::memcpy(im.byte(), getCArray(), width() * height() * 4);
- im.save(filename, fmt);
-}
-
-
-ReferenceCountedPointer<class Image1uint8> Image4uint8::getChannel(int c) const {
- debugAssert(c >= 0 && c <= 3);
-
- Image1uint8Ref dst = Image1uint8::createEmpty(width(), height(), wrapMode());
- const Color4uint8* srcArray = getCArray();
- Color1uint8* dstArray = dst->getCArray();
-
- const int N = width() * height();
- for (int i = 0; i < N; ++i) {
- dstArray[i] = Color1uint8(srcArray[i][c]);
- }
-
- return dst;
-}
-
-
-const ImageFormat* Image4uint8::format() const {
- return ImageFormat::RGBA8();
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/ImageFormat.cpp b/externals/g3dlite/G3D.lib/source/ImageFormat.cpp
deleted file mode 100644
index 3cbf6ad711e..00000000000
--- a/externals/g3dlite/G3D.lib/source/ImageFormat.cpp
+++ /dev/null
@@ -1,440 +0,0 @@
-/**
- @file ImageFormat.cpp
-
- @maintainer Morgan McGuire, morgan@graphics3d.com
-
- @created 2003-05-23
- @edited 2006-01-11
- */
-
-#include "../../GLG3D.lib/include/GLG3D/glheaders.h"
-#include "../../GLG3D.lib/include/GLG3D/glcalls.h"
-#include "G3D/ImageFormat.h"
-
-namespace G3D {
-
-ImageFormat::ImageFormat(
- int _numComponents,
- bool _compressed,
- int _glFormat,
- int _glBaseFormat,
- int _luminanceBits,
- int _alphaBits,
- int _redBits,
- int _greenBits,
- int _blueBits,
- int _depthBits,
- int _stencilBits,
- int _hardwareBitsPerTexel,
- int _packedBitsPerTexel,
- int glDataFormat,
- bool _opaque,
- bool _floatingPoint,
- Code _code,
- ColorSpace _colorSpace,
- BayerPattern _bayerPattern) :
-
- numComponents(_numComponents),
- compressed(_compressed),
- code(_code),
- colorSpace(_colorSpace),
- bayerPattern(_bayerPattern),
- openGLFormat(_glFormat),
- openGLBaseFormat(_glBaseFormat),
- luminanceBits(_luminanceBits),
- alphaBits(_alphaBits),
- redBits(_redBits),
- greenBits(_greenBits),
- blueBits(_blueBits),
- stencilBits(_stencilBits),
- depthBits(_depthBits),
- cpuBitsPerPixel(_packedBitsPerTexel),
- packedBitsPerTexel(_packedBitsPerTexel),
- openGLBitsPerPixel(_hardwareBitsPerTexel),
- hardwareBitsPerTexel(_hardwareBitsPerTexel),
- openGLDataFormat(glDataFormat),
- opaque(_opaque),
- floatingPoint(_floatingPoint) {
-
- debugAssert(_packedBitsPerTexel <= _hardwareBitsPerTexel);
-}
-
-const ImageFormat* ImageFormat::depth(int depthBits) {
-
- switch (depthBits) {
- case 16:
- return DEPTH16();
-
- case 24:
- return DEPTH24();
-
- case 32:
- return DEPTH32();
-
- default:
- debugAssertM(false, "Depth must be 16, 24, or 32.");
- return DEPTH32();
- }
-}
-
-
-const ImageFormat* ImageFormat::stencil(int bits) {
- switch (bits) {
- case 1:
- return STENCIL1();
-
- case 4:
- return STENCIL4();
-
- case 8:
- return STENCIL8();
-
- case 16:
- return STENCIL16();
-
- default:
- debugAssertM(false, "Stencil must be 1, 4, 8 or 16.");
- return STENCIL16();
- }
-}
-
-
-std::string ImageFormat::name() const {
-
- static const std::string nameArray[] =
- {
- "L8",
- "L16",
- "L16F",
- "L32F",
-
- "A8",
- "A16",
- "A16F",
- "A32F",
-
- "LA4",
- "LA8",
- "LA16",
- "LA16F",
- "LA32F",
-
- "RGB5",
- "RGB5A1",
- "RGB8",
- "RGB10",
- "RGB10A2",
- "RGB16",
- "RGB16F",
- "RGB32F",
-
- "ARGB8",
- "BGR8",
-
- "RGBA8",
- "RGBA16",
- "RGBA16F",
- "RGBA32F",
-
- "BAYER_RGGB8",
- "BAYER_GRBG8",
- "BAYER_GBRG8",
- "BAYER_BGGR8",
- "BAYER_RGGB32F",
- "BAYER_GRBG32F",
- "BAYER_GBRG32F",
- "BAYER_BGGR32F",
-
- "HSV8",
- "HSV32F",
-
- "YUV420_PLANAR",
- "YUV422",
- "YUV444",
-
- "RGB_DXT1",
- "RGBA_DXT1",
- "RGBA_DXT3",
- "RGBA_DXT5",
-
- "DEPTH16",
- "DEPTH24",
- "DEPTH32",
- "DEPTH32F",
-
- "STENCIL1",
- "STENCIL4",
- "STENCIL8",
- "STENCIL16",
-
- "DEPTH24_STENCIL8"
- };
-
- debugAssert(code < CODE_NUM);
- return nameArray[code];
-}
-
-
-const ImageFormat* ImageFormat::fromCode(ImageFormat::Code code) {
- switch (code) {
- case ImageFormat::CODE_L8:
- return ImageFormat::L8();
- break;
- case ImageFormat::CODE_L16:
- return ImageFormat::L16();
- break;
- case ImageFormat::CODE_L16F:
- return ImageFormat::L16F();
- break;
- case ImageFormat::CODE_L32F:
- return ImageFormat::L32F();
- break;
-
- case ImageFormat::CODE_A8:
- return ImageFormat::A8();
- break;
- case ImageFormat::CODE_A16:
- return ImageFormat::A16();
- break;
- case ImageFormat::CODE_A16F:
- return ImageFormat::A16F();
- break;
- case ImageFormat::CODE_A32F:
- return ImageFormat::A32F();
- break;
-
- case ImageFormat::CODE_LA4:
- return ImageFormat::LA4();
- break;
- case ImageFormat::CODE_LA8:
- return ImageFormat::LA8();
- break;
- case ImageFormat::CODE_LA16:
- return ImageFormat::LA16();
- break;
- case ImageFormat::CODE_LA16F:
- return ImageFormat::LA16F();
- break;
- case ImageFormat::CODE_LA32F:
- return ImageFormat::LA32F();
- break;
-
- case ImageFormat::CODE_RGB5:
- return ImageFormat::RGB5();
- break;
- case ImageFormat::CODE_RGB5A1:
- return ImageFormat::RGB5A1();
- break;
- case ImageFormat::CODE_RGB8:
- return ImageFormat::RGB8();
- break;
- case ImageFormat::CODE_RGB10:
- return ImageFormat::RGB10();
- break;
- case ImageFormat::CODE_RGB10A2:
- return ImageFormat::RGB10A2();
- break;
- case ImageFormat::CODE_RGB16:
- return ImageFormat::RGB16();
- break;
- case ImageFormat::CODE_RGB16F:
- return ImageFormat::RGB16F();
- break;
- case ImageFormat::CODE_RGB32F:
- return ImageFormat::RGB32F();
- break;
-
- case ImageFormat::CODE_ARGB8:
- return NULL;
-
- case ImageFormat::CODE_BGR8:
- return NULL;
-
- case ImageFormat::CODE_RGBA8:
- return ImageFormat::RGBA8();
- break;
- case ImageFormat::CODE_RGBA16:
- return ImageFormat::RGBA16();
- break;
- case ImageFormat::CODE_RGBA16F:
- return ImageFormat::RGBA16F();
- break;
- case ImageFormat::CODE_RGBA32F:
- return ImageFormat::RGBA32F();
- break;
-
- case ImageFormat::CODE_BAYER_RGGB8:
- case ImageFormat::CODE_BAYER_GRBG8:
- case ImageFormat::CODE_BAYER_GBRG8:
- case ImageFormat::CODE_BAYER_BGGR8:
- case ImageFormat::CODE_BAYER_RGGB32F:
- case ImageFormat::CODE_BAYER_GRBG32F:
- case ImageFormat::CODE_BAYER_GBRG32F:
- case ImageFormat::CODE_BAYER_BGGR32F:
-
- case ImageFormat::CODE_HSV8:
- case ImageFormat::CODE_HSV32F:
-
- case ImageFormat::CODE_RGB_DXT1:
- return ImageFormat::RGB_DXT1();
- break;
- case ImageFormat::CODE_RGBA_DXT1:
- return ImageFormat::RGBA_DXT1();
- break;
- case ImageFormat::CODE_RGBA_DXT3:
- return ImageFormat::RGBA_DXT3();
- break;
- case ImageFormat::CODE_RGBA_DXT5:
- return ImageFormat::RGBA_DXT5();
- break;
-
- case ImageFormat::CODE_DEPTH16:
- return ImageFormat::DEPTH16();
- break;
- case ImageFormat::CODE_DEPTH24:
- return ImageFormat::DEPTH24();
- break;
- case ImageFormat::CODE_DEPTH32:
- return ImageFormat::DEPTH32();
- break;
- case ImageFormat::CODE_DEPTH32F:
- return ImageFormat::DEPTH32F();
- break;
-
- case ImageFormat::CODE_STENCIL1:
- return ImageFormat::STENCIL1();
- break;
- case ImageFormat::CODE_STENCIL4:
- return ImageFormat::STENCIL4();
- break;
- case ImageFormat::CODE_STENCIL8:
- return ImageFormat::STENCIL8();
- break;
- case ImageFormat::CODE_STENCIL16:
- return ImageFormat::STENCIL16();
- break;
-
- case ImageFormat::CODE_DEPTH24_STENCIL8:
- return ImageFormat::DEPTH24_STENCIL8();
- break;
-
- case ImageFormat::CODE_YUV420_PLANAR:
- return ImageFormat::YUV420_PLANAR();
- break;
-
- case ImageFormat::CODE_YUV422:
- return ImageFormat::YUV422();
- break;
-
- case ImageFormat::CODE_YUV444:
- return ImageFormat::YUV444();
- break;
-
- default:
- return NULL;
- }
-}
-
-// Helper variables for defining texture formats
-
-// Is floating point format
-static const bool FLOAT_FORMAT = true;
-static const bool INT_FORMAT = false;
-
-// Is opaque format (no alpha)
-static const bool OPAQUE_FORMAT = true;
-static const bool CLEAR_FORMAT = false;
-
-// Is compressed format (not raw component data)
-static const bool COMP_FORMAT = true;
-static const bool UNCOMP_FORMAT = false;
-
-#define DEFINE_TEXTUREFORMAT_METHOD(name, cmpnts, cmprssd, glf, glbf, lb, rb, gb, bb, db, sb, hbpt, pbpt, gldf, opq, fp, code, cs, bp) \
- const ImageFormat* ImageFormat::name() { \
- static const ImageFormat format(cmpnts, cmprssd, glf, glbf, lb, rb, gb, bb, db, sb, hbpt, pbpt, gldf, opq, fp, code, cs, bp); \
- return &format; }
-
-DEFINE_TEXTUREFORMAT_METHOD(L8, 1, UNCOMP_FORMAT, GL_LUMINANCE8, GL_LUMINANCE, 8, 0, 0, 0, 0, 0, 0, 8, 8, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, CODE_L8, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(L16, 1, UNCOMP_FORMAT, GL_LUMINANCE16, GL_LUMINANCE, 16, 0, 0, 0, 0, 0, 0, 16, 16,GL_UNSIGNED_SHORT, OPAQUE_FORMAT, INT_FORMAT, CODE_L16, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(L16F, 1, UNCOMP_FORMAT, GL_LUMINANCE16F_ARB,GL_LUMINANCE, 16, 0, 0, 0, 0, 0, 0, 16, 16, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, CODE_L16F, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(L32F, 1, UNCOMP_FORMAT, GL_LUMINANCE32F_ARB,GL_LUMINANCE, 32, 0, 0, 0, 0, 0, 0, 32, 32, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, CODE_L32F, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(A8, 1, UNCOMP_FORMAT, GL_ALPHA8, GL_ALPHA, 0, 8, 0, 0, 0, 0, 0, 8, 8, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, CODE_A8, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(A16, 1, UNCOMP_FORMAT, GL_ALPHA16, GL_ALPHA, 0, 16, 0, 0, 0, 0, 0, 16, 16, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, CODE_A16, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(A16F, 1, UNCOMP_FORMAT, GL_ALPHA16F_ARB, GL_ALPHA, 0, 16, 0, 0, 0, 0, 0, 16, 16, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, CODE_A16F, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(A32F, 1, UNCOMP_FORMAT, GL_ALPHA32F_ARB, GL_ALPHA, 0, 32, 0, 0, 0, 0, 0, 32, 32, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, CODE_A32F, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(LA4, 2, UNCOMP_FORMAT, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, 4, 4, 0, 0, 0, 0, 0, 8, 8, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, CODE_LA4, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(LA8, 2, UNCOMP_FORMAT, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, 8, 8, 0, 0, 0, 0, 0, 16, 16, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, CODE_LA8, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(LA16, 2, UNCOMP_FORMAT, GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA, 16, 16, 0, 0, 0, 0, 0, 16*2, 16*2, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, CODE_LA16, COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(LA16F, 2, UNCOMP_FORMAT, GL_LUMINANCE_ALPHA16F_ARB, GL_LUMINANCE_ALPHA, 16, 16, 0, 0, 0, 0, 0, 16*2, 16*2, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_LA16F, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(LA32F, 2, UNCOMP_FORMAT, GL_LUMINANCE_ALPHA32F_ARB, GL_LUMINANCE_ALPHA, 32, 32, 0, 0, 0, 0, 0, 32*2, 32*2, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_LA32F, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(BGR8, 3, UNCOMP_FORMAT, GL_RGB8, GL_BGR, 0, 0, 8, 8, 8, 0, 0, 32, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_BGR8, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB5, 3, UNCOMP_FORMAT, GL_RGB5, GL_RGBA, 0, 0, 5, 5, 5, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB5, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB5A1, 4, UNCOMP_FORMAT, GL_RGB5_A1, GL_RGBA, 0, 1, 5, 5, 5, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB5A1, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB8, 3, UNCOMP_FORMAT, GL_RGB8, GL_RGB, 0, 0, 8, 8, 8, 0, 0, 32, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB8, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB10, 3, UNCOMP_FORMAT, GL_RGB10, GL_RGB, 0, 0, 10, 10, 10, 0, 0, 32, 10*3, GL_UNSIGNED_SHORT, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB10, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB10A2, 4, UNCOMP_FORMAT, GL_RGB10_A2, GL_RGBA, 0, 2, 10, 10, 10, 0, 0, 32, 32, GL_UNSIGNED_INT_10_10_10_2, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB10A2, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB16, 3, UNCOMP_FORMAT, GL_RGB16, GL_RGB, 0, 0, 16, 16, 16, 0, 0, 16*3, 16*3, GL_UNSIGNED_SHORT, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB16, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB16F, 3, UNCOMP_FORMAT, GL_RGB16F_ARB, GL_RGB, 0, 0, 16, 16, 16, 0, 0, 16*3, 16*3, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGB16F, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB32F, 3, UNCOMP_FORMAT, GL_RGB32F_ARB, GL_RGB, 0, 0, 32, 32, 32, 0, 0, 32*3, 32*3, GL_FLOAT, OPAQUE_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGB32F, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGBA8, 4, UNCOMP_FORMAT, GL_RGBA8, GL_RGBA, 0, 8, 8, 8, 8, 0, 0, 32, 32, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA8, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGBA16, 4, UNCOMP_FORMAT, GL_RGBA16, GL_RGBA, 0, 16, 16, 16, 16, 0, 0, 16*4, 16*4, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA16, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGBA16F, 4, UNCOMP_FORMAT, GL_RGBA16F_ARB, GL_RGBA, 0, 16, 16, 16, 16, 0, 0, 16*4, 16*4, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGB16F, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGBA32F, 4, UNCOMP_FORMAT, GL_RGBA32F_ARB, GL_RGBA, 0, 32, 32, 32, 32, 0, 0, 32*4, 32*4, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_RGBA32F, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGB_DXT1, 3, COMP_FORMAT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, 0, 0, 0, 0, 0, 0, 0, 64, 64, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_RGB_DXT1, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGBA_DXT1, 4, COMP_FORMAT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 64, 64, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA_DXT1, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGBA_DXT3, 4, COMP_FORMAT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 128, 128, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA_DXT3, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(RGBA_DXT5, 4, COMP_FORMAT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, 0, 0, 0, 0, 0, 0, 0, 128, 128, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_RGBA_DXT5, ImageFormat::COLOR_SPACE_RGB);
-
-DEFINE_TEXTUREFORMAT_METHOD(DEPTH16, 1, UNCOMP_FORMAT, GL_DEPTH_COMPONENT16_ARB, GL_DEPTH_COMPONENT, 0, 0, 0, 0, 0, 0, 16, 16, 16, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_DEPTH16, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(DEPTH24, 1, UNCOMP_FORMAT, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT, 0, 0, 0, 0, 0, 0, 24, 32, 24, GL_UNSIGNED_INT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_DEPTH24, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(DEPTH32, 1, UNCOMP_FORMAT, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT, 0, 0, 0, 0, 0, 0, 32, 32, 32, GL_UNSIGNED_INT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_DEPTH32, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(DEPTH32F, 1, UNCOMP_FORMAT, GL_DEPTH_COMPONENT32_ARB, GL_DEPTH_COMPONENT, 0, 0, 0, 0, 0, 0, 32, 32, 32, GL_FLOAT, CLEAR_FORMAT, FLOAT_FORMAT, ImageFormat::CODE_DEPTH32F, ImageFormat::COLOR_SPACE_NONE);
-
-// These formats are for use with Renderbuffers only!
-DEFINE_TEXTUREFORMAT_METHOD(STENCIL1, 1, UNCOMP_FORMAT, GL_STENCIL_INDEX1_EXT, GL_STENCIL_INDEX_EXT, 0, 0, 0, 0, 0, 0, 1, 1, 1, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_STENCIL1, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(STENCIL4, 1, UNCOMP_FORMAT, GL_STENCIL_INDEX4_EXT, GL_STENCIL_INDEX_EXT, 0, 0, 0, 0, 0, 0, 4, 4, 4, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_STENCIL4, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(STENCIL8, 1, UNCOMP_FORMAT, GL_STENCIL_INDEX8_EXT, GL_STENCIL_INDEX_EXT, 0, 0, 0, 0, 0, 0, 8, 8, 8, GL_UNSIGNED_BYTE, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_STENCIL8, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(STENCIL16, 1, UNCOMP_FORMAT, GL_STENCIL_INDEX16_EXT, GL_STENCIL_INDEX_EXT, 0, 0, 0, 0, 0, 0, 16, 16, 16, GL_UNSIGNED_SHORT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_STENCIL16, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(DEPTH24_STENCIL8, 2, UNCOMP_FORMAT, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_STENCIL_EXT,0, 0, 0, 0, 0, 24, 8, 32, 32, GL_UNSIGNED_INT, CLEAR_FORMAT, INT_FORMAT, ImageFormat::CODE_DEPTH24_STENCIL8, ImageFormat::COLOR_SPACE_NONE);
-
-DEFINE_TEXTUREFORMAT_METHOD(YUV420_PLANAR, 3, UNCOMP_FORMAT, GL_NONE, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 12, 12, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_YUV420_PLANAR, ImageFormat::COLOR_SPACE_YUV);
-DEFINE_TEXTUREFORMAT_METHOD(YUV422, 3, UNCOMP_FORMAT, GL_NONE, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 16, 16, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_YUV422, ImageFormat::COLOR_SPACE_YUV);
-DEFINE_TEXTUREFORMAT_METHOD(YUV444, 3, UNCOMP_FORMAT, GL_NONE, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 24, 24, GL_UNSIGNED_BYTE, OPAQUE_FORMAT, INT_FORMAT, ImageFormat::CODE_YUV444, ImageFormat::COLOR_SPACE_YUV);
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/ImageFormat_convert.cpp b/externals/g3dlite/G3D.lib/source/ImageFormat_convert.cpp
deleted file mode 100644
index 9cbc4edcb39..00000000000
--- a/externals/g3dlite/G3D.lib/source/ImageFormat_convert.cpp
+++ /dev/null
@@ -1,1305 +0,0 @@
-#include "G3D/ImageFormat.h"
-#include "G3D/Color1uint8.h"
-#include "G3D/Color3uint8.h"
-#include "G3D/Color4uint8.h"
-#include "G3D/Color1.h"
-#include "G3D/Color3.h"
-#include "G3D/Color4.h"
-
-
-namespace G3D {
-
-// this is the signature for all conversion routines (same parameters as ImageFormat::convert)
-typedef void (*ConvertFunc)(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg);
-
-// this defines the conversion routines for converting between compatible formats
-static const int NUM_CONVERT_IMAGE_FORMATS = 5;
-struct ConvertAttributes {
- ConvertFunc m_converter;
- ImageFormat::Code m_sourceFormats[NUM_CONVERT_IMAGE_FORMATS];
- ImageFormat::Code m_destFormats[NUM_CONVERT_IMAGE_FORMATS];
- bool m_handlesSourcePadding;
- bool m_handlesDestPadding;
- bool m_handleInvertY;
-};
-
-// forward declare the converters we can use them below
-#define DECLARE_CONVERT_FUNC(name) static void name(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg);
-
-DECLARE_CONVERT_FUNC(l8_to_rgb8);
-DECLARE_CONVERT_FUNC(l32f_to_rgb8);
-DECLARE_CONVERT_FUNC(rgb8_to_rgba8);
-DECLARE_CONVERT_FUNC(rgb8_to_bgr8);
-DECLARE_CONVERT_FUNC(rgb8_to_rgba32f);
-DECLARE_CONVERT_FUNC(bgr8_to_rgb8);
-DECLARE_CONVERT_FUNC(bgr8_to_rgba8);
-DECLARE_CONVERT_FUNC(bgr8_to_rgba32f);
-DECLARE_CONVERT_FUNC(rgba8_to_rgb8);
-DECLARE_CONVERT_FUNC(rgba8_to_bgr8);
-DECLARE_CONVERT_FUNC(rgba8_to_rgba32f);
-DECLARE_CONVERT_FUNC(rgb32f_to_rgba32f);
-DECLARE_CONVERT_FUNC(rgba32f_to_rgb8);
-DECLARE_CONVERT_FUNC(rgba32f_to_rgba8);
-DECLARE_CONVERT_FUNC(rgba32f_to_bgr8);
-DECLARE_CONVERT_FUNC(rgba32f_to_rgb32f);
-DECLARE_CONVERT_FUNC(rgba32f_to_bayer_rggb8);
-DECLARE_CONVERT_FUNC(rgba32f_to_bayer_gbrg8);
-DECLARE_CONVERT_FUNC(rgba32f_to_bayer_grbg8);
-DECLARE_CONVERT_FUNC(rgba32f_to_bayer_bggr8);
-DECLARE_CONVERT_FUNC(bayer_rggb8_to_rgba32f);
-DECLARE_CONVERT_FUNC(bayer_gbrg8_to_rgba32f);
-DECLARE_CONVERT_FUNC(bayer_grbg8_to_rgba32f);
-DECLARE_CONVERT_FUNC(bayer_bggr8_to_rgba32f);
-DECLARE_CONVERT_FUNC(rgb8_to_yuv420p);
-DECLARE_CONVERT_FUNC(rgb8_to_yuv422);
-DECLARE_CONVERT_FUNC(rgb8_to_yuv444);
-DECLARE_CONVERT_FUNC(yuv420p_to_rgb8);
-DECLARE_CONVERT_FUNC(yuv422_to_rgb8);
-DECLARE_CONVERT_FUNC(yuv444_to_rgb8);
-
-// this is the list of mappings between formats and the routines to perform them
-static const ConvertAttributes sConvertMappings[] = {
-
- // RGB -> RGB color space
- // L8 ->
- {l8_to_rgb8, {ImageFormat::CODE_L8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, true},
-
- // L32F ->
- {l32f_to_rgb8, {ImageFormat::CODE_L32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, true},
-
- // RGB8 ->
- {rgb8_to_rgba8, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, false, false, true},
- {rgb8_to_bgr8, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, false, false, true},
- {rgb8_to_rgba32f, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, true, false, true},
-
- // BGR8 ->
- {bgr8_to_rgb8, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, true},
- {bgr8_to_rgba8, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, false, false, true},
- {bgr8_to_rgba32f, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, true, false, true},
-
- // RGBA8 ->
- {rgba8_to_rgb8, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, true},
- {rgba8_to_bgr8, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, false, false, true},
- {rgba8_to_rgba32f, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, true, false, true},
-
- // RGB32F ->
- {rgb32f_to_rgba32f, {ImageFormat::CODE_RGB32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, true, false, true},
-
- // RGBA32F ->
- {rgba32f_to_rgb8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, true, true},
- {rgba32f_to_rgba8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA8, ImageFormat::CODE_NONE}, false, true, true},
- {rgba32f_to_bgr8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BGR8, ImageFormat::CODE_NONE}, false, true, true},
- {rgba32f_to_rgb32f, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB32F, ImageFormat::CODE_NONE}, false, true, true},
-
- // RGB -> BAYER color space
- {rgba32f_to_bayer_rggb8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BAYER_RGGB8, ImageFormat::CODE_NONE}, false, true, true},
- {rgba32f_to_bayer_gbrg8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BAYER_GBRG8, ImageFormat::CODE_NONE}, false, true, true},
- {rgba32f_to_bayer_grbg8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BAYER_GRBG8, ImageFormat::CODE_NONE}, false, true, true},
- {rgba32f_to_bayer_bggr8, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, {ImageFormat::CODE_BAYER_BGGR8, ImageFormat::CODE_NONE}, false, true, true},
-
- // BAYER -> RGB color space
- {bayer_rggb8_to_rgba32f, {ImageFormat::CODE_BAYER_RGGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, false, false, true},
- {bayer_gbrg8_to_rgba32f, {ImageFormat::CODE_BAYER_GBRG8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, false, false, true},
- {bayer_grbg8_to_rgba32f, {ImageFormat::CODE_BAYER_GRBG8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, false, false, true},
- {bayer_bggr8_to_rgba32f, {ImageFormat::CODE_BAYER_BGGR8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGBA32F, ImageFormat::CODE_NONE}, false, false, true},
-
- // RGB <-> YUV color space
- {rgb8_to_yuv420p, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_YUV420_PLANAR, ImageFormat::CODE_NONE}, false, false, false},
- {rgb8_to_yuv422, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_YUV422, ImageFormat::CODE_NONE}, false, false, false},
- {rgb8_to_yuv444, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, {ImageFormat::CODE_YUV444, ImageFormat::CODE_NONE}, false, false, false},
- {yuv420p_to_rgb8, {ImageFormat::CODE_YUV420_PLANAR, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, false},
- {yuv422_to_rgb8, {ImageFormat::CODE_YUV422, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, false},
- {yuv444_to_rgb8, {ImageFormat::CODE_YUV444, ImageFormat::CODE_NONE}, {ImageFormat::CODE_RGB8, ImageFormat::CODE_NONE}, false, false, false},
-};
-
-static ConvertFunc findConverter(TextureFormat::Code sourceCode, TextureFormat::Code destCode, bool needsSourcePadding, bool needsDestPadding, bool needsInvertY) {
- int numRoutines = sizeof(sConvertMappings) / sizeof(ConvertAttributes);
- for (int routineIndex = 0; routineIndex < numRoutines; ++routineIndex) {
- int sourceIndex = 0;
- ConvertAttributes routine = sConvertMappings[routineIndex];
-
- while (routine.m_sourceFormats[sourceIndex] != ImageFormat::CODE_NONE) {
- // check for matching source
- if (routine.m_sourceFormats[sourceIndex] == sourceCode) {
- int destIndex = 0;
-
- // now check for matching dest to see if the routine fits
- while (routine.m_destFormats[destIndex] != ImageFormat::CODE_NONE) {
-
- // check if dest format matches and padding + invert rules match
- if ((routine.m_destFormats[destIndex] == destCode) &&
- (!needsSourcePadding || (routine.m_handlesSourcePadding == needsSourcePadding)) &&
- (!needsDestPadding || (routine.m_handlesDestPadding == needsDestPadding)) &&
- (!needsInvertY || (routine.m_handleInvertY == needsInvertY))) {
-
- // found compatible converter
- return routine.m_converter;
- }
- ++destIndex;
- }
- }
- ++sourceIndex;
- }
- }
-
- return NULL;
-}
-
-bool conversionAvailable(const ImageFormat* srcFormat, int srcRowPadBits, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY = false) {
- bool conversionAvailable = false;
-
- // check if a conversion is available
- if ( (srcFormat->code == dstFormat->code) && (srcRowPadBits == dstRowPadBits) && !invertY) {
- conversionAvailable = true;
- } else {
- ConvertFunc directConverter = findConverter(srcFormat->code, dstFormat->code, srcRowPadBits > 0, dstRowPadBits > 0, invertY);
-
- conversionAvailable = (directConverter != NULL);
- }
-
- return conversionAvailable;
-}
-
-bool ImageFormat::convert(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits,
- const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits,
- bool invertY, BayerAlgorithm bayerAlg) {
-
- bool conversionAvailable = false;
-
- // Handle direct copy of image to same format
- if ( (srcFormat->code == dstFormat->code) && (srcRowPadBits == dstRowPadBits) && !invertY) {
-
- System::memcpy(dstBytes[0], srcBytes[0], iCeil(((srcWidth * srcFormat->cpuBitsPerPixel + srcRowPadBits) * srcHeight) / 8.0f));
- conversionAvailable = true;
- } else {
- // if no direct conversion routine exists,
- // then look for conversion to intermediate
- // and then from intermediate to dest.
- // intermediate format is RGBA32F
- ConvertFunc directConverter = findConverter(srcFormat->code, dstFormat->code, srcRowPadBits > 0, dstRowPadBits > 0, invertY);
-
- // if we have a direct converter, use it, otherwise find intermdiate path
- if (directConverter) {
- directConverter(srcBytes, srcWidth, srcHeight, srcFormat, srcRowPadBits, dstBytes, dstFormat, dstRowPadBits, invertY, bayerAlg);
- conversionAvailable = true;
- } else {
- ConvertFunc toInterConverter = findConverter(srcFormat->code, ImageFormat::CODE_RGBA32F, srcRowPadBits > 0, false, false);;
- ConvertFunc fromInterConverter = findConverter(ImageFormat::CODE_RGBA32F, dstFormat->code, false, dstRowPadBits > 0, invertY);;
-
- if (toInterConverter && fromInterConverter) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * ImageFormat::RGBA32F()->cpuBitsPerPixel * 8));
-
- toInterConverter(srcBytes, srcWidth, srcHeight, srcFormat, srcRowPadBits, tmp, ImageFormat::RGBA32F(), 0, false, bayerAlg);
- fromInterConverter(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, dstBytes, dstFormat, dstRowPadBits, invertY, bayerAlg);
-
- System::free(tmp[0]);
-
- conversionAvailable = true;
- }
- }
- }
-
- return conversionAvailable;
-}
-
-
-// *******************
-// RGB -> RGB color space conversions
-// *******************
-
-// L8 ->
-static void l8_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
- int i3 = i * 3;
-
- dst[i3 + 0] = src[i];
- dst[i3 + 1] = src[i];
- dst[i3 + 2] = src[i];
- }
- }
-}
-
-// L32F ->
-static void l32f_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- int srcIndex = 0;
- int dstByteOffset = 0;
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const float* src = static_cast<const float*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- srcIndex = srcWidth * (srcHeight - y - 1);
- }
-
- for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 3) {
- Color3uint8& d = *reinterpret_cast<Color3uint8*>(dst + dstByteOffset);
- float s = src[srcIndex];
-
- uint8 c = iMin(255, iFloor(s * 256));
- d = Color3uint8(c, c, c);
- }
- }
-}
-
-// RGB8 ->
-static void rgb8_to_rgba8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
- int i3 = i * 3;
- int i4 = i3 + i;
-
- dst[i4 + 0] = src[i3 + 0];
- dst[i4 + 1] = src[i3 + 1];
- dst[i4 + 2] = src[i3 + 2];
- dst[i4 + 3] = 255;
- }
- }
-}
-
-static void rgb8_to_bgr8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
- int i3 = i * 3;
- dst[i3 + 0] = src[i3 + 2];
- dst[i3 + 1] = src[i3 + 1];
- dst[i3 + 2] = src[i3 + 0];
- }
- }
-}
-
-static void rgb8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits % 8 == 0, "Source row padding must be a multiple of 8 bits for this format");
-
- int dstIndex = 0;
- int srcByteOffset = 0;
- int srcRowPadBytes = srcRowPadBits / 8;
- Color4* dst = static_cast<Color4*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- dstIndex = srcWidth * (srcHeight - 1 - y);
- }
- for (int x = 0; x < srcWidth; ++x, ++dstIndex, srcByteOffset += 3) {
- const Color3uint8& s = *reinterpret_cast<const Color3uint8*>(src + srcByteOffset);
- dst[dstIndex] = Color4(Color3(s), 1.0f);
- }
- srcByteOffset += srcRowPadBytes;
- }
-}
-
-// BGR8 ->
-static void bgr8_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
- int i3 = i * 3;
- dst[i3 + 0] = src[i3 + 2];
- dst[i3 + 1] = src[i3 + 1];
- dst[i3 + 2] = src[i3 + 0];
- }
- }
-}
-
-static void bgr8_to_rgba8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
- int i3 = i * 3;
- int i4 = i3 + i;
-
- dst[i4 + 0] = src[i3 + 2];
- dst[i4 + 1] = src[i3 + 1];
- dst[i4 + 2] = src[i3 + 0];
- dst[i4 + 3] = 255;
- }
- }
-}
-
-static void bgr8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits % 8 == 0, "Source row padding must be a multiple of 8 bits for this format");
-
- int dstIndex = 0;
- int srcByteOffset = 0;
- int srcRowPadBytes = srcRowPadBits / 8;
- Color4* dst = static_cast<Color4*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- dstIndex = srcWidth * (srcHeight - 1 - y);
- }
-
- for (int x = 0; x < srcWidth; ++x, ++dstIndex, srcByteOffset += 3) {
- const Color3uint8& s = *reinterpret_cast<const Color3uint8*>(src + srcByteOffset);
- dst[dstIndex] = Color4(Color3(s).bgr(), 1.0f);
- }
- srcByteOffset += srcRowPadBytes;
- }
-}
-
-// RGBA8 ->
-static void rgba8_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
- int i3 = i * 3;
- int i4 = i3 + i;
-
- dst[i3 + 0] = src[i4 + 0];
- dst[i3 + 1] = src[i4 + 1];
- dst[i3 + 2] = src[i4 + 2];
- }
- }
-}
-
-static void rgba8_to_bgr8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- int i = (invertY) ? ((srcHeight-1-y) * srcWidth +x) : (y * srcWidth + x);
- int i3 = i * 3;
- int i4 = i3 + i;
-
- dst[i3 + 0] = src[i4 + 2];
- dst[i3 + 1] = src[i4 + 1];
- dst[i3 + 2] = src[i4 + 0];
- }
- }
-}
-
-static void rgba8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits % 8 == 0, "Source row padding must be a multiple of 8 bits for this format");
-
- int dstIndex = 0;
- int srcByteOffset = 0;
- int srcRowPadBytes = srcRowPadBits / 8;
- Color4* dst = static_cast<Color4*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- dstIndex = srcWidth * (srcHeight - 1 - y);
- }
-
- for (int x = 0; x < srcWidth; ++x, ++dstIndex, srcByteOffset += 4) {
- const Color4uint8& s = *reinterpret_cast<const Color4uint8*>(src + srcByteOffset);
- dst[dstIndex] = Color4(s);
- }
- srcByteOffset += srcRowPadBytes;
- }
-}
-
-// RGB32F ->
-static void rgb32f_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits % 8 == 0, "Source row padding must be a multiple of 8 bits for this format");
-
- int dstIndex = 0;
- int srcByteOffset = 0;
- int srcRowPadBytes = srcRowPadBits / 8;
- Color4* dst = static_cast<Color4*>(dstBytes[0]);
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- dstIndex = srcWidth * (srcHeight - 1 - y);
- }
-
- for (int x = 0; x < srcWidth; ++x, ++dstIndex, srcByteOffset += 3 * sizeof(float)) {
- const Color3& s = *reinterpret_cast<const Color3*>(src + srcByteOffset);
- dst[dstIndex] = Color4(Color3(s), 1.0f);
- }
- srcByteOffset += srcRowPadBytes;
- }
-}
-
-// RGBA32F ->
-static void rgba32f_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(dstRowPadBits % 8 == 0, "Destination row padding must be a multiple of 8 bits for this format");
-
- int srcIndex = 0;
- int dstByteOffset = 0;
- int dstRowPadBytes = dstRowPadBits / 8;
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const Color4* src = static_cast<const Color4*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- srcIndex = srcWidth * (srcHeight - y - 1);
- }
-
- for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 3) {
- Color3uint8& d = *reinterpret_cast<Color3uint8*>(dst + dstByteOffset);
- const Color4& s = src[srcIndex];
-
- d = Color3uint8(s.rgb());
- }
- dstByteOffset += dstRowPadBytes;
- }
-}
-
-static void rgba32f_to_rgba8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(dstRowPadBits % 8 == 0, "Destination row padding must be a multiple of 8 bits for this format");
-
- int srcIndex = 0;
- int dstByteOffset = 0;
- int dstRowPadBytes = dstRowPadBits / 8;
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const Color4* src = static_cast<const Color4*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- srcIndex = srcWidth * (srcHeight - 1 - y);
- }
- for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 4) {
- Color4uint8& d = *reinterpret_cast<Color4uint8*>(dst + dstByteOffset);
- const Color4& s = src[srcIndex];
-
- d = Color4uint8(s);
- }
- dstByteOffset += dstRowPadBytes;
- }
-}
-
-static void rgba32f_to_bgr8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(dstRowPadBits % 8 == 0, "Destination row padding must be a multiple of 8 bits for this format");
-
- int srcIndex = 0;
- int dstByteOffset = 0;
- int dstRowPadBytes = dstRowPadBits / 8;
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const Color4* src = static_cast<const Color4*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- srcIndex = srcWidth * (srcHeight - y - 1);
- }
-
- for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 3) {
- Color3uint8& d = *reinterpret_cast<Color3uint8*>(dst + dstByteOffset);
- const Color4& s = src[srcIndex];
-
- d = Color3uint8(s.rgb()).bgr();
- }
- dstByteOffset += dstRowPadBytes;
- }
-}
-
-static void rgba32f_to_rgb32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(dstRowPadBits % 8 == 0, "Destination row padding must be a multiple of 8 bits for this format");
-
- int srcIndex = 0;
- int dstByteOffset = 0;
- int dstRowPadBytes = dstRowPadBits / 8;
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
- const Color4* src = static_cast<const Color4*>(srcBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- if (invertY) {
- srcIndex = srcWidth * (srcHeight - 1 - y);
- }
- for (int x = 0; x < srcWidth; ++x, ++srcIndex, dstByteOffset += 3 * sizeof(float)) {
- Color3& d = *reinterpret_cast<Color3*>(dst + dstByteOffset);
- const Color4& s = src[srcIndex];
- d = Color3(s);
- }
- dstByteOffset += dstRowPadBytes;
- }
-}
-
-// *******************
-// RGB <-> YUV color space conversions
-// *******************
-
-static uint32 blendPixels(uint32 pixel1, uint32 pixel2) {
- static const uint32 rbMask = 0x00FF00FF;
- static const uint32 agMask = 0xFF00FF00;
-
- // Compute two color channels at a time. Use >> 1 for fast division by two
- // Using alternating color channels prevents overflow
- const uint32 rb = ((pixel1 & rbMask) + (pixel2 & rbMask)) >> 1;
-
- // Shift first to avoid overflow in alpha channel
- const uint32 ag = (((pixel1 & agMask) >> 1) + ((pixel2 & agMask) >> 1));
-
- return ((rb & rbMask) | (ag & agMask));
-}
-
-#define PIXEL_RGB8_TO_YUV_Y(r, g, b) static_cast<uint8>(iClamp(((66 * r + 129 * g + 25 * b + 128) >> 8) + 16, 0, 255))
-#define PIXEL_RGB8_TO_YUV_U(r, g, b) static_cast<uint8>(iClamp(((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128, 0, 255))
-#define PIXEL_RGB8_TO_YUV_V(r, g, b) static_cast<uint8>(iClamp(((112 * r - 94 * g - 18 * b + 128) >> 8) + 128, 0, 255))
-
-static void rgb8_to_yuv420p(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
- debugAssertM((srcWidth % 2 == 0) && (srcHeight % 2 == 0), "Source width and height must be a multiple of two");
-
- const Color3uint8* src = static_cast<const Color3uint8*>(srcBytes[0]);
-
- uint8* dstY = static_cast<uint8*>(dstBytes[0]);
- uint8* dstU = static_cast<uint8*>(dstBytes[1]);
- uint8* dstV = static_cast<uint8*>(dstBytes[2]);
-
- for (int y = 0; y < srcHeight; y += 2) {
- for (int x = 0; x < srcWidth; x += 2) {
-
- // convert 4-pixel block at a time
- int srcPixelOffset0 = y * srcWidth + x;
- int srcPixelOffset1 = srcPixelOffset0 + 1;
- int srcPixelOffset2 = srcPixelOffset0 + srcWidth;
- int srcPixelOffset3 = srcPixelOffset2 + 1;
-
- int yIndex = y * srcWidth + x;
-
- dstY[yIndex] = PIXEL_RGB8_TO_YUV_Y(src[srcPixelOffset0].r, src[srcPixelOffset0].g, src[srcPixelOffset0].b);
- dstY[yIndex + 1] = PIXEL_RGB8_TO_YUV_Y(src[srcPixelOffset1].r, src[srcPixelOffset1].g, src[srcPixelOffset1].b);
-
- yIndex += srcWidth;
- dstY[yIndex] = PIXEL_RGB8_TO_YUV_Y(src[srcPixelOffset2].r, src[srcPixelOffset2].g, src[srcPixelOffset2].b);
- dstY[yIndex + 1] = PIXEL_RGB8_TO_YUV_Y(src[srcPixelOffset3].r, src[srcPixelOffset3].g, src[srcPixelOffset3].b);
-
- uint32 blendedPixel = blendPixels(src[srcPixelOffset0].asUInt32(), src[srcPixelOffset2].asUInt32());
- Color3uint8 uvSrcColor = Color3uint8::fromARGB(blendedPixel);
-
- int uvIndex = y / 2 * srcWidth / 2 + x / 2;
- dstU[uvIndex] = PIXEL_RGB8_TO_YUV_U(uvSrcColor.r, uvSrcColor.g, uvSrcColor.b);
- dstV[uvIndex] = PIXEL_RGB8_TO_YUV_V(uvSrcColor.r, uvSrcColor.g, uvSrcColor.b);
- }
- }
-}
-
-static void rgb8_to_yuv422(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
- debugAssertM((srcWidth % 2 == 0), "Source width must be a multiple of two");
-
- const Color3uint8* src = static_cast<const Color3uint8*>(srcBytes[0]);
-
- uint8* dst = static_cast<uint8*>(dstBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; x += 2) {
-
- // convert 2-pixel horizontal block at a time
- int srcIndex = y * srcWidth + x;
- int dstIndex = srcIndex * 2;
-
- uint32 blendedPixel = blendPixels(src[srcIndex].asUInt32(), src[srcIndex + 1].asUInt32());
- Color3uint8 uvSrcColor = Color3uint8::fromARGB(blendedPixel);
-
- dst[dstIndex] = PIXEL_RGB8_TO_YUV_Y(src[srcIndex].r, src[srcIndex].g, src[srcIndex].b);
-
- dst[dstIndex + 1] = PIXEL_RGB8_TO_YUV_U(uvSrcColor.r, uvSrcColor.g, uvSrcColor.b);
-
- dst[dstIndex + 2] = PIXEL_RGB8_TO_YUV_Y(src[srcIndex + 1].r, src[srcIndex + 1].g, src[srcIndex + 1].b);
-
- dst[dstIndex + 3] = PIXEL_RGB8_TO_YUV_V(uvSrcColor.r, uvSrcColor.g, uvSrcColor.b);
-
- }
- }
-}
-
-static void rgb8_to_yuv444(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
-
- const Color3uint8* src = static_cast<const Color3uint8*>(srcBytes[0]);
-
- Color3uint8* dst = static_cast<Color3uint8*>(dstBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
-
- // convert 1-pixels at a time
- int index = y * srcWidth + x;
- uint8 y = PIXEL_RGB8_TO_YUV_Y(src[index].r, src[index].g, src[index].b);
- uint8 u = PIXEL_RGB8_TO_YUV_U(src[index].r, src[index].g, src[index].b);
- uint8 v = PIXEL_RGB8_TO_YUV_V(src[index].r, src[index].g, src[index].b);
-
- dst[index].r = y;
- dst[index].g = u;
- dst[index].b = v;
- }
- }
-}
-
-
-#define PIXEL_YUV_TO_RGB8_R(y, u, v) static_cast<uint8>(iClamp((298 * (y - 16) + 409 * (v - 128) + 128) >> 8, 0, 255))
-#define PIXEL_YUV_TO_RGB8_G(y, u, v) static_cast<uint8>(iClamp((298 * (y - 16) - 100 * (u - 128) - 208 * (v - 128) + 128) >> 8, 0, 255))
-#define PIXEL_YUV_TO_RGB8_B(y, u, v) static_cast<uint8>(iClamp((298 * (y - 16) + 516 * (u - 128) + 128) >> 8, 0, 255))
-
-static void yuv420p_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
- debugAssertM((srcWidth % 2 == 0) && (srcHeight % 2 == 0), "Source width and height must be a multiple of two");
-
- const uint8* srcY = static_cast<const uint8*>(srcBytes[0]);
- const uint8* srcU = static_cast<const uint8*>(srcBytes[1]);
- const uint8* srcV = static_cast<const uint8*>(srcBytes[2]);
-
- Color3uint8* dst = static_cast<Color3uint8*>(dstBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; x += 2) {
-
- // convert to two rgb pixels in a row
- Color3uint8* rgb = &dst[y * srcWidth + x];
-
- int yOffset = y * srcWidth + x;
- int uvOffset = y / 2 * srcWidth / 2 + x / 2;
-
- rgb->r = PIXEL_YUV_TO_RGB8_R(srcY[yOffset], srcU[uvOffset], srcV[uvOffset]);
- rgb->g = PIXEL_YUV_TO_RGB8_G(srcY[yOffset], srcU[uvOffset], srcV[uvOffset]);
- rgb->b = PIXEL_YUV_TO_RGB8_B(srcY[yOffset], srcU[uvOffset], srcV[uvOffset]);
-
- rgb += 1;
- rgb->r = PIXEL_YUV_TO_RGB8_R(srcY[yOffset + 1], srcU[uvOffset], srcV[uvOffset]);
- rgb->g = PIXEL_YUV_TO_RGB8_G(srcY[yOffset + 1], srcU[uvOffset], srcV[uvOffset]);
- rgb->b = PIXEL_YUV_TO_RGB8_B(srcY[yOffset + 1], srcU[uvOffset], srcV[uvOffset]);
- }
- }
-}
-
-static void yuv422_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
- debugAssertM((srcWidth % 2 == 0), "Source width must be a multiple of two");
-
- const uint8* src = static_cast<const uint8*>(srcBytes[0]);
-
- Color3uint8* dst = static_cast<Color3uint8*>(dstBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; x += 2) {
-
- // convert to two rgb pixels in a row
- Color3uint8* rgb = &dst[y * srcWidth + x];
-
- int srcIndex = (y * srcWidth + x) * 2;
- uint8 y = src[srcIndex];
- uint8 u = src[srcIndex + 1];
- uint8 y2 = src[srcIndex + 2];
- uint8 v = src[srcIndex + 3];
-
- rgb->r = PIXEL_YUV_TO_RGB8_R(y, u, v);
- rgb->g = PIXEL_YUV_TO_RGB8_G(y, u, v);
- rgb->b = PIXEL_YUV_TO_RGB8_B(y, u, v);
-
- rgb += 1;
- rgb->r = PIXEL_YUV_TO_RGB8_R(y2, u, v);
- rgb->g = PIXEL_YUV_TO_RGB8_G(y2, u, v);
- rgb->b = PIXEL_YUV_TO_RGB8_B(y2, u, v);
- }
- }
-}
-
-static void yuv444_to_rgb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- debugAssertM(srcRowPadBits == 0, "Source row padding must be 0 for this format");
-
- const Color3uint8* src = static_cast<const Color3uint8*>(srcBytes[0]);
-
- Color3uint8* dst = static_cast<Color3uint8*>(dstBytes[0]);
-
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
-
- // convert to one rgb pixels at a time
- int index = y * srcWidth + x;
- Color3uint8* rgb = &dst[index];
-
- rgb->r = PIXEL_YUV_TO_RGB8_R(src[index].r, src[index].g, src[index].b);
- rgb->g = PIXEL_YUV_TO_RGB8_G(src[index].r, src[index].g, src[index].b);
- rgb->b = PIXEL_YUV_TO_RGB8_B(src[index].r, src[index].g, src[index].b);
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// Bayer conversions
-//
-
-// There are two kinds of rows (GR and BG).
-// In each row, there are two kinds of pixels (G/R, B/G).
-// We express the four kinds of INPUT pixels as:
-// GRG, GRG, BGB, BGG
-//
-// There are three kinds of OUTPUT pixels: R, G, B.
-// Thus there are nominally 12 different I/O combinations,
-// but several are impulses because needed output at that
-// location *is* the input (e.g., G_GRG and G_BGG).
-//
-// The following 5x5 row-major filters are named as output_input.
-
-// Green
-static const float G_GRR[5][5] =
- {{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
- { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
- { -1.0f, 2.0f, 4.0f, 2.0f, -1.0f},
- { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
- { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
-
-static const float G_BGB[5][5] =
- {{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
- { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
- { -1.0f, 2.0f, 4.0f, 2.0f, -1.0f},
- { 0.0f, 0.0f, 2.0f, 0.0f, 0.0f},
- { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
-
-// Red
-//(the caption in the paper is wrong for this case:
-// "R row B column really means R row G column"
-static const float R_GRG[5][5] =
- {{ 0.0f, 0.0f, 0.5f, 0.0f, 0.0f},
- { 0.0f, -1.0f, 0.0f, -1.0f, 0.0f},
- { -1.0f, 4.0f, 5.0f, 4.0f, -1.0f},
- { 0.0f, -1.0f, 0.0f, -1.0f, 0.0f},
- { 0.0f, 0.0f, 0.5f, 0.0f, 0.0f}};
-
-static const float R_BGG[5][5] =
- {{ 0.0f, 0.0f, -1.0f, 0.0f, 0.0f},
- { 0.0f, -1.0f, 4.0f, -1.0f, 0.0f},
- { 0.5f, 0.0f, 5.0f, 0.0f, 0.5f},
- { 0.0f, -1.0f, 4.0f, -1.0f, 0.0f},
- { 0.0f, 0.0f, -1.0f, 0.0f, 0.0f}};
-
-static const float R_BGB[5][5] =
- {{ 0.0f, 0.0f, -3.0f/2.0f, 0.0f, 0.0f},
- { 0.0f, 2.0f, 0.0f, 2.0f, 0.0f},
- {-3.0f/2.0f, 0.0f, 6.0f, 0.0f, -3.0f/2.0f},
- { 0.0f, 2.0f, 0.0f, 2.0f, 0.0f},
- { 0.0f, 0.0f, -3.0f/2.0f, 0.0f, 0.0f}};
-
-
-// Blue
-//(the caption in the paper is wrong for this case:
-// "B row R column really means B row G column")
-#define B_BGG R_GRG
-#define B_GRG R_BGG
-#define B_GRR R_BGB
-
-// =====================================================================
-// Helper methods
-// =====================================================================
-
-
-/** Applies a 5x5 filter to monochrome image I (wrapping at the boundaries) */
-static uint8 applyFilter(const uint8* I,
- int x,
- int y,
- int w,
- int h,
- const float filter[5][5]) {
-
- debugAssert(isEven(w));
- debugAssert(isEven(h));
-
- float sum = 0.0f;
- float denom = 0.0f;
-
- for (int dy = 0; dy < 5; ++dy) {
- int offset = ((y + dy + h - 2) % h) * w;
-
- for (int dx = 0; dx < 5; ++dx) {
- float f = filter[dy][dx];
- sum += f * I[((x + dx + w - 2) % w) + offset];
- denom += f;
- }
- }
-
- return (uint8)iClamp(iRound(sum / denom), 0, 255);
-}
-
-/** Helper method for Bayer grbg and bggr --> rgb8 */
-static void swapRedAndBlue(int N, Color3uint8* out) {
- for (int i = N - 1; i >= 0; --i) {
- uint8 tmp = out[i].r;
- out[i].r = out[i].b;
- out[i].b = tmp;
- }
-}
-
-// RGB -> BAYER color space
-
-// =====================================================================
-// rgb8 --> bayer helpers
-// =====================================================================
-static void rgb8_to_bayer_rggb8(const int w, const int h,
- const uint8* src, uint8* dst) {
- Color3uint8* srcColor = (Color3uint8*)src;
- Color1uint8* dstColor = (Color1uint8*)dst;
-
- // Top row pixels
- for (int y = 0; y < h - 1; y += 2) {
- int offset = y * w;
-
- // Top left pixels
- for(int x = 0; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].r);
- }
-
- // Top right pixels
- for(int x = 1; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].g);
- }
- }
-
- // Bottom row pixels
- for (int y = 1; y < h - 1; y += 2) {
- int offset = y * w;
-
- // Bottom left pixels
- for (int x = 0; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].g);
- }
-
- // Bottom right pixels
- for (int x = 1; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].b);
- }
- }
-}
-
-
-static void rgb8_to_bayer_grbg8(const int w, const int h,
- const uint8* src, uint8* dst) {
- Color3uint8* srcColor = (Color3uint8*)src;
- Color1uint8* dstColor = (Color1uint8*)dst;
-
- // Top row pixels
- for (int y = 0; y < h - 1; y += 2) {
- int offset = y * w;
-
- // Top left pixels
- for (int x = 0; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].g);
- }
-
- // Top right pixels
- for (int x = 1; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].r);
- }
- }
-
- // Bottom row pixels
- for (int y = 1; y < h - 1; y += 2) {
- int offset = y * w;
-
- // Bottom left pixels
- for (int x = 0; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].b);
- }
-
- // Bottom right pixels
- for (int x = 1; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].g);
- }
- }
-}
-
-
-static void rgb8_to_bayer_bggr8(const int w, const int h,
- const uint8* src, uint8* dst) {
- Color3uint8* srcColor = (Color3uint8*)src;
- Color1uint8* dstColor = (Color1uint8*)dst;
-
- // Top row pixels
- for (int y = 0; y < h - 1; y += 2) {
- int offset = y * w;
-
- // Top left pixels
- for (int x = 0; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].b);
- }
-
- // Top right pixels
- for (int x = 1; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].g);
- }
- }
-
- // Bottom row pixels
- for (int y = 1; y < h - 1; y += 2) {
- int offset = y * w;
-
- // Bottom left pixels
- for(int x = 0; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].g);
- }
-
- // Bottom right pixels
- for(int x = 1; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].r);
- }
- }
-}
-
-
-static void rgb8_to_bayer_gbrg8(const int w, const int h,
- const uint8* src, uint8* dst) {
- Color3uint8* srcColor = (Color3uint8*)src;
- Color1uint8* dstColor = (Color1uint8*)dst;
-
- // Top row pixels
- for(int y = 0; y < h - 1; y += 2) {
- int offset = y * w;
-
- // Top left pixels
- for(int x = 0; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].g);
- }
-
- // Top right pixels
- for(int x = 1; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].b);
- }
- }
-
- // Bottom row pixels
- for(int y = 1; y < h - 1; y += 2) {
- int offset = y * w;
-
- // Bottom left pixels
- for(int x = 0; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].r);
- }
-
- // Bottom right pixels
- for(int x = 1; x < w - 1; x += 2) {
- dstColor[x + offset] = Color1(srcColor[x + offset].g);
- }
- }
-}
-
-// =====================================================================
-// rgba32f (-->rgb8) --> bayer converter implementations
-// =====================================================================
-static void rgba32f_to_bayer_rggb8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
-
- rgba32f_to_rgb8(srcBytes, srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, tmp, ImageFormat::RGB8(), 0, invertY, bayerAlg);
- rgb8_to_bayer_rggb8(srcWidth, srcHeight, static_cast<uint8*>(tmp[0]), static_cast<uint8*>(dstBytes[0]));
-
- System::free(tmp[0]);
-}
-
-static void rgba32f_to_bayer_gbrg8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
-
- rgba32f_to_rgb8(srcBytes, srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, tmp, ImageFormat::RGB8(), 0, invertY, bayerAlg);
- rgb8_to_bayer_grbg8(srcWidth, srcHeight, static_cast<uint8*>(tmp[0]), static_cast<uint8*>(dstBytes[0]));
-
- System::free(tmp[0]);
-}
-
-static void rgba32f_to_bayer_grbg8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
-
- rgba32f_to_rgb8(srcBytes, srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, tmp, ImageFormat::RGB8(), 0, invertY, bayerAlg);
- rgb8_to_bayer_gbrg8(srcWidth, srcHeight, static_cast<uint8*>(tmp[0]), static_cast<uint8*>(dstBytes[0]));
-
- System::free(tmp[0]);
-}
-
-static void rgba32f_to_bayer_bggr8(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
-
- rgba32f_to_rgb8(srcBytes, srcWidth, srcHeight, ImageFormat::RGBA32F(), 0, tmp, ImageFormat::RGB8(), 0, invertY, bayerAlg);
- rgb8_to_bayer_bggr8(srcWidth, srcHeight, static_cast<uint8*>(tmp[0]), static_cast<uint8*>(dstBytes[0]));
-
- System::free(tmp[0]);
-}
-
-// BAYER -> RGB color space
-
-// =====================================================================
-// bayer --> rgb8 helpers
-// =====================================================================
-static void bayer_rggb8_to_rgb8_mhc(int w, int h,
- const uint8* in, uint8* _out) {
- debugAssert(in != _out);
-
- Color3uint8* out = (Color3uint8*)_out;
-
- for (int y = 0; y < h; ++y) {
-
- // Row beginning in the input array.
- int offset = y * w;
-
- // RG row
- for (int x = 0; x < w; ++x, ++out) {
- // R pixel
- {
- out->r = in[x + offset];
- out->g = applyFilter(in, x, y, w, h, G_GRR);
- out->b = applyFilter(in, x, y, w, h, B_GRR);
- }
- ++x; ++out;
-
- // G pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_GRG);
- out->g = in[x + offset];
- out->b = applyFilter(in, x, y, w, h, B_GRG);
- }
- }
-
- ++y;
- offset += w;
-
- // GB row
- for (int x = 0; x < w; ++x, ++out) {
- // G pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_BGG);
- out->g = in[x + offset];
- out->b = applyFilter(in, x, y, w, h, B_BGG);
- }
- ++x; ++out;
-
- // B pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_BGB);
- out->g = applyFilter(in, x, y, w, h, G_BGB);
- out->b = in[x + offset];
- }
- }
- }
-}
-
-
-
-static void bayer_gbrg8_to_rgb8_mhc(int w, int h,
- const uint8* in, uint8* _out) {
-
- debugAssert(in != _out);
-
- Color3uint8* out = (Color3uint8*)_out;
-
- for (int y = 0; y < h; ++y) {
-
- // Row beginning in the input array.
- int offset = y * w;
-
- // GB row
- for (int x = 0; x < w; ++x, ++out) {
- // G pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_BGG);
- out->g = in[x + offset];
- out->b = applyFilter(in, x, y, w, h, B_BGG);
- }
- ++x; ++out;
-
- // B pixel
- {
- out->r = applyFilter(in, x, y, w, h, R_BGB);
- out->g = applyFilter(in, x, y, w, h, G_BGB);
- out->b = in[x + offset];
- }
- }
- }
-}
-
-
-static void bayer_grbg8_to_rgb8_mhc(int w, int h,
- const uint8* in, uint8* _out) {
- // Run the equivalent function for red
- bayer_gbrg8_to_rgb8_mhc(w, h, in, _out);
-
- // Now swap red and blue
- swapRedAndBlue(w * h, (Color3uint8*)_out);
-}
-
-
-static void bayer_bggr8_to_rgb8_mhc(int w, int h,
- const uint8* in, uint8* _out) {
- // Run the equivalent function for red
- bayer_rggb8_to_rgb8_mhc(w, h, in, _out);
-
- // Now swap red and blue
- swapRedAndBlue(w * h, (Color3uint8*)_out);
-}
-
-// =====================================================================
-// bayer (--> rgb8) --> rgba32f converter implementations
-// =====================================================================
-static void bayer_rggb8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
-
- bayer_rggb8_to_rgb8_mhc(srcWidth, srcHeight, static_cast<const uint8*>(srcBytes[0]), static_cast<uint8*>(tmp[0]));
- rgb8_to_rgba32f(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGB8(), 0, dstBytes, ImageFormat::RGBA32F(), 0, invertY, bayerAlg);
-
- System::free(tmp[0]);
-}
-
-static void bayer_gbrg8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
-
- bayer_grbg8_to_rgb8_mhc(srcWidth, srcHeight, static_cast<const uint8*>(srcBytes[0]), static_cast<uint8*>(tmp[0]));
- rgb8_to_rgba32f(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGB8(), 0, dstBytes, ImageFormat::RGBA32F(), 0, invertY, bayerAlg);
-
- System::free(tmp[0]);
-}
-
-static void bayer_grbg8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
-
- bayer_gbrg8_to_rgb8_mhc(srcWidth, srcHeight, static_cast<const uint8*>(srcBytes[0]), static_cast<uint8*>(tmp[0]));
- rgb8_to_rgba32f(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGB8(), 0, dstBytes, ImageFormat::RGBA32F(), 0, invertY, bayerAlg);
-
- System::free(tmp[0]);
-}
-
-static void bayer_bggr8_to_rgba32f(const Array<const void*>& srcBytes, int srcWidth, int srcHeight, const ImageFormat* srcFormat, int srcRowPadBits, const Array<void*>& dstBytes, const ImageFormat* dstFormat, int dstRowPadBits, bool invertY, ImageFormat::BayerAlgorithm bayerAlg) {
- Array<void*> tmp;
- tmp.append(System::malloc(srcWidth * srcHeight * sizeof(Color3uint8)));
-
- bayer_bggr8_to_rgb8_mhc(srcWidth, srcHeight, static_cast<const uint8*>(srcBytes[0]), static_cast<uint8*>(tmp[0]));
- rgb8_to_rgba32f(reinterpret_cast<Array<const void*>&>(tmp), srcWidth, srcHeight, ImageFormat::RGB8(), 0, dstBytes, ImageFormat::RGBA32F(), 0, invertY, bayerAlg);
-
- System::free(tmp[0]);
-}
-
-
-
-
-
- // TODO: The following region is commented out because so far
- // those conversions are not used anywhere else. Until it is
- // decided that such conversions are not needed, this region
- // remains commented out.
-
-
-// // =====================================================================
-// // bayer --> bgr8
-// // =====================================================================
-
-// static void bayer_rggb8_to_bgr8_mhc(int w, int h,
-// const uint8* in, uint8* _out) {
-// debugAssert(in != _out);
-
-// Color3uint8* out = (Color3uint8*)_out;
-
-// for (int y = 0; y < h; ++y) {
-
-// // Row beginning in the input array.
-// int offset = y * w;
-
-// // RG row
-// for (int x = 0; x < w; ++x, ++out) {
-// // R pixel
-// {
-// out->b = in[x + offset];
-// out->g = applyFilter(in, x, y, w, h, G_GRR);
-// out->r = applyFilter(in, x, y, w, h, B_GRR);
-// }
-// ++x; ++out;
-
-// // G pixel
-// {
-// out->b = applyFilter(in, x, y, w, h, R_GRG);
-// out->g = in[x + offset];
-// out->r = applyFilter(in, x, y, w, h, B_GRG);
-// }
-// }
-
-// ++y;
-// offset += w;
-
-// // GB row
-// for (int x = 0; x < w; ++x, ++out) {
-// // G pixel
-// {
-// out->b = applyFilter(in, x, y, w, h, R_BGG);
-// out->g = in[x + offset];
-// out->r = applyFilter(in, x, y, w, h, B_BGG);
-// }
-// ++x; ++out;
-
-// // B pixel
-// {
-// out->b = applyFilter(in, x, y, w, h, R_BGB);
-// out->g = applyFilter(in, x, y, w, h, G_BGB);
-// out->r = in[x + offset];
-// }
-// }
-// }
-// }
-
-
-// static void bayer_gbrg8_to_bgr8_mhc(int w, int h,
-// const uint8* in, uint8* _out) {
-
-// debugAssert(in != _out);
-
-// Color3uint8* out = (Color3uint8*)_out;
-
-// for (int y = 0; y < h; ++y) {
-
-// // Row beginning in the input array.
-// int offset = y * w;
-
-// // GB row
-// for (int x = 0; x < srcWidth; ++x, ++out) {
-// // G pixel
-// {
-// out->b = applyFilter(in, x, y, w, h, R_BGG);
-// out->g = in[x + offset];
-// out->r = applyFilter(in, x, y, w, h, B_BGG);
-// }
-// ++x; ++out;
-
-// // B pixel
-// {
-// out->b = applyFilter(in, x, y, w, h, R_BGB);
-// out->g = applyFilter(in, x, y, w, h, G_BGB);
-// out->r = in[x + offset];
-// }
-// }
-// }
-// }
-
-// static void bayer_grbg8_to_bgr8_mhc(int w, int h,
-// const uint8* in, uint8* _out) {
-// // Run the equivalent function for red
-// bayer_gbrg8_to_bgr8_mhc(w, h, in, _out);
-
-// // Now swap red and blue
-// swapRedAndBlue(srcWidth * h, (Color3uint8*)_out);
-// }
-
-// static void bayer_bggr8_to_bgr8_mhc(int w, int h,
-// const uint8* in, uint8* _out) {
-// // Run the equivalent function for red
-// bayer_rggb8_to_bgr8_mhc(w, h, in, _out);
-
-// // Now swap red and blue
-// swapRedAndBlue(srcWidth * h, (Color3uint8*)_out);
-// }
-
-
-
-///////////////////////////////////////////////////
-
-} // namespace G3D
diff --git a/externals/g3dlite/G3D.lib/source/Line.cpp b/externals/g3dlite/G3D.lib/source/Line.cpp
deleted file mode 100644
index 195ae7197f2..00000000000
--- a/externals/g3dlite/G3D.lib/source/Line.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- @file Line.cpp
-
- Line class
-
- @maintainer Morgan McGuire, graphics3d.com
-
- @created 2001-06-02
- @edited 2006-01-28
- */
-
-#include "G3D/Line.h"
-#include "G3D/Plane.h"
-
-namespace G3D {
-
-Vector3 Line::intersection(const Plane& plane) const {
- float d;
- Vector3 normal = plane.normal();
- plane.getEquation(normal, d);
- float rate = _direction.dot(normal);
-
- if (rate == 0) {
-
- return Vector3::inf();
-
- } else {
- float t = -(d + _point.dot(normal)) / rate;
-
- return _point + _direction * t;
- }
-}
-
-
-Line::Line(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-void Line::serialize(class BinaryOutput& b) const {
- _point.serialize(b);
- _direction.serialize(b);
-}
-
-
-void Line::deserialize(class BinaryInput& b) {
- _point.deserialize(b);
- _direction.deserialize(b);
-}
-
-
-Vector3 Line::closestPoint(const Vector3& pt) const {
- float t = _direction.dot(pt - _point);
- return _point + _direction * t;
-}
-
-
-Vector3 Line::point() const {
- return _point;
-}
-
-
-Vector3 Line::direction() const {
- return _direction;
-}
-
-
-Vector3 Line::closestPoint(const Line& B, float& minDist) const {
- const Vector3& P1 = _point;
- const Vector3& U1 = _direction;
-
- Vector3 P2 = B.point();
- Vector3 U2 = B.direction();
-
- const Vector3& P21 = P2 - P1;
- const Vector3& M = U2.cross(U1);
- float m2 = M.length();
-
- Vector3 R = P21.cross(M) / m2;
-
- float t1 = R.dot(U2);
-
- minDist = abs(P21.dot(M)) / sqrt(m2);
-
- return P1 + t1 * U1;
-}
-
-}
-
diff --git a/externals/g3dlite/G3D.lib/source/LineSegment.cpp b/externals/g3dlite/G3D.lib/source/LineSegment.cpp
deleted file mode 100644
index 44dfcb48bc1..00000000000
--- a/externals/g3dlite/G3D.lib/source/LineSegment.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/**
- @file LineSegment.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-02-08
- @edited 2008-02-02
- */
-
-#include "G3D/platform.h"
-#include "G3D/LineSegment.h"
-#include "G3D/Sphere.h"
-#include "G3D/debug.h"
-
-namespace G3D {
-
-
-Vector3 LineSegment::closestPoint(const Vector3& p) const {
-
- // The vector from the end of the capsule to the point in question.
- Vector3 v(p - _point);
-
- // Projection of v onto the line segment scaled by
- // the length of direction.
- float t = direction.dot(v);
-
- // Avoid some square roots. Derivation:
- // t/direction.length() <= direction.length()
- // t <= direction.squaredLength()
-
- if ((t >= 0) && (t <= direction.squaredMagnitude())) {
-
- // The point falls within the segment. Normalize direction,
- // divide t by the length of direction.
- return _point + direction * t / direction.squaredMagnitude();
-
- } else {
-
- // The point does not fall within the segment; see which end is closer.
-
- // Distance from 0, squared
- float d0Squared = v.squaredMagnitude();
-
- // Distance from 1, squared
- float d1Squared = (v - direction).squaredMagnitude();
-
- if (d0Squared < d1Squared) {
-
- // Point 0 is closer
- return _point;
-
- } else {
-
- // Point 1 is closer
- return _point + direction;
-
- }
- }
-
-}
-
-Vector3 LineSegment::point(int i) const {
- switch (i) {
- case 0:
- return _point;
-
- case 1:
- return _point + direction;
-
- default:
- debugAssertM(i == 0 || i == 1, "Argument to point must be 0 or 1");
- return _point;
- }
-}
-
-
-bool LineSegment::intersectsSolidSphere(const class Sphere& s) const {
- return distanceSquared(s.center) <= square(s.radius);
-}
-
-
-LineSegment::LineSegment(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-void LineSegment::serialize(class BinaryOutput& b) const {
- _point.serialize(b);
- direction.serialize(b);
-}
-
-
-void LineSegment::deserialize(class BinaryInput& b) {
- _point.deserialize(b);
- direction.deserialize(b);
-}
-
-
-Vector3 LineSegment::randomPoint() const {
- return _point + uniformRandom(0, 1) * direction;
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////
-
-LineSegment2D LineSegment2D::fromTwoPoints(const Vector2& p0, const Vector2& p1) {
- LineSegment2D s;
- s.m_origin = p0;
- s.m_direction = p1 - p0;
- s.m_length = s.m_direction.length();
- return s;
-}
-
-
-Vector2 LineSegment2D::point(int i) const {
- debugAssert(i == 0 || i == 1);
- if (i == 0) {
- return m_origin;
- } else {
- return m_direction + m_origin;
- }
-}
-
-
-Vector2 LineSegment2D::closestPoint(const Vector2& Q) const {
- // Two constants that appear in the result
- const Vector2 k1(m_origin - Q);
- const Vector2& k2 = m_direction;
-
- if (fuzzyEq(m_length, 0)) {
- // This line segment has no length
- return m_origin;
- }
-
- // Time [0, 1] at which we hit the closest point travelling from p0 to p1.
- // Derivation can be obtained by minimizing the expression
- // ||P0 + (P1 - P0)t - Q||.
- const float t = -k1.dot(k2) / (m_length * m_length);
-
- if (t < 0) {
- // Clipped to low end point
- return m_origin;
- } else if (t > 1) {
- // Clipped to high end point
- return m_origin + m_direction;
- } else {
- // Subsitute into the line equation to find
- // the point on the segment.
- return m_origin + k2 * t;
- }
-}
-
-
-float LineSegment2D::distance(const Vector2& p) const {
- Vector2 closest = closestPoint(p);
- return (closest - p).length();
-}
-
-
-float LineSegment2D::length() const {
- return m_length;
-}
-
-
-Vector2 LineSegment2D::intersection(const LineSegment2D& other) const {
-
- if ((m_origin == other.m_origin) ||
- (m_origin == other.m_origin + other.m_direction)) {
- return m_origin;
- }
-
- if (m_origin + m_direction == other.m_origin) {
- return other.m_origin;
- }
-
- // Note: Now that we've checked the endpoints, all other parallel lines can now be assumed
- // to not intersect (within numerical precision)
-
- Vector2 dir1 = m_direction;
- Vector2 dir2 = other.m_direction;
- Vector2 origin1 = m_origin;
- Vector2 origin2 = other.m_origin;
-
- if (dir1.x == 0) {
- // Avoid an upcoming divide by zero
- dir1 = dir1.yx();
- dir2 = dir2.yx();
- origin1 = origin1.yx();
- origin2 = origin2.yx();
- }
-
- // t1 = ((other.m_origin.x - m_origin.x) + other.m_direction.x * t2) / m_direction.x
- //
- // ((other.m_origin.x - m_origin.x) + other.m_direction.x * t2) * m_direction.y / m_direction.x =
- // (other.m_origin.y - m_origin.y) + other.m_direction.y * t2
- //
- // m = m_direction.y / m_direction.x
- // d = other.m_origin - m_origin
- //
- // (d.x + other.m_direction.x * t2) * m = d.y + other.m_direction.y * t2
- //
- // d.x * m + other.m_direction.x * m * t2 = d.y + other.m_direction.y * t2
- //
- // d.x * m - d.y = (other.m_direction.y - other.m_direction.x * m) * t2
- //
- // (d.x * m - d.y) / (other.m_direction.y - other.m_direction.x * m) = t2
- //
-
- Vector2 d = origin2 - origin1;
- float m = dir1.y / dir1.x;
-
- float t2 = (d.x * m - d.y) / (dir2.y - dir2.x * m);
- if (! isFinite(t2)) {
- // Parallel lines: no intersection
- return Vector2::inf();
- }
-
- if ((t2 < 0.0f) || (t2 > 1.0f)) {
- // Intersection occurs past the end of the line segments
- return Vector2::inf();
- }
-
- float t1 = (d.x + dir2.x * t2) / dir1.x;
- if ((t1 < 0.0f) || (t1 > 1.0f)) {
- // Intersection occurs past the end of the line segments
- return Vector2::inf();
- }
-
- // Return the intersection point (computed from non-transposed
- // variables even if we flipped above)
- return m_origin + m_direction * t1;
-
-}
-
-}
-
diff --git a/externals/g3dlite/G3D.lib/source/Log.cpp b/externals/g3dlite/G3D.lib/source/Log.cpp
deleted file mode 100644
index 13cea7a31f0..00000000000
--- a/externals/g3dlite/G3D.lib/source/Log.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- @file Log.cpp
-
- @maintainer Morgan McGuire, morgan@graphics3d.com
- @created 2001-08-04
- @edited 2005-07-01
- */
-
-#include "G3D/platform.h"
-#include "G3D/Log.h"
-#include "G3D/format.h"
-#include "G3D/Array.h"
-#include "G3D/fileutils.h"
-#include <time.h>
-
-#ifdef G3D_WIN32
- #include <imagehlp.h>
-#else
- #include <stdarg.h>
-#endif
-
-namespace G3D {
-
-void logPrintf(const char* fmt, ...) {
- va_list arg_list;
- va_start(arg_list, fmt);
- Log::common()->vprintf(fmt, arg_list);
- va_end(arg_list);
-}
-
-
-Log* Log::commonLog = NULL;
-
-Log::Log(const std::string& filename, int stripFromStackBottom) :
- stripFromStackBottom(stripFromStackBottom) {
-
- this->filename = filename;
-
- logFile = fopen(filename.c_str(), "w");
-
- if (logFile == NULL) {
- std::string drive, base, ext;
- Array<std::string> path;
- parseFilename(filename, drive, path, base, ext);
- std::string logName = base + ((ext != "") ? ("." + ext) : "");
-
- // Write time is greater than 1ms. This may be a network drive.... try another file.
- #ifdef G3D_WIN32
- logName = std::string(std::getenv("TEMP")) + logName;
- #else
- logName = std::string("/tmp/") + logName;
- #endif
-
- logFile = fopen(logName.c_str(), "w");
- }
-
- // Turn off buffering.
- setvbuf(logFile, NULL, _IONBF, 0);
-
- fprintf(logFile, "Application Log\n");
- time_t t;
- time(&t);
- fprintf(logFile, "Start: %s\n", ctime(&t));
- fflush(logFile);
-
- if (commonLog == NULL) {
- commonLog = this;
- }
-}
-
-
-Log::~Log() {
- section("Shutdown");
- println("Closing log file");
-
- // Make sure we don't leave a dangling pointer
- if (Log::commonLog == this) {
- Log::commonLog = NULL;
- }
-
- fclose(logFile);
-}
-
-
-FILE* Log::getFile() const {
- return logFile;
-}
-
-Log* Log::common() {
- if (commonLog == NULL) {
- commonLog = new Log();
- }
- return commonLog;
-}
-
-
-std::string Log::getCommonLogFilename() {
- return common()->filename;
-}
-
-
-void Log::section(const std::string& s) {
- fprintf(logFile, "_____________________________________________________\n");
- fprintf(logFile, "\n ### %s ###\n\n", s.c_str());
-}
-
-
-void __cdecl Log::printf(const char* fmt, ...) {
- printHeader();
-
- va_list arg_list;
- va_start(arg_list, fmt);
- print(vformat(fmt, arg_list));
- va_end(arg_list);
-}
-
-
-void __cdecl Log::vprintf(const char* fmt, va_list argPtr) {
- vfprintf(logFile, fmt, argPtr);
-}
-
-
-void Log::print(const std::string& s) {
- printHeader();
- fprintf(logFile, "%s", s.c_str());
-}
-
-
-void Log::println(const std::string& s) {
- printHeader();
- fprintf(logFile, "%s\n", s.c_str());
-}
-
-
-void Log::printHeader() {
- time_t t;
- if (time(&t) != ((time_t)-1)) {
- /*
- char buf[32];
- strftime(buf, 32, "[%H:%M:%S]", localtime(&t));
-
- Removed because this doesn't work on SDL threads.
-
- #ifdef _DEBUG
- std::string bt = getBacktrace(15, 2, stripFromStackBottom);
- fprintf(logFile, "\n %s %s\n\n", buf, bt.c_str());
- #endif
-
- fprintf(logFile, "\n %s \n", buf);
- */
-
- } else {
- println("[Error getting time]");
- }
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Matrix.cpp b/externals/g3dlite/G3D.lib/source/Matrix.cpp
deleted file mode 100644
index 0c6db214543..00000000000
--- a/externals/g3dlite/G3D.lib/source/Matrix.cpp
+++ /dev/null
@@ -1,1801 +0,0 @@
-/**
- @file Matrix.cpp
- @author Morgan McGuire, matrix@graphics3d.com
- */
-#include "G3D/Matrix.h"
-#include "G3D/TextOutput.h"
-
-static inline G3D::Matrix::T negate(G3D::Matrix::T x) {
- return -x;
-}
-
-namespace G3D {
-
-int Matrix::debugNumCopyOps = 0;
-int Matrix::debugNumAllocOps = 0;
-
-void Matrix::serialize(TextOutput& t) const {
- t.writeSymbol("%");
- t.writeNumber(rows());
- t.writeSymbol("x");
- t.writeNumber(cols());
- t.pushIndent();
- t.writeNewline();
-
- t.writeSymbol("[");
- for (int r = 0; r < rows(); ++r) {
- for (int c = 0; c < cols(); ++c) {
- t.writeNumber(impl->get(r, c));
- if (c < cols() - 1) {
- t.writeSymbol(",");
- } else {
- if (r < rows() - 1) {
- t.writeSymbol(";");
- t.writeNewline();
- }
- }
- }
- }
- t.writeSymbol("]");
- t.popIndent();
- t.writeNewline();
-}
-
-
-std::string Matrix::toString(const std::string& name) const {
- std::string s;
-
- if (name != "") {
- s += format("%s = \n", name.c_str());
- }
-
- s += "[";
- for (int r = 0; r < rows(); ++r) {
- for (int c = 0; c < cols(); ++c) {
- double v = impl->get(r, c);
-
- if (::fabs(v) < 0.00001) {
- // Don't print "negative zero"
- s += format("% 10.04g", 0.0);
- } else if (v == iRound(v)) {
- // Print integers nicely
- s += format("% 10.04g", v);
- } else {
- s += format("% 10.04f", v);
- }
-
- if (c < cols() - 1) {
- s += ",";
- } else if (r < rows() - 1) {
- s += ";\n ";
- } else {
- s += "]\n";
- }
- }
- }
- return s;
-}
-
-
-#define INPLACE(OP)\
- ImplRef A = impl;\
-\
- if (! A.isLastReference()) {\
- impl = new Impl(A->R, A->C);\
- }\
-\
- A->OP(B, *impl);
-
-Matrix& Matrix::operator*=(const T& B) {
- INPLACE(mul)
- return *this;
-}
-
-
-Matrix& Matrix::operator-=(const T& B) {
- INPLACE(sub)
- return *this;
-}
-
-
-Matrix& Matrix::operator+=(const T& B) {
- INPLACE(add)
- return *this;
-}
-
-
-Matrix& Matrix::operator/=(const T& B) {
- INPLACE(div)
- return *this;
-}
-
-
-Matrix& Matrix::operator*=(const Matrix& B) {
- // We can't optimize this one
- *this = *this * B;
- return *this;
-}
-
-
-Matrix& Matrix::operator-=(const Matrix& _B) {
- const Impl& B = *_B.impl;
- INPLACE(sub)
- return *this;
-}
-
-
-Matrix& Matrix::operator+=(const Matrix& _B) {
- const Impl& B = *_B.impl;
- INPLACE(add)
- return *this;
-}
-
-
-void Matrix::arrayMulInPlace(const Matrix& _B) {
- const Impl& B = *_B.impl;
- INPLACE(arrayMul)
-}
-
-
-void Matrix::arrayDivInPlace(const Matrix& _B) {
- const Impl& B = *_B.impl;
- INPLACE(arrayDiv)
-}
-
-#undef INPLACE
-
-Matrix Matrix::fromDiagonal(const Matrix& d) {
- debugAssert((d.rows() == 1) || (d.cols() == 1));
-
- int n = d.numElements();
- Matrix D = zero(n, n);
- for (int i = 0; i < n; ++i) {
- D.set(i, i, d.impl->data[i]);
- }
-
- return D;
-}
-
-void Matrix::set(int r, int c, T v) {
- if (! impl.isLastReference()) {
- // Copy the data before mutating; this object is shared
- impl = new Impl(*impl);
- }
- impl->set(r, c, v);
-}
-
-
-void Matrix::setRow(int r, const Matrix& vec) {
- debugAssertM(vec.cols() == cols(),
- "A row must be set to a vector of the same size.");
- debugAssertM(vec.rows() == 1,
- "A row must be set to a row vector.");
-
- debugAssert(r >= 0);
- debugAssert(r < rows());
-
- if (! impl.isLastReference()) {
- // Copy the data before mutating; this object is shared
- impl = new Impl(*impl);
- }
- impl->setRow(r, vec.impl->data);
-}
-
-
-void Matrix::setCol(int c, const Matrix& vec) {
- debugAssertM(vec.rows() == rows(),
- "A column must be set to a vector of the same size.");
- debugAssertM(vec.cols() == 1,
- "A column must be set to a column vector.");
-
- debugAssert(c >= 0);
-
- debugAssert(c < cols());
-
- if (! impl.isLastReference()) {
- // Copy the data before mutating; this object is shared
- impl = new Impl(*impl);
- }
- impl->setCol(c, vec.impl->data);
-}
-
-
-Matrix::T Matrix::get(int r, int c) const {
- return impl->get(r, c);
-}
-
-
-Matrix Matrix::row(int r) const {
- debugAssert(r >= 0);
- debugAssert(r < rows());
- Matrix out(1, cols());
- out.impl->setRow(1, impl->elt[r]);
- return out;
-}
-
-
-Matrix Matrix::col(int c) const {
- debugAssert(c >= 0);
- debugAssert(c < cols());
- Matrix out(rows(), 1);
-
- T* outData = out.impl->data;
- // Get a pointer to the first element in the column
- const T* inElt = &(impl->elt[0][c]);
- int R = rows();
- int C = cols();
- for (int r = 0; r < R; ++r) {
- outData[r] = *inElt;
- // Skip around to the next row
- inElt += C;
- }
-
- return out;
-}
-
-
-Matrix Matrix::zero(int R, int C) {
- Impl* A = new Impl(R, C);
- A->setZero();
- return Matrix(A);
-}
-
-
-Matrix Matrix::one(int R, int C) {
- Impl* A = new Impl(R, C);
- for (int i = R * C - 1; i >= 0; --i) {
- A->data[i] = 1.0;
- }
- return Matrix(A);
-}
-
-
-Matrix Matrix::random(int R, int C) {
- Impl* A = new Impl(R, C);
- for (int i = R * C - 1; i >= 0; --i) {
- A->data[i] = G3D::uniformRandom(0.0, 1.0);
- }
- return Matrix(A);
-}
-
-
-Matrix Matrix::identity(int N) {
- Impl* m = new Impl(N, N);
- m->setZero();
- for (int i = 0; i < N; ++i) {
- m->elt[i][i] = 1.0;
- }
- return Matrix(m);
-}
-
-
-// Implement an explicit-output unary method by trampolining to the impl
-#define TRAMPOLINE_EXPLICIT_1(method)\
-void Matrix::method(Matrix& out) const {\
- if ((out.impl == impl) && impl.isLastReference()) {\
- impl->method(*out.impl);\
- } else {\
- out = this->method();\
- }\
-}
-
-TRAMPOLINE_EXPLICIT_1(abs)
-TRAMPOLINE_EXPLICIT_1(negate)
-TRAMPOLINE_EXPLICIT_1(arrayLog)
-TRAMPOLINE_EXPLICIT_1(arrayExp)
-TRAMPOLINE_EXPLICIT_1(arrayCos)
-TRAMPOLINE_EXPLICIT_1(arraySin)
-
-void Matrix::mulRow(int r, const T& v) {
- debugAssert(r >= 0 && r < rows());
-
- if (! impl.isLastReference()) {
- impl = new Impl(*impl);
- }
-
- impl->mulRow(r, v);
-}
-
-
-void Matrix::transpose(Matrix& out) const {
- if ((out.impl == impl) && impl.isLastReference() && (impl->R == impl->C)) {
- // In place
- impl->transpose(*out.impl);
- } else {
- out = this->transpose();
- }
-}
-
-
-Matrix3 Matrix::toMatrix3() const {
- debugAssert(impl->R == 3);
- debugAssert(impl->C == 3);
- return Matrix3(
- impl->get(0,0), impl->get(0,1), impl->get(0,2),
- impl->get(1,0), impl->get(1,1), impl->get(1,2),
- impl->get(2,0), impl->get(2,1), impl->get(2,2));
-}
-
-
-Matrix4 Matrix::toMatrix4() const {
- debugAssert(impl->R == 4);
- debugAssert(impl->C == 4);
- return Matrix4(
- impl->get(0,0), impl->get(0,1), impl->get(0,2), impl->get(0,3),
- impl->get(1,0), impl->get(1,1), impl->get(1,2), impl->get(1,3),
- impl->get(2,0), impl->get(2,1), impl->get(2,2), impl->get(2,3),
- impl->get(3,0), impl->get(3,1), impl->get(3,2), impl->get(3,3));
-}
-
-
-Vector2 Matrix::toVector2() const {
- debugAssert(impl->R * impl->C == 2);
- if (impl->R > impl->C) {
- return Vector2(impl->get(0,0), impl->get(1,0));
- } else {
- return Vector2(impl->get(0,0), impl->get(0,1));
- }
-}
-
-
-Vector3 Matrix::toVector3() const {
- debugAssert(impl->R * impl->C == 3);
- if (impl->R > impl->C) {
- return Vector3(impl->get(0,0), impl->get(1,0), impl->get(2, 0));
- } else {
- return Vector3(impl->get(0,0), impl->get(0,1), impl->get(0, 2));
- }
-}
-
-
-Vector4 Matrix::toVector4() const {
- debugAssert(
- ((impl->R == 4) && (impl->C == 1)) ||
- ((impl->R == 1) && (impl->C == 4)));
-
- if (impl->R > impl->C) {
- return Vector4(impl->get(0,0), impl->get(1,0), impl->get(2, 0), impl->get(3,0));
- } else {
- return Vector4(impl->get(0,0), impl->get(0,1), impl->get(0, 2), impl->get(0,3));
- }
-}
-
-
-void Matrix::swapRows(int r0, int r1) {
- debugAssert(r0 >= 0 && r0 < rows());
- debugAssert(r1 >= 0 && r1 < rows());
-
- if (r0 == r1) {
- return;
- }
-
- if (! impl.isLastReference()) {
- impl = new Impl(*impl);
- }
-
- impl->swapRows(r0, r1);
-}
-
-
-void Matrix::swapAndNegateCols(int c0, int c1) {
- debugAssert(c0 >= 0 && c0 < cols());
- debugAssert(c1 >= 0 && c1 < cols());
-
- if (c0 == c1) {
- return;
- }
-
- if (! impl.isLastReference()) {
- impl = new Impl(*impl);
- }
-
- impl->swapAndNegateCols(c0, c1);
-}
-
-Matrix Matrix::subMatrix(int r1, int r2, int c1, int c2) const {
- debugAssert(r2>=r1);
- debugAssert(c2>=c1);
- debugAssert(c2<cols());
- debugAssert(r2<rows());
- debugAssert(r1>=0);
- debugAssert(c1>=0);
-
- Matrix X(r2 - r1 + 1, c2 - c1 + 1);
-
- for (int r = 0; r < X.rows(); ++r) {
- for (int c = 0; c < X.cols(); ++c) {
- X.set(r, c, get(r + r1, c + c1));
- }
- }
-
- return X;
-}
-
-
-bool Matrix::anyNonZero() const {
- return impl->anyNonZero();
-}
-
-
-bool Matrix::allNonZero() const {
- return impl->allNonZero();
-}
-
-
-void Matrix::svd(Matrix& U, Array<T>& d, Matrix& V, bool sort) const {
- debugAssert(rows() >= cols());
- debugAssertM(&U != &V, "Arguments to SVD must be different matrices");
- debugAssertM(&U != this, "Arguments to SVD must be different matrices");
- debugAssertM(&V != this, "Arguments to SVD must be different matrices");
-
- int R = rows();
- int C = cols();
-
- // Make sure we don't overwrite a shared matrix
- if (! V.impl.isLastReference()) {
- V = Matrix::zero(C, C);
- } else {
- V.impl->setSize(C, C);
- }
-
- if (&U != this || ! impl.isLastReference()) {
- // Make a copy of this for in-place SVD
- U.impl = new Impl(*impl);
- }
-
- d.resize(C);
- const char* ret = svdCore(U.impl->elt, R, C, d.getCArray(), V.impl->elt);
-
- debugAssertM(ret == NULL, ret);
- (void)ret;
-
- if (sort) {
- // Sort the singular values from greatest to least
-
- Array<SortRank> rank(C);
- for (int c = 0; c < C; ++c) {
- rank[c].col = c;
- rank[c].value = d[c];
- }
-
- rank.sort(SORT_INCREASING);
-
- Matrix Uold = U;
- Matrix Vold = V;
-
- U = Matrix(U.rows(), U.cols());
- V = Matrix(V.rows(), V.cols());
-
- // Now permute U, d, and V appropriately
- for (int c0 = 0; c0 < C; ++c0) {
- const int c1 = rank[c0].col;
-
- d[c0] = rank[c0].value;
- U.setCol(c0, Uold.col(c1));
- V.setCol(c0, Vold.col(c1));
- }
-
- }
-}
-
-
-#define COMPARE_SCALAR(OP)\
-Matrix Matrix::operator OP (const T& scalar) const {\
- int R = rows();\
- int C = cols();\
- int N = R * C;\
- Matrix out = Matrix::zero(R, C);\
-\
- const T* raw = impl->data;\
- T* outRaw = out.impl->data;\
- for (int i = 0; i < N; ++i) {\
- outRaw[i] = raw[i] OP scalar;\
- }\
-\
- return out;\
-}
-
-COMPARE_SCALAR(<)
-COMPARE_SCALAR(<=)
-COMPARE_SCALAR(>)
-COMPARE_SCALAR(>=)
-COMPARE_SCALAR(==)
-COMPARE_SCALAR(!=)
-
-#undef COMPARE_SCALAR
-
-double Matrix::normSquared() const {
- int R = rows();
- int C = cols();
- int N = R * C;
-
- double sum = 0.0;
-
- const T* raw = impl->data;
- for (int i = 0; i < N; ++i) {
- sum += square(raw[i]);
- }
-
- return sum;
-}
-
-double Matrix::norm() const {
- return sqrt(normSquared());
-}
-
-///////////////////////////////////////////////////////////
-
-Matrix::Impl::Impl(const Matrix3& M) : elt(NULL), data(NULL), R(0), C(0), dataSize(0){
- setSize(3, 3);
- for (int r = 0; r < 3; ++r) {
- for (int c = 0; c < 3; ++c) {
- set(r, c, M[r][c]);
- }
- }
-
-}
-
-
-Matrix::Impl::Impl(const Matrix4& M): elt(NULL), data(NULL), R(0), C(0), dataSize(0) {
- setSize(4, 4);
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- set(r, c, M[r][c]);
- }
- }
-}
-
-
-void Matrix::Impl::setSize(int newRows, int newCols) {
- if ((R == newRows) && (C == newCols)) {
- // Nothing to do
- return;
- }
-
- int newSize = newRows * newCols;
-
- R = newRows; C = newCols;
-
- // Only allocate if we need more space
- // or the size difference is ridiculous
- if ((newSize > dataSize) || (newSize < dataSize / 4)) {
- System::alignedFree(data);
- data = (float*)System::alignedMalloc(R * C * sizeof(T), 16);
- ++Matrix::debugNumAllocOps;
- dataSize = newSize;
- }
-
- // Construct the row pointers
- //delete[] elt;
- System::free(elt);
- elt = (T**)System::malloc(R * sizeof(T*));// new T*[R];
-
- for (int r = 0; r < R; ++ r) {
- elt[r] = data + r * C;
- }
-}
-
-
-Matrix::Impl::~Impl() {
- //delete[] elt;
- System::free(elt);
- System::alignedFree(data);
-}
-
-
-Matrix::Impl& Matrix::Impl::operator=(const Impl& m) {
- setSize(m.R, m.C);
- System::memcpy(data, m.data, R * C * sizeof(T));
- ++Matrix::debugNumCopyOps;
- return *this;
-}
-
-
-void Matrix::Impl::setZero() {
- System::memset(data, 0, R * C * sizeof(T));
-}
-
-
-void Matrix::Impl::swapRows(int r0, int r1) {
- T* R0 = elt[r0];
- T* R1 = elt[r1];
-
- for (int c = 0; c < C; ++c) {
- T temp = R0[c];
- R0[c] = R1[c];
- R1[c] = temp;
- }
-}
-
-
-void Matrix::Impl::swapAndNegateCols(int c0, int c1) {
- for (int r = 0; r < R; ++r) {
- T* row = elt[r];
-
- const T temp = -row[c0];
- row[c0] = -row[c1];
- row[c1] = temp;
- }
-}
-
-
-void Matrix::Impl::mulRow(int r, const T& v) {
- T* row = elt[r];
-
- for (int c = 0; c < C; ++c) {
- row[c] *= v;
- }
-}
-
-
-void Matrix::Impl::mul(const Impl& B, Impl& out) const {
- const Impl& A = *this;
-
- debugAssertM(
- (this != &out) && (&B != &out),
- "Output argument to mul cannot be the same as an input argument.");
-
- debugAssert(A.C == B.R);
- debugAssert(A.R == out.R);
- debugAssert(B.C == out.C);
-
- for (int r = 0; r < out.R; ++r) {
- for (int c = 0; c < out.C; ++c) {
- T sum = 0.0;
- for (int i = 0; i < A.C; ++i) {
- sum += A.get(r, i) * B.get(i, c);
- }
- out.set(r, c, sum);
- }
- }
-}
-
-
-// We're about to define several similar methods,
-// so use a macro to share implementations. This
-// must be a macro because the difference between
-// the macros is the operation in the inner loop.
-#define IMPLEMENT_ARRAY_2(method, OP)\
-void Matrix::Impl::method(const Impl& B, Impl& out) const {\
- const Impl& A = *this;\
- \
- debugAssert(A.C == B.C);\
- debugAssert(A.R == B.R);\
- debugAssert(A.C == out.C);\
- debugAssert(A.R == out.R);\
- \
- for (int i = R * C - 1; i >= 0; --i) {\
- out.data[i] = A.data[i] OP B.data[i];\
- }\
-}
-
-
-#define IMPLEMENT_ARRAY_1(method, f)\
-void Matrix::Impl::method(Impl& out) const {\
- const Impl& A = *this;\
- \
- debugAssert(A.C == out.C);\
- debugAssert(A.R == out.R);\
- \
- for (int i = R * C - 1; i >= 0; --i) {\
- out.data[i] = f(A.data[i]);\
- }\
-}
-
-
-#define IMPLEMENT_ARRAY_SCALAR(method, OP)\
-void Matrix::Impl::method(Matrix::T B, Impl& out) const {\
- const Impl& A = *this;\
- \
- debugAssert(A.C == out.C);\
- debugAssert(A.R == out.R);\
- \
- for (int i = R * C - 1; i >= 0; --i) {\
- out.data[i] = A.data[i] OP B;\
- }\
-}
-
-IMPLEMENT_ARRAY_2(add, +)
-IMPLEMENT_ARRAY_2(sub, -)
-IMPLEMENT_ARRAY_2(arrayMul, *)
-IMPLEMENT_ARRAY_2(arrayDiv, /)
-
-IMPLEMENT_ARRAY_SCALAR(add, +)
-IMPLEMENT_ARRAY_SCALAR(sub, -)
-IMPLEMENT_ARRAY_SCALAR(mul, *)
-IMPLEMENT_ARRAY_SCALAR(div, /)
-
-IMPLEMENT_ARRAY_1(abs, ::fabs)
-IMPLEMENT_ARRAY_1(negate, ::negate)
-IMPLEMENT_ARRAY_1(arrayLog, ::log)
-IMPLEMENT_ARRAY_1(arraySqrt, ::sqrt)
-IMPLEMENT_ARRAY_1(arrayExp, ::exp)
-IMPLEMENT_ARRAY_1(arrayCos, ::cos)
-IMPLEMENT_ARRAY_1(arraySin, ::sin)
-
-#undef IMPLEMENT_ARRAY_SCALAR
-#undef IMPLEMENT_ARRAY_1
-#undef IMPLEMENT_ARRAY_2
-
-// lsub is special because the argument order is reversed
-void Matrix::Impl::lsub(Matrix::T B, Impl& out) const {
- const Impl& A = *this;
-
- debugAssert(A.C == out.C);
- debugAssert(A.R == out.R);
-
- for (int i = R * C - 1; i >= 0; --i) {
- out.data[i] = B - A.data[i];
- }
-}
-
-
-void Matrix::Impl::inverseViaAdjoint(Impl& out) const {
- debugAssert(&out != this);
-
- // Inverse = adjoint / determinant
-
- adjoint(out);
-
- // Don't call the determinant method when we already have an
- // adjoint matrix; there's a faster way of computing it: the dot
- // product of the first row and the adjoint's first col.
- double det = 0.0;
- for (int r = R - 1; r >= 0; --r) {
- det += elt[0][r] * out.elt[r][0];
- }
-
- out.div(Matrix::T(det), out);
-}
-
-
-void Matrix::Impl::transpose(Impl& out) const {
- debugAssert(out.R == C);
- debugAssert(out.C == R);
-
- if (&out == this) {
- // Square matrix in place
- for (int r = 0; r < R; ++r) {
- for (int c = r + 1; c < C; ++c) {
- T temp = get(r, c);
- out.set(r, c, get(c, r));
- out.set(c, r, temp);
- }
- }
- } else {
- for (int r = 0; r < R; ++r) {
- for (int c = 0; c < C; ++c) {
- out.set(c, r, get(r, c));
- }
- }
- }
-}
-
-
-void Matrix::Impl::adjoint(Impl& out) const {
- cofactor(out);
- // Transpose is safe to perform in place
- out.transpose(out);
-}
-
-
-void Matrix::Impl::cofactor(Impl& out) const {
- debugAssert(&out != this);
- for(int r = 0; r < R; ++r) {
- for(int c = 0; c < C; ++c) {
- out.set(r, c, cofactor(r, c));
- }
- }
-}
-
-
-Matrix::T Matrix::Impl::cofactor(int r, int c) const {
- // Strang p. 217
- float s = isEven(r + c) ? 1.0f : -1.0f;
-
- return s * determinant(r, c);
-}
-
-
-Matrix::T Matrix::Impl::determinant(int nr, int nc) const {
- debugAssert(R > 0);
- debugAssert(C > 0);
- Impl A(R - 1, C - 1);
- withoutRowAndCol(nr, nc, A);
- return A.determinant();
-}
-
-
-void Matrix::Impl::setRow(int r, const T* vals) {
- debugAssert(r >= 0);
- System::memcpy(elt[r], vals, sizeof(T) * C);
-}
-
-
-void Matrix::Impl::setCol(int c, const T* vals) {
- for (int r = 0; r < R; ++r) {
- elt[r][c] = vals[r];
- }
-}
-
-
-Matrix::T Matrix::Impl::determinant() const {
-
- debugAssert(R == C);
-
- // Compute using cofactors
- switch(R) {
- case 0:
- return 0;
-
- case 1:
- // Determinant of a 1x1 is the element
- return elt[0][0];
-
- case 2:
- // Determinant of a 2x2 is ad-bc
- return elt[0][0] * elt[1][1] - elt[0][1] * elt[1][0];
-
- case 3:
- {
- // Determinant of an nxn matrix is the dot product of the first
- // row with the first row of cofactors. The base cases of this
- // method get called a lot, so we spell out the implementation
- // for the 3x3 case.
-
- double cofactor00 = elt[1][1] * elt[2][2] - elt[1][2] * elt[2][1];
- double cofactor10 = elt[1][2] * elt[2][0] - elt[1][0] * elt[2][2];
- double cofactor20 = elt[1][0] * elt[2][1] - elt[1][1] * elt[2][0];
-
- return Matrix::T(
- elt[0][0] * cofactor00 +
- elt[0][1] * cofactor10 +
- elt[0][2] * cofactor20);
- }
-
- default:
- {
- // Determinant of an n x n matrix is the dot product of the first
- // row with the first row of cofactors
- T det = 0.0;
-
- for (int c = 0; c < C; ++c) {
- det += elt[0][c] * cofactor(0, c);
- }
-
- return det;
- }
- }
-}
-
-
-void Matrix::Impl::withoutRowAndCol(int excludeRow, int excludeCol, Impl& out) const {
- debugAssert(out.R == R - 1);
- debugAssert(out.C == C - 1);
-
- for (int r = 0; r < out.R; ++r) {
- for (int c = 0; c < out.C; ++c) {
- out.elt[r][c] = elt[r + ((r >= excludeRow) ? 1 : 0)][c + ((c >= excludeCol) ? 1 : 0)];
- }
- }
-}
-
-
-Matrix Matrix::pseudoInverse(float tolerance) const {
- if ((cols() == 1) || (rows() == 1)) {
- return vectorPseudoInverse();
- } else if ((cols() <= 4) || (rows() <= 4)) {
- return partitionPseudoInverse();
- } else {
- return svdPseudoInverse(tolerance);
- }
-}
-
-/*
- Public function for testing purposes only. Use pseudoInverse(), as it contains optimizations for
- nonsingular matrices with at least one small (<5) dimension.
-*/
-Matrix Matrix::svdPseudoInverse(float tolerance) const {
- if (cols() > rows()) {
- return transpose().svdPseudoInverse(tolerance).transpose();
- }
-
- // Matrices from SVD
- Matrix U, V;
-
- // Diagonal elements
- Array<T> d;
-
- svd(U, d, V);
-
- if (rows() == 1) {
- d.resize(1, false);
- }
-
- if (tolerance < 0) {
- // TODO: Should be eps(d[0]), which is the largest diagonal
- tolerance = G3D::max(rows(), cols()) * 0.0001f;
- }
-
- Matrix X;
-
- int r = 0;
- for (int i = 0; i < d.size(); ++i) {
- if (d[i] > tolerance) {
- d[i] = Matrix::T(1) / d[i];
- ++r;
- }
- }
-
- if (r == 0) {
- // There were no non-zero elements
- X = zero(cols(), rows());
- } else {
- // Use the first r columns
-
- // Test code (the rest is below)
- /*
- d.resize(r);
- Matrix testU = U.subMatrix(0, U.rows() - 1, 0, r - 1);
- Matrix testV = V.subMatrix(0, V.rows() - 1, 0, r - 1);
- Matrix testX = testV * Matrix::fromDiagonal(d) * testU.transpose();
- X = testX;
- */
-
-
- // We want to do this:
- //
- // d.resize(r);
- // U = U.subMatrix(0, U.rows() - 1, 0, r - 1);
- // X = V * Matrix::fromDiagonal(d) * U.transpose();
- //
- // but creating a large diagonal matrix and then
- // multiplying by it is wasteful. So we instead
- // explicitly perform A = (D * U')' = U * D, and
- // then multiply X = V * A'.
-
- Matrix A = Matrix(U.rows(), r);
-
- const T* dPtr = d.getCArray();
- for (int i = 0; i < A.rows(); ++i) {
- const T* Urow = U.impl->elt[i];
- T* Arow = A.impl->elt[i];
- const int Acols = A.cols();
- for (int j = 0; j < Acols; ++j) {
- // A(i,j) = U(i,:) * D(:,j)
- // This is non-zero only at j = i because D is diagonal
- // A(i,j) = U(i,j) * D(j,j)
- Arow[j] = Urow[j] * dPtr[j];
- }
- }
-
- //
- // Compute X = V.subMatrix(0, V.rows() - 1, 0, r - 1) * A.transpose()
- //
- // Avoid the explicit subMatrix call, and by storing A' instead of A, avoid
- // both the transpose and the memory incoherence of striding across memory
- // in big steps.
-
- alwaysAssertM(A.cols() == r,
- "Internal dimension mismatch during pseudoInverse()");
- alwaysAssertM(V.cols() >= r,
- "Internal dimension mismatch during pseudoInverse()");
-
- X = Matrix(V.rows(), A.rows());
- T** Xelt = X.impl->elt;
- for (int i = 0; i < X.rows(); ++i) {
- const T* Vrow = V.impl->elt[i];
- for (int j = 0; j < X.cols(); ++j) {
- const T* Arow = A.impl->elt[j];
- T sum = 0;
- for (int k = 0; k < r; ++k) {
- sum += Vrow[k] * Arow[k];
- }
- Xelt[i][j] = sum;
- }
- }
-
- /*
- // Test that results are the same after optimizations:
- Matrix diff = X - testX;
- T n = diff.norm();
- debugAssert(n < 0.0001);
- */
- }
- return X;
-}
-
-// Computes pseudoinverse for a vector
-Matrix Matrix::vectorPseudoInverse() const {
- // If vector A has nonzero elements: transpose A, then divide each elt. by the squared norm
- // If A is zero vector: transpose A
- double x = 0.0;
-
- if (anyNonZero()) {
- x = 1.0 / normSquared();
- }
-
- Matrix A(cols(), rows());
- T** Aelt = A.impl->elt;
- for (int r = 0; r < rows(); ++r) {
- const T* MyRow = impl->elt[r];
- for (int c = 0; c < cols(); ++c) {
- Aelt[c][r] = T(MyRow[c] * x);
- }
- }
- return Matrix(A);
-}
-
-
-Matrix Matrix::rowPartPseudoInverse() const{
- int m = rows();
- int n = cols();
- alwaysAssertM((m<=n),"Row-partitioned block matrix pseudoinverse requires R<C");
-
- // B = A * A'
- Matrix A = *this;
- Matrix B = Matrix(m,m);
-
- T** Aelt = A.impl->elt;
- T** Belt = B.impl->elt;
- for (int i = 0; i < m; ++i) {
- const T* Arow = Aelt[i];
- for (int j = 0; j < m; ++j) {
- const T* Brow = Aelt[j];
- T sum = 0;
- for (int k = 0; k < n; ++k) {
- sum += Arow[k] * Brow[k];
- }
- Belt[i][j] = sum;
- }
- }
-
- // B has size m x m
- switch (m) {
- case 2:
- return row2PseudoInverse(B);
-
- case 3:
- return row3PseudoInverse(B);
-
- case 4:
- return row4PseudoInverse(B);
-
- default:
- alwaysAssertM(false, "G3D internal error: Should have used the vector or general case!");
- return Matrix();
- }
-}
-
-Matrix Matrix::colPartPseudoInverse() const{
- int m = rows();
- int n = cols();
- alwaysAssertM((m>=n),"Column-partitioned block matrix pseudoinverse requires R>C");
- // TODO: Put each of the individual cases in its own helper function
- // TODO: Push the B computation down into the individual cases
- // B = A' * A
- Matrix A = *this;
- Matrix B = Matrix(n, n);
- T** Aelt = A.impl->elt;
- T** Belt = B.impl->elt;
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- T sum = 0;
- for (int k = 0; k < m; ++k) {
- sum += Aelt[k][i] * Aelt[k][j];
- }
- Belt[i][j] = sum;
- }
- }
-
- // B has size n x n
- switch (n) {
- case 2:
- return col2PseudoInverse(B);
-
- case 3:
- return col3PseudoInverse(B);
-
- case 4:
- return col4PseudoInverse(B);
-
- default:
- alwaysAssertM(false, "G3D internal error: Should have used the vector or general case!");
- return Matrix();
- }
-}
-
-Matrix Matrix::col2PseudoInverse(const Matrix& B) const {
-
- Matrix A = *this;
- int m = rows();
- int n = cols();
- (void)n;
-
- // Row-major 2x2 matrix
- const float B2[2][2] =
- {{B.get(0,0), B.get(0,1)},
- {B.get(1,0), B.get(1,1)}};
-
- float det = (B2[0][0]*B2[1][1]) - (B2[0][1]*B2[1][0]);
-
- if (fuzzyEq(det, T(0))) {
-
- // Matrix was singular; the block matrix pseudo-inverse can't
- // handle that, so fall back to the old case
- return svdPseudoInverse();
-
- } else {
- // invert using formula at http://www.netsoc.tcd.ie/~jgilbert/maths_site/applets/algebra/matrix_inversion.html
-
- // Multiply by Binv * A'
- Matrix X(cols(), rows());
-
- T** Xelt = X.impl->elt;
- T** Aelt = A.impl->elt;
- float binv00 = B2[1][1]/det, binv01 = -B2[1][0]/det;
- float binv10 = -B2[0][1]/det, binv11 = B2[0][0]/det;
- for (int j = 0; j < m; ++j) {
- const T* Arow = Aelt[j];
- float a0 = Arow[0];
- float a1 = Arow[1];
- Xelt[0][j] = binv00 * a0 + binv01 * a1;
- Xelt[1][j] = binv10 * a0 + binv11 * a1;
- }
- return X;
- }
-}
-
-Matrix Matrix::col3PseudoInverse(const Matrix& B) const {
- Matrix A = *this;
- int m = rows();
- int n = cols();
-
- Matrix3 B3 = B.toMatrix3();
- if (fuzzyEq(B3.determinant(), (T)0.0)) {
-
- // Matrix was singular; the block matrix pseudo-inverse can't
- // handle that, so fall back to the old case
- return svdPseudoInverse();
-
- } else {
- Matrix3 B3inv = B3.inverse();
-
- // Multiply by Binv * A'
- Matrix X(cols(), rows());
-
- T** Xelt = X.impl->elt;
- T** Aelt = A.impl->elt;
- for (int i = 0; i < n; ++i) {
- T* Xrow = Xelt[i];
- for (int j = 0; j < m; ++j) {
- const T* Arow = Aelt[j];
- T sum = 0;
- const float* Binvrow = B3inv[i];
- for (int k = 0; k < n; ++k) {
- sum += Binvrow[k] * Arow[k];
- }
- Xrow[j] = sum;
- }
- }
- return X;
- }
-}
-
-Matrix Matrix::col4PseudoInverse(const Matrix& B) const {
- Matrix A = *this;
- int m = rows();
- int n = cols();
-
- Matrix4 B4 = B.toMatrix4();
- if (fuzzyEq(B4.determinant(), (T)0.0)) {
-
- // Matrix was singular; the block matrix pseudo-inverse can't
- // handle that, so fall back to the old case
- return svdPseudoInverse();
-
- } else {
- Matrix4 B4inv = B4.inverse();
-
- // Multiply by Binv * A'
- Matrix X(cols(), rows());
-
- T** Xelt = X.impl->elt;
- T** Aelt = A.impl->elt;
- for (int i = 0; i < n; ++i) {
- T* Xrow = Xelt[i];
- for (int j = 0; j < m; ++j) {
- const T* Arow = Aelt[j];
- T sum = 0;
- const float* Binvrow = B4inv[i];
- for (int k = 0; k < n; ++k) {
- sum += Binvrow[k] * Arow[k];
- }
- Xrow[j] = sum;
- }
- }
- return X;
- }
-}
-
-Matrix Matrix::row2PseudoInverse(const Matrix& B) const {
-
- Matrix A = *this;
- int m = rows();
- int n = cols();
- (void)m;
-
- // Row-major 2x2 matrix
- const float B2[2][2] =
- {{B.get(0,0), B.get(0,1)},
- {B.get(1,0), B.get(1,1)}};
-
- float det = (B2[0][0]*B2[1][1]) - (B2[0][1]*B2[1][0]);
-
- if (fuzzyEq(det, T(0))) {
-
- // Matrix was singular; the block matrix pseudo-inverse can't
- // handle that, so fall back to the old case
- return svdPseudoInverse();
-
- } else {
- // invert using formula at http://www.netsoc.tcd.ie/~jgilbert/maths_site/applets/algebra/matrix_inversion.html
-
- // Multiply by Binv * A'
- Matrix X(cols(), rows());
-
- T** Xelt = X.impl->elt;
- T** Aelt = A.impl->elt;
- float binv00 = B2[1][1]/det, binv01 = -B2[1][0]/det;
- float binv10 = -B2[0][1]/det, binv11 = B2[0][0]/det;
- for (int j = 0; j < n; ++j) {
- Xelt[j][0] = Aelt[0][j] * binv00 + Aelt[1][j] * binv10;
- Xelt[j][1] = Aelt[0][j] * binv01 + Aelt[1][j] * binv11;
- }
- return X;
- }
-}
-
-Matrix Matrix::row3PseudoInverse(const Matrix& B) const {
-
- Matrix A = *this;
- int m = rows();
- int n = cols();
-
- Matrix3 B3 = B.toMatrix3();
- if (fuzzyEq(B3.determinant(), (T)0.0)) {
-
- // Matrix was singular; the block matrix pseudo-inverse can't
- // handle that, so fall back to the old case
- return svdPseudoInverse();
-
- } else {
- Matrix3 B3inv = B3.inverse();
-
- // Multiply by Binv * A'
- Matrix X(cols(), rows());
-
- T** Xelt = X.impl->elt;
- T** Aelt = A.impl->elt;
- for (int i = 0; i < n; ++i) {
- T* Xrow = Xelt[i];
- for (int j = 0; j < m; ++j) {
- T sum = 0;
- for (int k = 0; k < m; ++k) {
- sum += Aelt[k][i] * B3inv[j][k];
- }
- Xrow[j] = sum;
- }
- }
- return X;
- }
-}
-
-Matrix Matrix::row4PseudoInverse(const Matrix& B) const {
-
- Matrix A = *this;
- int m = rows();
- int n = cols();
-
- Matrix4 B4 = B.toMatrix4();
- if (fuzzyEq(B4.determinant(), (T)0.0)) {
-
- // Matrix was singular; the block matrix pseudo-inverse can't
- // handle that, so fall back to the old case
- return svdPseudoInverse();
-
- } else {
- Matrix4 B4inv = B4.inverse();
-
- // Multiply by Binv * A'
- Matrix X(cols(), rows());
-
- T** Xelt = X.impl->elt;
- T** Aelt = A.impl->elt;
- for (int i = 0; i < n; ++i) {
- T* Xrow = Xelt[i];
- for (int j = 0; j < m; ++j) {
- T sum = 0;
- for (int k = 0; k < m; ++k) {
- sum += Aelt[k][i] * B4inv[j][k];
- }
- Xrow[j] = sum;
- }
- }
- return X;
- }
-}
-
-// Uses the block matrix pseudoinverse to compute the pseudoinverse of a full-rank mxn matrix with m >= n
-// http://en.wikipedia.org/wiki/Block_matrix_pseudoinverse
-Matrix Matrix::partitionPseudoInverse() const {
-
- // Logic:
- // A^-1 = (A'A)^-1 A'
- // A has few (n) columns, so A'A is small (n x n) and fast to invert
-
- int m = rows();
- int n = cols();
-
- if (m < n) {
- // TODO: optimize by pushing through the transpose
- //return transpose().partitionPseudoInverse().transpose();
- return rowPartPseudoInverse();
-
- } else {
- return colPartPseudoInverse();
- }
-}
-
-void Matrix::Impl::inverseInPlaceGaussJordan() {
- debugAssertM(R == C,
- format(
- "Cannot perform Gauss-Jordan inverse on a non-square matrix."
- " (Argument was %dx%d)",
- R, C));
-
- // Exchange to float elements
-# define SWAP(x, y) {float temp = x; x = y; y = temp;}
-
- // The integer arrays pivot, rowIndex, and colIndex are
- // used for bookkeeping on the pivoting
- static Array<int> colIndex, rowIndex, pivot;
-
- int col = 0, row = 0;
-
- colIndex.resize(R);
- rowIndex.resize(R);
- pivot.resize(R);
-
- static const int NO_PIVOT = -1;
-
- // Initialize the pivot array to default values.
- for (int i = 0; i < R; ++i) {
- pivot[i] = NO_PIVOT;
- }
-
- // This is the main loop over the columns to be reduced
- // Loop over the columns.
- for (int c = 0; c < R; ++c) {
-
- // Find the largest element and use that as a pivot
- float largestMagnitude = 0.0;
-
- // This is the outer loop of the search for a pivot element
- for (int r = 0; r < R; ++r) {
-
- // Unless we've already found the pivot, keep going
- if (pivot[r] != 0) {
-
- // Find the largest pivot
- for (int k = 0; k < R; ++k) {
- if (pivot[k] == NO_PIVOT) {
- const float mag = fabs(elt[r][k]);
-
- if (mag >= largestMagnitude) {
- largestMagnitude = mag;
- row = r; col = k;
- }
- }
- }
- }
- }
-
- pivot[col] += 1;
-
- // Interchange columns so that the pivot element is on the diagonal (we'll have to undo this
- // at the end)
- if (row != col) {
- for (int k = 0; k < R; ++k) {
- SWAP(elt[row][k], elt[col][k])
- }
- }
-
- // The pivot is now at [row, col]
- rowIndex[c] = row;
- colIndex[c] = col;
-
- double piv = elt[col][col];
-
- debugAssertM(piv != 0.0, "Matrix is singular");
-
- // Divide everything by the pivot (avoid computing the division
- // multiple times).
- const double pivotInverse = 1.0 / piv;
- elt[col][col] = 1.0;
-
- for (int k = 0; k < R; ++k) {
- elt[col][k] *= Matrix::T(pivotInverse);
- }
-
- // Reduce all rows
- for (int r = 0; r < R; ++r) {
- // Skip over the pivot row
- if (r != col) {
-
- double oldValue = elt[r][col];
- elt[r][col] = 0.0;
-
- for (int k = 0; k < R; ++k) {
- elt[r][k] -= Matrix::T(elt[col][k] * oldValue);
- }
- }
- }
- }
-
-
- // Put the columns back in the correct locations
- for (int i = R - 1; i >= 0; --i) {
- if (rowIndex[i] != colIndex[i]) {
- for (int k = 0; k < R; ++k) {
- SWAP(elt[k][rowIndex[i]], elt[k][colIndex[i]]);
- }
- }
- }
-
-# undef SWAP
-}
-
-
-bool Matrix::Impl::anyNonZero() const {
- int N = R * C;
- for (int i = 0; i < N; ++i) {
- if (data[i] != 0.0) {
- return true;
- }
- }
- return false;
-}
-
-
-bool Matrix::Impl::allNonZero() const {
- int N = R * C;
- for (int i = 0; i < N; ++i) {
- if (data[i] == 0.0) {
- return false;
- }
- }
- return true;
-}
-
-
-/** Helper for svdCore */
-static double pythag(double a, double b) {
-
- double at = fabs(a), bt = fabs(b), ct, result;
-
- if (at > bt) {
- ct = bt / at;
- result = at * sqrt(1.0 + square(ct));
- } else if (bt > 0.0) {
- ct = at / bt;
- result = bt * sqrt(1.0 + square(ct));
- } else {
- result = 0.0;
- }
-
- return result;
-}
-
-#define SIGN(a, b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
-
-const char* Matrix::svdCore(float** U, int rows, int cols, float* D, float** V) {
- const int MAX_ITERATIONS = 30;
-
- int flag, i, its, j, jj, k, l = 0, nm = 0;
- double c, f, h, s, x, y, z;
- double anorm = 0.0, g = 0.0, scale = 0.0;
-
- // Temp row vector
- double* rv1;
-
- debugAssertM(rows >= cols, "Must have more rows than columns");
-
- rv1 = (double*)System::alignedMalloc(cols * sizeof(double), 16);
- debugAssert(rv1);
-
- // Householder reduction to bidiagonal form
- for (i = 0; i < cols; ++i) {
-
- // Left-hand reduction
- l = i + 1;
- rv1[i] = scale * g;
- g = s = scale = 0.0;
-
- if (i < rows) {
-
- for (k = i; k < rows; ++k) {
- scale += fabs((double)U[k][i]);
- }
-
- if (scale) {
- for (k = i; k < rows; ++k) {
- U[k][i] = (float)((double)U[k][i]/scale);
- s += ((double)U[k][i] * (double)U[k][i]);
- }
-
- f = (double)U[i][i];
-
- // TODO: what is this 2-arg sign function?
- g = -SIGN(sqrt(s), f);
- h = f * g - s;
- U[i][i] = (float)(f - g);
-
- if (i != cols - 1) {
- for (j = l; j < cols; j++) {
-
- for (s = 0.0, k = i; k < rows; ++k) {
- s += ((double)U[k][i] * (double)U[k][j]);
- }
-
- f = s / h;
- for (k = i; k < rows; ++k) {
- U[k][j] += (float)(f * (double)U[k][i]);
- }
- }
- }
- for (k = i; k < rows; ++k) {
- U[k][i] = (float)((double)U[k][i]*scale);
- }
- }
- }
- D[i] = (float)(scale * g);
-
- // right-hand reduction
- g = s = scale = 0.0;
- if (i < rows && i != cols - 1) {
- for (k = l; k < cols; ++k) {
- scale += fabs((double)U[i][k]);
- }
-
- if (scale) {
- for (k = l; k < cols; ++k) {
- U[i][k] = (float)((double)U[i][k]/scale);
- s += ((double)U[i][k] * (double)U[i][k]);
- }
-
- f = (double)U[i][l];
- g = -SIGN(sqrt(s), f);
- h = f * g - s;
- U[i][l] = (float)(f - g);
-
- for (k = l; k < cols; ++k) {
- rv1[k] = (double)U[i][k] / h;
- }
-
- if (i != rows - 1) {
-
- for (j = l; j < rows; ++j) {
- for (s = 0.0, k = l; k < cols; ++k) {
- s += ((double)U[j][k] * (double)U[i][k]);
- }
-
- for (k = l; k < cols; ++k) {
- U[j][k] += (float)(s * rv1[k]);
- }
- }
- }
-
- for (k = l; k < cols; ++k) {
- U[i][k] = (float)((double)U[i][k]*scale);
- }
- }
- }
-
- anorm = max(anorm, fabs((double)D[i]) + fabs(rv1[i]));
- }
-
- // accumulate the right-hand transformation
- for (i = cols - 1; i >= 0; --i) {
- if (i < cols - 1) {
- if (g) {
- for (j = l; j < cols; j++) {
- V[j][i] = (float)(((double)U[i][j] / (double)U[i][l]) / g);
- }
-
- // double division to avoid underflow
- for (j = l; j < cols; ++j) {
- for (s = 0.0, k = l; k < cols; k++) {
- s += ((double)U[i][k] * (double)V[k][j]);
- }
-
- for (k = l; k < cols; ++k) {
- V[k][j] += (float)(s * (double)V[k][i]);
- }
- }
- }
-
- for (j = l; j < cols; ++j) {
- V[i][j] = V[j][i] = 0.0;
- }
- }
-
- V[i][i] = 1.0;
- g = rv1[i];
- l = i;
- }
-
- // accumulate the left-hand transformation
- for (i = cols - 1; i >= 0; --i) {
- l = i + 1;
- g = (double)D[i];
- if (i < cols - 1) {
- for (j = l; j < cols; ++j) {
- U[i][j] = 0.0;
- }
- }
-
- if (g) {
- g = 1.0 / g;
- if (i != cols - 1) {
- for (j = l; j < cols; ++j) {
- for (s = 0.0, k = l; k < rows; ++k) {
- s += ((double)U[k][i] * (double)U[k][j]);
- }
-
- f = (s / (double)U[i][i]) * g;
-
- for (k = i; k < rows; ++k) {
- U[k][j] += (float)(f * (double)U[k][i]);
- }
- }
- }
-
- for (j = i; j < rows; ++j) {
- U[j][i] = (float)((double)U[j][i]*g);
- }
-
- } else {
- for (j = i; j < rows; ++j) {
- U[j][i] = 0.0;
- }
- }
- ++U[i][i];
- }
-
- // diagonalize the bidiagonal form
- for (k = cols - 1; k >= 0; --k) {
- // loop over singular values
- for (its = 0; its < MAX_ITERATIONS; ++its) {
- // loop over allowed iterations
- flag = 1;
-
- for (l = k; l >= 0; --l) {
- // test for splitting
- nm = l - 1;
- if (fabs(rv1[l]) + anorm == anorm) {
- flag = 0;
- break;
- }
-
- if (fabs((double)D[nm]) + anorm == anorm) {
- break;
- }
- }
-
- if (flag) {
- c = 0.0;
- s = 1.0;
- for (i = l; i <= k; ++i) {
- f = s * rv1[i];
- if (fabs(f) + anorm != anorm) {
- g = (double)D[i];
- h = pythag(f, g);
- D[i] = (float)h;
- h = 1.0 / h;
- c = g * h;
- s = (- f * h);
- for (j = 0; j < rows; ++j) {
- y = (double)U[j][nm];
- z = (double)U[j][i];
- U[j][nm] = (float)(y * c + z * s);
- U[j][i] = (float)(z * c - y * s);
- }
- }
- }
- }
-
- z = (double)D[k];
- if (l == k) {
- // convergence
- if (z < 0.0) {
- // make singular value nonnegative
- D[k] = (float)(-z);
-
- for (j = 0; j < cols; ++j) {
- V[j][k] = (-V[j][k]);
- }
- }
- break;
- }
-
- if (its >= MAX_ITERATIONS) {
- free(rv1);
- rv1 = NULL;
- return "Failed to converge.";
- }
-
- // shift from bottom 2 x 2 minor
- x = (double)D[l];
- nm = k - 1;
- y = (double)D[nm];
- g = rv1[nm];
- h = rv1[k];
- f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
- g = pythag(f, 1.0);
- f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
-
- // next QR transformation
- c = s = 1.0;
- for (j = l; j <= nm; ++j) {
- i = j + 1;
- g = rv1[i];
- y = (double)D[i];
- h = s * g;
- g = c * g;
- z = pythag(f, h);
- rv1[j] = z;
- c = f / z;
- s = h / z;
- f = x * c + g * s;
- g = g * c - x * s;
- h = y * s;
- y = y * c;
-
- for (jj = 0; jj < cols; ++jj) {
- x = (double)V[jj][j];
- z = (double)V[jj][i];
- V[jj][j] = (float)(x * c + z * s);
- V[jj][i] = (float)(z * c - x * s);
- }
- z = pythag(f, h);
- D[j] = (float)z;
- if (z) {
- z = 1.0 / z;
- c = f * z;
- s = h * z;
- }
- f = (c * g) + (s * y);
- x = (c * y) - (s * g);
- for (jj = 0; jj < rows; jj++) {
- y = (double)U[jj][j];
- z = (double)U[jj][i];
- U[jj][j] = (float)(y * c + z * s);
- U[jj][i] = (float)(z * c - y * s);
- }
- }
- rv1[l] = 0.0;
- rv1[k] = f;
- D[k] = (float)x;
- }
- }
-
- System::alignedFree(rv1);
- rv1 = NULL;
-
- return NULL;
-}
-
-#undef SIGN
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Matrix3.cpp b/externals/g3dlite/G3D.lib/source/Matrix3.cpp
deleted file mode 100644
index 7fb6648d3f7..00000000000
--- a/externals/g3dlite/G3D.lib/source/Matrix3.cpp
+++ /dev/null
@@ -1,1725 +0,0 @@
-/**
- @file Matrix3.cpp
-
- 3x3 matrix class
-
- @author Morgan McGuire, graphics3d.com
-
- @created 2001-06-02
- @edited 2006-04-06
-*/
-
-#include "G3D/platform.h"
-#include <memory.h>
-#include <assert.h>
-#include "G3D/Matrix3.h"
-#include "G3D/g3dmath.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Quat.h"
-
-namespace G3D {
-
-const float Matrix3::EPSILON = 1e-06f;
-
-const Matrix3& Matrix3::zero() {
- static Matrix3 m(0, 0, 0, 0, 0, 0, 0, 0, 0);
- return m;
-}
-
-const Matrix3& Matrix3::identity() {
- static Matrix3 m(1, 0, 0, 0, 1, 0, 0, 0, 1);
- return m;
-}
-
-
-const float Matrix3::ms_fSvdEpsilon = 1e-04f;
-const int Matrix3::ms_iSvdMaxIterations = 32;
-
-Matrix3::Matrix3(BinaryInput& b) {
- deserialize(b);
-}
-
-bool Matrix3::fuzzyEq(const Matrix3& b) const {
- for (int r = 0; r < 3; ++r) {
- for (int c = 0; c < 3; ++c) {
- if (! G3D::fuzzyEq(elt[r][c], b[r][c])) {
- return false;
- }
- }
- }
- return true;
-}
-
-
-bool Matrix3::isOrthonormal() const {
- Vector3 X = column(0);
- Vector3 Y = column(1);
- Vector3 Z = column(2);
-
- return
- (G3D::fuzzyEq(X.dot(Y), 0.0f) &&
- G3D::fuzzyEq(Y.dot(Z), 0.0f) &&
- G3D::fuzzyEq(X.dot(Z), 0.0f) &&
- G3D::fuzzyEq(X.squaredMagnitude(), 1.0f) &&
- G3D::fuzzyEq(Y.squaredMagnitude(), 1.0f) &&
- G3D::fuzzyEq(Z.squaredMagnitude(), 1.0f));
-}
-
-//----------------------------------------------------------------------------
-Matrix3::Matrix3(const Quat& _q) {
- // Implementation from Watt and Watt, pg 362
- // See also http://www.flipcode.com/documents/matrfaq.html#Q54
- Quat q = _q;
- q.unitize();
- float xx = 2.0f * q.x * q.x;
- float xy = 2.0f * q.x * q.y;
- float xz = 2.0f * q.x * q.z;
- float xw = 2.0f * q.x * q.w;
-
- float yy = 2.0f * q.y * q.y;
- float yz = 2.0f * q.y * q.z;
- float yw = 2.0f * q.y * q.w;
-
- float zz = 2.0f * q.z * q.z;
- float zw = 2.0f * q.z * q.w;
-
- set(1.0f - yy - zz, xy - zw, xz + yw,
- xy + zw, 1.0f - xx - zz, yz - xw,
- xz - yw, yz + xw, 1.0f - xx - yy);
-}
-
-//----------------------------------------------------------------------------
-
-Matrix3::Matrix3 (const float aafEntry[3][3]) {
- memcpy(elt, aafEntry, 9*sizeof(float));
-}
-
-//----------------------------------------------------------------------------
-Matrix3::Matrix3 (const Matrix3& rkMatrix) {
- memcpy(elt, rkMatrix.elt, 9*sizeof(float));
-}
-
-//----------------------------------------------------------------------------
-Matrix3::Matrix3(
- float fEntry00, float fEntry01, float fEntry02,
- float fEntry10, float fEntry11, float fEntry12,
- float fEntry20, float fEntry21, float fEntry22) {
- set(fEntry00, fEntry01, fEntry02,
- fEntry10, fEntry11, fEntry12,
- fEntry20, fEntry21, fEntry22);
-}
-
-void Matrix3::set(
- float fEntry00, float fEntry01, float fEntry02,
- float fEntry10, float fEntry11, float fEntry12,
- float fEntry20, float fEntry21, float fEntry22) {
-
- elt[0][0] = fEntry00;
- elt[0][1] = fEntry01;
- elt[0][2] = fEntry02;
- elt[1][0] = fEntry10;
- elt[1][1] = fEntry11;
- elt[1][2] = fEntry12;
- elt[2][0] = fEntry20;
- elt[2][1] = fEntry21;
- elt[2][2] = fEntry22;
-}
-
-
-void Matrix3::deserialize(BinaryInput& b) {
- int r,c;
- for (c = 0; c < 3; ++c) {
- for (r = 0; r < 3; ++r) {
- elt[r][c] = b.readFloat32();
- }
- }
-}
-
-
-void Matrix3::serialize(BinaryOutput& b) const {
- int r,c;
- for (c = 0; c < 3; ++c) {
- for (r = 0; r < 3; ++r) {
- b.writeFloat32(elt[r][c]);
- }
- }
-}
-
-
-//----------------------------------------------------------------------------
-Vector3 Matrix3::column (int iCol) const {
- assert((0 <= iCol) && (iCol < 3));
- return Vector3(elt[0][iCol], elt[1][iCol],
- elt[2][iCol]);
-}
-
-const Vector3& Matrix3::row (int iRow) const {
- assert((0 <= iRow) && (iRow < 3));
- return *reinterpret_cast<const Vector3*>(elt[iRow]);
-}
-
-
-Vector3 Matrix3::getColumn (int iCol) const {
- assert((0 <= iCol) && (iCol < 3));
- return Vector3(elt[0][iCol], elt[1][iCol],
- elt[2][iCol]);
-}
-
-Vector3 Matrix3::getRow (int iRow) const {
- return Vector3(elt[iRow][0], elt[iRow][1], elt[iRow][2]);
-}
-
-void Matrix3::setColumn(int iCol, const Vector3 &vector) {
- debugAssert((iCol >= 0) && (iCol < 3));
- elt[0][iCol] = vector.x;
- elt[1][iCol] = vector.y;
- elt[2][iCol] = vector.z;
-}
-
-
-void Matrix3::setRow(int iRow, const Vector3 &vector) {
- debugAssert((iRow >= 0) && (iRow < 3));
- elt[iRow][0] = vector.x;
- elt[iRow][1] = vector.y;
- elt[iRow][2] = vector.z;
-}
-
-
-//----------------------------------------------------------------------------
-bool Matrix3::operator== (const Matrix3& rkMatrix) const {
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- if ( elt[iRow][iCol] != rkMatrix.elt[iRow][iCol] )
- return false;
- }
- }
-
- return true;
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::operator!= (const Matrix3& rkMatrix) const {
- return !operator==(rkMatrix);
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::operator+ (const Matrix3& rkMatrix) const {
- Matrix3 kSum;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- kSum.elt[iRow][iCol] = elt[iRow][iCol] +
- rkMatrix.elt[iRow][iCol];
- }
- }
-
- return kSum;
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::operator- (const Matrix3& rkMatrix) const {
- Matrix3 kDiff;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- kDiff.elt[iRow][iCol] = elt[iRow][iCol] -
- rkMatrix.elt[iRow][iCol];
- }
- }
-
- return kDiff;
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::operator* (const Matrix3& rkMatrix) const {
- Matrix3 kProd;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- kProd.elt[iRow][iCol] =
- elt[iRow][0] * rkMatrix.elt[0][iCol] +
- elt[iRow][1] * rkMatrix.elt[1][iCol] +
- elt[iRow][2] * rkMatrix.elt[2][iCol];
- }
- }
-
- return kProd;
-}
-
-Matrix3& Matrix3::operator+= (const Matrix3& rkMatrix) {
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- elt[iRow][iCol] = elt[iRow][iCol] + rkMatrix.elt[iRow][iCol];
- }
- }
-
- return *this;
-}
-
-Matrix3& Matrix3::operator-= (const Matrix3& rkMatrix) {
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- elt[iRow][iCol] = elt[iRow][iCol] - rkMatrix.elt[iRow][iCol];
- }
- }
-
- return *this;
-}
-
-Matrix3& Matrix3::operator*= (const Matrix3& rkMatrix) {
- Matrix3 mulMat;
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- mulMat.elt[iRow][iCol] =
- elt[iRow][0] * rkMatrix.elt[0][iCol] +
- elt[iRow][1] * rkMatrix.elt[1][iCol] +
- elt[iRow][2] * rkMatrix.elt[2][iCol];
- }
- }
-
- *this = mulMat;
- return *this;
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::operator- () const {
- Matrix3 kNeg;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- kNeg[iRow][iCol] = -elt[iRow][iCol];
- }
- }
-
- return kNeg;
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::operator* (float fScalar) const {
- Matrix3 kProd;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- kProd[iRow][iCol] = fScalar * elt[iRow][iCol];
- }
- }
-
- return kProd;
-}
-
-//----------------------------------------------------------------------------
-Matrix3 operator* (double fScalar, const Matrix3& rkMatrix) {
- Matrix3 kProd;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- kProd[iRow][iCol] = fScalar * rkMatrix.elt[iRow][iCol];
- }
- }
-
- return kProd;
-}
-
-Matrix3 operator* (float fScalar, const Matrix3& rkMatrix) {
- return (double)fScalar * rkMatrix;
-}
-
-
-Matrix3 operator* (int fScalar, const Matrix3& rkMatrix) {
- return (double)fScalar * rkMatrix;
-}
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::transpose () const {
- Matrix3 kTranspose;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- kTranspose[iRow][iCol] = elt[iCol][iRow];
- }
- }
-
- return kTranspose;
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::inverse (Matrix3& rkInverse, float fTolerance) const {
- // Invert a 3x3 using cofactors. This is about 8 times faster than
- // the Numerical Recipes code which uses Gaussian elimination.
-
- rkInverse[0][0] = elt[1][1] * elt[2][2] -
- elt[1][2] * elt[2][1];
- rkInverse[0][1] = elt[0][2] * elt[2][1] -
- elt[0][1] * elt[2][2];
- rkInverse[0][2] = elt[0][1] * elt[1][2] -
- elt[0][2] * elt[1][1];
- rkInverse[1][0] = elt[1][2] * elt[2][0] -
- elt[1][0] * elt[2][2];
- rkInverse[1][1] = elt[0][0] * elt[2][2] -
- elt[0][2] * elt[2][0];
- rkInverse[1][2] = elt[0][2] * elt[1][0] -
- elt[0][0] * elt[1][2];
- rkInverse[2][0] = elt[1][0] * elt[2][1] -
- elt[1][1] * elt[2][0];
- rkInverse[2][1] = elt[0][1] * elt[2][0] -
- elt[0][0] * elt[2][1];
- rkInverse[2][2] = elt[0][0] * elt[1][1] -
- elt[0][1] * elt[1][0];
-
- float fDet =
- elt[0][0] * rkInverse[0][0] +
- elt[0][1] * rkInverse[1][0] +
- elt[0][2] * rkInverse[2][0];
-
- if ( G3D::abs(fDet) <= fTolerance )
- return false;
-
- float fInvDet = 1.0 / fDet;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++)
- rkInverse[iRow][iCol] *= fInvDet;
- }
-
- return true;
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::inverse (float fTolerance) const {
- Matrix3 kInverse = Matrix3::zero();
- inverse(kInverse, fTolerance);
- return kInverse;
-}
-
-//----------------------------------------------------------------------------
-float Matrix3::determinant () const {
- float fCofactor00 = elt[1][1] * elt[2][2] -
- elt[1][2] * elt[2][1];
- float fCofactor10 = elt[1][2] * elt[2][0] -
- elt[1][0] * elt[2][2];
- float fCofactor20 = elt[1][0] * elt[2][1] -
- elt[1][1] * elt[2][0];
-
- float fDet =
- elt[0][0] * fCofactor00 +
- elt[0][1] * fCofactor10 +
- elt[0][2] * fCofactor20;
-
- return fDet;
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::bidiagonalize (Matrix3& kA, Matrix3& kL,
- Matrix3& kR) {
- float afV[3], afW[3];
- float fLength, fSign, fT1, fInvT1, fT2;
- bool bIdentity;
-
- // map first column to (*,0,0)
- fLength = sqrt(kA[0][0] * kA[0][0] + kA[1][0] * kA[1][0] +
- kA[2][0] * kA[2][0]);
-
- if ( fLength > 0.0 ) {
- fSign = (kA[0][0] > 0.0 ? 1.0 : -1.0);
- fT1 = kA[0][0] + fSign * fLength;
- fInvT1 = 1.0 / fT1;
- afV[1] = kA[1][0] * fInvT1;
- afV[2] = kA[2][0] * fInvT1;
-
- fT2 = -2.0 / (1.0 + afV[1] * afV[1] + afV[2] * afV[2]);
- afW[0] = fT2 * (kA[0][0] + kA[1][0] * afV[1] + kA[2][0] * afV[2]);
- afW[1] = fT2 * (kA[0][1] + kA[1][1] * afV[1] + kA[2][1] * afV[2]);
- afW[2] = fT2 * (kA[0][2] + kA[1][2] * afV[1] + kA[2][2] * afV[2]);
- kA[0][0] += afW[0];
- kA[0][1] += afW[1];
- kA[0][2] += afW[2];
- kA[1][1] += afV[1] * afW[1];
- kA[1][2] += afV[1] * afW[2];
- kA[2][1] += afV[2] * afW[1];
- kA[2][2] += afV[2] * afW[2];
-
- kL[0][0] = 1.0 + fT2;
- kL[0][1] = kL[1][0] = fT2 * afV[1];
- kL[0][2] = kL[2][0] = fT2 * afV[2];
- kL[1][1] = 1.0 + fT2 * afV[1] * afV[1];
- kL[1][2] = kL[2][1] = fT2 * afV[1] * afV[2];
- kL[2][2] = 1.0 + fT2 * afV[2] * afV[2];
- bIdentity = false;
- } else {
- kL = Matrix3::identity();
- bIdentity = true;
- }
-
- // map first row to (*,*,0)
- fLength = sqrt(kA[0][1] * kA[0][1] + kA[0][2] * kA[0][2]);
-
- if ( fLength > 0.0 ) {
- fSign = (kA[0][1] > 0.0 ? 1.0 : -1.0);
- fT1 = kA[0][1] + fSign * fLength;
- afV[2] = kA[0][2] / fT1;
-
- fT2 = -2.0 / (1.0 + afV[2] * afV[2]);
- afW[0] = fT2 * (kA[0][1] + kA[0][2] * afV[2]);
- afW[1] = fT2 * (kA[1][1] + kA[1][2] * afV[2]);
- afW[2] = fT2 * (kA[2][1] + kA[2][2] * afV[2]);
- kA[0][1] += afW[0];
- kA[1][1] += afW[1];
- kA[1][2] += afW[1] * afV[2];
- kA[2][1] += afW[2];
- kA[2][2] += afW[2] * afV[2];
-
- kR[0][0] = 1.0;
- kR[0][1] = kR[1][0] = 0.0;
- kR[0][2] = kR[2][0] = 0.0;
- kR[1][1] = 1.0 + fT2;
- kR[1][2] = kR[2][1] = fT2 * afV[2];
- kR[2][2] = 1.0 + fT2 * afV[2] * afV[2];
- } else {
- kR = Matrix3::identity();
- }
-
- // map second column to (*,*,0)
- fLength = sqrt(kA[1][1] * kA[1][1] + kA[2][1] * kA[2][1]);
-
- if ( fLength > 0.0 ) {
- fSign = (kA[1][1] > 0.0 ? 1.0 : -1.0);
- fT1 = kA[1][1] + fSign * fLength;
- afV[2] = kA[2][1] / fT1;
-
- fT2 = -2.0 / (1.0 + afV[2] * afV[2]);
- afW[1] = fT2 * (kA[1][1] + kA[2][1] * afV[2]);
- afW[2] = fT2 * (kA[1][2] + kA[2][2] * afV[2]);
- kA[1][1] += afW[1];
- kA[1][2] += afW[2];
- kA[2][2] += afV[2] * afW[2];
-
- float fA = 1.0 + fT2;
- float fB = fT2 * afV[2];
- float fC = 1.0 + fB * afV[2];
-
- if ( bIdentity ) {
- kL[0][0] = 1.0;
- kL[0][1] = kL[1][0] = 0.0;
- kL[0][2] = kL[2][0] = 0.0;
- kL[1][1] = fA;
- kL[1][2] = kL[2][1] = fB;
- kL[2][2] = fC;
- } else {
- for (int iRow = 0; iRow < 3; iRow++) {
- float fTmp0 = kL[iRow][1];
- float fTmp1 = kL[iRow][2];
- kL[iRow][1] = fA * fTmp0 + fB * fTmp1;
- kL[iRow][2] = fB * fTmp0 + fC * fTmp1;
- }
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::golubKahanStep (Matrix3& kA, Matrix3& kL,
- Matrix3& kR) {
- float fT11 = kA[0][1] * kA[0][1] + kA[1][1] * kA[1][1];
- float fT22 = kA[1][2] * kA[1][2] + kA[2][2] * kA[2][2];
- float fT12 = kA[1][1] * kA[1][2];
- float fTrace = fT11 + fT22;
- float fDiff = fT11 - fT22;
- float fDiscr = sqrt(fDiff * fDiff + 4.0 * fT12 * fT12);
- float fRoot1 = 0.5 * (fTrace + fDiscr);
- float fRoot2 = 0.5 * (fTrace - fDiscr);
-
- // adjust right
- float fY = kA[0][0] - (G3D::abs(fRoot1 - fT22) <=
- G3D::abs(fRoot2 - fT22) ? fRoot1 : fRoot2);
- float fZ = kA[0][1];
- float fInvLength = 1.0 / sqrt(fY * fY + fZ * fZ);
- float fSin = fZ * fInvLength;
- float fCos = -fY * fInvLength;
-
- float fTmp0 = kA[0][0];
- float fTmp1 = kA[0][1];
- kA[0][0] = fCos * fTmp0 - fSin * fTmp1;
- kA[0][1] = fSin * fTmp0 + fCos * fTmp1;
- kA[1][0] = -fSin * kA[1][1];
- kA[1][1] *= fCos;
-
- int iRow;
-
- for (iRow = 0; iRow < 3; iRow++) {
- fTmp0 = kR[0][iRow];
- fTmp1 = kR[1][iRow];
- kR[0][iRow] = fCos * fTmp0 - fSin * fTmp1;
- kR[1][iRow] = fSin * fTmp0 + fCos * fTmp1;
- }
-
- // adjust left
- fY = kA[0][0];
-
- fZ = kA[1][0];
-
- fInvLength = 1.0 / sqrt(fY * fY + fZ * fZ);
-
- fSin = fZ * fInvLength;
-
- fCos = -fY * fInvLength;
-
- kA[0][0] = fCos * kA[0][0] - fSin * kA[1][0];
-
- fTmp0 = kA[0][1];
-
- fTmp1 = kA[1][1];
-
- kA[0][1] = fCos * fTmp0 - fSin * fTmp1;
-
- kA[1][1] = fSin * fTmp0 + fCos * fTmp1;
-
- kA[0][2] = -fSin * kA[1][2];
-
- kA[1][2] *= fCos;
-
- int iCol;
-
- for (iCol = 0; iCol < 3; iCol++) {
- fTmp0 = kL[iCol][0];
- fTmp1 = kL[iCol][1];
- kL[iCol][0] = fCos * fTmp0 - fSin * fTmp1;
- kL[iCol][1] = fSin * fTmp0 + fCos * fTmp1;
- }
-
- // adjust right
- fY = kA[0][1];
-
- fZ = kA[0][2];
-
- fInvLength = 1.0 / sqrt(fY * fY + fZ * fZ);
-
- fSin = fZ * fInvLength;
-
- fCos = -fY * fInvLength;
-
- kA[0][1] = fCos * kA[0][1] - fSin * kA[0][2];
-
- fTmp0 = kA[1][1];
-
- fTmp1 = kA[1][2];
-
- kA[1][1] = fCos * fTmp0 - fSin * fTmp1;
-
- kA[1][2] = fSin * fTmp0 + fCos * fTmp1;
-
- kA[2][1] = -fSin * kA[2][2];
-
- kA[2][2] *= fCos;
-
- for (iRow = 0; iRow < 3; iRow++) {
- fTmp0 = kR[1][iRow];
- fTmp1 = kR[2][iRow];
- kR[1][iRow] = fCos * fTmp0 - fSin * fTmp1;
- kR[2][iRow] = fSin * fTmp0 + fCos * fTmp1;
- }
-
- // adjust left
- fY = kA[1][1];
-
- fZ = kA[2][1];
-
- fInvLength = 1.0 / sqrt(fY * fY + fZ * fZ);
-
- fSin = fZ * fInvLength;
-
- fCos = -fY * fInvLength;
-
- kA[1][1] = fCos * kA[1][1] - fSin * kA[2][1];
-
- fTmp0 = kA[1][2];
-
- fTmp1 = kA[2][2];
-
- kA[1][2] = fCos * fTmp0 - fSin * fTmp1;
-
- kA[2][2] = fSin * fTmp0 + fCos * fTmp1;
-
- for (iCol = 0; iCol < 3; iCol++) {
- fTmp0 = kL[iCol][1];
- fTmp1 = kL[iCol][2];
- kL[iCol][1] = fCos * fTmp0 - fSin * fTmp1;
- kL[iCol][2] = fSin * fTmp0 + fCos * fTmp1;
- }
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::singularValueDecomposition (Matrix3& kL, Vector3& kS,
- Matrix3& kR) const {
- int iRow, iCol;
-
- Matrix3 kA = *this;
- bidiagonalize(kA, kL, kR);
-
- for (int i = 0; i < ms_iSvdMaxIterations; i++) {
- float fTmp, fTmp0, fTmp1;
- float fSin0, fCos0, fTan0;
- float fSin1, fCos1, fTan1;
-
- bool bTest1 = (G3D::abs(kA[0][1]) <=
- ms_fSvdEpsilon * (G3D::abs(kA[0][0]) + G3D::abs(kA[1][1])));
- bool bTest2 = (G3D::abs(kA[1][2]) <=
- ms_fSvdEpsilon * (G3D::abs(kA[1][1]) + G3D::abs(kA[2][2])));
-
- if ( bTest1 ) {
- if ( bTest2 ) {
- kS[0] = kA[0][0];
- kS[1] = kA[1][1];
- kS[2] = kA[2][2];
- break;
- } else {
- // 2x2 closed form factorization
- fTmp = (kA[1][1] * kA[1][1] - kA[2][2] * kA[2][2] +
- kA[1][2] * kA[1][2]) / (kA[1][2] * kA[2][2]);
- fTan0 = 0.5 * (fTmp + sqrt(fTmp * fTmp + 4.0));
- fCos0 = 1.0 / sqrt(1.0 + fTan0 * fTan0);
- fSin0 = fTan0 * fCos0;
-
- for (iCol = 0; iCol < 3; iCol++) {
- fTmp0 = kL[iCol][1];
- fTmp1 = kL[iCol][2];
- kL[iCol][1] = fCos0 * fTmp0 - fSin0 * fTmp1;
- kL[iCol][2] = fSin0 * fTmp0 + fCos0 * fTmp1;
- }
-
- fTan1 = (kA[1][2] - kA[2][2] * fTan0) / kA[1][1];
- fCos1 = 1.0 / sqrt(1.0 + fTan1 * fTan1);
- fSin1 = -fTan1 * fCos1;
-
- for (iRow = 0; iRow < 3; iRow++) {
- fTmp0 = kR[1][iRow];
- fTmp1 = kR[2][iRow];
- kR[1][iRow] = fCos1 * fTmp0 - fSin1 * fTmp1;
- kR[2][iRow] = fSin1 * fTmp0 + fCos1 * fTmp1;
- }
-
- kS[0] = kA[0][0];
- kS[1] = fCos0 * fCos1 * kA[1][1] -
- fSin1 * (fCos0 * kA[1][2] - fSin0 * kA[2][2]);
- kS[2] = fSin0 * fSin1 * kA[1][1] +
- fCos1 * (fSin0 * kA[1][2] + fCos0 * kA[2][2]);
- break;
- }
- } else {
- if ( bTest2 ) {
- // 2x2 closed form factorization
- fTmp = (kA[0][0] * kA[0][0] + kA[1][1] * kA[1][1] -
- kA[0][1] * kA[0][1]) / (kA[0][1] * kA[1][1]);
- fTan0 = 0.5 * ( -fTmp + sqrt(fTmp * fTmp + 4.0));
- fCos0 = 1.0 / sqrt(1.0 + fTan0 * fTan0);
- fSin0 = fTan0 * fCos0;
-
- for (iCol = 0; iCol < 3; iCol++) {
- fTmp0 = kL[iCol][0];
- fTmp1 = kL[iCol][1];
- kL[iCol][0] = fCos0 * fTmp0 - fSin0 * fTmp1;
- kL[iCol][1] = fSin0 * fTmp0 + fCos0 * fTmp1;
- }
-
- fTan1 = (kA[0][1] - kA[1][1] * fTan0) / kA[0][0];
- fCos1 = 1.0 / sqrt(1.0 + fTan1 * fTan1);
- fSin1 = -fTan1 * fCos1;
-
- for (iRow = 0; iRow < 3; iRow++) {
- fTmp0 = kR[0][iRow];
- fTmp1 = kR[1][iRow];
- kR[0][iRow] = fCos1 * fTmp0 - fSin1 * fTmp1;
- kR[1][iRow] = fSin1 * fTmp0 + fCos1 * fTmp1;
- }
-
- kS[0] = fCos0 * fCos1 * kA[0][0] -
- fSin1 * (fCos0 * kA[0][1] - fSin0 * kA[1][1]);
- kS[1] = fSin0 * fSin1 * kA[0][0] +
- fCos1 * (fSin0 * kA[0][1] + fCos0 * kA[1][1]);
- kS[2] = kA[2][2];
- break;
- } else {
- golubKahanStep(kA, kL, kR);
- }
- }
- }
-
- // positize diagonal
- for (iRow = 0; iRow < 3; iRow++) {
- if ( kS[iRow] < 0.0 ) {
- kS[iRow] = -kS[iRow];
-
- for (iCol = 0; iCol < 3; iCol++)
- kR[iRow][iCol] = -kR[iRow][iCol];
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::singularValueComposition (const Matrix3& kL,
- const Vector3& kS, const Matrix3& kR) {
- int iRow, iCol;
- Matrix3 kTmp;
-
- // product S*R
- for (iRow = 0; iRow < 3; iRow++) {
- for (iCol = 0; iCol < 3; iCol++)
- kTmp[iRow][iCol] = kS[iRow] * kR[iRow][iCol];
- }
-
- // product L*S*R
- for (iRow = 0; iRow < 3; iRow++) {
- for (iCol = 0; iCol < 3; iCol++) {
- elt[iRow][iCol] = 0.0;
-
- for (int iMid = 0; iMid < 3; iMid++)
- elt[iRow][iCol] += kL[iRow][iMid] * kTmp[iMid][iCol];
- }
- }
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::orthonormalize () {
- // Algorithm uses Gram-Schmidt orthogonalization. If 'this' matrix is
- // M = [m0|m1|m2], then orthonormal output matrix is Q = [q0|q1|q2],
- //
- // q0 = m0/|m0|
- // q1 = (m1-(q0*m1)q0)/|m1-(q0*m1)q0|
- // q2 = (m2-(q0*m2)q0-(q1*m2)q1)/|m2-(q0*m2)q0-(q1*m2)q1|
- //
- // where |V| indicates length of vector V and A*B indicates dot
- // product of vectors A and B.
-
- // compute q0
- float fInvLength = 1.0 / sqrt(elt[0][0] * elt[0][0]
- + elt[1][0] * elt[1][0] +
- elt[2][0] * elt[2][0]);
-
- elt[0][0] *= fInvLength;
- elt[1][0] *= fInvLength;
- elt[2][0] *= fInvLength;
-
- // compute q1
- float fDot0 =
- elt[0][0] * elt[0][1] +
- elt[1][0] * elt[1][1] +
- elt[2][0] * elt[2][1];
-
- elt[0][1] -= fDot0 * elt[0][0];
- elt[1][1] -= fDot0 * elt[1][0];
- elt[2][1] -= fDot0 * elt[2][0];
-
- fInvLength = 1.0 / sqrt(elt[0][1] * elt[0][1] +
- elt[1][1] * elt[1][1] +
- elt[2][1] * elt[2][1]);
-
- elt[0][1] *= fInvLength;
- elt[1][1] *= fInvLength;
- elt[2][1] *= fInvLength;
-
- // compute q2
- float fDot1 =
- elt[0][1] * elt[0][2] +
- elt[1][1] * elt[1][2] +
- elt[2][1] * elt[2][2];
-
- fDot0 =
- elt[0][0] * elt[0][2] +
- elt[1][0] * elt[1][2] +
- elt[2][0] * elt[2][2];
-
- elt[0][2] -= fDot0 * elt[0][0] + fDot1 * elt[0][1];
- elt[1][2] -= fDot0 * elt[1][0] + fDot1 * elt[1][1];
- elt[2][2] -= fDot0 * elt[2][0] + fDot1 * elt[2][1];
-
- fInvLength = 1.0 / sqrt(elt[0][2] * elt[0][2] +
- elt[1][2] * elt[1][2] +
- elt[2][2] * elt[2][2]);
-
- elt[0][2] *= fInvLength;
- elt[1][2] *= fInvLength;
- elt[2][2] *= fInvLength;
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::qDUDecomposition (Matrix3& kQ,
- Vector3& kD, Vector3& kU) const {
- // Factor M = QR = QDU where Q is orthogonal, D is diagonal,
- // and U is upper triangular with ones on its diagonal. Algorithm uses
- // Gram-Schmidt orthogonalization (the QR algorithm).
- //
- // If M = [ m0 | m1 | m2 ] and Q = [ q0 | q1 | q2 ], then
- //
- // q0 = m0/|m0|
- // q1 = (m1-(q0*m1)q0)/|m1-(q0*m1)q0|
- // q2 = (m2-(q0*m2)q0-(q1*m2)q1)/|m2-(q0*m2)q0-(q1*m2)q1|
- //
- // where |V| indicates length of vector V and A*B indicates dot
- // product of vectors A and B. The matrix R has entries
- //
- // r00 = q0*m0 r01 = q0*m1 r02 = q0*m2
- // r10 = 0 r11 = q1*m1 r12 = q1*m2
- // r20 = 0 r21 = 0 r22 = q2*m2
- //
- // so D = diag(r00,r11,r22) and U has entries u01 = r01/r00,
- // u02 = r02/r00, and u12 = r12/r11.
-
- // Q = rotation
- // D = scaling
- // U = shear
-
- // D stores the three diagonal entries r00, r11, r22
- // U stores the entries U[0] = u01, U[1] = u02, U[2] = u12
-
- // build orthogonal matrix Q
- float fInvLength = 1.0 / sqrt(elt[0][0] * elt[0][0]
- + elt[1][0] * elt[1][0] +
- elt[2][0] * elt[2][0]);
- kQ[0][0] = elt[0][0] * fInvLength;
- kQ[1][0] = elt[1][0] * fInvLength;
- kQ[2][0] = elt[2][0] * fInvLength;
-
- float fDot = kQ[0][0] * elt[0][1] + kQ[1][0] * elt[1][1] +
- kQ[2][0] * elt[2][1];
- kQ[0][1] = elt[0][1] - fDot * kQ[0][0];
- kQ[1][1] = elt[1][1] - fDot * kQ[1][0];
- kQ[2][1] = elt[2][1] - fDot * kQ[2][0];
- fInvLength = 1.0 / sqrt(kQ[0][1] * kQ[0][1] + kQ[1][1] * kQ[1][1] +
- kQ[2][1] * kQ[2][1]);
- kQ[0][1] *= fInvLength;
- kQ[1][1] *= fInvLength;
- kQ[2][1] *= fInvLength;
-
- fDot = kQ[0][0] * elt[0][2] + kQ[1][0] * elt[1][2] +
- kQ[2][0] * elt[2][2];
- kQ[0][2] = elt[0][2] - fDot * kQ[0][0];
- kQ[1][2] = elt[1][2] - fDot * kQ[1][0];
- kQ[2][2] = elt[2][2] - fDot * kQ[2][0];
- fDot = kQ[0][1] * elt[0][2] + kQ[1][1] * elt[1][2] +
- kQ[2][1] * elt[2][2];
- kQ[0][2] -= fDot * kQ[0][1];
- kQ[1][2] -= fDot * kQ[1][1];
- kQ[2][2] -= fDot * kQ[2][1];
- fInvLength = 1.0 / sqrt(kQ[0][2] * kQ[0][2] + kQ[1][2] * kQ[1][2] +
- kQ[2][2] * kQ[2][2]);
- kQ[0][2] *= fInvLength;
- kQ[1][2] *= fInvLength;
- kQ[2][2] *= fInvLength;
-
- // guarantee that orthogonal matrix has determinant 1 (no reflections)
- float fDet = kQ[0][0] * kQ[1][1] * kQ[2][2] + kQ[0][1] * kQ[1][2] * kQ[2][0] +
- kQ[0][2] * kQ[1][0] * kQ[2][1] - kQ[0][2] * kQ[1][1] * kQ[2][0] -
- kQ[0][1] * kQ[1][0] * kQ[2][2] - kQ[0][0] * kQ[1][2] * kQ[2][1];
-
- if ( fDet < 0.0 ) {
- for (int iRow = 0; iRow < 3; iRow++)
- for (int iCol = 0; iCol < 3; iCol++)
- kQ[iRow][iCol] = -kQ[iRow][iCol];
- }
-
- // build "right" matrix R
- Matrix3 kR;
-
- kR[0][0] = kQ[0][0] * elt[0][0] + kQ[1][0] * elt[1][0] +
- kQ[2][0] * elt[2][0];
-
- kR[0][1] = kQ[0][0] * elt[0][1] + kQ[1][0] * elt[1][1] +
- kQ[2][0] * elt[2][1];
-
- kR[1][1] = kQ[0][1] * elt[0][1] + kQ[1][1] * elt[1][1] +
- kQ[2][1] * elt[2][1];
-
- kR[0][2] = kQ[0][0] * elt[0][2] + kQ[1][0] * elt[1][2] +
- kQ[2][0] * elt[2][2];
-
- kR[1][2] = kQ[0][1] * elt[0][2] + kQ[1][1] * elt[1][2] +
- kQ[2][1] * elt[2][2];
-
- kR[2][2] = kQ[0][2] * elt[0][2] + kQ[1][2] * elt[1][2] +
- kQ[2][2] * elt[2][2];
-
- // the scaling component
- kD[0] = kR[0][0];
-
- kD[1] = kR[1][1];
-
- kD[2] = kR[2][2];
-
- // the shear component
- float fInvD0 = 1.0 / kD[0];
-
- kU[0] = kR[0][1] * fInvD0;
-
- kU[1] = kR[0][2] * fInvD0;
-
- kU[2] = kR[1][2] / kD[1];
-}
-
-//----------------------------------------------------------------------------
-float Matrix3::maxCubicRoot (float afCoeff[3]) {
- // Spectral norm is for A^T*A, so characteristic polynomial
- // P(x) = c[0]+c[1]*x+c[2]*x^2+x^3 has three positive float roots.
- // This yields the assertions c[0] < 0 and c[2]*c[2] >= 3*c[1].
-
- // quick out for uniform scale (triple root)
- const float fOneThird = 1.0f / 3.0f;
- const float fEpsilon = 1e-06f;
- float fDiscr = afCoeff[2] * afCoeff[2] - 3.0f * afCoeff[1];
-
- if ( fDiscr <= fEpsilon )
- return -fOneThird*afCoeff[2];
-
- // Compute an upper bound on roots of P(x). This assumes that A^T*A
- // has been scaled by its largest entry.
- float fX = 1.0f;
-
- float fPoly = afCoeff[0] + fX * (afCoeff[1] + fX * (afCoeff[2] + fX));
-
- if ( fPoly < 0.0f ) {
- // uses a matrix norm to find an upper bound on maximum root
- fX = G3D::abs(afCoeff[0]);
- float fTmp = 1.0 + G3D::abs(afCoeff[1]);
-
- if ( fTmp > fX )
- fX = fTmp;
-
- fTmp = 1.0 + G3D::abs(afCoeff[2]);
-
- if ( fTmp > fX )
- fX = fTmp;
- }
-
- // Newton's method to find root
- float fTwoC2 = 2.0f * afCoeff[2];
-
- for (int i = 0; i < 16; i++) {
- fPoly = afCoeff[0] + fX * (afCoeff[1] + fX * (afCoeff[2] + fX));
-
- if ( G3D::abs(fPoly) <= fEpsilon )
- return fX;
-
- float fDeriv = afCoeff[1] + fX * (fTwoC2 + 3.0f * fX);
-
- fX -= fPoly / fDeriv;
- }
-
- return fX;
-}
-
-//----------------------------------------------------------------------------
-float Matrix3::spectralNorm () const {
- Matrix3 kP;
- int iRow, iCol;
- float fPmax = 0.0;
-
- for (iRow = 0; iRow < 3; iRow++) {
- for (iCol = 0; iCol < 3; iCol++) {
- kP[iRow][iCol] = 0.0;
-
- for (int iMid = 0; iMid < 3; iMid++) {
- kP[iRow][iCol] +=
- elt[iMid][iRow] * elt[iMid][iCol];
- }
-
- if ( kP[iRow][iCol] > fPmax )
- fPmax = kP[iRow][iCol];
- }
- }
-
- float fInvPmax = 1.0 / fPmax;
-
- for (iRow = 0; iRow < 3; iRow++) {
- for (iCol = 0; iCol < 3; iCol++)
- kP[iRow][iCol] *= fInvPmax;
- }
-
- float afCoeff[3];
- afCoeff[0] = -(kP[0][0] * (kP[1][1] * kP[2][2] - kP[1][2] * kP[2][1]) +
- kP[0][1] * (kP[2][0] * kP[1][2] - kP[1][0] * kP[2][2]) +
- kP[0][2] * (kP[1][0] * kP[2][1] - kP[2][0] * kP[1][1]));
- afCoeff[1] = kP[0][0] * kP[1][1] - kP[0][1] * kP[1][0] +
- kP[0][0] * kP[2][2] - kP[0][2] * kP[2][0] +
- kP[1][1] * kP[2][2] - kP[1][2] * kP[2][1];
- afCoeff[2] = -(kP[0][0] + kP[1][1] + kP[2][2]);
-
- float fRoot = maxCubicRoot(afCoeff);
- float fNorm = sqrt(fPmax * fRoot);
- return fNorm;
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::toAxisAngle (Vector3& rkAxis, float& rfRadians) const {
- //
- // Let (x,y,z) be the unit-length axis and let A be an angle of rotation.
- // The rotation matrix is R = I + sin(A)*P + (1-cos(A))*P^2 (Rodrigues' formula) where
- // I is the identity and
- //
- // +- -+
- // P = | 0 -z +y |
- // | +z 0 -x |
- // | -y +x 0 |
- // +- -+
- //
- // If A > 0, R represents a counterclockwise rotation about the axis in
- // the sense of looking from the tip of the axis vector towards the
- // origin. Some algebra will show that
- //
- // cos(A) = (trace(R)-1)/2 and R - R^t = 2*sin(A)*P
- //
- // In the event that A = pi, R-R^t = 0 which prevents us from extracting
- // the axis through P. Instead note that R = I+2*P^2 when A = pi, so
- // P^2 = (R-I)/2. The diagonal entries of P^2 are x^2-1, y^2-1, and
- // z^2-1. We can solve these for axis (x,y,z). Because the angle is pi,
- // it does not matter which sign you choose on the square roots.
-
- float fTrace = elt[0][0] + elt[1][1] + elt[2][2];
- float fCos = 0.5f * (fTrace - 1.0f);
- rfRadians = G3D::aCos(fCos); // in [0,PI]
-
- if ( rfRadians > 0.0 ) {
- if ( rfRadians < pi() ) {
- rkAxis.x = elt[2][1] - elt[1][2];
- rkAxis.y = elt[0][2] - elt[2][0];
- rkAxis.z = elt[1][0] - elt[0][1];
- rkAxis.unitize();
- } else {
- // angle is PI
- float fHalfInverse;
-
- if ( elt[0][0] >= elt[1][1] ) {
- // r00 >= r11
- if ( elt[0][0] >= elt[2][2] ) {
- // r00 is maximum diagonal term
- rkAxis.x = 0.5 * sqrt(elt[0][0] -
- elt[1][1] - elt[2][2] + 1.0);
- fHalfInverse = 0.5 / rkAxis.x;
- rkAxis.y = fHalfInverse * elt[0][1];
- rkAxis.z = fHalfInverse * elt[0][2];
- } else {
- // r22 is maximum diagonal term
- rkAxis.z = 0.5 * sqrt(elt[2][2] -
- elt[0][0] - elt[1][1] + 1.0);
- fHalfInverse = 0.5 / rkAxis.z;
- rkAxis.x = fHalfInverse * elt[0][2];
- rkAxis.y = fHalfInverse * elt[1][2];
- }
- } else {
- // r11 > r00
- if ( elt[1][1] >= elt[2][2] ) {
- // r11 is maximum diagonal term
- rkAxis.y = 0.5 * sqrt(elt[1][1] -
- elt[0][0] - elt[2][2] + 1.0);
- fHalfInverse = 0.5 / rkAxis.y;
- rkAxis.x = fHalfInverse * elt[0][1];
- rkAxis.z = fHalfInverse * elt[1][2];
- } else {
- // r22 is maximum diagonal term
- rkAxis.z = 0.5 * sqrt(elt[2][2] -
- elt[0][0] - elt[1][1] + 1.0);
- fHalfInverse = 0.5 / rkAxis.z;
- rkAxis.x = fHalfInverse * elt[0][2];
- rkAxis.y = fHalfInverse * elt[1][2];
- }
- }
- }
- } else {
- // The angle is 0 and the matrix is the identity. Any axis will
- // work, so just use the x-axis.
- rkAxis.x = 1.0;
- rkAxis.y = 0.0;
- rkAxis.z = 0.0;
- }
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::fromAxisAngle (const Vector3& _axis, float fRadians) {
- Vector3 axis = _axis.direction();
-
- Matrix3 m;
- float fCos = cos(fRadians);
- float fSin = sin(fRadians);
- float fOneMinusCos = 1.0 - fCos;
- float fX2 = square(axis.x);
- float fY2 = square(axis.y);
- float fZ2 = square(axis.z);
- float fXYM = axis.x * axis.y * fOneMinusCos;
- float fXZM = axis.x * axis.z * fOneMinusCos;
- float fYZM = axis.y * axis.z * fOneMinusCos;
- float fXSin = axis.x * fSin;
- float fYSin = axis.y * fSin;
- float fZSin = axis.z * fSin;
-
- m.elt[0][0] = fX2 * fOneMinusCos + fCos;
- m.elt[0][1] = fXYM - fZSin;
- m.elt[0][2] = fXZM + fYSin;
-
- m.elt[1][0] = fXYM + fZSin;
- m.elt[1][1] = fY2 * fOneMinusCos + fCos;
- m.elt[1][2] = fYZM - fXSin;
-
- m.elt[2][0] = fXZM - fYSin;
- m.elt[2][1] = fYZM + fXSin;
- m.elt[2][2] = fZ2 * fOneMinusCos + fCos;
-
- return m;
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::toEulerAnglesXYZ (float& rfXAngle, float& rfYAngle,
- float& rfZAngle) const {
- // rot = cy*cz -cy*sz sy
- // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx
- // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy
-
- if ( elt[0][2] < 1.0f ) {
- if ( elt[0][2] > -1.0f ) {
- rfXAngle = G3D::aTan2( -elt[1][2], elt[2][2]);
- rfYAngle = (float) G3D::aSin(elt[0][2]);
- rfZAngle = G3D::aTan2( -elt[0][1], elt[0][0]);
- return true;
- } else {
- // WARNING. Not unique. XA - ZA = -atan2(r10,r11)
- rfXAngle = -G3D::aTan2(elt[1][0], elt[1][1]);
- rfYAngle = -(float)halfPi();
- rfZAngle = 0.0f;
- return false;
- }
- } else {
- // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11)
- rfXAngle = G3D::aTan2(elt[1][0], elt[1][1]);
- rfYAngle = (float)halfPi();
- rfZAngle = 0.0f;
- return false;
- }
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::toEulerAnglesXZY (float& rfXAngle, float& rfZAngle,
- float& rfYAngle) const {
- // rot = cy*cz -sz cz*sy
- // sx*sy+cx*cy*sz cx*cz -cy*sx+cx*sy*sz
- // -cx*sy+cy*sx*sz cz*sx cx*cy+sx*sy*sz
-
- if ( elt[0][1] < 1.0f ) {
- if ( elt[0][1] > -1.0f ) {
- rfXAngle = G3D::aTan2(elt[2][1], elt[1][1]);
- rfZAngle = (float) asin( -elt[0][1]);
- rfYAngle = G3D::aTan2(elt[0][2], elt[0][0]);
- return true;
- } else {
- // WARNING. Not unique. XA - YA = atan2(r20,r22)
- rfXAngle = G3D::aTan2(elt[2][0], elt[2][2]);
- rfZAngle = (float)halfPi();
- rfYAngle = 0.0;
- return false;
- }
- } else {
- // WARNING. Not unique. XA + YA = atan2(-r20,r22)
- rfXAngle = G3D::aTan2( -elt[2][0], elt[2][2]);
- rfZAngle = -(float)halfPi();
- rfYAngle = 0.0f;
- return false;
- }
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::toEulerAnglesYXZ (float& rfYAngle, float& rfXAngle,
- float& rfZAngle) const {
- // rot = cy*cz+sx*sy*sz cz*sx*sy-cy*sz cx*sy
- // cx*sz cx*cz -sx
- // -cz*sy+cy*sx*sz cy*cz*sx+sy*sz cx*cy
-
- if ( elt[1][2] < 1.0 ) {
- if ( elt[1][2] > -1.0 ) {
- rfYAngle = G3D::aTan2(elt[0][2], elt[2][2]);
- rfXAngle = (float) asin( -elt[1][2]);
- rfZAngle = G3D::aTan2(elt[1][0], elt[1][1]);
- return true;
- } else {
- // WARNING. Not unique. YA - ZA = atan2(r01,r00)
- rfYAngle = G3D::aTan2(elt[0][1], elt[0][0]);
- rfXAngle = (float)halfPi();
- rfZAngle = 0.0;
- return false;
- }
- } else {
- // WARNING. Not unique. YA + ZA = atan2(-r01,r00)
- rfYAngle = G3D::aTan2( -elt[0][1], elt[0][0]);
- rfXAngle = -(float)halfPi();
- rfZAngle = 0.0f;
- return false;
- }
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::toEulerAnglesYZX (float& rfYAngle, float& rfZAngle,
- float& rfXAngle) const {
- // rot = cy*cz sx*sy-cx*cy*sz cx*sy+cy*sx*sz
- // sz cx*cz -cz*sx
- // -cz*sy cy*sx+cx*sy*sz cx*cy-sx*sy*sz
-
- if ( elt[1][0] < 1.0 ) {
- if ( elt[1][0] > -1.0 ) {
- rfYAngle = G3D::aTan2( -elt[2][0], elt[0][0]);
- rfZAngle = (float) asin(elt[1][0]);
- rfXAngle = G3D::aTan2( -elt[1][2], elt[1][1]);
- return true;
- } else {
- // WARNING. Not unique. YA - XA = -atan2(r21,r22);
- rfYAngle = -G3D::aTan2(elt[2][1], elt[2][2]);
- rfZAngle = -(float)halfPi();
- rfXAngle = 0.0;
- return false;
- }
- } else {
- // WARNING. Not unique. YA + XA = atan2(r21,r22)
- rfYAngle = G3D::aTan2(elt[2][1], elt[2][2]);
- rfZAngle = (float)halfPi();
- rfXAngle = 0.0f;
- return false;
- }
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::toEulerAnglesZXY (float& rfZAngle, float& rfXAngle,
- float& rfYAngle) const {
- // rot = cy*cz-sx*sy*sz -cx*sz cz*sy+cy*sx*sz
- // cz*sx*sy+cy*sz cx*cz -cy*cz*sx+sy*sz
- // -cx*sy sx cx*cy
-
- if ( elt[2][1] < 1.0 ) {
- if ( elt[2][1] > -1.0 ) {
- rfZAngle = G3D::aTan2( -elt[0][1], elt[1][1]);
- rfXAngle = (float) asin(elt[2][1]);
- rfYAngle = G3D::aTan2( -elt[2][0], elt[2][2]);
- return true;
- } else {
- // WARNING. Not unique. ZA - YA = -atan(r02,r00)
- rfZAngle = -G3D::aTan2(elt[0][2], elt[0][0]);
- rfXAngle = -(float)halfPi();
- rfYAngle = 0.0f;
- return false;
- }
- } else {
- // WARNING. Not unique. ZA + YA = atan2(r02,r00)
- rfZAngle = G3D::aTan2(elt[0][2], elt[0][0]);
- rfXAngle = (float)halfPi();
- rfYAngle = 0.0f;
- return false;
- }
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::toEulerAnglesZYX (float& rfZAngle, float& rfYAngle,
- float& rfXAngle) const {
- // rot = cy*cz cz*sx*sy-cx*sz cx*cz*sy+sx*sz
- // cy*sz cx*cz+sx*sy*sz -cz*sx+cx*sy*sz
- // -sy cy*sx cx*cy
-
- if ( elt[2][0] < 1.0 ) {
- if ( elt[2][0] > -1.0 ) {
- rfZAngle = atan2f(elt[1][0], elt[0][0]);
- rfYAngle = asinf(-(double)elt[2][1]);
- rfXAngle = atan2f(elt[2][1], elt[2][2]);
- return true;
- } else {
- // WARNING. Not unique. ZA - XA = -atan2(r01,r02)
- rfZAngle = -G3D::aTan2(elt[0][1], elt[0][2]);
- rfYAngle = (float)halfPi();
- rfXAngle = 0.0f;
- return false;
- }
- } else {
- // WARNING. Not unique. ZA + XA = atan2(-r01,-r02)
- rfZAngle = G3D::aTan2( -elt[0][1], -elt[0][2]);
- rfYAngle = -(float)halfPi();
- rfXAngle = 0.0f;
- return false;
- }
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::fromEulerAnglesXYZ (float fYAngle, float fPAngle,
- float fRAngle) {
- float fCos, fSin;
-
- fCos = cosf(fYAngle);
- fSin = sinf(fYAngle);
- Matrix3 kXMat(1.0f, 0.0f, 0.0f, 0.0f, fCos, -fSin, 0.0, fSin, fCos);
-
- fCos = cosf(fPAngle);
- fSin = sinf(fPAngle);
- Matrix3 kYMat(fCos, 0.0f, fSin, 0.0f, 1.0f, 0.0f, -fSin, 0.0f, fCos);
-
- fCos = cosf(fRAngle);
- fSin = sinf(fRAngle);
- Matrix3 kZMat(fCos, -fSin, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 1.0f);
-
- return kXMat * (kYMat * kZMat);
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::fromEulerAnglesXZY (float fYAngle, float fPAngle,
- float fRAngle) {
-
- float fCos, fSin;
-
- fCos = cosf(fYAngle);
- fSin = sinf(fYAngle);
- Matrix3 kXMat(1.0, 0.0, 0.0, 0.0, fCos, -fSin, 0.0, fSin, fCos);
-
- fCos = cosf(fPAngle);
- fSin = sinf(fPAngle);
- Matrix3 kZMat(fCos, -fSin, 0.0, fSin, fCos, 0.0, 0.0, 0.0, 1.0);
-
- fCos = cosf(fRAngle);
- fSin = sinf(fRAngle);
- Matrix3 kYMat(fCos, 0.0, fSin, 0.0, 1.0, 0.0, -fSin, 0.0, fCos);
-
- return kXMat * (kZMat * kYMat);
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::fromEulerAnglesYXZ(
- float fYAngle,
- float fPAngle,
- float fRAngle) {
-
- float fCos, fSin;
-
- fCos = cos(fYAngle);
- fSin = sin(fYAngle);
- Matrix3 kYMat(fCos, 0.0f, fSin, 0.0f, 1.0f, 0.0f, -fSin, 0.0f, fCos);
-
- fCos = cos(fPAngle);
- fSin = sin(fPAngle);
- Matrix3 kXMat(1.0f, 0.0f, 0.0f, 0.0f, fCos, -fSin, 0.0f, fSin, fCos);
-
- fCos = cos(fRAngle);
- fSin = sin(fRAngle);
- Matrix3 kZMat(fCos, -fSin, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 1.0f);
-
- return kYMat * (kXMat * kZMat);
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::fromEulerAnglesYZX(
- float fYAngle,
- float fPAngle,
- float fRAngle) {
-
- float fCos, fSin;
-
- fCos = cos(fYAngle);
- fSin = sin(fYAngle);
- Matrix3 kYMat(fCos, 0.0f, fSin, 0.0f, 1.0f, 0.0f, -fSin, 0.0f, fCos);
-
- fCos = cos(fPAngle);
- fSin = sin(fPAngle);
- Matrix3 kZMat(fCos, -fSin, 0.0f, fSin, fCos, 0.0f, 0.0f, 0.0f, 1.0f);
-
- fCos = cos(fRAngle);
- fSin = sin(fRAngle);
- Matrix3 kXMat(1.0f, 0.0f, 0.0f, 0.0f, fCos, -fSin, 0.0f, fSin, fCos);
-
- return kYMat * (kZMat * kXMat);
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::fromEulerAnglesZXY (float fYAngle, float fPAngle,
- float fRAngle) {
- float fCos, fSin;
-
- fCos = cos(fYAngle);
- fSin = sin(fYAngle);
- Matrix3 kZMat(fCos, -fSin, 0.0, fSin, fCos, 0.0, 0.0, 0.0, 1.0);
-
- fCos = cos(fPAngle);
- fSin = sin(fPAngle);
- Matrix3 kXMat(1.0, 0.0, 0.0, 0.0, fCos, -fSin, 0.0, fSin, fCos);
-
- fCos = cos(fRAngle);
- fSin = sin(fRAngle);
- Matrix3 kYMat(fCos, 0.0, fSin, 0.0, 1.0, 0.0, -fSin, 0.0, fCos);
-
- return kZMat * (kXMat * kYMat);
-}
-
-//----------------------------------------------------------------------------
-Matrix3 Matrix3::fromEulerAnglesZYX (float fYAngle, float fPAngle,
- float fRAngle) {
- float fCos, fSin;
-
- fCos = cos(fYAngle);
- fSin = sin(fYAngle);
- Matrix3 kZMat(fCos, -fSin, 0.0, fSin, fCos, 0.0, 0.0, 0.0, 1.0);
-
- fCos = cos(fPAngle);
- fSin = sin(fPAngle);
- Matrix3 kYMat(fCos, 0.0, fSin, 0.0, 1.0, 0.0, -fSin, 0.0, fCos);
-
- fCos = cos(fRAngle);
- fSin = sin(fRAngle);
- Matrix3 kXMat(1.0, 0.0, 0.0, 0.0, fCos, -fSin, 0.0, fSin, fCos);
-
- return kZMat * (kYMat * kXMat);
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::tridiagonal (float afDiag[3], float afSubDiag[3]) {
- // Householder reduction T = Q^t M Q
- // Input:
- // mat, symmetric 3x3 matrix M
- // Output:
- // mat, orthogonal matrix Q
- // diag, diagonal entries of T
- // subd, subdiagonal entries of T (T is symmetric)
-
- float fA = elt[0][0];
- float fB = elt[0][1];
- float fC = elt[0][2];
- float fD = elt[1][1];
- float fE = elt[1][2];
- float fF = elt[2][2];
-
- afDiag[0] = fA;
- afSubDiag[2] = 0.0;
-
- if ( G3D::abs(fC) >= EPSILON ) {
- float fLength = sqrt(fB * fB + fC * fC);
- float fInvLength = 1.0 / fLength;
- fB *= fInvLength;
- fC *= fInvLength;
- float fQ = 2.0 * fB * fE + fC * (fF - fD);
- afDiag[1] = fD + fC * fQ;
- afDiag[2] = fF - fC * fQ;
- afSubDiag[0] = fLength;
- afSubDiag[1] = fE - fB * fQ;
- elt[0][0] = 1.0;
- elt[0][1] = 0.0;
- elt[0][2] = 0.0;
- elt[1][0] = 0.0;
- elt[1][1] = fB;
- elt[1][2] = fC;
- elt[2][0] = 0.0;
- elt[2][1] = fC;
- elt[2][2] = -fB;
- } else {
- afDiag[1] = fD;
- afDiag[2] = fF;
- afSubDiag[0] = fB;
- afSubDiag[1] = fE;
- elt[0][0] = 1.0;
- elt[0][1] = 0.0;
- elt[0][2] = 0.0;
- elt[1][0] = 0.0;
- elt[1][1] = 1.0;
- elt[1][2] = 0.0;
- elt[2][0] = 0.0;
- elt[2][1] = 0.0;
- elt[2][2] = 1.0;
- }
-}
-
-//----------------------------------------------------------------------------
-bool Matrix3::qLAlgorithm (float afDiag[3], float afSubDiag[3]) {
- // QL iteration with implicit shifting to reduce matrix from tridiagonal
- // to diagonal
-
- for (int i0 = 0; i0 < 3; i0++) {
- const int iMaxIter = 32;
- int iIter;
-
- for (iIter = 0; iIter < iMaxIter; iIter++) {
- int i1;
-
- for (i1 = i0; i1 <= 1; i1++) {
- float fSum = G3D::abs(afDiag[i1]) +
- G3D::abs(afDiag[i1 + 1]);
-
- if ( G3D::abs(afSubDiag[i1]) + fSum == fSum )
- break;
- }
-
- if ( i1 == i0 )
- break;
-
- float fTmp0 = (afDiag[i0 + 1] - afDiag[i0]) / (2.0 * afSubDiag[i0]);
-
- float fTmp1 = sqrt(fTmp0 * fTmp0 + 1.0);
-
- if ( fTmp0 < 0.0 )
- fTmp0 = afDiag[i1] - afDiag[i0] + afSubDiag[i0] / (fTmp0 - fTmp1);
- else
- fTmp0 = afDiag[i1] - afDiag[i0] + afSubDiag[i0] / (fTmp0 + fTmp1);
-
- float fSin = 1.0;
-
- float fCos = 1.0;
-
- float fTmp2 = 0.0;
-
- for (int i2 = i1 - 1; i2 >= i0; i2--) {
- float fTmp3 = fSin * afSubDiag[i2];
- float fTmp4 = fCos * afSubDiag[i2];
-
- if (G3D::abs(fTmp3) >= G3D::abs(fTmp0)) {
- fCos = fTmp0 / fTmp3;
- fTmp1 = sqrt(fCos * fCos + 1.0);
- afSubDiag[i2 + 1] = fTmp3 * fTmp1;
- fSin = 1.0 / fTmp1;
- fCos *= fSin;
- } else {
- fSin = fTmp3 / fTmp0;
- fTmp1 = sqrt(fSin * fSin + 1.0);
- afSubDiag[i2 + 1] = fTmp0 * fTmp1;
- fCos = 1.0 / fTmp1;
- fSin *= fCos;
- }
-
- fTmp0 = afDiag[i2 + 1] - fTmp2;
- fTmp1 = (afDiag[i2] - fTmp0) * fSin + 2.0 * fTmp4 * fCos;
- fTmp2 = fSin * fTmp1;
- afDiag[i2 + 1] = fTmp0 + fTmp2;
- fTmp0 = fCos * fTmp1 - fTmp4;
-
- for (int iRow = 0; iRow < 3; iRow++) {
- fTmp3 = elt[iRow][i2 + 1];
- elt[iRow][i2 + 1] = fSin * elt[iRow][i2] +
- fCos * fTmp3;
- elt[iRow][i2] = fCos * elt[iRow][i2] -
- fSin * fTmp3;
- }
- }
-
- afDiag[i0] -= fTmp2;
- afSubDiag[i0] = fTmp0;
- afSubDiag[i1] = 0.0;
- }
-
- if ( iIter == iMaxIter ) {
- // should not get here under normal circumstances
- return false;
- }
- }
-
- return true;
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::eigenSolveSymmetric (float afEigenvalue[3],
- Vector3 akEigenvector[3]) const {
- Matrix3 kMatrix = *this;
- float afSubDiag[3];
- kMatrix.tridiagonal(afEigenvalue, afSubDiag);
- kMatrix.qLAlgorithm(afEigenvalue, afSubDiag);
-
- for (int i = 0; i < 3; i++) {
- akEigenvector[i][0] = kMatrix[0][i];
- akEigenvector[i][1] = kMatrix[1][i];
- akEigenvector[i][2] = kMatrix[2][i];
- }
-
- // make eigenvectors form a right--handed system
- Vector3 kCross = akEigenvector[1].cross(akEigenvector[2]);
-
- float fDet = akEigenvector[0].dot(kCross);
-
- if ( fDet < 0.0 ) {
- akEigenvector[2][0] = - akEigenvector[2][0];
- akEigenvector[2][1] = - akEigenvector[2][1];
- akEigenvector[2][2] = - akEigenvector[2][2];
- }
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::tensorProduct (const Vector3& rkU, const Vector3& rkV,
- Matrix3& rkProduct) {
- for (int iRow = 0; iRow < 3; iRow++) {
- for (int iCol = 0; iCol < 3; iCol++) {
- rkProduct[iRow][iCol] = rkU[iRow] * rkV[iCol];
- }
- }
-}
-
-//----------------------------------------------------------------------------
-
-// Runs in 52 cycles on AMD, 76 cycles on Intel Centrino
-//
-// The loop unrolling is necessary for performance.
-// I was unable to improve performance further by flattening the matrices
-// into float*'s instead of 2D arrays.
-//
-// -morgan
-void Matrix3::_mul(const Matrix3& A, const Matrix3& B, Matrix3& out) {
- const float* ARowPtr = A.elt[0];
- float* outRowPtr = out.elt[0];
- outRowPtr[0] =
- ARowPtr[0] * B.elt[0][0] +
- ARowPtr[1] * B.elt[1][0] +
- ARowPtr[2] * B.elt[2][0];
- outRowPtr[1] =
- ARowPtr[0] * B.elt[0][1] +
- ARowPtr[1] * B.elt[1][1] +
- ARowPtr[2] * B.elt[2][1];
- outRowPtr[2] =
- ARowPtr[0] * B.elt[0][2] +
- ARowPtr[1] * B.elt[1][2] +
- ARowPtr[2] * B.elt[2][2];
-
- ARowPtr = A.elt[1];
- outRowPtr = out.elt[1];
-
- outRowPtr[0] =
- ARowPtr[0] * B.elt[0][0] +
- ARowPtr[1] * B.elt[1][0] +
- ARowPtr[2] * B.elt[2][0];
- outRowPtr[1] =
- ARowPtr[0] * B.elt[0][1] +
- ARowPtr[1] * B.elt[1][1] +
- ARowPtr[2] * B.elt[2][1];
- outRowPtr[2] =
- ARowPtr[0] * B.elt[0][2] +
- ARowPtr[1] * B.elt[1][2] +
- ARowPtr[2] * B.elt[2][2];
-
- ARowPtr = A.elt[2];
- outRowPtr = out.elt[2];
-
- outRowPtr[0] =
- ARowPtr[0] * B.elt[0][0] +
- ARowPtr[1] * B.elt[1][0] +
- ARowPtr[2] * B.elt[2][0];
- outRowPtr[1] =
- ARowPtr[0] * B.elt[0][1] +
- ARowPtr[1] * B.elt[1][1] +
- ARowPtr[2] * B.elt[2][1];
- outRowPtr[2] =
- ARowPtr[0] * B.elt[0][2] +
- ARowPtr[1] * B.elt[1][2] +
- ARowPtr[2] * B.elt[2][2];
-}
-
-//----------------------------------------------------------------------------
-void Matrix3::_transpose(const Matrix3& A, Matrix3& out) {
- out[0][0] = A.elt[0][0];
- out[0][1] = A.elt[1][0];
- out[0][2] = A.elt[2][0];
- out[1][0] = A.elt[0][1];
- out[1][1] = A.elt[1][1];
- out[1][2] = A.elt[2][1];
- out[2][0] = A.elt[0][2];
- out[2][1] = A.elt[1][2];
- out[2][2] = A.elt[2][2];
-}
-
-//-----------------------------------------------------------------------------
-std::string Matrix3::toString() const {
- return G3D::format("[%g, %g, %g; %g, %g, %g; %g, %g, %g]",
- elt[0][0], elt[0][1], elt[0][2],
- elt[1][0], elt[1][1], elt[1][2],
- elt[2][0], elt[2][1], elt[2][2]);
-}
-
-
-
-} // namespace
-
diff --git a/externals/g3dlite/G3D.lib/source/Matrix4.cpp b/externals/g3dlite/G3D.lib/source/Matrix4.cpp
deleted file mode 100644
index 091af4a9bd5..00000000000
--- a/externals/g3dlite/G3D.lib/source/Matrix4.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-/**
- @file Matrix4.cpp
-
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-10-02
- @edited 2008-07-17
- */
-
-#include "G3D/platform.h"
-#include "G3D/Matrix4.h"
-#include "G3D/Matrix3.h"
-#include "G3D/Vector4.h"
-#include "G3D/Vector3.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/CoordinateFrame.h"
-#include "G3D/Rect2D.h"
-
-namespace G3D {
-
-const Matrix4& Matrix4::identity() {
- static Matrix4 m(
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- return m;
-}
-
-
-const Matrix4& Matrix4::zero() {
- static Matrix4 m(
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0);
- return m;
-}
-
-
-Matrix4::Matrix4(const class CoordinateFrame& cframe) {
- for (int r = 0; r < 3; ++r) {
- for (int c = 0; c < 3; ++c) {
- elt[r][c] = cframe.rotation[r][c];
- }
- elt[r][3] = cframe.translation[r];
- }
- elt[3][0] = 0.0f;
- elt[3][1] = 0.0f;
- elt[3][2] = 0.0f;
- elt[3][3] = 1.0f;
-}
-
-Matrix4::Matrix4(const Matrix3& upper3x3, const Vector3& lastCol) {
- for (int r = 0; r < 3; ++r) {
- for (int c = 0; c < 3; ++c) {
- elt[r][c] = upper3x3[r][c];
- }
- elt[r][3] = lastCol[r];
- }
- elt[3][0] = 0.0f;
- elt[3][1] = 0.0f;
- elt[3][2] = 0.0f;
- elt[3][3] = 1.0f;
-}
-
-
-Matrix3 Matrix4::upper3x3() const {
- return Matrix3(elt[0][0], elt[0][1], elt[0][2],
- elt[1][0], elt[1][1], elt[1][2],
- elt[2][0], elt[2][1], elt[2][2]);
-}
-
-
-Matrix4 Matrix4::orthogonalProjection(
- const class Rect2D& rect,
- float nearval,
- float farval) {
- return Matrix4::orthogonalProjection(rect.x0(), rect.x1(), rect.y1(), rect.y0(), nearval, farval);
-}
-
-
-Matrix4 Matrix4::orthogonalProjection(
- float left,
- float right,
- float bottom,
- float top,
- float nearval,
- float farval) {
-
- // Adapted from Mesa. Note that Microsoft (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/glfunc03_8qnj.asp)
- // and Linux (http://www.xfree86.org/current/glOrtho.3.html) have different matrices shown in their documentation.
-
- float x, y, z;
- float tx, ty, tz;
-
- x = 2.0f / (right-left);
- y = 2.0f / (top-bottom);
- z = -2.0f / (farval-nearval);
- tx = -(right+left) / (right-left);
- ty = -(top+bottom) / (top-bottom);
- tz = -(farval+nearval) / (farval-nearval);
-
- return
- Matrix4( x , 0.0f, 0.0f, tx,
- 0.0f, y , 0.0f, ty,
- 0.0f, 0.0f, z , tz,
- 0.0f, 0.0f, 0.0f, 1.0f);
-}
-
-
-Matrix4 Matrix4::perspectiveProjection(
- float left,
- float right,
- float bottom,
- float top,
- float nearval,
- float farval) {
-
- float x, y, a, b, c, d;
-
- x = (2.0f*nearval) / (right-left);
- y = (2.0f*nearval) / (top-bottom);
- a = (right+left) / (right-left);
- b = (top+bottom) / (top-bottom);
-
- if ((float)farval >= (float)inf()) {
- // Infinite view frustum
- c = -1.0f;
- d = -2.0f * nearval;
- } else {
- c = -(farval+nearval) / (farval-nearval);
- d = -(2.0f*farval*nearval) / (farval-nearval);
- }
-
- return Matrix4(
- x, 0, a, 0,
- 0, y, b, 0,
- 0, 0, c, d,
- 0, 0, -1, 0);
-}
-
-
-Matrix4::Matrix4(
- float r1c1, float r1c2, float r1c3, float r1c4,
- float r2c1, float r2c2, float r2c3, float r2c4,
- float r3c1, float r3c2, float r3c3, float r3c4,
- float r4c1, float r4c2, float r4c3, float r4c4) {
- elt[0][0] = r1c1; elt[0][1] = r1c2; elt[0][2] = r1c3; elt[0][3] = r1c4;
- elt[1][0] = r2c1; elt[1][1] = r2c2; elt[1][2] = r2c3; elt[1][3] = r2c4;
- elt[2][0] = r3c1; elt[2][1] = r3c2; elt[2][2] = r3c3; elt[2][3] = r3c4;
- elt[3][0] = r4c1; elt[3][1] = r4c2; elt[3][2] = r4c3; elt[3][3] = r4c4;
-}
-
-/**
- init should be <B>row major</B>.
- */
-Matrix4::Matrix4(const float* init) {
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- elt[r][c] = init[r * 4 + c];
- }
- }
-}
-
-
-Matrix4::Matrix4(const double* init) {
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- elt[r][c] = (float)init[r * 4 + c];
- }
- }
-}
-
-
-Matrix4::Matrix4() {
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- elt[r][c] = 0;
- }
- }
-}
-
-
-void Matrix4::setRow(int r, const Vector4& v) {
- for (int c = 0; c < 4; ++c) {
- elt[r][c] = v[c];
- }
-}
-
-
-void Matrix4::setColumn(int c, const Vector4& v) {
- for (int r = 0; r < 4; ++r) {
- elt[r][c] = v[r];
- }
-}
-
-
-Vector4 Matrix4::getRow(int r) const {
- return row(r);
-}
-
-
-const Vector4& Matrix4::row(int r) const {
- return reinterpret_cast<const Vector4*>(elt[r])[0];
-}
-
-
-Vector4 Matrix4::getColumn(int c) const {
- return column(c);
-}
-
-Vector4 Matrix4::column(int c) const {
- Vector4 v;
- for (int r = 0; r < 4; ++r) {
- v[r] = elt[r][c];
- }
- return v;
-}
-
-
-Matrix4 Matrix4::operator*(const Matrix4& other) const {
- Matrix4 result;
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- for (int i = 0; i < 4; ++i) {
- result.elt[r][c] += elt[r][i] * other.elt[i][c];
- }
- }
- }
-
- return result;
-}
-
-
-Matrix4 Matrix4::operator*(const float s) const {
- Matrix4 result;
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- result.elt[r][c] = elt[r][c] * s;
- }
- }
-
- return result;
-}
-
-
-Vector3 Matrix4::homoMul(const class Vector3& v, float w) const {
- Vector4 r = (*this) * Vector4(v, w);
- return r.xyz() * (1.0f / r.w);
-}
-
-
-Vector4 Matrix4::operator*(const Vector4& vector) const {
- Vector4 result(0,0,0,0);
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- result[r] += elt[r][c] * vector[c];
- }
- }
-
- return result;
-}
-
-
-Matrix4 Matrix4::transpose() const {
- Matrix4 result;
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- result.elt[c][r] = elt[r][c];
- }
- }
-
- return result;
-}
-
-
-bool Matrix4::operator!=(const Matrix4& other) const {
- return ! (*this == other);
-}
-
-
-bool Matrix4::operator==(const Matrix4& other) const {
-
- // If the bit patterns are identical, they must be
- // the same matrix. If not, they *might* still have
- // equal elements due to floating point weirdness.
- if (memcmp(this, &other, sizeof(Matrix4) == 0)) {
- return true;
- }
-
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- if (elt[r][c] != other.elt[r][c]) {
- return false;
- }
- }
- }
-
- return true;
-}
-
-
-float Matrix4::determinant() const {
- // Determinant is the dot product of the first row and the first row
- // of cofactors (i.e. the first col of the adjoint matrix)
- return cofactor().getRow(0).dot(getRow(0));
-}
-
-
-Matrix4 Matrix4::adjoint() const {
- return cofactor().transpose();
-}
-
-
-Matrix4 Matrix4::inverse() const {
- // Inverse = adjoint / determinant
-
- Matrix4 A = adjoint();
-
- // Determinant is the dot product of the first row and the first row
- // of cofactors (i.e. the first col of the adjoint matrix)
- float det = A.getColumn(0).dot(getRow(0));
-
- return A * (1.0f / det);
-}
-
-
-Matrix4 Matrix4::cofactor() const {
- Matrix4 out;
-
- // We'll use i to incrementally compute -1 ^ (r+c)
- int i = 1;
-
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- // Compute the determinant of the 3x3 submatrix
- float det = subDeterminant(r, c);
- out.elt[r][c] = i * det;
- i = -i;
- }
- i = -i;
- }
-
- return out;
-}
-
-
-float Matrix4::subDeterminant(int excludeRow, int excludeCol) const {
- // Compute non-excluded row and column indices
- int row[3];
- int col[3];
-
- for (int i = 0; i < 3; ++i) {
- row[i] = i;
- col[i] = i;
-
- if (i >= excludeRow) {
- ++row[i];
- }
- if (i >= excludeCol) {
- ++col[i];
- }
- }
-
- // Compute the first row of cofactors
- float cofactor00 =
- elt[row[1]][col[1]] * elt[row[2]][col[2]] -
- elt[row[1]][col[2]] * elt[row[2]][col[1]];
-
- float cofactor10 =
- elt[row[1]][col[2]] * elt[row[2]][col[0]] -
- elt[row[1]][col[0]] * elt[row[2]][col[2]];
-
- float cofactor20 =
- elt[row[1]][col[0]] * elt[row[2]][col[1]] -
- elt[row[1]][col[1]] * elt[row[2]][col[0]];
-
- // Product of the first row and the cofactors along the first row
- return
- elt[row[0]][col[0]] * cofactor00 +
- elt[row[0]][col[1]] * cofactor10 +
- elt[row[0]][col[2]] * cofactor20;
-}
-
-
-CoordinateFrame Matrix4::approxCoordinateFrame() const {
- CoordinateFrame cframe;
-
- for (int r = 0; r < 3; ++r) {
- for (int c = 0; c < 3; ++c) {
- cframe.rotation[r][c] = elt[r][c];
- }
- cframe.translation[r] = elt[r][3];
- }
-
- // Ensure that the rotation matrix is orthonormal
- cframe.rotation.orthonormalize();
-
- return cframe;
-}
-
-
-void Matrix4::serialize(class BinaryOutput& b) const {
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- b.writeFloat32(elt[r][c]);
- }
- }
-}
-
-
-void Matrix4::deserialize(class BinaryInput& b) {
- for (int r = 0; r < 4; ++r) {
- for (int c = 0; c < 4; ++c) {
- elt[r][c] = b.readFloat32();
- }
- }
-}
-
-std::string Matrix4::toString() const {
- return G3D::format("[%g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g; %g, %g, %g, %g]",
- elt[0][0], elt[0][1], elt[0][2], elt[0][3],
- elt[1][0], elt[1][1], elt[1][2], elt[1][3],
- elt[2][0], elt[2][1], elt[2][2], elt[2][3],
- elt[3][0], elt[3][1], elt[3][2], elt[3][3]);
-}
-
-} // namespace
-
-
diff --git a/externals/g3dlite/G3D.lib/source/MeshAlg.cpp b/externals/g3dlite/G3D.lib/source/MeshAlg.cpp
deleted file mode 100644
index 24b90ab5a92..00000000000
--- a/externals/g3dlite/G3D.lib/source/MeshAlg.cpp
+++ /dev/null
@@ -1,733 +0,0 @@
-/**
- @file MeshAlg.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
- @created 2003-09-14
- @edited 2008-09-03
-
- Copyright 2000-2008, Morgan McGuire.
- All rights reserved.
-
- */
-
-#include "G3D/MeshAlg.h"
-#include "G3D/Table.h"
-#include "G3D/Set.h"
-#include "G3D/Box.h"
-#include "G3D/Sphere.h"
-#include "G3D/vectorMath.h"
-#include "G3D/AABox.h"
-
-#include <climits>
-
-namespace G3D {
-
-const int MeshAlg::Face::NONE = INT_MIN;
-
-void MeshAlg::generateGrid(
- Array<Vector3>& vertex,
- Array<Vector2>& texCoord,
- Array<int>& index,
- int wCells,
- int hCells,
- const Vector2& textureScale,
- bool spaceCentered,
- bool twoSided,
- const CoordinateFrame& xform) {
-
- vertex.fastClear();
- texCoord.fastClear();
- index.fastClear();
-
- // Generate vertices
- for (int z = 0; z <= hCells; ++z) {
- for (int x = 0; x <= wCells; ++x) {
- Vector3 v(x / (float)wCells, 0, z / (float)hCells);
-
- Vector2 t = v.xz() * textureScale;
-
- texCoord.append(t);
-
- if (spaceCentered) {
- v -= Vector3(0.5f, 0, 0.5f);
- }
- v = xform.pointToWorldSpace(v);
- vertex.append(v);
- }
- }
-
- // Generate indices
- for (int z = 0; z < hCells; ++z) {
- for (int x = 0; x < wCells; ++x) {
- int A = x + z * (wCells + 1);
- int B = A + 1;
- int C = A + (wCells + 1);
- int D = C + 1;
-
- // A B
- // *-----*
- // | \ |
- // | \ |
- // *-----*
- // C D
-
- index.append(A, D, B);
- index.append(A, C, D);
- }
- }
-
- if (twoSided) {
- // The index array needs to have reversed winding for the bottom
- // and offset by the original number of vertices
- Array<int> ti = index;
- ti.reverse();
- for (int i = 0; i < ti.size(); ++i) {
- ti[i] += vertex.size();
- }
- index.append(ti);
-
- // Duplicate the arrays
- vertex.append(Array<Vector3>(vertex));
- texCoord.append(Array<Vector2>(texCoord));
- }
-}
-
-MeshAlg::Face::Face() {
- for (int i = 0; i < 3; ++i) {
- edgeIndex[i] = 0;
- vertexIndex[i] = 0;
- }
-}
-
-
-MeshAlg::Edge::Edge() {
- for (int i = 0; i < 2; ++i) {
- vertexIndex[i] = 0;
- // Negative face indices are faces that don't exist
- faceIndex[i] = -1;
- }
-}
-
-
-MeshAlg::Geometry& MeshAlg::Geometry::operator=(const MeshAlg::Geometry& src) {
- vertexArray.resize(src.vertexArray.size());
- normalArray.resize(src.vertexArray.size());
-
- System::memcpy(vertexArray.getCArray(), src.vertexArray.getCArray(), sizeof(Vector3)*vertexArray.size());
- System::memcpy(normalArray.getCArray(), src.normalArray.getCArray(), sizeof(Vector3)*normalArray.size());
-
- return *this;
-}
-
-
-void MeshAlg::computeNormals(
- Geometry& geometry,
- const Array<int>& indexArray) {
-
- Array<Face> faceArray;
- Array<Vertex> vertexArray;
- Array<Edge> edgeArray;
- Array<Vector3> faceNormalArray;
-
- computeAdjacency(geometry.vertexArray, indexArray, faceArray, edgeArray, vertexArray);
-
- computeNormals(geometry.vertexArray, faceArray, vertexArray,
- geometry.normalArray, faceNormalArray);
-}
-
-
-void MeshAlg::computeNormals(
- const Array<Vector3>& vertexGeometry,
- const Array<Face>& faceArray,
- const Array< Array<int> >& adjacentFaceArray,
- Array<Vector3>& vertexNormalArray,
- Array<Vector3>& faceNormalArray) {
-
- // Construct a fake vertex array for backwards compatibility
- Array<Vertex> fakeVertexArray(adjacentFaceArray.size());
-
- for (int v = 0; v < adjacentFaceArray.size(); ++v) {
- fakeVertexArray[v].faceIndex = adjacentFaceArray[v];
- // We leave out the edges because they aren't used to compute normals
- }
-
- computeNormals(vertexGeometry, faceArray, fakeVertexArray,
- vertexNormalArray, faceNormalArray);
-}
-
-
-void MeshAlg::computeNormals(
- const Array<Vector3>& vertexGeometry,
- const Array<Face>& faceArray,
- const Array<Vertex>& vertexArray,
- Array<Vector3>& vertexNormalArray,
- Array<Vector3>& faceNormalArray) {
-
- // Face normals (not unit length)
- faceNormalArray.resize(faceArray.size());
- for (int f = 0; f < faceArray.size(); ++f) {
- const Face& face = faceArray[f];
-
- Vector3 vertex[3];
- for (int j = 0; j < 3; ++j) {
- vertex[j] = vertexGeometry[face.vertexIndex[j]];
- debugAssert(vertex[j].isFinite());
- }
-
- faceNormalArray[f] = (vertex[1] - vertex[0]).cross(vertex[2] - vertex[0]);
-# ifdef G3D_DEBUG
- const Vector3& N = faceNormalArray[f];
- debugAssert(N.isFinite());
-# endif
- }
-
- // Per-vertex normals, computed by averaging
- vertexNormalArray.resize(vertexGeometry.size());
- for (int v = 0; v < vertexNormalArray.size(); ++v) {
- Vector3 sum = Vector3::zero();
- for (int k = 0; k < vertexArray[v].faceIndex.size(); ++k) {
- const int f = vertexArray[v].faceIndex[k];
- sum += faceNormalArray[f];
- }
- vertexNormalArray[v] = sum.directionOrZero();
-# ifdef G3D_DEBUG
- const Vector3& N = vertexNormalArray[v];
- debugAssert(N.isUnit() || N.isZero());
-# endif
- }
-
-
- for (int f = 0; f < faceArray.size(); ++f) {
- faceNormalArray[f] = faceNormalArray[f].directionOrZero();
-# ifdef G3D_DEBUG
- const Vector3& N = faceNormalArray[f];
- debugAssert(N.isUnit() || N.isZero());
-# endif
- }
-
-}
-
-
-void MeshAlg::computeFaceNormals(
- const Array<Vector3>& vertexArray,
- const Array<MeshAlg::Face>& faceArray,
- Array<Vector3>& faceNormals,
- bool normalize) {
-
- faceNormals.resize(faceArray.size());
-
- for (int f = 0; f < faceArray.size(); ++f) {
- const MeshAlg::Face& face = faceArray[f];
-
- const Vector3& v0 = vertexArray[face.vertexIndex[0]];
- const Vector3& v1 = vertexArray[face.vertexIndex[1]];
- const Vector3& v2 = vertexArray[face.vertexIndex[2]];
-
- faceNormals[f] = (v1 - v0).cross(v2 - v0);
- }
-
- if (normalize) {
- for (int f = 0; f < faceArray.size(); ++f) {
- faceNormals[f] = faceNormals[f].direction();
- }
- }
-}
-
-
-void MeshAlg::identifyBackfaces(
- const Array<Vector3>& vertexArray,
- const Array<MeshAlg::Face>& faceArray,
- const Vector4& HP,
- Array<bool>& backface) {
-
- Vector3 P = HP.xyz();
-
- backface.resize(faceArray.size());
-
- if (fuzzyEq(HP.w, 0.0)) {
- // Infinite case
- for (int f = faceArray.size() - 1; f >= 0; --f) {
- const MeshAlg::Face& face = faceArray[f];
-
- const Vector3& v0 = vertexArray[face.vertexIndex[0]];
- const Vector3& v1 = vertexArray[face.vertexIndex[1]];
- const Vector3& v2 = vertexArray[face.vertexIndex[2]];
-
- const Vector3 N = (v1 - v0).cross(v2 - v0);
-
- backface[f] = N.dot(P) < 0;
- }
- } else {
- // Finite case
- for (int f = faceArray.size() - 1; f >= 0; --f) {
- const MeshAlg::Face& face = faceArray[f];
-
- const Vector3& v0 = vertexArray[face.vertexIndex[0]];
- const Vector3& v1 = vertexArray[face.vertexIndex[1]];
- const Vector3& v2 = vertexArray[face.vertexIndex[2]];
-
- const Vector3 N = (v1 - v0).cross(v2 - v0);
-
- backface[f] = N.dot(P - v0) < 0;
- }
- }
-}
-
-
-void MeshAlg::identifyBackfaces(
- const Array<Vector3>& vertexArray,
- const Array<MeshAlg::Face>& faceArray,
- const Vector4& HP,
- Array<bool>& backface,
- const Array<Vector3>& faceNormals) {
-
- Vector3 P = HP.xyz();
-
- backface.resize(faceArray.size());
-
- if (fuzzyEq(HP.w, 0.0)) {
- // Infinite case
- for (int f = faceArray.size() - 1; f >= 0; --f) {
- const Vector3& N = faceNormals[f];
- backface[f] = N.dot(P) < 0;
- }
- } else {
- // Finite case
- for (int f = faceArray.size() - 1; f >= 0; --f) {
- const MeshAlg::Face& face = faceArray[f];
- const Vector3& v0 = vertexArray[face.vertexIndex[0]];
- const Vector3& N = faceNormals[f];
-
- backface[f] = N.dot(P - v0) < 0;
- }
- }
-}
-
-
-void MeshAlg::createIndexArray(int n, Array<int>& array, int start, int run, int skip) {
- debugAssert(skip >= 0);
- debugAssert(run >= 0);
-
- array.resize(n);
- if (skip == 0) {
- for (int i = 0; i < n; ++i) {
- array[i] = start + i;
- }
- } else {
- int rcount = 0;
- int j = start;
- for (int i = 0; i < n; ++i) {
- array[i] = j;
-
- ++j;
- ++rcount;
-
- if (rcount == run) {
- rcount = 0;
- j += skip;
- }
- }
- }
-}
-
-
-void MeshAlg::computeAreaStatistics(
- const Array<Vector3>& vertexArray,
- const Array<int>& indexArray,
- double& minEdgeLength,
- double& meanEdgeLength,
- double& medianEdgeLength,
- double& maxEdgeLength,
- double& minFaceArea,
- double& meanFaceArea,
- double& medianFaceArea,
- double& maxFaceArea) {
-
- debugAssert(indexArray.size() % 3 == 0);
-
- Array<double> area(indexArray.size() / 3);
- Array<double> magnitude(indexArray.size());
-
- for (int i = 0; i < indexArray.size(); i += 3) {
- const Vector3& v0 = vertexArray[indexArray[i]];
- const Vector3& v1 = vertexArray[indexArray[i + 1]];
- const Vector3& v2 = vertexArray[indexArray[i + 2]];
-
- area[i / 3] = (v1 - v0).cross(v2 - v0).magnitude() / 2.0;
- magnitude[i] = (v1 - v0).magnitude();
- magnitude[i + 1] = (v2 - v1).magnitude();
- magnitude[i + 2] = (v0 - v2).magnitude();
- }
-
- area.sort();
- magnitude.sort();
-
- minEdgeLength = max(0.0, magnitude[0]);
- maxEdgeLength = max(0.0, magnitude.last());
- medianEdgeLength = max(0.0, magnitude[magnitude.size() / 2]);
- meanEdgeLength = 0;
- for (int i = 0; i < magnitude.size(); ++i) {
- meanEdgeLength += magnitude[i];
- }
- meanEdgeLength /= magnitude.size();
-
- minFaceArea = max(0.0, area[0]);
- maxFaceArea = max(0.0, area.last());
- medianFaceArea = max(0.0, area[area.size() / 2]);
- meanFaceArea = 0;
- for (int i = 0; i < area.size(); ++i) {
- meanFaceArea += area[i];
- }
- meanFaceArea /= area.size();
-
-
- // Make sure round-off hasn't pushed values less than zero
- meanFaceArea = max(0.0, meanFaceArea);
- meanEdgeLength = max(0.0, meanEdgeLength);
-}
-
-
-int MeshAlg::countBoundaryEdges(const Array<MeshAlg::Edge>& edgeArray) {
- int b = 0;
-
- for (int i = 0; i < edgeArray.size(); ++i) {
- if ((edgeArray[i].faceIndex[0] == MeshAlg::Face::NONE) !=
- (edgeArray[i].faceIndex[1] == MeshAlg::Face::NONE)) {
- ++b;
- }
- }
-
- return b;
-}
-
-void MeshAlg::computeBounds(
- const Array<Vector3>& vertexArray,
- const Array<int>& indexArray,
- Box& box,
- Sphere& sphere) {
-
- Array<Vector3> newArray(indexArray.size());
- for (int i = 0; i < indexArray.size(); ++i) {
- newArray[i] = vertexArray[indexArray[i]];
- }
- computeBounds(newArray, box, sphere);
-}
-
-
-void MeshAlg::computeBounds(
- const Array<Vector3>& vertexArray,
- Box& box,
- Sphere& sphere) {
-
- Vector3 xmin, xmax, ymin, ymax, zmin, zmax;
-
- // FIRST PASS: find 6 minima/maxima points
- xmin.x = ymin.y = zmin.z = inf();
- xmax.x = ymax.y = zmax.z = -inf();
-
- for (int v = 0; v < vertexArray.size(); ++v) {
- const Vector3& vertex = vertexArray[v];
-
- if (vertex.x < xmin.x) {
- xmin = vertex;
- }
-
- if (vertex.x > xmax.x) {
- xmax = vertex;
- }
-
- if (vertex.y < ymin.y) {
- ymin = vertex;
- }
-
- if (vertex.y > ymax.y) {
- ymax = vertex;
- }
-
- if (vertex.z < zmin.z) {
- zmin = vertex;
- }
-
- if (vertex.z > zmax.z) {
- zmax = vertex;
- }
- }
-
- // Set points dia1 & dia2 to the maximally separated pair
- Vector3 dia1 = xmin;
- Vector3 dia2 = xmax;
- {
- // Set xspan = distance between the 2 points xmin & xmax (squared)
- double xspan = (xmax - xmin).squaredMagnitude();
-
- // Same for y & z spans
- double yspan = (ymax - ymin).squaredMagnitude();
- double zspan = (zmax - zmin).squaredMagnitude();
-
- double maxspan = xspan;
-
- if (yspan > maxspan) {
- maxspan = yspan;
- dia1 = ymin;
- dia2 = ymax;
- }
-
- if (zspan > maxspan) {
- maxspan = zspan;
- dia1 = zmin;
- dia2 = zmax;
- }
- }
-
-
- // dia1, dia2 is a diameter of initial sphere
-
- // calc initial center
- Vector3 center = (dia1 + dia2) / 2.0;
-
- // calculate initial radius^2 and radius
- Vector3 d = dia2 - sphere.center;
-
- double radSq = d.squaredMagnitude();
- double rad = sqrt(radSq);
-
- // SECOND PASS: increment current sphere
- double old_to_p, old_to_new;
-
- for (int v = 0; v < vertexArray.size(); ++v) {
- const Vector3& vertex = vertexArray[v];
-
- d = vertex - center;
-
- double old_to_p_sq = d.squaredMagnitude();
-
- // do r^2 test first
- if (old_to_p_sq > radSq) {
- // this point is outside of current sphere
- old_to_p = sqrt(old_to_p_sq);
-
- // calc radius of new sphere
- rad = (rad + old_to_p) / 2.0;
-
- // for next r^2 compare
- radSq = rad * rad;
- old_to_new = old_to_p - rad;
-
- // calc center of new sphere
- center = (rad * center + old_to_new * vertex) / old_to_p;
- }
- }
-
- const Vector3 min(xmin.x, ymin.y, zmin.z);
- const Vector3 max(xmax.x, ymax.y, zmax.z);
-
- box = Box(min, max);
-
- const double boxRadSq = (max - min).squaredMagnitude() * 0.25;
-
- if (boxRadSq >= radSq){
- if (isNaN(center.x) || ! isFinite(rad)) {
- sphere = Sphere(Vector3::zero(), inf());
- } else {
- sphere = Sphere(center, rad);
- }
- }else{
- sphere = Sphere((max + min) * 0.5, sqrt(boxRadSq));
- }
-}
-
-
-void MeshAlg::computeTangentVectors(
- const Vector3& normal,
- const Vector3 position[3],
- const Vector2 texCoord[3],
- Vector3& tangent,
- Vector3& binormal) {
-
- Vector3 v[3];
- Vector2 t[3];
-
- // TODO: don't need the copy
- // Make a copy so that we can sort
- for (int i = 0; i < 3; ++i) {
- v[i] = position[i];
- t[i] = texCoord[i];
- }
-
- /////////////////////////////////////////////////
- // Begin by computing the tangent
-
- // Bubble sort the vertices by decreasing texture coordinate y.
- if (t[0].y < t[1].y) {
- std::swap(v[0], v[1]);
- std::swap(t[0], t[1]);
- }
-
- // t0 >= t1
-
- if (t[0].y < t[2].y) {
- std::swap(v[0], v[2]);
- std::swap(t[0], t[2]);
- }
-
- // t0 >= t2, t0 >= t1
-
- if (t[1].y < t[2].y) {
- std::swap(v[1], v[2]);
- std::swap(t[1], t[2]);
- }
-
- // t0 >= t1 >= t2
-
- float amount;
-
- // Compute the direction of constant y.
- if (fuzzyEq(t[2].y, t[0].y)) {
- // Degenerate case-- the texture coordinates do not vary across this
- // triangle.
- amount = 1.0;
- } else {
- // Solve lerp(t[0].y, t[2].y, amount) = t[1].y for amount:
- //
- // t0 + (t2 - t0) * a = t1
- // a = (t1 - t0) / (t2 - t0)
-
- amount = (t[1].y - t[0].y) / (t[2].y - t[0].y);
- }
-
- tangent = lerp(v[0], v[2], amount) - v[1];
-
- // Make sure the tangent points in the right direction and is
- // perpendicular to the normal.
- if (lerp(t[0].x, t[2].x, amount) < t[1].x) {
- tangent = -tangent;
- }
-
- // TODO: do we need this? We take this component off
- // at the end anyway
- tangent -= tangent.dot(normal) * normal;
-
- // Normalize the tangent so it contributes
- // equally at the vertex (TODO: do we need this?)
- if (fuzzyEq(tangent.magnitude(), 0.0)) {
- tangent = Vector3::unitX();
- } else {
- tangent = tangent.direction();
- }
-
- //////////////////////////////////////////////////
- // Now compute the binormal (same code, but in x)
-
- // Sort the vertices by texture coordinate x.
- if (t[0].x < t[1].x) {
- std::swap(v[0], v[1]);
- std::swap(t[0], t[1]);
- }
-
- if (t[0].x < t[2].x) {
- std::swap(v[0], v[2]);
- std::swap(t[0], t[2]);
- }
-
- if (t[1].x < t[2].x) {
- std::swap(v[1], v[2]);
- std::swap(t[1], t[2]);
- }
-
- // Compute the direction of constant x.
- if (fuzzyEq(t[2].x, t[0].x)) {
- amount = 1.0;
- } else {
- amount = (t[1].x - t[0].x) / (t[2].x - t[0].x);
- }
-
- binormal = lerp(v[0], v[2], amount) - v[1];
-
- // Make sure the binormal points in the right direction and is
- // perpendicular to the normal.
- if (lerp(t[0].y, t[2].y, amount) < t[1].y) {
- binormal = -binormal;
- }
-
- binormal -= binormal.dot(normal) * normal;
-
- // Normalize the binormal so that it contributes
- // an equal amount to the per-vertex value (TODO: do we need this?
- // Nelson Max showed that we don't for computing per-vertex normals)
- if (fuzzyEq(binormal.magnitude(), 0.0)) {
- binormal = Vector3::unitZ();
- } else {
- binormal = binormal.direction();
- }
-
- // This computation gives the opposite convention of what we want.
- binormal = -binormal;
-
-}
-
-
-void MeshAlg::computeTangentSpaceBasis(
- const Array<Vector3>& vertexArray,
- const Array<Vector2>& texCoordArray,
- const Array<Vector3>& vertexNormalArray,
- const Array<Face>& faceArray,
- Array<Vector3>& tangent,
- Array<Vector3>& binormal) {
-
- debugAssertM(faceArray.size() != 0, "Unable to calculate valid tangent space without faces.");
-
- // The three vertices and texCoords of each face
- Vector3 position[3];
- Vector2 texCoord[3];
- Vector3 t, b;
-
- tangent.resize(vertexArray.size());
- binormal.resize(vertexArray.size());
-
- // Zero the output arrays.
- System::memset(tangent.getCArray(), 0, sizeof(Vector3) * tangent.size());
- System::memset(binormal.getCArray(), 0, sizeof(Vector3) * binormal.size());
-
- // Iterate over faces, computing the tangent vectors for each
- // vertex. Accumulate those into the tangent and binormal arrays
- // and then orthonormalize at the end.
-
- for (int f = 0; f < faceArray.size(); ++f) {
- const Face& face = faceArray[f];
-
- for (int v = 0; v < 3; ++v) {
- int i = face.vertexIndex[v];
- position[v] = vertexArray[i];
- texCoord[v] = texCoordArray[i];
- }
-
- const Vector3 faceNormal((position[1] - position[0]).cross(position[2] - position[0]).direction());
- computeTangentVectors(faceNormal, position, texCoord, t, b);
-
- for (int v = 0; v < 3; ++v) {
- int i = face.vertexIndex[v];
- tangent[i] += t;
- binormal[i] += b;
- }
- }
-
- // Normalize the basis vectors
- for (int v = 0; v < vertexArray.size(); ++v) {
- // Remove the component parallel to the normal
- const Vector3& N = vertexNormalArray[v];
- debugAssertM(N.isUnit() || N.isZero(), "Input normals must have unit length");
-
- tangent[v] -= tangent[v].dot(N) * N;
- binormal[v] -= binormal[v].dot(N) * N;
-
- // Normalize
- tangent[v] = tangent[v].directionOrZero();
- binormal[v] = binormal[v].directionOrZero();
-
- // Note that the tangent and binormal might not be perpendicular anymore
- }
-}
-
-
-
-} // G3D namespace
diff --git a/externals/g3dlite/G3D.lib/source/MeshAlgAdjacency.cpp b/externals/g3dlite/G3D.lib/source/MeshAlgAdjacency.cpp
deleted file mode 100644
index a8b35f32c86..00000000000
--- a/externals/g3dlite/G3D.lib/source/MeshAlgAdjacency.cpp
+++ /dev/null
@@ -1,729 +0,0 @@
-/**
- @file MeshAlgAdjacency.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
- @created 2003-09-14
- @edited 2005-02-24
-
- Copyright 2000-2003, Morgan McGuire.
- All rights reserved.
-
- */
-
-#include "G3D/Table.h"
-#include "G3D/MeshAlg.h"
-#include "G3D/Set.h"
-
-
-namespace G3D {
-
-/**
- A half [i.e. directed] edge.
- */
-class MeshDirectedEdgeKey {
-public:
-
- /** vertexIndex[0] <= vertexIndex[1] */
- int vertexIndex[2];
-
- MeshDirectedEdgeKey() {}
-
- MeshDirectedEdgeKey(
- const int i0,
- const int i1) {
-
- if (i0 <= i1) {
- vertexIndex[0] = i0;
- vertexIndex[1] = i1;
- } else {
- vertexIndex[0] = i1;
- vertexIndex[1] = i0;
- }
- }
-
-
- bool operator==(const MeshDirectedEdgeKey& e2) const {
- for (int i = 0; i < 2; ++i) {
- if (vertexIndex[i] != e2.vertexIndex[i]) {
- return false;
- }
- }
- return true;
- }
-};
-
-}
-
-template<> struct HashTrait<G3D::MeshDirectedEdgeKey> {
- static size_t hashCode(const G3D::MeshDirectedEdgeKey& key) {
- return key.vertexIndex[0] + (key.vertexIndex[1] << 16);
- }
-};
-
-namespace G3D {
-
-/**
- A hashtable mapping edges to lists of indices for
- faces. This is used instead of Table because of the
- special logic in insert.
-
- Used only for MeshAlg::computeAdjacency.
-
- In the face lists, index <I>f</I> >= 0 indicates that
- <I>f</I> contains the edge as a forward edge. Index <I>f</I> < 0
- indicates that ~<I>f</I> contains the edge as a backward edge.
- */
-class MeshEdgeTable {
-public:
- typedef Table<MeshDirectedEdgeKey, Array<int> > ET;
-
-private:
-
- ET table;
-
-public:
-
- /**
- Clears the table.
- */
- void clear() {
- table.clear();
- }
-
- /**
- Inserts the faceIndex into the edge's face list.
- The index may be a negative number indicating a backface.
- */
- void insert(const MeshDirectedEdgeKey& edge, int faceIndex) {
-
- // debugAssertM((table.size() > 20) && (table.debugGetLoad() < 0.5 || table.debugGetNumBuckets() < 20),
- // "MeshEdgeTable is using a poor hash function.");
-
- if (! table.containsKey(edge)) {
- // First time
- Array<int> x(1);
- x[0] = faceIndex;
- table.set(edge, x);
- } else {
- table[edge].append(faceIndex);
- }
- }
-
- /**
- Returns the face list for a given edge
- */
- const Array<int>& get(const MeshDirectedEdgeKey& edge) {
- return table[edge];
- }
-
- ET::Iterator begin() {
- return table.begin();
- }
-
- const ET::Iterator end() const {
- return table.end();
- }
-
-};
-
-
-/**
- edgeTable[edgeKey] is a list of faces containing
-
- Used and cleared by MeshModel::computeAdjacency()
- */
-static MeshEdgeTable edgeTable;
-
-/**
- Assigns the edge index into the next unassigned edge
- index. The edge index may be negative, indicating
- a reverse edge.
- */
-static void assignEdgeIndex(MeshAlg::Face& face, int e) {
- for (int i = 0; i < 3; ++i) {
- if (face.edgeIndex[i] == MeshAlg::Face::NONE) {
- face.edgeIndex[i] = e;
- return;
- }
- }
-
- debugAssertM(false, "Face has already been assigned 3 edges");
-}
-
-
-void MeshAlg::computeAdjacency(
- const Array<Vector3>& vertexGeometry,
- const Array<int>& indexArray,
- Array<Face>& faceArray,
- Array<Edge>& edgeArray,
- Array< Array<int> >& adjacentFaceArray) {
-
- Array<Vertex> vertexArray;
-
- computeAdjacency(vertexGeometry, indexArray, faceArray, edgeArray, vertexArray);
-
- // Convert the vertexArray into adjacentFaceArray
- adjacentFaceArray.clear();
- adjacentFaceArray.resize(vertexArray.size());
- for (int v = 0; v < adjacentFaceArray.size(); ++v) {
- adjacentFaceArray[v] = vertexArray[v].faceIndex;
- }
-}
-
-
-void MeshAlg::computeAdjacency(
- const Array<Vector3>& vertexGeometry,
- const Array<int>& indexArray,
- Array<Face>& faceArray,
- Array<Edge>& edgeArray,
- Array<Vertex>& vertexArray) {
-
- edgeArray.clear();
- vertexArray.clear();
- faceArray.clear();
- edgeTable.clear();
-
- // Face normals
- Array<Vector3> faceNormal;
-
- // This array has the same size as the vertex array
- vertexArray.resize(vertexGeometry.size());
-
- // Iterate through the triangle list
- for (int q = 0; q < indexArray.size(); q += 3) {
-
- Vector3 vertex[3];
- int f = faceArray.size();
- MeshAlg::Face& face = faceArray.next();
-
- // Construct the face
- for (int j = 0; j < 3; ++j) {
- int v = indexArray[q + j];
- face.vertexIndex[j] = v;
- face.edgeIndex[j] = Face::NONE;
-
- // Store back pointers in the vertices
- vertexArray[v].faceIndex.append(f);
-
- // We'll need these vertices to find the face normal
- vertex[j] = vertexGeometry[v];
- }
-
- // Compute the face normal
- Vector3 N = (vertex[1] - vertex[0]).cross(vertex[2] - vertex[0]);
- faceNormal.append(N.directionOrZero());
-
- static const int nextIndex[] = {1, 2, 0};
-
- // Add each edge to the edge table.
- for (int j = 0; j < 3; ++j) {
- const int i0 = indexArray[q + j];
- const int i1 = indexArray[q + nextIndex[j]];
-
- const MeshDirectedEdgeKey edge(i0, i1);
-
- if (i0 == edge.vertexIndex[0]) {
- // The edge was directed in the same manner as in the face
- edgeTable.insert(edge, f);
- } else {
- // The edge was directed in the opposite manner as in the face
- edgeTable.insert(edge, ~f);
- }
- }
- }
-
- // For each edge in the edge table, create an edge in the edge array.
- // Collapse every 2 edges from adjacent faces.
-
- MeshEdgeTable::ET::Iterator cur = edgeTable.begin();
- MeshEdgeTable::ET::Iterator end = edgeTable.end();
-
- Array<Edge> tempEdgeArray;
- while (cur != end) {
- MeshDirectedEdgeKey& edgeKey = cur->key;
- Array<int>& faceIndexArray = cur->value;
-
- // Process this edge
- while (faceIndexArray.size() > 0) {
-
- // Remove the last index
- int f0 = faceIndexArray.pop();
-
- // Find the normal to that face
- const Vector3& n0 = faceNormal[(f0 >= 0) ? f0 : ~f0];
-
- bool found = false;
-
- // We try to find the matching face with the closest
- // normal. This ensures that we don't introduce a lot
- // of artificial ridges into flat parts of a mesh.
- double ndotn = -2;
- int f1 = -1, i1 = -1;
-
- // Try to Find the face with the matching edge
- for (int i = faceIndexArray.size() - 1; i >= 0; --i) {
- int f = faceIndexArray[i];
-
- if ((f >= 0) != (f0 >= 0)) {
- // This face contains the oppositely oriented edge
- // and has not been assigned too many edges
-
- const Vector3& n1 = faceNormal[(f >= 0) ? f : ~f];
- double d = n1.dot(n0);
-
- if (found) {
- // We previously found a good face; see if this
- // one is better.
- if (d > ndotn) {
- // This face is better.
- ndotn = d;
- f1 = f;
- i1 = i;
- }
- } else {
- // This is the first face we've found
- found = true;
- ndotn = d;
- f1 = f;
- i1 = i;
- }
- }
- }
-
- // Create the new edge
- int e = tempEdgeArray.size();
- Edge& edge = tempEdgeArray.next();
-
- edge.vertexIndex[0] = edgeKey.vertexIndex[0];
- edge.vertexIndex[1] = edgeKey.vertexIndex[1];
-
- if (f0 >= 0) {
- edge.faceIndex[0] = f0;
- edge.faceIndex[1] = Face::NONE;
- assignEdgeIndex(faceArray[f0], e);
- } else {
- // The face indices above are two's complemented.
- // this code restores them to regular indices.
- debugAssert((~f0) >= 0);
- edge.faceIndex[1] = ~f0;
- edge.faceIndex[0] = Face::NONE;
-
- // The edge index *does* need to be inverted, however.
- assignEdgeIndex(faceArray[~f0], ~e);
- }
-
- if (found) {
- // We found a matching face; remove both
- // faces from the active list.
- faceIndexArray.fastRemove(i1);
-
- if (f1 >= 0) {
- edge.faceIndex[0] = f1;
- assignEdgeIndex(faceArray[f1], e);
- } else {
- edge.faceIndex[1] = ~f1;
- assignEdgeIndex(faceArray[~f1], ~e);
- }
- }
- }
-
- ++cur;
- }
-
- edgeTable.clear();
-
- // Move boundary edges to the end of the list and then
- // clean up the face references into them
- {
- // Map old edge indices to new edge indices
- Array<int> newIndex(tempEdgeArray.size());
-
-
- // Index of the start and end of the edge array
- int i = 0;
- int j = tempEdgeArray.size() - 1;
-
- edgeArray.resize(tempEdgeArray.size());
- for (int e = 0; e < tempEdgeArray.size(); ++e) {
- if (tempEdgeArray[e].boundary()) {
- newIndex[e] = j;
- --j;
- } else {
- newIndex[e] = i;
- ++i;
- }
- edgeArray[newIndex[e]] = tempEdgeArray[e];
- }
-
- debugAssertM(i == j + 1, "Counting from front and back of array did not match");
-
- // Fix the faces
- for (int f = 0; f < faceArray.size(); ++f) {
- Face& face = faceArray[f];
- for (int q = 0; q < 3; ++q) {
- int e = face.edgeIndex[q];
- if (e < 0) {
- // Backwards edge; twiddle before and after conversion
- face.edgeIndex[q] = ~newIndex[~e];
- } else {
- // Regular edge; remap the index
- face.edgeIndex[q] = newIndex[e];
- }
- }
- }
- }
-
- // Now order the edge indices inside the faces correctly.
- for (int f = 0; f < faceArray.size(); ++f) {
- Face& face = faceArray[f];
- int e0 = face.edgeIndex[0];
- int e1 = face.edgeIndex[1];
- int e2 = face.edgeIndex[2];
-
- // e0 will always remain first. The only
- // question is whether e1 and e2 should be swapped.
-
- // See if e1 begins at the vertex where e1 ends.
- const int e0End = (e0 < 0) ?
- edgeArray[~e0].vertexIndex[0] :
- edgeArray[e0].vertexIndex[1];
-
- const int e1Begin = (e1 < 0) ?
- edgeArray[~e1].vertexIndex[1] :
- edgeArray[e1].vertexIndex[0];
-
- if (e0End != e1Begin) {
- // We must swap e1 and e2
- face.edgeIndex[1] = e2;
- face.edgeIndex[2] = e1;
- }
- }
-
- // Fill out the edge adjacency information in the vertex array
- for (int e = 0; e < edgeArray.size(); ++e) {
- const Edge& edge = edgeArray[e];
- vertexArray[edge.vertexIndex[0]].edgeIndex.append(e);
- vertexArray[edge.vertexIndex[1]].edgeIndex.append(~e);
- }
-}
-
-
-void MeshAlg::weldBoundaryEdges(
- Array<Face>& faceArray,
- Array<Edge>& edgeArray,
- Array<Vertex>& vertexArray) {
-
- // Copy over the original edge array
- Array<Edge> oldEdgeArray = edgeArray;
-
- // newEdgeIndex[e] is the new index of the old edge with index e
- // Note that newEdgeIndex[e] might be negative, indicating that
- // the edge switched direction between the arrays.
- Array<int> newEdgeIndex(edgeArray.size());
- edgeArray.resize(0);
-
- // boundaryEdgeIndices[v_low] is an array of the indices of
- // all boundary edges whose lower vertex is v_low.
- Table<int, Array<int> > boundaryEdgeIndices;
-
- // Copy over non-boundary edges to the new array
- for (int e = 0; e < oldEdgeArray.size(); ++e) {
- if (oldEdgeArray[e].boundary()) {
-
- // Add to the boundary table
- const int v_low = iMin(oldEdgeArray[e].vertexIndex[0], oldEdgeArray[e].vertexIndex[1]);
- if (! boundaryEdgeIndices.containsKey(v_low)) {
- boundaryEdgeIndices.set(v_low, Array<int>());
- }
- boundaryEdgeIndices[v_low].append(e);
-
- // We'll fill out newEdgeIndex[e] later, when we find pairs
-
- } else {
-
- // Copy the edge to the new array
- newEdgeIndex[e] = edgeArray.size();
- edgeArray.append(oldEdgeArray[e]);
-
- }
- }
-
-
- // Remove all edges from the table that have pairs.
- Table<int, Array<int> >::Iterator cur = boundaryEdgeIndices.begin();
- Table<int, Array<int> >::Iterator end = boundaryEdgeIndices.end();
- while (cur != end) {
- Array<int>& boundaryEdge = cur->value;
-
- for (int i = 0; i < boundaryEdge.size(); ++i) {
- int ei = boundaryEdge[i];
- const Edge& edgei = oldEdgeArray[ei];
-
- for (int j = i + 1; j < boundaryEdge.size(); ++j) {
- int ej = boundaryEdge[j];
- const Edge& edgej = oldEdgeArray[ej];
-
- // See if edge ei is the reverse (match) of edge ej.
-
- // True if the edges match
- bool match = false;
-
- // True if edgej's vertex indices are reversed from
- // edgei's (usually true).
- bool reversej = false;
-
- int u = edgei.vertexIndex[0];
- int v = edgei.vertexIndex[1];
-
- if (edgei.faceIndex[0] != Face::NONE) {
- // verts|faces
- // edgei = [u v A /]
-
- if (edgej.faceIndex[0] != Face::NONE) {
- if ((edgej.vertexIndex[0] == v) && (edgej.vertexIndex[1] == u)) {
- // This is the most common of the four cases
-
- // edgej = [v u B /]
- match = true;
- reversej = true;
- }
- } else {
- if ((edgej.vertexIndex[0] == u) && (edgej.vertexIndex[1] == v)) {
- // edgej = [u v / B]
- match = true;
- }
- }
- } else {
- // edgei = [u v / A]
- if (edgej.faceIndex[0] != Face::NONE) {
- if ((edgej.vertexIndex[0] == u) && (edgej.vertexIndex[1] == v)) {
- // edgej = [u v B /]
- match = true;
- }
- } else {
- if ((edgej.vertexIndex[0] == v) && (edgej.vertexIndex[1] == u)) {
- // edgej = [v u / B]
- match = true;
- reversej = true;
- }
- }
- }
-
- if (match) {
- // ei and ej can be paired as a single edge
- int e = edgeArray.size();
- Edge& edge = edgeArray.next();
-
- // Follow the direction of edgei.
- edge = edgei;
- newEdgeIndex[ei] = e;
-
- // Insert the face index for edgej.
- int fj = edgej.faceIndex[0];
- if (fj == Face::NONE) {
- fj = edgej.faceIndex[1];
- }
-
- if (edge.faceIndex[0] == Face::NONE) {
- edge.faceIndex[0] = fj;
- } else {
- edge.faceIndex[1] = fj;
- }
-
- if (reversej) {
- // The new edge is backwards of the old edge for ej
- newEdgeIndex[ej] = ~e;
- } else {
- newEdgeIndex[ej] = e;
- }
-
- // Remove both ei and ej from being candidates for future pairing.
- // Remove ej first since it comes later in the list (removing
- // ei would decrease the index of ej to j - 1).
- boundaryEdge.fastRemove(j);
- boundaryEdge.fastRemove(i);
-
- // Re-process element i, which is now a new edge index
- --i;
-
- // Jump out of the j for-loop
- break;
- }
- }
- }
- ++cur;
- }
-
- // Anything remaining in the table is a real boundary edge; just copy it to
- // the end of the array.
- cur = boundaryEdgeIndices.begin();
- end = boundaryEdgeIndices.end();
- while (cur != end) {
- Array<int>& boundaryEdge = cur->value;
-
- for (int b = 0; b < boundaryEdge.size(); ++b) {
- const int e = boundaryEdge[b];
-
- newEdgeIndex[e] = edgeArray.size();
- edgeArray.append(oldEdgeArray[e]);
- }
-
- ++cur;
- }
-
- // Finally, fix up edge indices in the face and vertex arrays
- for (int f = 0; f < faceArray.size(); ++f) {
- Face& face = faceArray[f];
- for (int i = 0; i < 3; ++i) {
- int e = face.edgeIndex[i];
-
- if (e < 0) {
- face.edgeIndex[i] = ~newEdgeIndex[~e];
- } else {
- face.edgeIndex[i] = newEdgeIndex[e];
- }
- }
- }
-
- for (int v = 0; v < vertexArray.size(); ++v) {
- Vertex& vertex = vertexArray[v];
- for (int i = 0; i < vertex.edgeIndex.size(); ++i) {
- int e = vertex.edgeIndex[i];
-
- if (e < 0) {
- vertex.edgeIndex[i] = ~newEdgeIndex[~e];
- } else {
- vertex.edgeIndex[i] = newEdgeIndex[e];
- }
- }
- }
-}
-
-
-void MeshAlg::weldAdjacency(
- const Array<Vector3>& originalGeometry,
- Array<Face>& faceArray,
- Array<Edge>& edgeArray,
- Array<Vertex>& vertexArray,
- double radius) {
-
- // Num vertices
- const int n = originalGeometry.size();
-
- // canonical[v] = first occurance of any vertex near oldVertexArray[v]
- Array<int> canonical(n);
-
- Array<int> toNew, toOld;
- // Throw away the new vertex array
- Array<Vector3> dummy;
- computeWeld(originalGeometry, dummy, toNew, toOld, radius);
-
- for (int v = 0; v < canonical.size(); ++v) {
- // Round-trip through the toNew/toOld process. This will give
- // us the original vertex.
- canonical[v] = toOld[toNew[v]];
- }
-
- // Destroy vertexArray (we reconstruct it below)
- vertexArray.clear();
- vertexArray.resize(n);
-
- bool hasBoundaryEdges = false;
-
- // Fix edge vertex indices
- for (int e = 0; e < edgeArray.size(); ++e) {
- Edge& edge = edgeArray[e];
-
- const int v0 = canonical[edge.vertexIndex[0]];
- const int v1 = canonical[edge.vertexIndex[1]];
-
- edge.vertexIndex[0] = v0;
- edge.vertexIndex[1] = v1;
-
- vertexArray[v0].edgeIndex.append(e);
- vertexArray[v1].edgeIndex.append(~e);
-
- hasBoundaryEdges = hasBoundaryEdges || edge.boundary();
- }
-
- // Fix face vertex indices
- for (int f = 0; f < faceArray.size(); ++f) {
- Face& face = faceArray[f];
- for (int i = 0; i < 3; ++i) {
- const int v = canonical[face.vertexIndex[i]];
-
- face.vertexIndex[i] = v;
-
- // Add the back pointer
- vertexArray[v].faceIndex.append(f);
- }
- }
-
- if (hasBoundaryEdges) {
- // As a result of the welding, some of the boundary edges at
- // the end of the array may now have mates and no longer be
- // boundaries. Try to pair these up.
-
- weldBoundaryEdges(faceArray, edgeArray, vertexArray);
- }
-}
-
-
-void MeshAlg::debugCheckConsistency(
- const Array<Face>& faceArray,
- const Array<Edge>& edgeArray,
- const Array<Vertex>& vertexArray) {
-
-#ifdef _DEBUG
- for (int v = 0; v < vertexArray.size(); ++v) {
- const MeshAlg::Vertex& vertex = vertexArray[v];
-
- for (int i = 0; i < vertex.edgeIndex.size(); ++i) {
- const int e = vertex.edgeIndex[i];
- debugAssert(edgeArray[(e >= 0) ? e : ~e].containsVertex(v));
- }
-
- for (int i = 0; i < vertex.faceIndex.size(); ++i) {
- const int f = vertex.faceIndex[i];
- debugAssert(faceArray[f].containsVertex(v));
- }
-
- }
-
- for (int e = 0; e < edgeArray.size(); ++e) {
- const MeshAlg::Edge& edge = edgeArray[e];
-
- for (int i = 0; i < 2; ++i) {
- debugAssert((edge.faceIndex[i] == MeshAlg::Face::NONE) ||
- faceArray[edge.faceIndex[i]].containsEdge(e));
-
- debugAssert(vertexArray[edge.vertexIndex[i]].inEdge(e));
- }
- }
-
- // Every face's edge must be on that face
- for (int f = 0; f < faceArray.size(); ++f) {
- const MeshAlg::Face& face = faceArray[f];
- for (int i = 0; i < 3; ++i) {
- int e = face.edgeIndex[i];
- int ei = (e >= 0) ? e : ~e;
- debugAssert(edgeArray[ei].inFace(f));
-
- // Make sure the edge is oriented appropriately
- if (e >= 0) {
- debugAssert(edgeArray[ei].faceIndex[0] == (int)f);
- } else {
- debugAssert(edgeArray[ei].faceIndex[1] == (int)f);
- }
-
- debugAssert(vertexArray[face.vertexIndex[i]].inFace(f));
- }
- }
-#else
- (void)faceArray;
- (void)edgeArray;
- (void)vertexArray;
-#endif // _DEBUG
-}
-
-} // G3D namespace
diff --git a/externals/g3dlite/G3D.lib/source/MeshAlgWeld.cpp b/externals/g3dlite/G3D.lib/source/MeshAlgWeld.cpp
deleted file mode 100644
index cd4d1f9c7d5..00000000000
--- a/externals/g3dlite/G3D.lib/source/MeshAlgWeld.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- @file MeshAlgWeld.cpp
-
- The MeshAlg::computeWeld method.
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
- @created 2003-10-22
- @edited 2005-02-24
-
- Copyright 2000-2003, Morgan McGuire.
- All rights reserved.
-
- */
-
-#include "G3D/MeshAlg.h"
-#include "G3D/Table.h"
-#include "G3D/Set.h"
-
-namespace G3D {
-
-namespace _internal {
-
-class Welder {
-private:
-
- // Intentionally illegal
- Welder& operator=(const Welder& w);
-
-public:
- /** Indices of newVertexArray elements in <B>or near</B> a grid cell. */
- typedef Array<int> List;
-
- enum {GRID_RES = 32};
-
- List grid[GRID_RES][GRID_RES][GRID_RES];
-
- const Array<Vector3>& oldVertexArray;
- Array<Vector3>& newVertexArray;
- Array<int>& toNew;
- Array<int>& toOld;
-
- /** Must be less than one grid cell, not checked */
- const double radius;
-
- /** (oldVertexArray[i] - offset) * scale is on the range [0, 1] */
- Vector3 offset;
- Vector3 scale;
-
- Welder(
- const Array<Vector3>& _oldVertexArray,
- Array<Vector3>& _newVertexArray,
- Array<int>& _toNew,
- Array<int>& _toOld,
- double _radius);
-
- /**
- Computes the grid index from an ordinate.
- */
- void toGridCoords(Vector3 v, int& x, int& y, int& z) const;
-
- /** Gets the index of a vertex, adding it to
- newVertexArray if necessary. */
- int getIndex(const Vector3& vertex);
-
- void weld();
-};
-
-} // namespace _internal
-
-} // namespace G3D
-
-template<> struct HashTrait<G3D::_internal::Welder::List*> {
- static size_t hashCode(const G3D::_internal::Welder::List* key) { return reinterpret_cast<size_t>(key); }
-};
-
-namespace G3D {
-namespace _internal {
-
-Welder::Welder(
- const Array<Vector3>& _oldVertexArray,
- Array<Vector3>& _newVertexArray,
- Array<int>& _toNew,
- Array<int>& _toOld,
- double _radius) :
- oldVertexArray(_oldVertexArray),
- newVertexArray(_newVertexArray),
- toNew(_toNew),
- toOld(_toOld),
- radius(_radius) {
-
- // Compute a scale factor that moves the range
- // of all ordinates to [0, 1]
- Vector3 minBound = Vector3::inf();
- Vector3 maxBound = -minBound;
-
- for (int i = 0; i < oldVertexArray.size(); ++i) {
- minBound = minBound.min(oldVertexArray[i]);
- maxBound = maxBound.max(oldVertexArray[i]);
- }
-
- offset = minBound;
- scale = maxBound - minBound;
- for (int i = 0; i < 3; ++i) {
- // The model might have zero extent along some axis
- if (fuzzyEq(scale[i], 0.0)) {
- scale[i] = 1.0;
- } else {
- scale[i] = 1.0 / scale[i];
- }
- }
-}
-
-
-void Welder::toGridCoords(Vector3 v, int& x, int& y, int& z) const {
- v = (v - offset) * scale;
- x = iClamp(iFloor(v.x * GRID_RES), 0, GRID_RES - 1);
- y = iClamp(iFloor(v.y * GRID_RES), 0, GRID_RES - 1);
- z = iClamp(iFloor(v.z * GRID_RES), 0, GRID_RES - 1);
-}
-
-
-int Welder::getIndex(const Vector3& vertex) {
-
- int closestIndex = -1;
- double distanceSquared = inf();
-
- int ix, iy, iz;
- toGridCoords(vertex, ix, iy, iz);
-
- // Check against all vertices within radius of this grid cube
- const List& list = grid[ix][iy][iz];
-
- for (int i = 0; i < list.size(); ++i) {
- double d = (newVertexArray[list[i]] - vertex).squaredMagnitude();
-
- if (d < distanceSquared) {
- distanceSquared = d;
- closestIndex = list[i];
- }
- }
-
- if (distanceSquared <= radius * radius) {
-
- return closestIndex;
-
- } else {
-
- // This is a new vertex
- int newIndex = newVertexArray.size();
- newVertexArray.append(vertex);
-
- // Create a new vertex and store its index in the
- // neighboring grid cells (usually, only 1 neighbor)
-
- Set<List*> neighbors;
-
- for (float dx = -1; dx <= +1; ++dx) {
- for (float dy = -1; dy <= +1; ++dy) {
- for (float dz = -1; dz <= +1; ++dz) {
- int ix, iy, iz;
- toGridCoords(vertex + Vector3(dx, dy, dz) * radius, ix, iy, iz);
- neighbors.insert(&(grid[ix][iy][iz]));
- }
- }
- }
-
- Set<List*>::Iterator neighbor(neighbors.begin());
- Set<List*>::Iterator none(neighbors.end());
-
- while (neighbor != none) {
- (*neighbor)->append(newIndex);
- ++neighbor;
- }
-
- return newIndex;
- }
-}
-
-
-void Welder::weld() {
- newVertexArray.resize(0);
-
- // Prime the vertex positions
- for (int i = 0; i < oldVertexArray.size(); ++i) {
- getIndex(oldVertexArray[i]);
- }
-
- // Now create the official remapping by snapping to
- // nearby vertices.
- toNew.resize(oldVertexArray.size());
- toOld.resize(newVertexArray.size());
-
- for (int oi = 0; oi < oldVertexArray.size(); ++oi) {
- toNew[oi] = getIndex(oldVertexArray[oi]);
- toOld[toNew[oi]] = oi;
- }
-}
-
-} // internal namespace
-
-
-void MeshAlg::computeWeld(
- const Array<Vector3>& oldVertexArray,
- Array<Vector3>& newVertexArray,
- Array<int>& toNew,
- Array<int>& toOld,
- double radius) {
-
- _internal::Welder welder(oldVertexArray, newVertexArray, toNew, toOld, radius);
- welder.weld();
-}
-
-} // G3D namespace
diff --git a/externals/g3dlite/G3D.lib/source/MeshAlgWeld2.cpp b/externals/g3dlite/G3D.lib/source/MeshAlgWeld2.cpp
deleted file mode 100644
index 13f731353a6..00000000000
--- a/externals/g3dlite/G3D.lib/source/MeshAlgWeld2.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/**
- @file MeshAlgWeld2.cpp
-
- @author Morgan McGuire, Kyle Whitson, Corey Taylor
-
- @created 2008-07-30
- @edited 2008-11-10
- */
-
-#include "G3D/platform.h"
-#include "G3D/Vector2.h"
-#include "G3D/Vector3.h"
-#include "G3D/Sphere.h"
-#include "G3D/PointHashGrid.h"
-#include "G3D/MeshAlg.h"
-
-namespace G3D { namespace _internal{
-
-/** Used by WeldHelper2::smoothNormals. */
-class VN {
-public:
- Vector3 vertex;
- Vector3 normal;
-
- VN() {}
- VN(const Vector3& v, const Vector3& n) : vertex(v), normal(n) {}
-};
-
-/** Used by WeldHelper::getIndex to maintain a list of vertices by location. */
-class VNTi {
-public:
- Vector3 vertex;
- Vector3 normal;
- Vector2 texCoord;
- int index;
-
- VNTi() : index(0) {}
-
- VNTi(const Vector3& v, const Vector3& n, const Vector2& t, int i) :
- vertex(v), normal(n), texCoord(t), index(i) {}
-};
-
-
-}} // G3D
-
-template <> struct HashTrait <G3D::_internal::VN> {
- static size_t hashCode(const G3D::_internal::VN& k) { return static_cast<size_t>(k.vertex.hashCode()); }
-};
-template <> struct HashTrait <G3D::_internal::VNTi> {
- static size_t hashCode(const G3D::_internal::VNTi& k) { return static_cast<size_t>(k.vertex.hashCode()); }
-};
-
-
-template<> struct EqualsTrait <G3D::_internal::VN> {
- static bool equals(const G3D::_internal::VN& a, const G3D::_internal::VN& b) { return a.vertex == b.vertex; }
-};
-template<> struct EqualsTrait <G3D::_internal::VNTi> {
- static bool equals(const G3D::_internal::VNTi& a, const G3D::_internal::VNTi& b) { return a.vertex == b.vertex; }
-};
-
-template<> struct PositionTrait<G3D::_internal::VN> {
- static void getPosition(const G3D::_internal::VN& v, G3D::Vector3& p) { p = v.vertex; }
-};
-template<> struct PositionTrait<G3D::_internal::VNTi> {
- static void getPosition(const G3D::_internal::VNTi& v, G3D::Vector3& p) { p = v.vertex; }
-};
-
-namespace G3D { namespace _internal {
-
-class WeldHelper {
-private:
- /** Used by getIndex and updateTriLists */
- PointHashGrid<VNTi> weldGrid;
-
- Array<Vector3>* outputVertexArray;
- Array<Vector3>* outputNormalArray;
- Array<Vector2>* outputTexCoordArray;
-
- float vertexWeldRadius;
- /** Squared radius allowed for welding similar normals. */
- float normalWeldRadius2;
- float texCoordWeldRadius2;
-
- float normalSmoothingAngle;
-
- /**
- Returns the index of the vertex in
- outputVertexArray/outputNormalArray/outputTexCoordArray
- that is within the global tolerances of v,n,t. If there
- is no such vertex, adds it to the arrays and returns that index.
-
- Called from updateTriLists().
- */
- int getIndex(const Vector3& v, const Vector3& n, const Vector2& t) {
- PointHashGrid<VNTi>::SphereIterator it =
- weldGrid.beginSphereIntersection(Sphere(v, vertexWeldRadius));
-
- if (n.isZero()) {
- // Don't bother trying to match the surface normal, since this vertex has no surface normal.
- while (it.hasMore()) {
- if ((t - it->texCoord).squaredLength() <= texCoordWeldRadius2) {
- // This is the vertex
- return it->index;
- }
- ++it;
- }
- } else {
- while (it.hasMore()) {
- if (((n - it->normal).squaredLength() <= normalWeldRadius2) &&
- ((t - it->texCoord).squaredLength() <= texCoordWeldRadius2)) {
- // This is the vertex
- return it->index;
- }
- ++it;
- }
- }
-
- // Note that a sliver triangle processed before its neighbors may reach here
- // with a zero length normal.
-
- // The vertex does not exist. Create it.
- const int i = outputVertexArray->size();
- outputVertexArray->append(v);
- outputNormalArray->append(n);
- outputTexCoordArray->append(t);
-
- // Store in the grid so that it will be remembered.
- weldGrid.insert(VNTi(v, n, t, i));
-
- return i;
- }
-
-
- /**
- Updates each indexArray to refer to vertices in the
- outputVertexArray.
-
- Called from process()
- */
- void updateTriLists(
- Array<Array<int>*>& indexArrayArray,
- const Array<Vector3>& vertexArray,
- const Array<Vector3>& normalArray,
- const Array<Vector2>& texCoordArray) {
-
- // Compute a hash grid so that we can find neighbors quickly.
- // It begins empty and is extended as the tri lists are iterated
- // through.
- weldGrid.clear();
-
- // Process all triLists
- int numTriLists = indexArrayArray.size();
- int u = 0;
- for (int t = 0; t < numTriLists; ++t) {
- Array<int>& triList = *(indexArrayArray[t]);
-
- // For all vertices in this list
- for (int v = 0; v < triList.size(); ++v) {
- // This vertex mapped to u in the flatVertexArray
- triList[v] = getIndex(vertexArray[u], normalArray[u], texCoordArray[u]);
-
- /*
-# ifdef G3D_DEBUG
- {
- int i = triList[v];
- Vector3 N = normalArray[i];
- debugAssertM(N.length() > 0.9f, "Produced non-unit normal");
- }
-# endif
- */
- ++u;
- }
- }
- }
-
- /** Expands the indexed triangle lists into a triangle list.
-
- Called from process() */
- void unroll(
- const Array<Array<int>*>& indexArrayArray,
- const Array<Vector3>& vertexArray,
- const Array<Vector2>& texCoordArray,
- Array<Vector3>& unrolledVertexArray,
- Array<Vector2>& unrolledTexCoordArray) {
-
- int numTriLists = indexArrayArray.size();
- for (int t = 0; t < numTriLists; ++t) {
- const Array<int>& triList = *(indexArrayArray[t]);
- for (int v = 0; v < triList.size(); ++v) {
- int i = triList[v];
- unrolledVertexArray.append(vertexArray[i]);
- unrolledTexCoordArray.append(texCoordArray[i]);
- }
- }
- }
-
- /** For every three vertices, compute the face normal and store it three times.
- Sliver triangles have a zero surface normal, which we will later take to
- match *any* surface normal. */
- void computeFaceNormals(
- const Array<Vector3>& vertexArray,
- Array<Vector3>& faceNormalArray) {
-
- debugAssertM(vertexArray.size() % 3 == 0, "Input is not a triangle soup");
- debugAssertM(faceNormalArray.size() == 0, "Output must start empty.");
-
- for (int v = 0; v < vertexArray.size(); v += 3) {
- const Vector3& e0 = vertexArray[v + 1] - vertexArray[v];
- const Vector3& e1 = vertexArray[v + 2] - vertexArray[v];
-
- // Note that the length may be zero in the case of sliver polygons, e.g.,
- // those correcting a T-junction.
- const Vector3& n = e0.cross(e1).directionOrZero();
-
- // Append the normal once per vertex.
- faceNormalArray.append(n, n, n);
- }
- }
-
-
- /**
- Computes @a smoothNormalArray, whose elements are those of normalArray averaged
- with neighbors within the angular cutoff.
- */
- void smoothNormals(
- const Array<Vector3>& vertexArray,
- const Array<Vector3>& normalArray,
- Array<Vector3>& smoothNormalArray) {
-
- const float cosThresholdAngle = (float)cos(normalSmoothingAngle);
-
- debugAssert(vertexArray.size() == normalArray.size());
- smoothNormalArray.resize(normalArray.size());
-
- // Compute a hash grid so that we can find neighbors quickly.
- PointHashGrid<VN> grid(vertexWeldRadius);
- for (int v = 0; v < normalArray.size(); ++v) {
- grid.insert(VN(vertexArray[v], normalArray[v]));
- }
-
- for (int v = 0; v < normalArray.size(); ++v) {
- // Compute the sum of all nearby normals within the cutoff angle.
- // Search within the vertexWeldRadius, since those are the vertices
- // that will collapse to the same point.
- PointHashGrid<VN>::SphereIterator it =
- grid.beginSphereIntersection(Sphere(vertexArray[v], vertexWeldRadius));
-
- Vector3 sum;
-
- const Vector3& original = normalArray[v];
- while (it.hasMore()) {
- const Vector3& N = it->normal;
- const float cosAngle = N.dot(original);
-
- if (cosAngle > cosThresholdAngle) {
- // This normal is close enough to consider
- sum += N;
- }
- ++it;
- }
-
- const Vector3& average = sum.directionOrZero();
-
- const bool indeterminate = average.isZero();
- // Never "smooth" a normal so far that it points backwards
- const bool backFacing = original.dot(average) < 0;
-
- if (indeterminate || backFacing) {
- // Revert to the face normal
- smoothNormalArray[v] = original;
- } else {
- // Average available normals
- smoothNormalArray[v] = average;
- }
- }
- }
-
-public:
-
-
- /**
- Algorithm:
-
- 1. Unroll the indexed triangle list into a triangle list, where
- there are duplicated vertices.
-
- 2. Compute face normals for all triangles, and expand those into
- the triangle vertices.
-
- 3. At each vertex, average all normals that are within normalSmoothingAngle.
-
- 4. Generate output indexArrayArray. While doing so, merge all vertices where
- the distance between position, texCoord, and normal is within the thresholds.
- */
- void process(
- Array<Vector3>& vertexArray,
- Array<Vector2>& texCoordArray,
- Array<Vector3>& normalArray,
- Array<Array<int>*>& indexArrayArray,
- float normAngle,
- float texRadius,
- float normRadius) {
-
- normalSmoothingAngle = normAngle;
- normalWeldRadius2 = square(normRadius);
- texCoordWeldRadius2 = square(texRadius);
-
- const bool hasTexCoords = (texCoordArray.size() > 0);
-
- if (hasTexCoords) {
- debugAssertM(vertexArray.size() == texCoordArray.size(),
- "Input arrays are not parallel.");
- }
-
- Array<Vector3> unrolledVertexArray;
- Array<Vector3> unrolledFaceNormalArray;
- Array<Vector3> unrolledSmoothNormalArray;
- Array<Vector2> unrolledTexCoordArray;
-
- if (! hasTexCoords) {
- // Generate all zero texture coordinates
- texCoordArray.resize(vertexArray.size());
- }
-
- // Generate a flat (unrolled) triangle list with texture coordinates.
- unroll(indexArrayArray, vertexArray, texCoordArray,
- unrolledVertexArray, unrolledTexCoordArray);
-
- // Put the output back into the input slots. Clear immediately to reduce peak
- // memory.
- outputVertexArray = &vertexArray;
- outputNormalArray = &normalArray;
- outputTexCoordArray = &texCoordArray;
- outputVertexArray->fastClear();
- outputNormalArray->fastClear();
- outputTexCoordArray->fastClear();
-
- // For every three vertices, generate their face normal and store it at
- // each vertex. The output array has the same length as the input.
- computeFaceNormals(unrolledVertexArray, unrolledFaceNormalArray);
-
- // Compute smooth normals at vertices.
- smoothNormals(unrolledVertexArray, unrolledFaceNormalArray, unrolledSmoothNormalArray);
- unrolledFaceNormalArray.clear();
-
- // Regenerate the triangle lists
- updateTriLists(indexArrayArray, unrolledVertexArray, unrolledSmoothNormalArray, unrolledTexCoordArray);
-
- if (! hasTexCoords) {
- // Throw away the generated texCoords
- texCoordArray.resize(0);
- }
- }
-
- WeldHelper(float vertRadius) :
- weldGrid(vertRadius),
- vertexWeldRadius(vertRadius) {}
-
-};
-} // Internal
-
-void MeshAlg::weld(
- Array<Vector3>& vertexArray,
- Array<Vector2>& texCoordArray,
- Array<Vector3>& normalArray,
- Array<Array<int>*>& indexArrayArray,
- float normalSmoothingAngle,
- float vertexWeldRadius,
- float textureWeldRadius,
- float normalWeldRadius) {
-
- _internal::WeldHelper(vertexWeldRadius).process(
- vertexArray, texCoordArray, normalArray, indexArrayArray,
- normalSmoothingAngle, textureWeldRadius, normalWeldRadius);
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/MeshBuilder.cpp b/externals/g3dlite/G3D.lib/source/MeshBuilder.cpp
deleted file mode 100644
index 43ee6e50ac8..00000000000
--- a/externals/g3dlite/G3D.lib/source/MeshBuilder.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- @file MeshBuilder.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2002-02-27
- @edited 2005-02-24
- */
-
-#include "G3D/MeshBuilder.h"
-#include "G3D/MeshAlg.h"
-
-namespace G3D {
-
-void MeshBuilder::setName(const std::string& n) {
- name = n;
-}
-
-
-void MeshBuilder::commit(std::string& n, Array<int>& indexArray, Array<Vector3>& outvertexArray) {
- n = name;
-
- // Make the data fit in a unit cube
- centerTriList();
-
- Array<int> toNew, toOld;
-
- if (close == MeshBuilder::AUTO_WELD) {
- Array<int> index;
- MeshAlg::createIndexArray(triList.size(), index);
- double minEdgeLen, maxEdgeLen, meanEdgeLen, medianEdgeLen;
- double minFaceArea, maxFaceArea, meanFaceArea, medianFaceArea;
- MeshAlg::computeAreaStatistics(triList, index,
- minEdgeLen, meanEdgeLen, medianEdgeLen, maxEdgeLen,
- minFaceArea, meanFaceArea, medianFaceArea, maxFaceArea);
- close = minEdgeLen * 0.1;
- }
-
- MeshAlg::computeWeld(triList, outvertexArray, toNew, toOld, close);
-
- // Construct triangles
- for (int t = 0; t < triList.size(); t += 3) {
- int index[3];
-
- for (int i = 0; i < 3; ++i) {
- index[i] = toNew[t + i];
- }
-
- // Throw out zero size triangles
- if ((index[0] != index[1]) &&
- (index[1] != index[2]) &&
- (index[2] != index[0])) {
- indexArray.append(index[0], index[1], index[2]);
- }
- }
-}
-
-
-void MeshBuilder::centerTriList() {
- // Compute the range of the vertices
- Vector3 vmin, vmax;
-
- computeBounds(vmin, vmax);
-
- Vector3 diagonal = vmax - vmin;
- double scale = max(max(diagonal.x, diagonal.y), diagonal.z) / 2;
- debugAssert(scale > 0);
-
- Vector3 translation = vmin + diagonal / 2;
-
- // Center and scale all vertices in the input list
- int v;
-
- //Matrix3 rot90 = Matrix3::fromAxisAngle(Vector3::UNIT_Y, toRadians(180)) * Matrix3::fromAxisAngle(Vector3::UNIT_X, toRadians(90));
- for (v = 0; v < triList.size(); ++v) {
- triList[v] = (triList[v] - translation) / scale;
- //triList[v] = rot90 * triList[v];
- }
-}
-
-
-void MeshBuilder::computeBounds(Vector3& min, Vector3& max) {
- min = Vector3::inf();
- max = -min;
-
- int v;
- for (v = 0; v < triList.size(); ++v) {
- min = min.min(triList[v]);
- max = max.max(triList[v]);
- }
-}
-
-
-void MeshBuilder::addTriangle(const Vector3& a, const Vector3& b, const Vector3& c) {
- triList.append(a, b, c);
-
- if (_twoSided) {
- triList.append(c, b, a);
- }
-}
-
-
-void MeshBuilder::addQuad(const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& d) {
- addTriangle(a, b, c);
- addTriangle(a, c, d);
-}
-
-
-void MeshBuilder::addTriangle(const Triangle& t) {
- addTriangle(t.vertex(0), t.vertex(1), t.vertex(2));
-}
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/NetAddress.cpp b/externals/g3dlite/G3D.lib/source/NetAddress.cpp
deleted file mode 100644
index 64d692d4763..00000000000
--- a/externals/g3dlite/G3D.lib/source/NetAddress.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- @file NetMessage.cpp
-
- @maintainer Morgan McGuire, morgan@cs.brown.edu
- @created 2005-02-06
- @edited 2005-02-06
- */
-#include "G3D/platform.h"
-#include "G3D/NetAddress.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Array.h"
-#include "G3D/stringutils.h"
-#include "G3D/System.h"
-#include "G3D/NetworkDevice.h"
-
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- #include <unistd.h>
- #include <errno.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <netinet/tcp.h>
- #define _alloca alloca
-
-# ifndef SOCKADDR_IN
-# define SOCKADDR_IN struct sockaddr_in
-# endif
-# ifndef SOCKET
-# define SOCKET int
-# endif
-
-// SOCKADDR_IN is supposed to be defined in NetAddress.h
-#ifndef SOCKADDR_IN
-# error Network headers included in wrong order
-#endif
-#endif
-
-
-namespace G3D {
-
-NetAddress::NetAddress() {
- System::memset(&addr, 0, sizeof(addr));
-}
-
-void NetAddress::init(uint32 host, uint16 port) {
- if ((host != 0) || (port != 0)) {
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- if (host == 0) {
- host = INADDR_ANY;
- }
- addr.sin_addr.s_addr = htonl(host);
- } else {
- System::memset(&addr, 0, sizeof(addr));
- }
-}
-
-
-NetAddress::NetAddress(
- const std::string& hostname,
- uint16 port) {
- init(hostname, port);
-}
-
-
-void NetAddress::init(
- const std::string& hostname,
- uint16 port) {
-
- uint32 addr;
-
- if (hostname == "") {
- addr = INADDR_NONE;
- } else {
- addr = inet_addr(hostname.c_str());
- }
-
- // The address wasn't in numeric form, resolve it
- if (addr == INADDR_NONE) {
- // Get the IP address of the server and store it in host
- struct hostent* host = gethostbyname(hostname.c_str());
-
- if (host == NULL) {
- init(0, 0);
- return;
- }
-
- System::memcpy(&addr, host->h_addr_list[0], host->h_length);
- }
-
- if (addr != INADDR_NONE) {
- addr = ntohl(addr);
- }
- init(addr, port);
-}
-
-
-NetAddress::NetAddress(uint32 hostip, uint16 port) {
- init(hostip, port);
-}
-
-
-NetAddress NetAddress::broadcastAddress(uint16 port) {
- return NetAddress(NetworkDevice::instance()->broadcastAddressArray()[0], port);
-}
-
-
-NetAddress::NetAddress(const std::string& hostnameAndPort) {
-
- Array<std::string> part = stringSplit(hostnameAndPort, ':');
-
- debugAssert(part.length() == 2);
- init(part[0], atoi(part[1].c_str()));
-}
-
-
-NetAddress::NetAddress(const SOCKADDR_IN& a) {
- addr = a;
-}
-
-
-NetAddress::NetAddress(const struct in_addr& addr, uint16 port) {
- #ifdef G3D_WIN32
- init(ntohl(addr.S_un.S_addr), port);
- #else
- init(htonl(addr.s_addr), port);
- #endif
-}
-
-
-void NetAddress::serialize(class BinaryOutput& b) const {
- b.writeUInt32(ip());
- b.writeUInt16(port());
-}
-
-
-void NetAddress::deserialize(class BinaryInput& b) {
- uint32 i;
- uint16 p;
-
- i = b.readUInt32();
- p = b.readUInt16();
-
- init(i, p);
-}
-
-
-bool NetAddress::ok() const {
- return addr.sin_family != 0;
-}
-
-
-std::string NetAddress::ipString() const {
- return format("%s", inet_ntoa(*(in_addr*)&(addr.sin_addr)));
-}
-
-
-std::string NetAddress::toString() const {
- return ipString() + format(":%d", ntohs(addr.sin_port));
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/NetworkDevice.cpp b/externals/g3dlite/G3D.lib/source/NetworkDevice.cpp
deleted file mode 100644
index 246c97d4dbf..00000000000
--- a/externals/g3dlite/G3D.lib/source/NetworkDevice.cpp
+++ /dev/null
@@ -1,1362 +0,0 @@
-/**
- @file NetworkDevice.cpp
-
- @maintainer Morgan McGuire, morgan@cs.brown.edu
- @created 2002-11-22
- @edited 2006-02-24
- */
-
-#include <stdlib.h>
-#include <time.h>
-#include "G3D/platform.h"
-#include "G3D/TextOutput.h"
-#include "G3D/NetworkDevice.h"
-#include "G3D/NetAddress.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Log.h"
-#include "G3D/G3DGameUnits.h"
-#include "G3D/stringutils.h"
-#include "G3D/debug.h"
-
-#include <cstring>
-
-#if defined(G3D_LINUX) || defined(G3D_OSX) || defined(G3D_FREEBSD)
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <ifaddrs.h>
-# include <netinet/in.h>
-# include <net/if.h>
-# ifdef __linux__
-# include <sys/ioctl.h>
-# include <netinet/in.h>
-# include <unistd.h>
-# include <string.h>
-// Match Linux to FreeBSD
-# define AF_LINK AF_PACKET
-# else
-# include <net/if_dl.h>
-# include <sys/sockio.h>
-# endif
-
- #include <unistd.h>
- #include <errno.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <netinet/tcp.h>
- #include <sys/ioctl.h>
- #include <netinet/if_ether.h>
- #include <net/ethernet.h>
- #include <net/if.h>
-
- #include <sys/types.h>
-
- #define _alloca alloca
-
- /** Define an error code for non-windows platforms. */
- int WSAGetLastError() {
- return -1;
- }
-
- #define SOCKET_ERROR -1
-
- static std::string socketErrorCode(int code) {
- return G3D::format("CODE %d: %s\n", code, strerror(code));
- }
-
- static std::string socketErrorCode() {
- return socketErrorCode(errno);
- }
-
- static const int WSAEWOULDBLOCK = -100;
-
- typedef int SOCKET;
- typedef struct sockaddr_in SOCKADDR_IN;
-
-#else
-
- // Windows
- static std::string socketErrorCode(int code) {
- LPTSTR formatMsg = NULL;
-
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_IGNORE_INSERTS |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- code,
- 0,
- (LPTSTR)&formatMsg,
- 0,
- NULL);
-
- return G3D::format("CODE %d: %s\n", code, formatMsg);
- }
-
- static std::string socketErrorCode() {
- return socketErrorCode(GetLastError());
- }
-
-#endif
-
-
-#ifndef _SOCKLEN_T
-# if defined(G3D_WIN32) || defined(G3D_OSX)
- typedef int socklen_t;
-# endif
-#endif
-
-namespace G3D {
-
-NetworkDevice* NetworkDevice::s_instance = NULL;
-
-std::ostream& operator<<(std::ostream& os, const NetAddress& a) {
- return os << a.toString();
-}
-
-
-static void logSocketInfo(const SOCKET& sock) {
- uint32 val;
- socklen_t sz = 4;
- int ret;
-
- ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&val, (socklen_t*)&sz);
- logPrintf("SOL_SOCKET/SO_RCVBUF = %d\n", val);
-
- ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&val, (socklen_t*)&sz);
- logPrintf("SOL_SOCKET/SO_SNDBUF = %d\n", val);
-
- // Note: timeout = 0 means no timeout
- ret = getsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&val, (socklen_t*)&sz);
- logPrintf("SOL_SOCKET/SO_RCVTIMEO = %d\n", val);
-
- ret = getsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&val, (socklen_t*)&sz);
- logPrintf("SOL_SOCKET/SO_SNDTIMEO = %d\n", val);
-}
-
-
-/////////////////////////////////////////////////////////////////////////////
-
-/** Invokes select on one socket. Returns SOCKET_ERROR on error, 0 if
- there is no read pending, sock if there a read pending. */
-static int selectOneReadSocket(const SOCKET& sock) {
- // 0 time timeout is specified to poll and return immediately
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
-
- // Create a set that contains just this one socket
- fd_set socketSet;
- FD_ZERO(&socketSet);
- FD_SET(sock, &socketSet);
-
- int ret = select(sock + 1, &socketSet, NULL, NULL, &timeout);
-
- return ret;
-}
-
-
-/** Returns true if the socket has a read pending */
-static bool readWaiting(const SOCKET& sock) {
- int ret = selectOneReadSocket(sock);
-
- switch (ret) {
- case SOCKET_ERROR:
- logPrintf("ERROR: selectOneReadSocket returned "
- "SOCKET_ERROR in readWaiting(). %s", socketErrorCode().c_str());
- // Return true so that we'll force an error on read and close
- // the socket.
- return true;
-
- case 0:
- return false;
-
- default:
- return true;
- }
-}
-
-
-/** Invokes select on one socket. */
-static int selectOneWriteSocket(const SOCKET& sock) {
- // 0 time timeout is specified to poll and return immediately
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
-
- // Create a set that contains just this one socket
- fd_set socketSet;
- FD_ZERO(&socketSet);
- FD_SET(sock, &socketSet);
-
- return select(sock + 1, NULL, &socketSet, NULL, &timeout);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-NetworkDevice* NetworkDevice::instance() {
- if (s_instance == NULL) {
- s_instance = new NetworkDevice();
- if (! s_instance->init()) {
- delete s_instance;
- s_instance = NULL;
- }
- }
- return s_instance;
-}
-
-
-void NetworkDevice::cleanup() {
- if (s_instance) {
- s_instance->_cleanup();
- delete s_instance;
- s_instance = NULL;
- }
-}
-
-
-NetworkDevice::NetworkDevice() {
- initialized = false;
-}
-
-
-NetworkDevice::~NetworkDevice() {
-}
-
-
-std::string NetworkDevice::localHostName() const {
- char ac[128];
- if (gethostname(ac, sizeof(ac)) == -1) {
- Log::common()->printf("Error while getting local host name\n");
- return "localhost";
- }
- return gethostbyname(ac)->h_name;
-}
-
-#ifndef G3D_WIN32
-const char* errnoToString() {
- switch (errno) {
- case EBADF:
- return "file descriptor is invalid.";
-
- case EINVAL:
- return "Request or argp is not valid.";
-
- case ENOTTY:
- return
- "file descriptor is not associated with a character special device OR "
- "The specified request does not apply to the "
- "kind of object that the descriptor fildes references.";
-
- case EADDRNOTAVAIL:
- return "Address not available.";
-
- default:
- {
- static char buffer[20];
- sprintf(buffer, "Error %d", errno);
- return buffer;
- }
- }
-}
-#endif
-
-
-NetworkDevice::EthernetAdapter::EthernetAdapter() {
- name = "";
- ip = 0;
- hostname = "";
- subnet = 0;
- broadcast = 0;
- for (int i = 0; i < 6; ++i) {
- mac[i] = 0;
- }
-}
-
-void NetworkDevice::EthernetAdapter::describe(TextOutput& t) const {
- t.writeSymbol("{");
- t.pushIndent();
- t.writeNewline();
-
- t.writeSymbols("hostname", "=");
- t.writeString(hostname);
- t.writeNewline();
-
- t.writeSymbols("name", "=");
- t.writeString(name);
- t.writeNewline();
-
- t.writeSymbols("ip", "=");
- t.writeSymbol(formatIP(ip));
- t.writeNewline();
-
- t.writeSymbols("subnet", "=");
- t.writeSymbol(formatIP(subnet));
- t.writeNewline();
-
- t.writeSymbols("broadcast", "=");
- t.writeSymbol(formatIP(broadcast));
- t.writeNewline();
-
- t.writeSymbols("mac", "=");
- t.writeSymbol(formatMAC(mac));
- t.writeNewline();
-
- t.popIndent();
- t.writeSymbol("}");
- t.writeNewline();
-}
-
-
-void NetworkDevice::addAdapter(const EthernetAdapter& a) {
- m_adapterArray.append(a);
- if (a.broadcast != 0) {
- int i = m_broadcastAddresses.findIndex(a.broadcast);
- if (i == -1) {
- m_broadcastAddresses.append(a.broadcast);
- }
- }
-}
-
-
-std::string NetworkDevice::formatIP(uint32 addr) {
- return format("%3d.%3d.%3d.%3d", (addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
- (addr >> 8) & 0xFF, addr & 0xFF);
-}
-
-
-std::string NetworkDevice::formatMAC(const uint8 MAC[6]) {
- return format("%02x:%02x:%02x:%02x:%02x:%02x", MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]);
-}
-
-
-#ifdef G3D_WIN32
-
-bool NetworkDevice::init() {
- debugAssert(! initialized);
-
- logPrintf("Network Startup");
- logPrintf("Starting WinSock networking.\n");
- WSADATA wsda;
- WSAStartup(MAKEWORD(G3D_WINSOCK_MAJOR_VERSION, G3D_WINSOCK_MINOR_VERSION), &wsda);
-
- std::string hostname = "localhost";
- {
- char ac[128];
- if (gethostname(ac, sizeof(ac)) == -1) {
- logPrintf("Warning: Error while getting local host name\n");
- } else {
- hostname = gethostbyname(ac)->h_name;
- }
- }
-
- EthernetAdapter a;
- a.hostname = hostname;
- a.name = "";
- a.ip = NetAddress(hostname, 0).ip();
-
- // TODO: Find subnet on Win32
- a.subnet = 0x0000FFFF;
-
- // TODO: Find broadcast on Win32
- a.broadcast = 0xFFFFFFFF;
-
- // TODO: find MAC on Win32
-
- addAdapter(a);
-
- std::string machine = localHostName();
- std::string addr = NetAddress(machine, 0).ipString();
- logPrintf(
- "Network:\n"
- " Status: %s\n"
- " Loaded winsock specification version %d (%d is "
- "the highest available)\n"
- " %d sockets available\n"
- " Largest UDP datagram packet size is %d bytes\n\n",
- wsda.szDescription,
- wsda.szSystemStatus,
- wsda.wVersion,
- wsda.wHighVersion,
- wsda.iMaxSockets,
- wsda.iMaxUdpDg);
-
- // TODO: WSAIoctl for subnet and broadcast addresses
- // http://msdn.microsoft.com/en-us/library/ms741621(VS.85).aspx
- //
- // TODO: SIO_GET_INTERFACE_LIST
-
- initialized = true;
-
- return true;
-}
-#endif
-
-
-#if defined(G3D_LINUX) || defined(G3D_OSX) || defined(G3D_FREEBSD)
-
-const sockaddr_in* castToIP4(const sockaddr* addr) {
- if (addr == NULL) {
- return NULL;
- } else if (addr->sa_family == AF_INET) {
- // An IPv4 address
- return reinterpret_cast<const sockaddr_in*>(addr);
- } else {
- // Not an IPv4 address
- return NULL;
- }
-}
-
-uint32 getIP(const sockaddr_in* addr) {
- if (addr != NULL) {
- return ntohl(addr->sin_addr.s_addr);
- } else {
- return 0;
- }
-}
-
-
-bool NetworkDevice::init() {
- debugAssert(! initialized);
-
- // Used for combining the MAC and ip information
- typedef Table<std::string, EthernetAdapter> AdapterTable;
-
- AdapterTable table;
-
- // Head of a linked list of network interfaces on this machine
- ifaddrs* ifap = NULL;
-
- int r = getifaddrs(&ifap);
-
- if (r != 0) {
- logPrintf("ERROR: getifaddrs returned %d\n", r);
- return false;
- }
-
- ifaddrs* current = ifap;
-
- if (current == NULL) {
- logPrintf("WARNING: No network interfaces found\n");
- EthernetAdapter a;
- a.name = "fallback";
- a.hostname = "localhost";
- a.ip = (127 << 24) | 1;
- a.broadcast = 0xFFFFFFFF;
- a.subnet = 0x000000FF;
- addAdapter(a);
-
- } else {
-
- while (current != NULL) {
-
- bool up = (current->ifa_flags & IFF_UP);
- bool loopback = (current->ifa_flags & IFF_LOOPBACK);
-
- if (! up || loopback) {
- // Skip this adapter; it is offline or is a loopback
- current = current->ifa_next;
- continue;
- }
-
- if (! table.containsKey(current->ifa_name)) {
- EthernetAdapter a;
- a.name = current->ifa_name;
- table.set(a.name, a);
- }
-
- // This adapter must exist because it was created above
- EthernetAdapter& adapter = table[current->ifa_name];
-
- const sockaddr_in* interfaceAddress = castToIP4(current->ifa_addr);
- const sockaddr_in* broadcastAddress = castToIP4(current->ifa_dstaddr);
- const sockaddr_in* subnetMask = castToIP4(current->ifa_netmask);
-
- uint32 ip = getIP(interfaceAddress);
- uint32 ba = getIP(broadcastAddress);
- uint32 sn = getIP(subnetMask);
-
- if (ip != 0) {
- adapter.ip = ip;
- }
-
- if (ba != 0) {
- adapter.broadcast = ba;
- }
-
- if (sn != 0) {
- adapter.subnet = sn;
- }
-
- uint8_t* MAC = NULL;
- // Extract MAC address
- if ((current->ifa_addr != NULL) && (current->ifa_addr->sa_family == AF_LINK)) {
-# ifdef __linux__
- {
- // Linux
- struct ifreq ifr;
-
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
-
- ifr.ifr_addr.sa_family = AF_INET;
- strcpy(ifr.ifr_name, current->ifa_name);
- ioctl(fd, SIOCGIFHWADDR, &ifr);
- close(fd);
-
- MAC = reinterpret_cast<uint8_t*>(ifr.ifr_hwaddr.sa_data);
- }
-# else
- {
- // The MAC address and the interfaceAddress come in as
- // different interfaces with the same name.
-
- // Posix/FreeBSD/Mac OS
- sockaddr_dl* sdl = (struct sockaddr_dl *)current->ifa_addr;
- MAC = reinterpret_cast<uint8_t*>(LLADDR(sdl));
- }
-# endif
-
- // See if there was a MAC address
- if (MAC != NULL) {
- bool anyNonZero = false;
- for (int i = 0; i < 6; ++i) {
- anyNonZero = anyNonZero || (MAC[i] != 0);
- }
- if (anyNonZero) {
- System::memcpy(adapter.mac, MAC, 6);
- }
- }
- }
-
- current = current->ifa_next;
- }
-
- freeifaddrs(ifap);
- ifap = NULL;
- }
-
- // Extract all interesting adapters from the table
- for (AdapterTable::Iterator it = table.begin(); it.hasMore(); ++it) {
- const EthernetAdapter& adapter = it->value;
-
- // Only add adapters that have IP addresses
- if (adapter.ip != 0) {
- addAdapter(adapter);
- } else {
- logPrintf("NetworkDevice: Ignored adapter %s because ip = 0\n", adapter.name.c_str());
- }
- }
-
- initialized = true;
-
- return true;
-}
-
-#endif
-
-
-void NetworkDevice::_cleanup() {
- debugAssert(initialized);
-
- logPrintf("Network Cleanup");
-# ifdef G3D_WIN32
- WSACleanup();
-# endif
- logPrintf("Network cleaned up.");
-}
-
-bool NetworkDevice::bind(SOCKET sock, const NetAddress& addr) const {
- Log::common()->printf("Binding socket %d on port %d ",
- sock, htons(addr.addr.sin_port));
- if (::bind(sock, (struct sockaddr*)&(addr.addr), sizeof(addr.addr)) ==
- SOCKET_ERROR) {
-
- Log::common()->println("FAIL");
- Log::common()->println(socketErrorCode());
- closesocket(sock);
- return false;
- }
-
- Log::common()->println("Ok");
- return true;
-}
-
-
-void NetworkDevice::closesocket(SOCKET& sock) const {
- if (sock != 0) {
- #ifdef G3D_WIN32
- ::closesocket(sock);
- #else
- close(sock);
- #endif
-
- Log::common()->printf("Closed socket %d\n", sock);
- sock = 0;
- }
-}
-
-
-void NetworkDevice::localHostAddresses(Array<NetAddress>& array) const {
- array.resize(0);
-
- char ac[128];
-
- if (gethostname(ac, sizeof(ac)) == SOCKET_ERROR) {
- Log::common()->printf("Error while getting local host name\n");
- return;
- }
-
- struct hostent* phe = gethostbyname(ac);
- if (phe == 0) {
- Log::common()->printf("Error while getting local host address\n");
- return;
- }
-
- for (int i = 0; (phe->h_addr_list[i] != 0); ++i) {
- struct in_addr addr;
- memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));
- array.append(NetAddress(addr));
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-Conduit::Conduit() : binaryOutput("<memory>", G3D_LITTLE_ENDIAN) {
- sock = 0;
- mSent = 0;
- mReceived = 0;
- bSent = 0;
- bReceived = 0;
-}
-
-
-Conduit::~Conduit() {
- NetworkDevice::instance()->closesocket(sock);
-}
-
-
-uint64 Conduit::bytesSent() const {
- return bSent;
-}
-
-
-uint64 Conduit::bytesReceived() const {
- return bReceived;
-}
-
-
-uint64 Conduit::messagesSent() const {
- return mSent;
-}
-
-
-uint64 Conduit::messagesReceived() const {
- return mReceived;
-}
-
-
-bool Conduit::ok() const {
- return (sock != 0) && (sock != SOCKET_ERROR);
-}
-
-
-bool Conduit::messageWaiting() {
- return readWaiting(sock);
-}
-
-
-/**
- Increases the send and receive sizes of a socket to 2 MB from 8k
- */
-static void increaseBufferSize(SOCKET sock) {
-
- // Increase the buffer size; the default (8192) is too easy to
- // overflow when the network latency is high.
- {
- uint32 val = 1024 * 1024 * 2;
- if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
- (char*)&val, sizeof(val)) == SOCKET_ERROR) {
- Log::common()->printf("WARNING: Increasing socket "
- "receive buffer to %d failed.\n", val);
- Log::common()->println(socketErrorCode());
- }
-
- if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
- (char*)&val, sizeof(val)) == SOCKET_ERROR) {
- Log::common()->printf("WARNING: Increasing socket "
- "send buffer to %d failed.\n", val);
- Log::common()->println(socketErrorCode());
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-ReliableConduitRef ReliableConduit::create(const NetAddress& address) {
- return new ReliableConduit(address);
-}
-
-
-ReliableConduit::ReliableConduit(
- const NetAddress& _addr) : state(NO_MESSAGE), receiveBuffer(NULL),
- receiveBufferTotalSize(0), receiveBufferUsedSize(0) {
-
- NetworkDevice* nd = NetworkDevice::instance();
-
- messageType = 0;
-
- addr = _addr;
- Log::common()->print("Creating a TCP socket ");
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
-
- if (sock == SOCKET_ERROR) {
- Log::common()->println("FAIL");
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- return;
- }
-
- Log::common()->println("Ok");
-
- // Setup socket options (both constructors should set the same options)
-
- // Disable Nagle's algorithm (we send lots of small packets)
- const int T = true;
- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
- (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
-
- Log::common()->println("WARNING: Disabling Nagel's "
- "algorithm failed.");
- Log::common()->println(socketErrorCode());
- } else {
- Log::common()->println("Disabled Nagel's algorithm.");
- }
-
- // Set the NO LINGER option so the socket doesn't hang around if
- // there is unsent data in the queue when it closes.
- struct linger ling;
- ling.l_onoff = 0;
- ling.l_linger = 0;
- if (setsockopt(sock, SOL_SOCKET, SO_LINGER,
- (const char*)&ling, sizeof(ling)) == SOCKET_ERROR) {
-
- Log::common()->println("WARNING: Setting socket no linger failed.");
- Log::common()->println(socketErrorCode());
- } else {
- Log::common()->println("Set socket option no_linger.");
- }
-
- // Set reuse address so that a new server can start up soon after
- // an old one has closed.
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
-
- Log::common()->println("WARNING: Setting socket reuseaddr failed.");
- Log::common()->println(socketErrorCode());
- } else {
- Log::common()->println("Set socket option reuseaddr.");
- }
-
- // Ideally, we'd like to specify IPTOS_LOWDELAY as well.
-
- logSocketInfo(sock);
-
- increaseBufferSize(sock);
-
- Log::common()->printf("Created TCP socket %d\n", sock);
-
- std::string x = addr.toString();
- Log::common()->printf("Connecting to %s on TCP socket %d ", x.c_str(), sock);
-
- int ret = connect(sock, (struct sockaddr *) &(addr.addr), sizeof(addr.addr));
-
- if (ret == WSAEWOULDBLOCK) {
- RealTime t = System::time() + 5.0;
- // Non-blocking; we must wait until select returns non-zero
- while ((selectOneWriteSocket(sock) == 0) && (System::time() < t)) {
- System::sleep(0.02);
- }
-
- // TODO: check for failure on the select call
-
- } else if (ret != 0) {
- sock = (SOCKET)SOCKET_ERROR;
- Log::common()->println("FAIL");
- Log::common()->println(socketErrorCode());
- return;
- }
-
- Log::common()->println("Ok");
-}
-
-
-ReliableConduit::ReliableConduit(
- const SOCKET& _sock,
- const NetAddress& _addr) :
- state(NO_MESSAGE),
- receiveBuffer(NULL),
- receiveBufferTotalSize(0),
- receiveBufferUsedSize(0) {
- sock = _sock;
- addr = _addr;
-
- messageType = 0;
-
- // Setup socket options (both constructors should set the same options)
-
- // Disable Nagle's algorithm (we send lots of small packets)
- const int T = true;
- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
- (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
-
- Log::common()->println("WARNING: Disabling Nagel's algorithm failed.");
- Log::common()->println(socketErrorCode());
- } else {
- Log::common()->println("Disabled Nagel's algorithm.");
- }
-
- // Set the NO LINGER option so the socket doesn't hang around if
- // there is unsent data in the queue when it closes.
- struct linger ling;
- ling.l_onoff = 0;
- ling.l_linger = 0;
- if (setsockopt(sock, SOL_SOCKET, SO_LINGER,
- (const char*)&ling, sizeof(ling)) == SOCKET_ERROR) {
-
- Log::common()->println("WARNING: Setting socket no linger failed.");
- Log::common()->println(socketErrorCode());
- } else {
- Log::common()->println("Set socket option no_linger.");
- }
-
- // Set reuse address so that a new server can start up soon after
- // an old one has closed.
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
-
- Log::common()->println("WARNING: Setting socket reuseaddr failed.");
- Log::common()->println(socketErrorCode());
- } else {
- Log::common()->println("Set socket option reuseaddr.");
- }
-
- // Ideally, we'd like to specify IPTOS_LOWDELAY as well.
-
- logSocketInfo(sock);
-}
-
-
-ReliableConduit::~ReliableConduit() {
- free(receiveBuffer);
- receiveBuffer = NULL;
- receiveBufferTotalSize = 0;
- receiveBufferUsedSize = 0;
-}
-
-
-bool ReliableConduit::messageWaiting() {
- switch (state) {
- case HOLDING:
- // We've already read the message and are waiting
- // for a receive call.
- return true;
-
- case RECEIVING:
-
- if (! ok()) {
- return false;
- }
- // We're currently receiving the message. Read a little more.
- receiveIntoBuffer();
-
- if (messageSize == receiveBufferUsedSize) {
- // We've read the whole mesage. Switch to holding state
- // and return true.
- state = HOLDING;
- return true;
- } else {
- // There are more bytes left to read. We'll read them on
- // the next call. Because the *entire* message is not ready,
- // return false.
- return false;
- }
- break;
-
- case NO_MESSAGE:
- if (Conduit::messageWaiting()) {
- // Message incoming. Read the header.
-
- state = RECEIVING;
- receiveHeader();
-
- // Loop back around now that we're in the receive state; we
- // may be able to read the whole message before returning
- // to the caller.
- return messageWaiting();
- } else {
- // No message incoming.
- return false;
- }
- }
-
- debugAssertM(false, "Should not reach this point");
- return false;
-}
-
-
-uint32 ReliableConduit::waitingMessageType() {
- // The messageWaiting call is what actually receives the message.
- if (messageWaiting()) {
- return messageType;
- } else {
- return 0;
- }
-}
-
-
-void ReliableConduit::sendBuffer(const BinaryOutput& b) {
- NetworkDevice* nd = NetworkDevice::instance();
- int ret = ::send(sock, (const char*)b.getCArray(), b.size(), 0);
-
- if (ret == SOCKET_ERROR) {
- Log::common()->println("Error occured while sending message.");
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- return;
- }
-
- ++mSent;
- bSent += b.size();
-
- // Verify the packet was actually sent
- // Conversion to unsigned is safe because -1 is caught earlier
- debugAssert(ret == b.size());
-}
-
-
-/** Null serializer. Used by reliable conduit::send(type) */
-class Dummy {
-public:
- void serialize(BinaryOutput& b) const { (void)b; }
-};
-
-
-void ReliableConduit::send(uint32 type) {
- static Dummy dummy;
- send(type, dummy);
-}
-
-
-
-NetAddress ReliableConduit::address() const {
- return addr;
-}
-
-
-void ReliableConduit::receiveHeader() {
- NetworkDevice* nd = NetworkDevice::instance();
- debugAssert(state == RECEIVING);
-
- // Read the type
- uint32 tmp;
- int ret = recv(sock, (char*)&tmp, sizeof(tmp), 0);
-
- // The type is the first four bytes. It is little endian.
- if (System::machineEndian() == G3D_LITTLE_ENDIAN) {
- messageType = tmp;
- } else {
- // Swap the byte order
- for (int i = 0; i < 4; ++i) {
- ((char*)&messageType)[i] = ((char*)&tmp)[3 - i];
- }
- }
-
- if ((ret == SOCKET_ERROR) || (ret != sizeof(messageType))) {
- Log::common()->printf("Call to recv failed. ret = %d,"
- " sizeof(messageType) = %d\n",
- (int)ret, (int)sizeof(messageType));
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- messageType = 0;
- return;
- }
-
- // Read the size
- ret = recv(sock, (char*)&messageSize, sizeof(messageSize), 0);
-
- if ((ret == SOCKET_ERROR) || (ret != sizeof(messageSize))) {
- Log::common()->printf("Call to recv failed. ret = %d,"
- " sizeof(len) = %d\n", (int)ret,
- (int)sizeof(messageSize));
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- messageType = 0;
- return;
- }
-
- messageSize = ntohl(messageSize);
- debugAssert(messageSize < 6e7);
-
- debugAssert(receiveBufferUsedSize == 0);
-
- // Extend the size of the buffer.
- if (messageSize > receiveBufferTotalSize) {
- receiveBuffer = realloc(receiveBuffer, messageSize);
- receiveBufferTotalSize = messageSize;
- }
-
- if (receiveBuffer == NULL) {
- Log::common()->println("Could not allocate a memory buffer "
- "during receivePacket.");
- nd->closesocket(sock);
- }
-
- bReceived += 4;
-}
-
-
-void ReliableConduit::receiveIntoBuffer() {
- NetworkDevice* nd = NetworkDevice::instance();
-
- debugAssert(state == RECEIVING);
- debugAssert(messageType != 0);
- debugAssertM(receiveBufferUsedSize < messageSize, "Message already received.");
- debugAssertM(messageSize >= receiveBufferUsedSize, "Message size overflow.");
-
- // Read the data itself
- int ret = 0;
- uint32 left = messageSize - receiveBufferUsedSize;
- int count = 0;
- while ((ret != SOCKET_ERROR) && (left > 0) && (count < 100)) {
-
- ret = recv(sock, ((char*)receiveBuffer) + receiveBufferUsedSize, left, 0);
-
- if (ret > 0) {
- left -= ret;
- receiveBufferUsedSize += ret;
- bReceived += ret;
-
- if (left > 0) {
- // There's still more. Give the machine a chance to read
- // more data, but don't wait forever.
-
- ++count;
- System::sleep(0.001);
- }
- } else {
- // Something went wrong; our blocking read returned nothing.
- break;
- }
- }
-
- if ((ret == 0) || (ret == SOCKET_ERROR)) {
-
- if (ret == SOCKET_ERROR) {
- Log::common()->printf("Call to recv failed. ret = %d,"
- " sizeof(messageSize) = %d\n", ret, messageSize);
- Log::common()->println(socketErrorCode());
- } else {
- Log::common()->printf("recv returned 0\n");
- }
- nd->closesocket(sock);
- return;
- }
-
- ++mReceived;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-LightweightConduitRef LightweightConduit::create(
- uint16 receivePort,
- bool enableReceive,
- bool enableBroadcast) {
-
- return new LightweightConduit(receivePort, enableReceive, enableBroadcast);
-}
-
-LightweightConduit::LightweightConduit(
- uint16 port,
- bool enableReceive,
- bool enableBroadcast) {
- NetworkDevice* nd = NetworkDevice::instance();
-
- Log::common()->print("Creating a UDP socket ");
- sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
- if (sock == SOCKET_ERROR) {
- sock = 0;
- Log::common()->println("FAIL");
- Log::common()->println(socketErrorCode());
- return;
- }
- Log::common()->println("Ok");
-
- if (enableReceive) {
- debugAssert(port != 0);
- if (! nd->bind(sock, NetAddress(0, port))) {
- nd->closesocket(sock);
- sock = (SOCKET)SOCKET_ERROR;
- }
- }
-
- // Figuring out the MTU seems very complicated, so we just set it to 1000,
- // which is likely to be safe. See IP_MTU for more information.
- MTU = 1000;
-
- increaseBufferSize(sock);
-
- if (enableBroadcast) {
- int TR = true;
- if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST,
- (const char*)&TR, sizeof(TR)) != 0) {
- Log::common()->println("Call to setsockopt failed");
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- sock = 0;
- return;
- }
- }
-
- Log::common()->printf("Done creating UDP socket %d\n", sock);
-
- alreadyReadMessage = false;
-}
-
-
-LightweightConduit::~LightweightConduit() {
-}
-
-
-bool LightweightConduit::receive(NetAddress& sender) {
- // This both checks to ensure that a message was waiting and
- // actively consumes the message from the network stream if
- // it has not been read yet.
- uint32 t = waitingMessageType();
- if (t == 0) {
- return false;
- }
-
- sender = messageSender;
- alreadyReadMessage = false;
-
- if (messageBuffer.size() < 4) {
- // Something went wrong
- return false;
- }
-
- return true;
-}
-
-
-void LightweightConduit::sendBuffer(const NetAddress& a, BinaryOutput& b) {
- NetworkDevice* nd = NetworkDevice::instance();
- if (sendto(sock, (const char*)b.getCArray(), b.size(), 0,
- (struct sockaddr *) &(a.addr), sizeof(a.addr)) == SOCKET_ERROR) {
- Log::common()->printf("Error occured while sending packet "
- "to %s\n", inet_ntoa(a.addr.sin_addr));
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- } else {
- ++mSent;
- bSent += b.size();
- }
-}
-
-
-bool LightweightConduit::messageWaiting() {
- // We may have already pulled the message off the network stream
- return alreadyReadMessage || Conduit::messageWaiting();
-}
-
-
-uint32 LightweightConduit::waitingMessageType() {
- NetworkDevice* nd = NetworkDevice::instance();
- if (! messageWaiting()) {
- return 0;
- }
-
- if (! alreadyReadMessage) {
- messageBuffer.resize(8192);
-
- SOCKADDR_IN remote_addr;
- int iRemoteAddrLen = sizeof(sockaddr);
-
- int ret = recvfrom(sock, (char*)messageBuffer.getCArray(),
- messageBuffer.size(), 0, (struct sockaddr *) &remote_addr,
- (socklen_t*)&iRemoteAddrLen);
-
- if (ret == SOCKET_ERROR) {
- Log::common()->println("Error: recvfrom failed in "
- "LightweightConduit::waitingMessageType().");
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- messageBuffer.resize(0);
- messageSender = NetAddress();
- messageType = 0;
- return 0;
- }
-
- messageSender = NetAddress(remote_addr);
-
- ++mReceived;
- bReceived += ret;
-
- messageBuffer.resize(ret, DONT_SHRINK_UNDERLYING_ARRAY);
-
- // The type is the first four bytes. It is little endian.
- if (System::machineEndian() == G3D_LITTLE_ENDIAN) {
- messageType = *((uint32*)messageBuffer.getCArray());
- } else {
- // Swap the byte order
- for (int i = 0; i < 4; ++i) {
- ((char*)&messageType)[i] = messageBuffer[3 - i];
- }
- }
-
- alreadyReadMessage = true;
- }
-
- return messageType;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-NetListenerRef NetListener::create(const uint16 port) {
- return new NetListener(port);
-}
-
-
-NetListener::NetListener(uint16 port) {
- NetworkDevice* nd = NetworkDevice::instance();
-
- // Start the listener socket
- Log::common()->print("Creating a listener ");
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
-
- if (sock == SOCKET_ERROR) {
- Log::common()->printf("FAIL");
- Log::common()->println(socketErrorCode());
- return;
- }
- Log::common()->println("Ok");
-
- const int T = true;
-
- // Set reuse address so that a new server can start up soon after
- // an old one has closed.
- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (const char*)&T, sizeof(T)) == SOCKET_ERROR) {
-
- Log::common()->println("WARNING: Setting socket reuseaddr failed.");
- Log::common()->println(socketErrorCode());
- } else {
- Log::common()->println("Set socket option reuseaddr.");
- }
-
-
- if (! nd->bind(sock, NetAddress(0, port))) {
- Log::common()->printf("Unable to bind!\n");
- nd->closesocket(sock);
- sock = (SOCKET)SOCKET_ERROR;
- return;
- }
-
- Log::common()->printf("Listening on port %5d ", port);
-
- // listen is supposed to return 0 when there is no error.
- // The 2nd argument is the number of connections to allow pending
- // at any time.
- int L = listen(sock, 100);
- if (L == SOCKET_ERROR) {
- Log::common()->println("FAIL");
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- sock = (SOCKET)SOCKET_ERROR;
- return;
- }
- Log::common()->println("Ok");
- Log::common()->printf("Now listening on socket %d.\n\n", sock);
-}
-
-
-NetListener::~NetListener() {
- NetworkDevice* nd = NetworkDevice::instance();
- nd->closesocket(sock);
-}
-
-
-ReliableConduitRef NetListener::waitForConnection() {
- NetworkDevice* nd = NetworkDevice::instance();
- // The address of the connecting host
- SOCKADDR_IN remote_addr;
- int iAddrLen = sizeof(remote_addr);
-
- Log::common()->println("Blocking in NetListener::waitForConnection().");
-
- SOCKET sClient = accept(sock, (struct sockaddr*) &remote_addr,
- (socklen_t*)&iAddrLen);
-
- if (sClient == SOCKET_ERROR) {
- Log::common()->println("Error in NetListener::acceptConnection.");
- Log::common()->println(socketErrorCode());
- nd->closesocket(sock);
- return NULL;
- }
-
- Log::common()->printf("%s connected, transferred to socket %d.\n",
- inet_ntoa(remote_addr.sin_addr), sClient);
-
- #ifndef G3D_WIN32
- return new ReliableConduit(sClient,
- NetAddress(htonl(remote_addr.sin_addr.s_addr),
- ntohs(remote_addr.sin_port)));
- #else
- return new ReliableConduit(sClient,
- NetAddress(ntohl(remote_addr.sin_addr.S_un.S_addr),
- ntohs(remote_addr.sin_port)));
- #endif
-}
-
-
-bool NetListener::ok() const {
- return (sock != 0) && (sock != SOCKET_ERROR);
-}
-
-
-bool NetListener::clientWaiting() const {
- return readWaiting(sock);
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////
-
-void NetworkDevice::describeSystem(
- TextOutput& t) {
-
- t.writeSymbols("Network", "{");
- t.writeNewline();
- t.pushIndent();
-
- for (int i = 0; i < m_adapterArray.size(); ++i) {
- m_adapterArray[i].describe(t);
- }
-
-
- t.popIndent();
- t.writeSymbols("}");
- t.writeNewline();
- t.writeNewline();
-}
-
-
-void NetworkDevice::describeSystem(
- std::string& s) {
-
- TextOutput t;
- describeSystem(t);
- t.commitString(s);
-}
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/PhysicsFrame.cpp b/externals/g3dlite/G3D.lib/source/PhysicsFrame.cpp
deleted file mode 100644
index 034e585d01f..00000000000
--- a/externals/g3dlite/G3D.lib/source/PhysicsFrame.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- @file PhysicsFrame.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2002-07-09
- @edited 2006-01-25
-*/
-
-#include "G3D/platform.h"
-#include "G3D/PhysicsFrame.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-PhysicsFrame::PhysicsFrame() {
- translation = Vector3::zero();
- rotation = Quat();
-}
-
-
-PhysicsFrame::PhysicsFrame(
- const CoordinateFrame& coordinateFrame) {
-
- translation = coordinateFrame.translation;
- rotation = Quat(coordinateFrame.rotation);
-}
-
-
-PhysicsFrame PhysicsFrame::operator*(const PhysicsFrame& other) const {
- PhysicsFrame result;
-
- result.rotation = rotation * other.rotation;
- result.translation = translation + rotation.toRotationMatrix() * other.translation;
-
- return result;
-}
-
-
-CoordinateFrame PhysicsFrame::toCoordinateFrame() const {
- CoordinateFrame f;
-
- f.translation = translation;
- f.rotation = rotation.toRotationMatrix();
-
- return f;
-}
-
-
-PhysicsFrame PhysicsFrame::lerp(
- const PhysicsFrame& other,
- float alpha) const {
-
- PhysicsFrame result;
-
- result.translation = translation.lerp(other.translation, alpha);
- result.rotation = rotation.slerp(other.rotation, alpha);
-
- return result;
-}
-
-
-void PhysicsFrame::deserialize(class BinaryInput& b) {
- translation.deserialize(b);
- rotation.deserialize(b);
-}
-
-
-void PhysicsFrame::serialize(class BinaryOutput& b) const {
- translation.serialize(b);
- rotation.serialize(b);
-}
-
-
-}; // namespace
-
diff --git a/externals/g3dlite/G3D.lib/source/Plane.cpp b/externals/g3dlite/G3D.lib/source/Plane.cpp
deleted file mode 100644
index bb8ed5c6033..00000000000
--- a/externals/g3dlite/G3D.lib/source/Plane.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- @file Plane.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-02-06
- @edited 2006-01-29
- */
-
-#include "G3D/platform.h"
-#include "G3D/Plane.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/stringutils.h"
-
-namespace G3D {
-
-Plane::Plane(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-void Plane::serialize(class BinaryOutput& b) const {
- _normal.serialize(b);
- b.writeFloat64(_distance);
-}
-
-
-void Plane::deserialize(class BinaryInput& b) {
- _normal.deserialize(b);
- _distance = (float)b.readFloat64();
-}
-
-
-Plane::Plane(
- Vector4 point0,
- Vector4 point1,
- Vector4 point2) {
-
- debugAssertM(
- point0.w != 0 ||
- point1.w != 0 ||
- point2.w != 0,
- "At least one point must be finite.");
-
- // Rotate the points around so that the finite points come first.
-
- while ((point0.w == 0) &&
- ((point1.w == 0) || (point2.w != 0))) {
- Vector4 temp = point0;
- point0 = point1;
- point1 = point2;
- point2 = temp;
- }
-
- Vector3 dir1;
- Vector3 dir2;
-
- if (point1.w == 0) {
- // 1 finite, 2 infinite points; the plane must contain
- // the direction of the two direcitons
- dir1 = point1.xyz();
- dir2 = point2.xyz();
- } else if (point2.w != 0) {
- // 3 finite points, the plane must contain the directions
- // betwseen the points.
- dir1 = point1.xyz() - point0.xyz();
- dir2 = point2.xyz() - point0.xyz();
- } else {
- // 2 finite, 1 infinite point; the plane must contain
- // the direction between the first two points and the
- // direction of the third point.
- dir1 = point1.xyz() - point0.xyz();
- dir2 = point2.xyz();
- }
-
- _normal = dir1.cross(dir2).direction();
- _distance = _normal.dot(point0.xyz());
-}
-
-
-Plane::Plane(
- const Vector3& point0,
- const Vector3& point1,
- const Vector3& point2) {
-
- _normal = (point1 - point0).cross(point2 - point0).direction();
- _distance = _normal.dot(point0);
-}
-
-
-Plane::Plane(
- const Vector3& __normal,
- const Vector3& point) {
-
- _normal = __normal.direction();
- _distance = _normal.dot(point);
-}
-
-
-Plane Plane::fromEquation(float a, float b, float c, float d) {
- Vector3 n(a, b, c);
- float magnitude = n.magnitude();
- d /= magnitude;
- n /= magnitude;
- return Plane(n, -d);
-}
-
-
-void Plane::flip() {
- _normal = -_normal;
- _distance = -_distance;
-}
-
-
-void Plane::getEquation(Vector3& n, float& d) const {
- double _d;
- getEquation(n, _d);
- d = (float)_d;
-}
-
-void Plane::getEquation(Vector3& n, double& d) const {
- n = _normal;
- d = -_distance;
-}
-
-
-void Plane::getEquation(float& a, float& b, float& c, float& d) const {
- double _a, _b, _c, _d;
- getEquation(_a, _b, _c, _d);
- a = (float)_a;
- b = (float)_b;
- c = (float)_c;
- d = (float)_d;
-}
-
-void Plane::getEquation(double& a, double& b, double& c, double& d) const {
- a = _normal.x;
- b = _normal.y;
- c = _normal.z;
- d = -_distance;
-}
-
-
-std::string Plane::toString() const {
- return format("Plane(%g, %g, %g, %g)", _normal.x, _normal.y, _normal.z, _distance);
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Quat.cpp b/externals/g3dlite/G3D.lib/source/Quat.cpp
deleted file mode 100644
index 225c5b51acc..00000000000
--- a/externals/g3dlite/G3D.lib/source/Quat.cpp
+++ /dev/null
@@ -1,583 +0,0 @@
-/**
- @file Quat.cpp
-
- Quaternion implementation based on Watt & Watt page 363
-
- @author Morgan McGuire, graphics3d.com
-
- @created 2002-01-23
- @edited 2006-01-31
- */
-
-#include "G3D/Quat.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-Quat Quat::fromAxisAngleRotation(
- const Vector3& axis,
- float angle) {
-
- Quat q;
-
- q.w = cos(angle / 2.0f);
- q.imag() = axis.direction() * sin(angle / 2.0f);
-
- return q;
-}
-
-
-Quat::Quat(
- const Matrix3& rot) {
-
- static const int plus1mod3[] = {1, 2, 0};
-
- // Find the index of the largest diagonal component
- // These ? operations hopefully compile to conditional
- // move instructions instead of branches.
- int i = (rot[1][1] > rot[0][0]) ? 1 : 0;
- i = (rot[2][2] > rot[i][i]) ? 2 : i;
-
- // Find the indices of the other elements
- int j = plus1mod3[i];
- int k = plus1mod3[j];
-
- // Index the elements of the vector part of the quaternion as a float*
- float* v = (float*)(this);
-
- // If we attempted to pre-normalize and trusted the matrix to be
- // perfectly orthonormal, the result would be:
- //
- // double c = sqrt((rot[i][i] - (rot[j][j] + rot[k][k])) + 1.0)
- // v[i] = -c * 0.5
- // v[j] = -(rot[i][j] + rot[j][i]) * 0.5 / c
- // v[k] = -(rot[i][k] + rot[k][i]) * 0.5 / c
- // w = (rot[j][k] - rot[k][j]) * 0.5 / c
- //
- // Since we're going to pay the sqrt anyway, we perform a post normalization, which also
- // fixes any poorly normalized input. Multiply all elements by 2*c in the above, giving:
-
- // nc2 = -c^2
- double nc2 = ((rot[j][j] + rot[k][k]) - rot[i][i]) - 1.0;
- v[i] = nc2;
- w = (rot[j][k] - rot[k][j]);
- v[j] = -(rot[i][j] + rot[j][i]);
- v[k] = -(rot[i][k] + rot[k][i]);
-
- // We now have the correct result with the wrong magnitude, so normalize it:
- float s = sqrt(x*x + y*y + z*z + w*w);
- if (s > 0.00001f) {
- s = 1.0f / s;
- x *= s;
- y *= s;
- z *= s;
- w *= s;
- } else {
- // The quaternion is nearly zero. Make it 0 0 0 1
- x = 0.0f;
- y = 0.0f;
- z = 0.0f;
- w = 1.0f;
- }
-}
-
-
-void Quat::toAxisAngleRotation(
- Vector3& axis,
- double& angle) const {
-
- // Decompose the quaternion into an angle and an axis.
-
- axis = Vector3(x, y, z);
- angle = 2 * acos(w);
-
- float len = sqrt(1.0f - w * w);
-
- if (fuzzyGt(abs(len), 0.0f)) {
- axis /= len;
- }
-
- // Reduce the range of the angle.
-
- if (angle < 0) {
- angle = -angle;
- axis = -axis;
- }
-
- while (angle > twoPi()) {
- angle -= twoPi();
- }
-
- if (abs(angle) > pi()) {
- angle -= twoPi();
- }
-
- // Make the angle positive.
-
- if (angle < 0.0f) {
- angle = -angle;
- axis = -axis;
- }
-}
-
-
-Matrix3 Quat::toRotationMatrix() const {
- Matrix3 out = Matrix3::zero();
-
- toRotationMatrix(out);
-
- return out;
-}
-
-
-void Quat::toRotationMatrix(
- Matrix3& rot) const {
-
- rot = Matrix3(*this);
-}
-
-
-Quat Quat::slerp(
- const Quat& _quat1,
- float alpha,
- float threshold) const {
-
- // From: Game Physics -- David Eberly pg 538-540
- // Modified to include lerp for small angles, which
- // is a common practice.
-
- // See also:
- // http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/index.html
-
- const Quat& quat0 = *this;
- Quat quat1 = _quat1;
-
- // angle between quaternion rotations
- float phi;
- float cosphi = quat0.dot(quat1);
-
-
- if (cosphi < 0) {
- // Change the sign and fix the dot product; we need to
- // loop the other way to get the shortest path
- quat1 = -quat1;
- cosphi = -cosphi;
- }
-
- // Using G3D::aCos will clamp the angle to 0 and pi
- phi = static_cast<float>(G3D::aCos(cosphi));
-
- if (phi >= threshold) {
- // For large angles, slerp
- float scale0, scale1;
-
- scale0 = sin((1.0f - alpha) * phi);
- scale1 = sin(alpha * phi);
-
- return ( (quat0 * scale0) + (quat1 * scale1) ) / sin(phi);
- } else {
- // For small angles, linear interpolate
- return quat0.nlerp(quat1, alpha);
- }
-}
-
-
-Quat Quat::nlerp(
- const Quat& quat1,
- float alpha) const {
-
- Quat result = (*this) * (1.0f - alpha) + quat1 * alpha;
- return result / result.magnitude();
-}
-
-
-Quat Quat::operator*(const Quat& other) const {
-
- // Following Watt & Watt, page 360
- const Vector3& v1 = imag();
- const Vector3& v2 = other.imag();
- float s1 = w;
- float s2 = other.w;
-
- return Quat(s1*v2 + s2*v1 + v1.cross(v2), s1*s2 - v1.dot(v2));
-}
-
-
-// From "Uniform Random Rotations", Ken Shoemake, Graphics Gems III.
-Quat Quat::unitRandom() {
- float x0 = uniformRandom();
- float r1 = sqrtf(1 - x0),
- r2 = sqrtf(x0);
- float t1 = (float)G3D::twoPi() * uniformRandom();
- float t2 = (float)G3D::twoPi() * uniformRandom();
- float c1 = cosf(t1),
- s1 = sinf(t1);
- float c2 = cosf(t2),
- s2 = sinf(t2);
- return Quat(s1 * r1, c1 * r1, s2 * r2, c2 * r2);
-}
-
-
-void Quat::deserialize(class BinaryInput& b) {
- x = b.readFloat32();
- y = b.readFloat32();
- z = b.readFloat32();
- w = b.readFloat32();
-}
-
-
-void Quat::serialize(class BinaryOutput& b) const {
- b.writeFloat32(x);
- b.writeFloat32(y);
- b.writeFloat32(z);
- b.writeFloat32(w);
-}
-
-
-// 2-char swizzles
-
-Vector2 Quat::xx() const { return Vector2 (x, x); }
-Vector2 Quat::yx() const { return Vector2 (y, x); }
-Vector2 Quat::zx() const { return Vector2 (z, x); }
-Vector2 Quat::wx() const { return Vector2 (w, x); }
-Vector2 Quat::xy() const { return Vector2 (x, y); }
-Vector2 Quat::yy() const { return Vector2 (y, y); }
-Vector2 Quat::zy() const { return Vector2 (z, y); }
-Vector2 Quat::wy() const { return Vector2 (w, y); }
-Vector2 Quat::xz() const { return Vector2 (x, z); }
-Vector2 Quat::yz() const { return Vector2 (y, z); }
-Vector2 Quat::zz() const { return Vector2 (z, z); }
-Vector2 Quat::wz() const { return Vector2 (w, z); }
-Vector2 Quat::xw() const { return Vector2 (x, w); }
-Vector2 Quat::yw() const { return Vector2 (y, w); }
-Vector2 Quat::zw() const { return Vector2 (z, w); }
-Vector2 Quat::ww() const { return Vector2 (w, w); }
-
-// 3-char swizzles
-
-Vector3 Quat::xxx() const { return Vector3 (x, x, x); }
-Vector3 Quat::yxx() const { return Vector3 (y, x, x); }
-Vector3 Quat::zxx() const { return Vector3 (z, x, x); }
-Vector3 Quat::wxx() const { return Vector3 (w, x, x); }
-Vector3 Quat::xyx() const { return Vector3 (x, y, x); }
-Vector3 Quat::yyx() const { return Vector3 (y, y, x); }
-Vector3 Quat::zyx() const { return Vector3 (z, y, x); }
-Vector3 Quat::wyx() const { return Vector3 (w, y, x); }
-Vector3 Quat::xzx() const { return Vector3 (x, z, x); }
-Vector3 Quat::yzx() const { return Vector3 (y, z, x); }
-Vector3 Quat::zzx() const { return Vector3 (z, z, x); }
-Vector3 Quat::wzx() const { return Vector3 (w, z, x); }
-Vector3 Quat::xwx() const { return Vector3 (x, w, x); }
-Vector3 Quat::ywx() const { return Vector3 (y, w, x); }
-Vector3 Quat::zwx() const { return Vector3 (z, w, x); }
-Vector3 Quat::wwx() const { return Vector3 (w, w, x); }
-Vector3 Quat::xxy() const { return Vector3 (x, x, y); }
-Vector3 Quat::yxy() const { return Vector3 (y, x, y); }
-Vector3 Quat::zxy() const { return Vector3 (z, x, y); }
-Vector3 Quat::wxy() const { return Vector3 (w, x, y); }
-Vector3 Quat::xyy() const { return Vector3 (x, y, y); }
-Vector3 Quat::yyy() const { return Vector3 (y, y, y); }
-Vector3 Quat::zyy() const { return Vector3 (z, y, y); }
-Vector3 Quat::wyy() const { return Vector3 (w, y, y); }
-Vector3 Quat::xzy() const { return Vector3 (x, z, y); }
-Vector3 Quat::yzy() const { return Vector3 (y, z, y); }
-Vector3 Quat::zzy() const { return Vector3 (z, z, y); }
-Vector3 Quat::wzy() const { return Vector3 (w, z, y); }
-Vector3 Quat::xwy() const { return Vector3 (x, w, y); }
-Vector3 Quat::ywy() const { return Vector3 (y, w, y); }
-Vector3 Quat::zwy() const { return Vector3 (z, w, y); }
-Vector3 Quat::wwy() const { return Vector3 (w, w, y); }
-Vector3 Quat::xxz() const { return Vector3 (x, x, z); }
-Vector3 Quat::yxz() const { return Vector3 (y, x, z); }
-Vector3 Quat::zxz() const { return Vector3 (z, x, z); }
-Vector3 Quat::wxz() const { return Vector3 (w, x, z); }
-Vector3 Quat::xyz() const { return Vector3 (x, y, z); }
-Vector3 Quat::yyz() const { return Vector3 (y, y, z); }
-Vector3 Quat::zyz() const { return Vector3 (z, y, z); }
-Vector3 Quat::wyz() const { return Vector3 (w, y, z); }
-Vector3 Quat::xzz() const { return Vector3 (x, z, z); }
-Vector3 Quat::yzz() const { return Vector3 (y, z, z); }
-Vector3 Quat::zzz() const { return Vector3 (z, z, z); }
-Vector3 Quat::wzz() const { return Vector3 (w, z, z); }
-Vector3 Quat::xwz() const { return Vector3 (x, w, z); }
-Vector3 Quat::ywz() const { return Vector3 (y, w, z); }
-Vector3 Quat::zwz() const { return Vector3 (z, w, z); }
-Vector3 Quat::wwz() const { return Vector3 (w, w, z); }
-Vector3 Quat::xxw() const { return Vector3 (x, x, w); }
-Vector3 Quat::yxw() const { return Vector3 (y, x, w); }
-Vector3 Quat::zxw() const { return Vector3 (z, x, w); }
-Vector3 Quat::wxw() const { return Vector3 (w, x, w); }
-Vector3 Quat::xyw() const { return Vector3 (x, y, w); }
-Vector3 Quat::yyw() const { return Vector3 (y, y, w); }
-Vector3 Quat::zyw() const { return Vector3 (z, y, w); }
-Vector3 Quat::wyw() const { return Vector3 (w, y, w); }
-Vector3 Quat::xzw() const { return Vector3 (x, z, w); }
-Vector3 Quat::yzw() const { return Vector3 (y, z, w); }
-Vector3 Quat::zzw() const { return Vector3 (z, z, w); }
-Vector3 Quat::wzw() const { return Vector3 (w, z, w); }
-Vector3 Quat::xww() const { return Vector3 (x, w, w); }
-Vector3 Quat::yww() const { return Vector3 (y, w, w); }
-Vector3 Quat::zww() const { return Vector3 (z, w, w); }
-Vector3 Quat::www() const { return Vector3 (w, w, w); }
-
-// 4-char swizzles
-
-Vector4 Quat::xxxx() const { return Vector4 (x, x, x, x); }
-Vector4 Quat::yxxx() const { return Vector4 (y, x, x, x); }
-Vector4 Quat::zxxx() const { return Vector4 (z, x, x, x); }
-Vector4 Quat::wxxx() const { return Vector4 (w, x, x, x); }
-Vector4 Quat::xyxx() const { return Vector4 (x, y, x, x); }
-Vector4 Quat::yyxx() const { return Vector4 (y, y, x, x); }
-Vector4 Quat::zyxx() const { return Vector4 (z, y, x, x); }
-Vector4 Quat::wyxx() const { return Vector4 (w, y, x, x); }
-Vector4 Quat::xzxx() const { return Vector4 (x, z, x, x); }
-Vector4 Quat::yzxx() const { return Vector4 (y, z, x, x); }
-Vector4 Quat::zzxx() const { return Vector4 (z, z, x, x); }
-Vector4 Quat::wzxx() const { return Vector4 (w, z, x, x); }
-Vector4 Quat::xwxx() const { return Vector4 (x, w, x, x); }
-Vector4 Quat::ywxx() const { return Vector4 (y, w, x, x); }
-Vector4 Quat::zwxx() const { return Vector4 (z, w, x, x); }
-Vector4 Quat::wwxx() const { return Vector4 (w, w, x, x); }
-Vector4 Quat::xxyx() const { return Vector4 (x, x, y, x); }
-Vector4 Quat::yxyx() const { return Vector4 (y, x, y, x); }
-Vector4 Quat::zxyx() const { return Vector4 (z, x, y, x); }
-Vector4 Quat::wxyx() const { return Vector4 (w, x, y, x); }
-Vector4 Quat::xyyx() const { return Vector4 (x, y, y, x); }
-Vector4 Quat::yyyx() const { return Vector4 (y, y, y, x); }
-Vector4 Quat::zyyx() const { return Vector4 (z, y, y, x); }
-Vector4 Quat::wyyx() const { return Vector4 (w, y, y, x); }
-Vector4 Quat::xzyx() const { return Vector4 (x, z, y, x); }
-Vector4 Quat::yzyx() const { return Vector4 (y, z, y, x); }
-Vector4 Quat::zzyx() const { return Vector4 (z, z, y, x); }
-Vector4 Quat::wzyx() const { return Vector4 (w, z, y, x); }
-Vector4 Quat::xwyx() const { return Vector4 (x, w, y, x); }
-Vector4 Quat::ywyx() const { return Vector4 (y, w, y, x); }
-Vector4 Quat::zwyx() const { return Vector4 (z, w, y, x); }
-Vector4 Quat::wwyx() const { return Vector4 (w, w, y, x); }
-Vector4 Quat::xxzx() const { return Vector4 (x, x, z, x); }
-Vector4 Quat::yxzx() const { return Vector4 (y, x, z, x); }
-Vector4 Quat::zxzx() const { return Vector4 (z, x, z, x); }
-Vector4 Quat::wxzx() const { return Vector4 (w, x, z, x); }
-Vector4 Quat::xyzx() const { return Vector4 (x, y, z, x); }
-Vector4 Quat::yyzx() const { return Vector4 (y, y, z, x); }
-Vector4 Quat::zyzx() const { return Vector4 (z, y, z, x); }
-Vector4 Quat::wyzx() const { return Vector4 (w, y, z, x); }
-Vector4 Quat::xzzx() const { return Vector4 (x, z, z, x); }
-Vector4 Quat::yzzx() const { return Vector4 (y, z, z, x); }
-Vector4 Quat::zzzx() const { return Vector4 (z, z, z, x); }
-Vector4 Quat::wzzx() const { return Vector4 (w, z, z, x); }
-Vector4 Quat::xwzx() const { return Vector4 (x, w, z, x); }
-Vector4 Quat::ywzx() const { return Vector4 (y, w, z, x); }
-Vector4 Quat::zwzx() const { return Vector4 (z, w, z, x); }
-Vector4 Quat::wwzx() const { return Vector4 (w, w, z, x); }
-Vector4 Quat::xxwx() const { return Vector4 (x, x, w, x); }
-Vector4 Quat::yxwx() const { return Vector4 (y, x, w, x); }
-Vector4 Quat::zxwx() const { return Vector4 (z, x, w, x); }
-Vector4 Quat::wxwx() const { return Vector4 (w, x, w, x); }
-Vector4 Quat::xywx() const { return Vector4 (x, y, w, x); }
-Vector4 Quat::yywx() const { return Vector4 (y, y, w, x); }
-Vector4 Quat::zywx() const { return Vector4 (z, y, w, x); }
-Vector4 Quat::wywx() const { return Vector4 (w, y, w, x); }
-Vector4 Quat::xzwx() const { return Vector4 (x, z, w, x); }
-Vector4 Quat::yzwx() const { return Vector4 (y, z, w, x); }
-Vector4 Quat::zzwx() const { return Vector4 (z, z, w, x); }
-Vector4 Quat::wzwx() const { return Vector4 (w, z, w, x); }
-Vector4 Quat::xwwx() const { return Vector4 (x, w, w, x); }
-Vector4 Quat::ywwx() const { return Vector4 (y, w, w, x); }
-Vector4 Quat::zwwx() const { return Vector4 (z, w, w, x); }
-Vector4 Quat::wwwx() const { return Vector4 (w, w, w, x); }
-Vector4 Quat::xxxy() const { return Vector4 (x, x, x, y); }
-Vector4 Quat::yxxy() const { return Vector4 (y, x, x, y); }
-Vector4 Quat::zxxy() const { return Vector4 (z, x, x, y); }
-Vector4 Quat::wxxy() const { return Vector4 (w, x, x, y); }
-Vector4 Quat::xyxy() const { return Vector4 (x, y, x, y); }
-Vector4 Quat::yyxy() const { return Vector4 (y, y, x, y); }
-Vector4 Quat::zyxy() const { return Vector4 (z, y, x, y); }
-Vector4 Quat::wyxy() const { return Vector4 (w, y, x, y); }
-Vector4 Quat::xzxy() const { return Vector4 (x, z, x, y); }
-Vector4 Quat::yzxy() const { return Vector4 (y, z, x, y); }
-Vector4 Quat::zzxy() const { return Vector4 (z, z, x, y); }
-Vector4 Quat::wzxy() const { return Vector4 (w, z, x, y); }
-Vector4 Quat::xwxy() const { return Vector4 (x, w, x, y); }
-Vector4 Quat::ywxy() const { return Vector4 (y, w, x, y); }
-Vector4 Quat::zwxy() const { return Vector4 (z, w, x, y); }
-Vector4 Quat::wwxy() const { return Vector4 (w, w, x, y); }
-Vector4 Quat::xxyy() const { return Vector4 (x, x, y, y); }
-Vector4 Quat::yxyy() const { return Vector4 (y, x, y, y); }
-Vector4 Quat::zxyy() const { return Vector4 (z, x, y, y); }
-Vector4 Quat::wxyy() const { return Vector4 (w, x, y, y); }
-Vector4 Quat::xyyy() const { return Vector4 (x, y, y, y); }
-Vector4 Quat::yyyy() const { return Vector4 (y, y, y, y); }
-Vector4 Quat::zyyy() const { return Vector4 (z, y, y, y); }
-Vector4 Quat::wyyy() const { return Vector4 (w, y, y, y); }
-Vector4 Quat::xzyy() const { return Vector4 (x, z, y, y); }
-Vector4 Quat::yzyy() const { return Vector4 (y, z, y, y); }
-Vector4 Quat::zzyy() const { return Vector4 (z, z, y, y); }
-Vector4 Quat::wzyy() const { return Vector4 (w, z, y, y); }
-Vector4 Quat::xwyy() const { return Vector4 (x, w, y, y); }
-Vector4 Quat::ywyy() const { return Vector4 (y, w, y, y); }
-Vector4 Quat::zwyy() const { return Vector4 (z, w, y, y); }
-Vector4 Quat::wwyy() const { return Vector4 (w, w, y, y); }
-Vector4 Quat::xxzy() const { return Vector4 (x, x, z, y); }
-Vector4 Quat::yxzy() const { return Vector4 (y, x, z, y); }
-Vector4 Quat::zxzy() const { return Vector4 (z, x, z, y); }
-Vector4 Quat::wxzy() const { return Vector4 (w, x, z, y); }
-Vector4 Quat::xyzy() const { return Vector4 (x, y, z, y); }
-Vector4 Quat::yyzy() const { return Vector4 (y, y, z, y); }
-Vector4 Quat::zyzy() const { return Vector4 (z, y, z, y); }
-Vector4 Quat::wyzy() const { return Vector4 (w, y, z, y); }
-Vector4 Quat::xzzy() const { return Vector4 (x, z, z, y); }
-Vector4 Quat::yzzy() const { return Vector4 (y, z, z, y); }
-Vector4 Quat::zzzy() const { return Vector4 (z, z, z, y); }
-Vector4 Quat::wzzy() const { return Vector4 (w, z, z, y); }
-Vector4 Quat::xwzy() const { return Vector4 (x, w, z, y); }
-Vector4 Quat::ywzy() const { return Vector4 (y, w, z, y); }
-Vector4 Quat::zwzy() const { return Vector4 (z, w, z, y); }
-Vector4 Quat::wwzy() const { return Vector4 (w, w, z, y); }
-Vector4 Quat::xxwy() const { return Vector4 (x, x, w, y); }
-Vector4 Quat::yxwy() const { return Vector4 (y, x, w, y); }
-Vector4 Quat::zxwy() const { return Vector4 (z, x, w, y); }
-Vector4 Quat::wxwy() const { return Vector4 (w, x, w, y); }
-Vector4 Quat::xywy() const { return Vector4 (x, y, w, y); }
-Vector4 Quat::yywy() const { return Vector4 (y, y, w, y); }
-Vector4 Quat::zywy() const { return Vector4 (z, y, w, y); }
-Vector4 Quat::wywy() const { return Vector4 (w, y, w, y); }
-Vector4 Quat::xzwy() const { return Vector4 (x, z, w, y); }
-Vector4 Quat::yzwy() const { return Vector4 (y, z, w, y); }
-Vector4 Quat::zzwy() const { return Vector4 (z, z, w, y); }
-Vector4 Quat::wzwy() const { return Vector4 (w, z, w, y); }
-Vector4 Quat::xwwy() const { return Vector4 (x, w, w, y); }
-Vector4 Quat::ywwy() const { return Vector4 (y, w, w, y); }
-Vector4 Quat::zwwy() const { return Vector4 (z, w, w, y); }
-Vector4 Quat::wwwy() const { return Vector4 (w, w, w, y); }
-Vector4 Quat::xxxz() const { return Vector4 (x, x, x, z); }
-Vector4 Quat::yxxz() const { return Vector4 (y, x, x, z); }
-Vector4 Quat::zxxz() const { return Vector4 (z, x, x, z); }
-Vector4 Quat::wxxz() const { return Vector4 (w, x, x, z); }
-Vector4 Quat::xyxz() const { return Vector4 (x, y, x, z); }
-Vector4 Quat::yyxz() const { return Vector4 (y, y, x, z); }
-Vector4 Quat::zyxz() const { return Vector4 (z, y, x, z); }
-Vector4 Quat::wyxz() const { return Vector4 (w, y, x, z); }
-Vector4 Quat::xzxz() const { return Vector4 (x, z, x, z); }
-Vector4 Quat::yzxz() const { return Vector4 (y, z, x, z); }
-Vector4 Quat::zzxz() const { return Vector4 (z, z, x, z); }
-Vector4 Quat::wzxz() const { return Vector4 (w, z, x, z); }
-Vector4 Quat::xwxz() const { return Vector4 (x, w, x, z); }
-Vector4 Quat::ywxz() const { return Vector4 (y, w, x, z); }
-Vector4 Quat::zwxz() const { return Vector4 (z, w, x, z); }
-Vector4 Quat::wwxz() const { return Vector4 (w, w, x, z); }
-Vector4 Quat::xxyz() const { return Vector4 (x, x, y, z); }
-Vector4 Quat::yxyz() const { return Vector4 (y, x, y, z); }
-Vector4 Quat::zxyz() const { return Vector4 (z, x, y, z); }
-Vector4 Quat::wxyz() const { return Vector4 (w, x, y, z); }
-Vector4 Quat::xyyz() const { return Vector4 (x, y, y, z); }
-Vector4 Quat::yyyz() const { return Vector4 (y, y, y, z); }
-Vector4 Quat::zyyz() const { return Vector4 (z, y, y, z); }
-Vector4 Quat::wyyz() const { return Vector4 (w, y, y, z); }
-Vector4 Quat::xzyz() const { return Vector4 (x, z, y, z); }
-Vector4 Quat::yzyz() const { return Vector4 (y, z, y, z); }
-Vector4 Quat::zzyz() const { return Vector4 (z, z, y, z); }
-Vector4 Quat::wzyz() const { return Vector4 (w, z, y, z); }
-Vector4 Quat::xwyz() const { return Vector4 (x, w, y, z); }
-Vector4 Quat::ywyz() const { return Vector4 (y, w, y, z); }
-Vector4 Quat::zwyz() const { return Vector4 (z, w, y, z); }
-Vector4 Quat::wwyz() const { return Vector4 (w, w, y, z); }
-Vector4 Quat::xxzz() const { return Vector4 (x, x, z, z); }
-Vector4 Quat::yxzz() const { return Vector4 (y, x, z, z); }
-Vector4 Quat::zxzz() const { return Vector4 (z, x, z, z); }
-Vector4 Quat::wxzz() const { return Vector4 (w, x, z, z); }
-Vector4 Quat::xyzz() const { return Vector4 (x, y, z, z); }
-Vector4 Quat::yyzz() const { return Vector4 (y, y, z, z); }
-Vector4 Quat::zyzz() const { return Vector4 (z, y, z, z); }
-Vector4 Quat::wyzz() const { return Vector4 (w, y, z, z); }
-Vector4 Quat::xzzz() const { return Vector4 (x, z, z, z); }
-Vector4 Quat::yzzz() const { return Vector4 (y, z, z, z); }
-Vector4 Quat::zzzz() const { return Vector4 (z, z, z, z); }
-Vector4 Quat::wzzz() const { return Vector4 (w, z, z, z); }
-Vector4 Quat::xwzz() const { return Vector4 (x, w, z, z); }
-Vector4 Quat::ywzz() const { return Vector4 (y, w, z, z); }
-Vector4 Quat::zwzz() const { return Vector4 (z, w, z, z); }
-Vector4 Quat::wwzz() const { return Vector4 (w, w, z, z); }
-Vector4 Quat::xxwz() const { return Vector4 (x, x, w, z); }
-Vector4 Quat::yxwz() const { return Vector4 (y, x, w, z); }
-Vector4 Quat::zxwz() const { return Vector4 (z, x, w, z); }
-Vector4 Quat::wxwz() const { return Vector4 (w, x, w, z); }
-Vector4 Quat::xywz() const { return Vector4 (x, y, w, z); }
-Vector4 Quat::yywz() const { return Vector4 (y, y, w, z); }
-Vector4 Quat::zywz() const { return Vector4 (z, y, w, z); }
-Vector4 Quat::wywz() const { return Vector4 (w, y, w, z); }
-Vector4 Quat::xzwz() const { return Vector4 (x, z, w, z); }
-Vector4 Quat::yzwz() const { return Vector4 (y, z, w, z); }
-Vector4 Quat::zzwz() const { return Vector4 (z, z, w, z); }
-Vector4 Quat::wzwz() const { return Vector4 (w, z, w, z); }
-Vector4 Quat::xwwz() const { return Vector4 (x, w, w, z); }
-Vector4 Quat::ywwz() const { return Vector4 (y, w, w, z); }
-Vector4 Quat::zwwz() const { return Vector4 (z, w, w, z); }
-Vector4 Quat::wwwz() const { return Vector4 (w, w, w, z); }
-Vector4 Quat::xxxw() const { return Vector4 (x, x, x, w); }
-Vector4 Quat::yxxw() const { return Vector4 (y, x, x, w); }
-Vector4 Quat::zxxw() const { return Vector4 (z, x, x, w); }
-Vector4 Quat::wxxw() const { return Vector4 (w, x, x, w); }
-Vector4 Quat::xyxw() const { return Vector4 (x, y, x, w); }
-Vector4 Quat::yyxw() const { return Vector4 (y, y, x, w); }
-Vector4 Quat::zyxw() const { return Vector4 (z, y, x, w); }
-Vector4 Quat::wyxw() const { return Vector4 (w, y, x, w); }
-Vector4 Quat::xzxw() const { return Vector4 (x, z, x, w); }
-Vector4 Quat::yzxw() const { return Vector4 (y, z, x, w); }
-Vector4 Quat::zzxw() const { return Vector4 (z, z, x, w); }
-Vector4 Quat::wzxw() const { return Vector4 (w, z, x, w); }
-Vector4 Quat::xwxw() const { return Vector4 (x, w, x, w); }
-Vector4 Quat::ywxw() const { return Vector4 (y, w, x, w); }
-Vector4 Quat::zwxw() const { return Vector4 (z, w, x, w); }
-Vector4 Quat::wwxw() const { return Vector4 (w, w, x, w); }
-Vector4 Quat::xxyw() const { return Vector4 (x, x, y, w); }
-Vector4 Quat::yxyw() const { return Vector4 (y, x, y, w); }
-Vector4 Quat::zxyw() const { return Vector4 (z, x, y, w); }
-Vector4 Quat::wxyw() const { return Vector4 (w, x, y, w); }
-Vector4 Quat::xyyw() const { return Vector4 (x, y, y, w); }
-Vector4 Quat::yyyw() const { return Vector4 (y, y, y, w); }
-Vector4 Quat::zyyw() const { return Vector4 (z, y, y, w); }
-Vector4 Quat::wyyw() const { return Vector4 (w, y, y, w); }
-Vector4 Quat::xzyw() const { return Vector4 (x, z, y, w); }
-Vector4 Quat::yzyw() const { return Vector4 (y, z, y, w); }
-Vector4 Quat::zzyw() const { return Vector4 (z, z, y, w); }
-Vector4 Quat::wzyw() const { return Vector4 (w, z, y, w); }
-Vector4 Quat::xwyw() const { return Vector4 (x, w, y, w); }
-Vector4 Quat::ywyw() const { return Vector4 (y, w, y, w); }
-Vector4 Quat::zwyw() const { return Vector4 (z, w, y, w); }
-Vector4 Quat::wwyw() const { return Vector4 (w, w, y, w); }
-Vector4 Quat::xxzw() const { return Vector4 (x, x, z, w); }
-Vector4 Quat::yxzw() const { return Vector4 (y, x, z, w); }
-Vector4 Quat::zxzw() const { return Vector4 (z, x, z, w); }
-Vector4 Quat::wxzw() const { return Vector4 (w, x, z, w); }
-Vector4 Quat::xyzw() const { return Vector4 (x, y, z, w); }
-Vector4 Quat::yyzw() const { return Vector4 (y, y, z, w); }
-Vector4 Quat::zyzw() const { return Vector4 (z, y, z, w); }
-Vector4 Quat::wyzw() const { return Vector4 (w, y, z, w); }
-Vector4 Quat::xzzw() const { return Vector4 (x, z, z, w); }
-Vector4 Quat::yzzw() const { return Vector4 (y, z, z, w); }
-Vector4 Quat::zzzw() const { return Vector4 (z, z, z, w); }
-Vector4 Quat::wzzw() const { return Vector4 (w, z, z, w); }
-Vector4 Quat::xwzw() const { return Vector4 (x, w, z, w); }
-Vector4 Quat::ywzw() const { return Vector4 (y, w, z, w); }
-Vector4 Quat::zwzw() const { return Vector4 (z, w, z, w); }
-Vector4 Quat::wwzw() const { return Vector4 (w, w, z, w); }
-Vector4 Quat::xxww() const { return Vector4 (x, x, w, w); }
-Vector4 Quat::yxww() const { return Vector4 (y, x, w, w); }
-Vector4 Quat::zxww() const { return Vector4 (z, x, w, w); }
-Vector4 Quat::wxww() const { return Vector4 (w, x, w, w); }
-Vector4 Quat::xyww() const { return Vector4 (x, y, w, w); }
-Vector4 Quat::yyww() const { return Vector4 (y, y, w, w); }
-Vector4 Quat::zyww() const { return Vector4 (z, y, w, w); }
-Vector4 Quat::wyww() const { return Vector4 (w, y, w, w); }
-Vector4 Quat::xzww() const { return Vector4 (x, z, w, w); }
-Vector4 Quat::yzww() const { return Vector4 (y, z, w, w); }
-Vector4 Quat::zzww() const { return Vector4 (z, z, w, w); }
-Vector4 Quat::wzww() const { return Vector4 (w, z, w, w); }
-Vector4 Quat::xwww() const { return Vector4 (x, w, w, w); }
-Vector4 Quat::ywww() const { return Vector4 (y, w, w, w); }
-Vector4 Quat::zwww() const { return Vector4 (z, w, w, w); }
-Vector4 Quat::wwww() const { return Vector4 (w, w, w, w); }
-}
-
diff --git a/externals/g3dlite/G3D.lib/source/Ray.cpp b/externals/g3dlite/G3D.lib/source/Ray.cpp
deleted file mode 100644
index bf6aadc08d1..00000000000
--- a/externals/g3dlite/G3D.lib/source/Ray.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- @file Ray.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2002-07-12
- @edited 2004-03-19
- */
-
-#include "G3D/platform.h"
-#include "G3D/Ray.h"
-#include "G3D/Plane.h"
-#include "G3D/Sphere.h"
-#include "G3D/CollisionDetection.h"
-
-namespace G3D {
-
-Ray::Ray(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-void Ray::serialize(class BinaryOutput& b) const {
- origin.serialize(b);
- direction.serialize(b);
-}
-
-
-void Ray::deserialize(class BinaryInput& b) {
- origin.deserialize(b);
- direction.deserialize(b);
-}
-
-
-Ray Ray::refract(
- const Vector3& newOrigin,
- const Vector3& normal,
- float iInside,
- float iOutside) const {
-
- Vector3 D = direction.refractionDirection(normal, iInside, iOutside);
- return Ray::fromOriginAndDirection(
- newOrigin + (direction + normal * (float)sign(direction.dot(normal))) * 0.001f, D);
-}
-
-
-Ray Ray::reflect(
- const Vector3& newOrigin,
- const Vector3& normal) const {
-
- Vector3 D = direction.reflectionDirection(normal);
- return Ray::fromOriginAndDirection(newOrigin + (D + normal) * 0.001f, D);
-}
-
-
-Vector3 Ray::intersection(const Plane& plane) const {
- float d;
- Vector3 normal = plane.normal();
- plane.getEquation(normal, d);
- float rate = direction.dot(normal);
-
- if (rate >= 0.0f) {
- return Vector3::inf();
- } else {
- float t = -(d + origin.dot(normal)) / rate;
-
- return origin + direction * t;
- }
-}
-
-
-float Ray::intersectionTime(const class Sphere& sphere) const {
- Vector3 dummy;
- return CollisionDetection::collisionTimeForMovingPointFixedSphere(
- origin, direction, sphere, dummy);
-}
-
-
-float Ray::intersectionTime(const class Plane& plane) const {
- Vector3 dummy;
- return CollisionDetection::collisionTimeForMovingPointFixedPlane(
- origin, direction, plane, dummy);
-}
-
-
-float Ray::intersectionTime(const class Box& box) const {
- Vector3 dummy;
- float time = CollisionDetection::collisionTimeForMovingPointFixedBox(
- origin, direction, box, dummy);
-
- if ((time == inf()) && (box.contains(origin))) {
- return 0.0f;
- } else {
- return time;
- }
-}
-
-
-float Ray::intersectionTime(const class AABox& box) const {
- Vector3 dummy;
- bool inside;
- float time = CollisionDetection::collisionTimeForMovingPointFixedAABox(
- origin, direction, box, dummy, inside);
-
- if ((time == inf()) && inside) {
- return 0.0f;
- } else {
- return time;
- }
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/RegistryUtil.cpp b/externals/g3dlite/G3D.lib/source/RegistryUtil.cpp
deleted file mode 100644
index 28ff6955d9b..00000000000
--- a/externals/g3dlite/G3D.lib/source/RegistryUtil.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/**
- @file RegistryUtil.cpp
-
- @created 2006-04-06
- @edited 2006-04-24
-
- Copyright 2000-2006, Morgan McGuire.
- All rights reserved.
-*/
-
-#include "G3D/platform.h"
-
-// This file is only used on Windows
-#ifdef G3D_WIN32
-
-#include "G3D/RegistryUtil.h"
-#include "G3D/System.h"
-
-namespace G3D {
-
-// static helpers
-static HKEY getRootKeyFromString(const char* str, size_t length);
-
-
-bool RegistryUtil::keyExists(const std::string& key) {
- size_t pos = key.find('\\', 0);
- if (pos == std::string::npos) {
- return false;
- }
-
- HKEY hkey = getRootKeyFromString(key.c_str(), pos);
-
- if (hkey == NULL) {
- return false;
- }
-
- HKEY openKey;
- int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
-
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
-
- if (result == ERROR_SUCCESS) {
- RegCloseKey(openKey);
- return true;
- } else {
- return false;
- }
-}
-
-bool RegistryUtil::valueExists(const std::string& key, const std::string& value) {
- size_t pos = key.find('\\', 0);
- if (pos == std::string::npos) {
- return false;
- }
-
- HKEY hkey = getRootKeyFromString(key.c_str(), pos);
-
- if ( hkey == NULL ) {
- return false;
- }
-
- HKEY openKey;
- int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
-
- if (result == ERROR_SUCCESS) {
- uint32 dataSize = 0;
- result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast<LPDWORD>(&dataSize));
-
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
- RegCloseKey(openKey);
- }
- return (result == ERROR_SUCCESS);
-}
-
-
-bool RegistryUtil::readInt32(const std::string& key, const std::string& value, int32& data) {
- size_t pos = key.find('\\', 0);
- if (pos == std::string::npos) {
- return false;
- }
-
- HKEY hkey = getRootKeyFromString(key.c_str(), pos);
-
- if ( hkey == NULL ) {
- return false;
- }
-
- HKEY openKey;
- int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
-
- if (result == ERROR_SUCCESS) {
- uint32 dataSize = sizeof(int32);
- result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&data), reinterpret_cast<LPDWORD>(&dataSize));
-
- debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value.");
-
- RegCloseKey(openKey);
- }
- return (result == ERROR_SUCCESS);
-}
-
-bool RegistryUtil::readBytes(const std::string& key, const std::string& value, uint8* data, uint32& dataSize) {
- size_t pos = key.find('\\', 0);
- if (pos == std::string::npos) {
- return false;
- }
-
- HKEY hkey = getRootKeyFromString(key.c_str(), pos);
-
- if (hkey == NULL) {
- return false;
- }
-
- HKEY openKey;
- int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
-
- if (result == ERROR_SUCCESS) {
- if (data == NULL) {
- result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast<LPDWORD>(&dataSize));
- } else {
- result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&data), reinterpret_cast<LPDWORD>(&dataSize));
- }
-
- debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value.");
-
- RegCloseKey(openKey);
- }
- return (result == ERROR_SUCCESS);
-}
-
-bool RegistryUtil::readString(const std::string& key, const std::string& value, std::string& data) {
- size_t pos = key.find('\\', 0);
- if (pos == std::string::npos) {
- return false;
- }
-
- HKEY hkey = getRootKeyFromString(key.c_str(), pos);
-
- if (hkey == NULL) {
- return false;
- }
-
- HKEY openKey;
- int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_READ, &openKey);
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
-
- if (result == ERROR_SUCCESS) {
- uint32 dataSize = 0;
-
- result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, NULL, reinterpret_cast<LPDWORD>(&dataSize));
- debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value.");
-
- // increment datasize to allow for non null-terminated strings in registry
- dataSize += 1;
-
- if (result == ERROR_SUCCESS) {
- char* tmpStr = static_cast<char*>(System::malloc(dataSize));
- System::memset(tmpStr, 0, dataSize);
-
- result = RegQueryValueExA(openKey, value.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(tmpStr), reinterpret_cast<LPDWORD>(&dataSize));
- debugAssertM(result == ERROR_SUCCESS, "Could not read registry key value.");
-
- if (result == ERROR_SUCCESS) {
- data = tmpStr;
- }
-
- RegCloseKey(openKey);
- System::free(tmpStr);
- }
- }
- return (result == ERROR_SUCCESS);
-}
-
-bool RegistryUtil::writeInt32(const std::string& key, const std::string& value, int32 data) {
- size_t pos = key.find('\\', 0);
- if (pos == std::string::npos) {
- return false;
- }
-
- HKEY hkey = getRootKeyFromString(key.c_str(), pos);
-
- if (hkey == NULL) {
- return false;
- }
-
- HKEY openKey;
- int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey);
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
-
- if (result == ERROR_SUCCESS) {
- result = RegSetValueExA(openKey, value.c_str(), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&data), sizeof(int32));
-
- debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value.");
-
- RegCloseKey(openKey);
- }
- return (result == ERROR_SUCCESS);
-}
-
-bool RegistryUtil::writeBytes(const std::string& key, const std::string& value, const uint8* data, uint32 dataSize) {
- debugAssert(data);
-
- size_t pos = key.find('\\', 0);
- if (pos == std::string::npos) {
- return false;
- }
-
- HKEY hkey = getRootKeyFromString(key.c_str(), pos);
-
- if (hkey == NULL) {
- return false;
- }
-
- HKEY openKey;
- int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey);
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
-
- if (result == ERROR_SUCCESS) {
- if (data) {
- result = RegSetValueExA(openKey, value.c_str(), 0, REG_BINARY, reinterpret_cast<const BYTE*>(data), dataSize);
- }
-
- debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value.");
-
- RegCloseKey(openKey);
- }
- return (result == ERROR_SUCCESS);
-}
-
-bool RegistryUtil::writeString(const std::string& key, const std::string& value, const std::string& data) {
- size_t pos = key.find('\\', 0);
- if (pos == std::string::npos) {
- return false;
- }
-
- HKEY hkey = getRootKeyFromString(key.c_str(), pos);
-
- if (hkey == NULL) {
- return false;
- }
-
- HKEY openKey;
- int32 result = RegOpenKeyExA(hkey, (key.c_str() + pos + 1), 0, KEY_WRITE, &openKey);
- debugAssert(result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND);
-
- if (result == ERROR_SUCCESS) {
- result = RegSetValueExA(openKey, value.c_str(), 0, REG_SZ, reinterpret_cast<const BYTE*>(data.c_str()), (data.size() + 1));
- debugAssertM(result == ERROR_SUCCESS, "Could not write registry key value.");
-
- RegCloseKey(openKey);
- }
- return (result == ERROR_SUCCESS);
-}
-
-
-// static helpers
-static HKEY getRootKeyFromString(const char* str, uint32 length) {
- debugAssert(str);
-
- if (str) {
- if ( strncmp(str, "HKEY_CLASSES_ROOT", length) == 0 ) {
- return HKEY_CLASSES_ROOT;
- } else if ( strncmp(str, "HKEY_CURRENT_CONFIG", length) == 0 ) {
- return HKEY_CURRENT_CONFIG;
- } else if ( strncmp(str, "HKEY_CURRENT_USER", length) == 0 ) {
- return HKEY_CURRENT_USER;
- } else if ( strncmp(str, "HKEY_LOCAL_MACHINE", length) == 0 ) {
- return HKEY_LOCAL_MACHINE;
- } else if ( strncmp(str, "HKEY_PERFORMANCE_DATA", length) == 0 ) {
- return HKEY_PERFORMANCE_DATA;
- } else if ( strncmp(str, "HKEY_PERFORMANCE_NLSTEXT", length) == 0 ) {
- return HKEY_PERFORMANCE_NLSTEXT;
- } else if ( strncmp(str, "HKEY_PERFORMANCE_TEXT", length) == 0 ) {
- return HKEY_PERFORMANCE_TEXT;
- } else if ( strncmp(str, "HKEY_CLASSES_ROOT", length) == 0 ) {
- return HKEY_CLASSES_ROOT;
- } else {
- return NULL;
- }
- } else {
- return NULL;
- }
-}
-
-} // namespace G3D
-
-#endif // G3D_WIN32
diff --git a/externals/g3dlite/G3D.lib/source/Sphere.cpp b/externals/g3dlite/G3D.lib/source/Sphere.cpp
deleted file mode 100644
index 935598d52dd..00000000000
--- a/externals/g3dlite/G3D.lib/source/Sphere.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- @file Sphere.cpp
-
- Sphere class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2001-04-17
- @edited 2006-02-05
- */
-
-#include "G3D/platform.h"
-#include "G3D/Sphere.h"
-#include "G3D/stringutils.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/AABox.h"
-#include "G3D/Plane.h"
-
-namespace G3D {
-
-int32 Sphere::dummy;
-
-Sphere::Sphere(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-void Sphere::serialize(class BinaryOutput& b) const {
- center.serialize(b);
- b.writeFloat64(radius);
-}
-
-
-void Sphere::deserialize(class BinaryInput& b) {
- center.deserialize(b);
- radius = (float)b.readFloat64();
-}
-
-
-std::string Sphere::toString() const {
- return format("Sphere(<%g, %g, %g>, %g)",
- center.x, center.y, center.z, radius);
-}
-
-
-bool Sphere::contains(const Vector3& point) const {
- double distance = (center - point).squaredMagnitude();
- return distance <= (radius * radius);
-}
-
-
-bool Sphere::intersects(const Sphere& other) const {
- return (other.center - center).length() <= (radius + other.radius);
-}
-
-bool Sphere::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask,
- uint32& outMask) const {
-
- return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask, outMask);
-}
-
-
-bool Sphere::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask) const {
-
- return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask);
-}
-
-
-bool Sphere::culledBy(
- const class Plane* plane,
- int numPlanes,
- int& cullingPlane,
- const uint32 _inMask,
- uint32& childMask) const {
-
- if (radius == inf()) {
- // No plane can cull the infinite box
- return false;
- }
-
- uint32 inMask = _inMask;
- assert(numPlanes < 31);
-
- childMask = 0;
-
- // See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < numPlanes; p++) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
-
- bool culledLow = ! plane[p].halfSpaceContainsFinite(center + plane[p].normal() * radius);
- bool culledHigh = ! plane[p].halfSpaceContainsFinite(center - plane[p].normal() * radius);
-
- if (culledLow) {
- // Plane p culled the sphere
- cullingPlane = p;
-
- // The caller should not recurse into the children,
- // since the parent is culled. If they do recurse,
- // make them only test against this one plane, which
- // will immediately cull the volume.
- childMask = 1 << p;
- return true;
-
- } else if (culledHigh) {
- // The bounding volume straddled the plane; we have
- // to keep testing against this plane
- childMask |= (1 << p);
- }
- }
-
- // Move on to the next bit.
- inMask = inMask >> 1;
- }
-
- // None of the planes could cull this box
- cullingPlane = -1;
- return false;
-}
-
-
-bool Sphere::culledBy(
- const class Plane* plane,
- int numPlanes,
- int& cullingPlane,
- const uint32 _inMask) const {
-
- uint32 inMask = _inMask;
- assert(numPlanes < 31);
-
- // See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < numPlanes; p++) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
- bool culled = ! plane[p].halfSpaceContains(center + plane[p].normal() * radius);
- if (culled) {
- // Plane p culled the sphere
- cullingPlane = p;
- return true;
- }
- }
-
- // Move on to the next bit.
- inMask = inMask >> 1;
- }
-
- // None of the planes could cull this box
- cullingPlane = -1;
- return false;
-}
-
-
-Vector3 Sphere::randomSurfacePoint() const {
- return Vector3::random() * radius + center;
-}
-
-
-Vector3 Sphere::randomInteriorPoint() const {
- Vector3 result;
- do {
- result = Vector3(uniformRandom(-1, 1),
- uniformRandom(-1, 1),
- uniformRandom(-1, 1));
- } while (result.squaredMagnitude() >= 1.0f);
-
- return result * radius + center;
-}
-
-
-float Sphere::volume() const {
- return (float)pi() * (4.0f / 3.0f) * powf((float)radius, 3.0f);
-}
-
-
-float Sphere::area() const {
- return (float)pi() * 4.0f * powf((float)radius, 2.0f);
-}
-
-
-void Sphere::getBounds(AABox& out) const {
- Vector3 extent(radius, radius, radius);
- out = AABox(center - extent, center + extent);
-}
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/SplineBase.cpp b/externals/g3dlite/G3D.lib/source/SplineBase.cpp
deleted file mode 100644
index 41221624b06..00000000000
--- a/externals/g3dlite/G3D.lib/source/SplineBase.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-#include "G3D/platform.h"
-#include "G3D/Spline.h"
-
-namespace G3D {
-
-float SplineBase::getFinalInterval() const {
- if (! cyclic) {
- return 0;
- } else if (finalInterval <= 0) {
- int N = time.size();
- if (N >= 2) {
- return (time[1] - time[0] + time[N - 1] - time[N - 2]) * 0.5f;
- } else {
- return 1.0f;
- }
- } else {
- return finalInterval;
- }
-}
-
-
-Matrix4 SplineBase::computeBasis() {
- // The standard Catmull-Rom spline basis (e.g., Watt & Watt p108)
- // is for [u^3 u^2 u^1 u^0] * B * [p[0] p[1] p[2] p[3]]^T.
- // We need a basis formed for:
- //
- // U * C * [2*p'[1] p[1] p[2] 2*p'[2]]^T
- //
- // U * C * [p2-p0 p1 p2 p3-p1]^T
- //
- // To make this transformation, compute the differences of columns in C:
- // For [p0 p1 p2 p3]
- Matrix4 basis =
- Matrix4( -1, 3, -3, 1,
- 2, -5, 4, -1,
- -1, 0, 1, 0,
- 0, 2, 0, 0) * 0.5f;
-
- // For [-p0 p1 p2 p3]^T
- basis.setColumn(0, -basis.column(0));
-
- // For [-p0 p1 p2 p3-p1]^T
- basis.setColumn(1, basis.column(1) + basis.column(3));
-
- // For [p2-p0 p1 p2 p3-p1]^T
- basis.setColumn(2, basis.column(2) - basis.column(0));
-
- return basis;
-}
-
-
-float SplineBase::duration() const {
- if (time.size() == 0) {
- return 0;
- } else {
- return time.last() - time[0] + getFinalInterval();
- }
-}
-
-
-void SplineBase::computeIndexInBounds(float s, int& i, float& u) const {
- int N = time.size();
- float t0 = time[0];
- float tn = time[N - 1];
-
- i = iFloor((N - 1) * (s - t0) / (tn - t0));
-
- // Inclusive bounds for binary search
- int hi = N - 1;
- int lo = 0;
-
- while ((time[i] > s) || (time[i + 1] <= s)) {
-
- if (time[i] > s) {
- // too big
- hi = i - 1;
- } else if (time[i + 1] <= s) {
- // too small
- lo = i + 1;
- }
-
- i = (hi + lo) / 2;
- }
-
- // Having exited the above loop, i must be correct, so compute u.
- u = (s - time[i]) / (time[i + 1] - time[i]);
-}
-
-
-void SplineBase::computeIndex(float s, int& i, float& u) const {
- int N = time.size();
- debugAssertM(N > 0, "No control points");
- float t0 = time[0];
- float tn = time[N - 1];
-
- if (N < 2) {
- // No control points to work with
- i = 0;
- u = 0.0;
- } else if (cyclic) {
- float fi = getFinalInterval();
-
- // Cyclic spline
- if ((s < t0) || (s >= tn + fi)) {
- // Cyclic, off the bottom or top
-
- // Compute offset and reduce to the in-bounds case
-
- float d = duration();
- // Number of times we wrapped around the cyclic array
- int wraps = iFloor((s - t0) / d);
-
- debugAssert(s - d * wraps >= t0);
- debugAssert(s - d * wraps < tn + getFinalInterval());
-
- computeIndex(s - d * wraps, i, u);
- i += wraps * N;
-
- } else if (s >= tn) {
- debugAssert(s < tn + fi);
- // Cyclic, off the top but before the end of the last interval
- i = N - 1;
- u = (s - tn) / fi;
-
- } else {
- // Cyclic, in bounds
- computeIndexInBounds(s, i, u);
- }
-
- } else {
- // Non-cyclic
-
- if (s < t0) {
- // Non-cyclic, off the bottom. Assume points are spaced
- // following the first time interval.
-
- float dt = time[1] - t0;
- float x = (s - t0) / dt;
- i = iFloor(x);
- u = x - i;
-
- } else if (s >= tn) {
- // Non-cyclic, off the top. Assume points are spaced following
- // the last time interval.
-
- float dt = tn - time[N - 2];
- float x = N - 1 + (s - tn) / dt;
- i = iFloor(x);
- u = x - i;
-
- } else {
- // In bounds, non-cyclic. Assume a regular
- // distribution (which gives O(1) for uniform spacing)
- // and then binary search to handle the general case
- // efficiently.
- computeIndexInBounds(s, i, u);
-
- } // if in bounds
- } // if cyclic
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Stopwatch.cpp b/externals/g3dlite/G3D.lib/source/Stopwatch.cpp
deleted file mode 100644
index e55f689a9e2..00000000000
--- a/externals/g3dlite/G3D.lib/source/Stopwatch.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- @file Stopwatch.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2005-10-05
- @edited 2005-10-05
-
- Copyright 2000-2003, Morgan McGuire.
- All rights reserved.
- */
-
-#include "G3D/Stopwatch.h"
-#include "G3D/System.h"
-
-namespace G3D {
-
-Stopwatch::Stopwatch() : inBetween(false), lastTockTime(-1),
- lastDuration(0), lastCycleCount(0), m_fps(0), emwaFPS(0),
- m_smoothFPS(0), emwaDuration(0) {
- computeOverhead();
-}
-
-
-void Stopwatch::computeOverhead() {
- cycleOverhead = 0;
- tick();
- tock();
- cycleOverhead = elapsedCycles();
-}
-
-
-void Stopwatch::tick() {
- // This is 'alwaysAssert' instead of 'debugAssert'
- // since people rarely profile in debug mode.
- alwaysAssertM(! inBetween, "Stopwatch::tick() called twice in a row.");
- inBetween = true;
-
- // We read RDTSC twice here, but it is more abstract to implement this
- // way and at least we're reading the cycle count last.
- timeStart = System::time();
- System::beginCycleCount(cycleStart);
-}
-
-
-void Stopwatch::tock() {
- System::endCycleCount(cycleStart);
- RealTime now = System::time();
- lastDuration = now - timeStart;
- if (abs(emwaDuration - lastDuration) > max(emwaDuration, lastDuration) * 0.50) {
- // Off by more than 50%
- emwaDuration = lastDuration;
- } else {
- emwaDuration = lastDuration * 0.05 + emwaDuration * 0.95;
- }
-
- lastCycleCount = cycleStart - cycleOverhead;
- if (lastCycleCount < 0) {
- lastCycleCount = 0;
- }
-
- if (lastTockTime != -1.0) {
- m_fps = 1.0 / (now - lastTockTime);
-
- // Time smooth the average
- emwaFPS = m_fps * 0.01 + emwaFPS * 0.99;
-
- if (abs(emwaFPS - m_fps) > max(emwaFPS, m_fps) * 0.08) {
- // The difference between emwa and m_fps is way off
- // update emwa directly.
- emwaFPS = m_fps;
- }
-
- // Update m_smoothFPS only when the value varies significantly
- // We round so as to not mislead the user as to the accuracy of
- // the number.
- if (m_smoothFPS == 0) {
- m_smoothFPS = m_fps;
- } else if (emwaFPS <= 10) {
- if (::fabs(m_smoothFPS - emwaFPS) > .75) {
- m_smoothFPS = floor(emwaFPS * 10.0 + 0.5) / 10.0;
- }
- } else {
- if (::fabs(m_smoothFPS - emwaFPS) > 1.25) {
- m_smoothFPS = floor(emwaFPS + 0.5);
- }
- }
- }
- lastTockTime = now;
-
- alwaysAssertM(inBetween, "Stopwatch::tock() called without matching tick.");
- inBetween = false;
-}
-
-}
-
diff --git a/externals/g3dlite/G3D.lib/source/System.cpp b/externals/g3dlite/G3D.lib/source/System.cpp
deleted file mode 100644
index 748e13257f1..00000000000
--- a/externals/g3dlite/G3D.lib/source/System.cpp
+++ /dev/null
@@ -1,1864 +0,0 @@
-/**
- @file System.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- Note: every routine must call init() first.
-
- There are two kinds of detection used in this file. At compile
- time, the _MSC_VER #define is used to determine whether x86 assembly
- can be used at all. At runtime, processor detection is used to
- determine if we can safely call the routines that use that assembly.
-
- @cite Rob Wyatt http://www.gamasutra.com/features/wyatts_world/19990709/processor_detection_01.htm
- @cite Benjamin Jurke http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-ProcessorDetectionClass&forum=cotd&id=-1
- @cite Michael Herf http://www.stereopsis.com/memcpy.html
-
- @created 2003-01-25
- @edited 2008-09-02
- */
-
-#include "G3D/platform.h"
-#include "G3D/System.h"
-#include "G3D/debug.h"
-#include "G3D/fileutils.h"
-#include "G3D/TextOutput.h"
-#include "G3D/G3DGameUnits.h"
-#include "G3D/Crypto.h"
-#include "G3D/prompt.h"
-#include "G3D/Log.h"
-#include <time.h>
-
-#include <cstring>
-#include <cstdio>
-
-// Uncomment the following line to turn off G3D::System memory
-// allocation and use the operating system's malloc.
-//#define NO_BUFFERPOOL
-
-#if defined(__i386__) || defined(__x86_64__) || defined(G3D_WIN32)
-# define G3D_NOT_OSX_PPC
-#endif
-
-#ifdef G3D_WIN32
-
-# include <conio.h>
-# include <sys/timeb.h>
-# include "G3D/RegistryUtil.h"
-
-#elif defined(G3D_LINUX)
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/select.h>
- #include <termios.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <sys/time.h>
- #include <pthread.h>
-
-#elif defined(G3D_OSX)
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/sysctl.h>
- #include <sys/select.h>
- #include <sys/time.h>
- #include <termios.h>
- #include <unistd.h>
- #include <pthread.h>
- #include <mach-o/arch.h>
-
- #include <sstream>
- #include <CoreServices/CoreServices.h>
-#endif
-
-#if defined(SSE)
- #include <xmmintrin.h>
-#endif
-
-namespace G3D {
-
-struct CpuInfo
-{
-public:
- int m_cpuSpeed;
- bool m_hasCPUID;
- bool m_hasRDTSC;
- bool m_hasMMX;
- bool m_hasSSE;
- bool m_hasSSE2;
- bool m_hasSSE3;
- bool m_has3DNOW;
- char m_cpuVendorStr[1024];
-};
-
-// helper macro to call cpuid functions and return all values
-#ifdef _MSC_VER
-
- // VC on Intel
-# define CALL_CPUID(func, areg, breg, creg, dreg) \
- __asm mov eax, func \
- __asm cpuid \
- __asm mov areg, eax \
- __asm mov breg, ebx \
- __asm mov creg, ecx \
- __asm mov dreg, edx
-
-#elif defined(__GNUC__) && defined(G3D_OSX_INTEL)
- // GCC on OS X intel
-# define CALL_CPUID(func, areg, breg, creg, dreg) \
- areg = 0; \
- breg = 0; \
- creg = 0; \
- dreg = 0;
-#else
- // Any other compiler/platform, likely GCC
-# define CALL_CPUID(func, areg, breg, creg, dreg) \
- __asm__ ( \
- "cpuid \n": \
- "=a" (areg), \
- "=b" (breg), \
- "=c" (creg), \
- "=d" (dreg): \
- "a" (func) \
- );
-#endif
-
-// this holds the data directory set by the application (currently GApp) for use by findDataFile
-static char g_appDataDir[FILENAME_MAX] = "";
-
-static CpuInfo g_cpuInfo = {
- 0, false, false, false, false, false, false, false, {'U', 'n', 'k', 'n', 'o', 'w', 'n', '\0'}};
-
-static G3DEndian _machineEndian = G3D_LITTLE_ENDIAN;
-static char _cpuArchCstr[1024];
-static char _operatingSystemCstr[1024];
-
-#ifdef G3D_WIN32
-/** Used by getTick() for timing */
-static LARGE_INTEGER _start;
-static LARGE_INTEGER _counterFrequency;
-#else
-static struct timeval _start;
-#endif
-
-static char versionCstr[1024];
-System::OutOfMemoryCallback System::outOfMemoryCallback = NULL;
-
-#ifdef G3D_OSX
-long System::m_OSXCPUSpeed;
-double System::m_secondsPerNS;
-#endif
-
-/** The Real-World time of System::getTick() time 0. Set by initTime */
-static RealTime realWorldGetTickTime0;
-
-
-static unsigned int maxSupportedCPUIDLevel = 0;
-static unsigned int maxSupportedExtendedLevel = 0;
-
-/** Checks if the CPUID command is available on the processor (called from init) */
-static void checkForCPUID();
-
-/** ReadRead the standard processor extensions. Called from init(). */
-static void getStandardProcessorExtensions();
-
-/** Called from init */
-static void initTime();
-
-
-std::string System::findDataFile
-(const std::string& full,
- bool errorIfNotFound) {
-
- if (fileExists(full)) {
- return full;
- }
-
- std::string initialAppDataDir(g_appDataDir);
-
- std::string name = filenameBaseExt(full);
- std::string originalPath = filenamePath(full);
-
- // Search several paths
- Array<std::string> pathBase;
-
- int backlen = 4;
-
- // add what should be the current working directory
- pathBase.append("");
-
- // add application specified data directory to be searched first
- pathBase.append(initialAppDataDir);
-
- // try walking back along the directory tree
- std::string prev = "";
- for (int i = 0; i < backlen; ++i) {
- pathBase.append(originalPath + prev);
- prev = prev + "../";
- }
-
- prev = "../";
- for (int i = 0; i < backlen; ++i) {
- pathBase.append(prev);
- prev = prev + "../";
- }
-
- // Hard-code in likely install directories
- int ver = G3D_VER;
- std::string lname = format("G3D-%d.%02d", ver / 10000, (ver / 100) % 100);
-
- if (G3D_VER % 100 != 0) {
- lname = lname + format("-b%02d/", ver % 100);
- } else {
- lname = lname + "/";
- }
-
- // Look in some other likely places
-# ifdef G3D_WIN32
- std::string lpath = "libraries/G3D/";
- pathBase.append(std::string("c:/") + lpath);
- pathBase.append(std::string("d:/") + lpath);
- pathBase.append(std::string("e:/") + lpath);
- pathBase.append(std::string("f:/") + lpath);
- pathBase.append(std::string("g:/") + lpath);
- pathBase.append(std::string("x:/") + lpath);
-# endif
-# if defined(G3D_LINUX)
- pathBase.append("/usr/local/");
- pathBase.append("/course/cs224/");
- pathBase.append("/map/gfx0/common/games/");
-# endif
-# if defined(G3D_FREEBSD)
- pathBase.append("/usr/local/");
- pathBase.append("/usr/local/371/");
- pathBase.append("/usr/cs-local/371/");
-# endif
-# if defined(G3D_OSX)
- pathBase.append("/usr/local/" + lname);
- pathBase.append("/Volumes/McGuire/Projects/");
-# endif
-
- // Add the library name to all variations
- int N = pathBase.size();
- for (int i = 0; i < N; ++i) {
- pathBase.append(pathBase[i] + lname);
- pathBase.append(pathBase[i] + "G3D/");
- }
-
- Array<std::string> subDir;
- subDir.append("", "font/", "sky/", "gui/");
- subDir.append("image/", "quake2/", "quake2/players/");
- subDir.append("quake3/", "SuperShader/", "ifs/", "3ds/");
- subDir.append("quake2/speedway/");
-
- Array<std::string> path;
- for (int p = 0; p < pathBase.size(); ++p) {
- for (int s = 0; s < subDir.size(); ++s) {
- path.append(pathBase[p] + subDir[s]);
- path.append(pathBase[p] + "data/" + subDir[s]);
- path.append(pathBase[p] + "data-files/" + subDir[s]);
- }
- }
-
- for (int i = 0; i < path.length(); ++i) {
- std::string filename = path[i] + name;
- if (fileExists(filename)) {
- logPrintf("\nWARNING: Could not find '%s' so '%s' "
- "was substituted.\n", full.c_str(),
- filename.c_str());
- return filename;
- }
- }
-
- if (errorIfNotFound) {
- // Generate an error message
- std::string locations;
- for (int i = 0; i < path.size(); ++i) {
- locations += path[i] + name + "\n";
- }
- alwaysAssertM(false, "Could not find '" + full + "' in:\n" + locations);
- }
- // Not found
- return "";
-}
-
-
-void System::setAppDataDir(const std::string& path) {
- // just copy the path, it needs to be valid
- strncpy(g_appDataDir, path.c_str(), sizeof(g_appDataDir));
-}
-
-
-std::string demoFindData(bool errorIfNotFound) {
- // Directories that might contain the data
- Array<std::string> potential;
-
- // Look back up the directory tree
- std::string x = "../";
- std::string f = "";
- for (int i = 0; i < 6; ++i) {
- potential.append(f);
- f = f + x;
- }
-
- // Hard-code in likely install directories
- int ver = G3D_VER;
- std::string lname = format("G3D-%d.%02d", ver / 10000, (ver / 100) % 100);
-
- if (G3D_VER % 100 != 0) {
- lname = lname + format("-b%02d/", ver % 100);
- } else {
- lname = lname + "/";
- }
-
- std::string lpath = "libraries/" + lname;
- #ifdef G3D_WIN32
- potential.append(std::string("c:/") + lpath);
- potential.append(std::string("d:/") + lpath);
- potential.append(std::string("e:/") + lpath);
- potential.append(std::string("f:/") + lpath);
- potential.append(std::string("g:/") + lpath);
- potential.append(std::string("x:/") + lpath);
- #elif defined(G3D_LINUX)
- potential.append("/usr/local/" + lname);
- potential.append("/course/cs224/");
- potential.append("/map/gfx0/common/games/");
- #elif defined(G3D_FREEBSD)
- potential.append("/usr/local/" + lname);
- potential.append("/usr/local/371/")
- potential.append("/usr/cs-local/371/")
- #elif defined(G3D_OSX)
- potential.append("/usr/local/" + lname);
- potential.append("/Volumes/McGuire/Projects/");
- potential.append("/Volumes/McGuire/Projects/G3D/");
- #endif
-
- // Scan all potentials for the font directory
- for (int p = 0; p < potential.size(); ++p) {
- std::string path = potential[p];
- //debugPrintf("Looking at: %sdata\n", path.c_str());
- if (fileExists(path + "data") && fileExists(path + "data/font")) {
- return path + "data/";
- }
- if (fileExists(path + "data-files") && fileExists(path + "data-files/font")) {
- return path + "data-files/";
- }
- }
-
- if (errorIfNotFound) {
- const char* choice[] = {"Exit"};
-
- prompt("Demo Error", "The demo could not locate the data directory. "
- "The data is required to run this demo. If you have not downloaded "
- "the data zipfile, get it from http://g3d-cpp.sf.net. If you have "
- "downloaded it, it needs to be no more than 4 directories above the "
- "demo directory.", choice, 1, true);
- }
-
- return "";
-}
-
-bool System::hasCPUID() {
- init();
- return g_cpuInfo.m_hasCPUID;
-}
-
-bool System::hasRDTSC() {
- init();
- return g_cpuInfo.m_hasRDTSC;
-}
-
-
-bool System::hasSSE() {
- init();
- return g_cpuInfo.m_hasSSE;
-}
-
-
-bool System::hasSSE2() {
- init();
- return g_cpuInfo.m_hasSSE2;
-}
-
-bool System::hasSSE3() {
- init();
- return g_cpuInfo.m_hasSSE3;
-}
-
-bool System::hasMMX() {
- init();
- return g_cpuInfo.m_hasMMX;
-}
-
-
-bool System::has3DNow() {
- init();
- return g_cpuInfo.m_has3DNOW;
-}
-
-
-const std::string& System::cpuVendor() {
- init();
- static const std::string _cpuVendor = g_cpuInfo.m_cpuVendorStr;
- return _cpuVendor;
-}
-
-
-G3DEndian System::machineEndian() {
- init();
- return _machineEndian;
-}
-
-const std::string& System::operatingSystem() {
- init();
- static const std::string _operatingSystem =_operatingSystemCstr;
- return _operatingSystem;
-}
-
-
-const std::string& System::cpuArchitecture() {
- init();
- static const std::string _cpuArch = _cpuArchCstr;
- return _cpuArch;
-}
-
-const std::string& System::build() {
- const static std::string b =
-# ifdef _DEBUG
- "Debug";
-# else
- "Release";
-# endif
-
- return b;
-}
-
-const std::string& System::version() {
- init();
-
- static const std::string _version = versionCstr;
- return _version;
-}
-
-
-void System::init() {
- // Cannot use most G3D data structures or utility functions in here because
- // they are not initialized.
-
- static bool initialized = false;
-
- if (initialized) {
- return;
- }
-
- initialized = true;
-
- if ((G3D_VER % 100) != 0) {
- sprintf(versionCstr, "G3D %d.%02d beta %d",
- G3D_VER / 10000,
- (G3D_VER / 100) % 100,
- G3D_VER % 100);
- } else {
- sprintf(versionCstr, "G3D %d.%02d",
- G3D_VER / 10000,
- (G3D_VER / 100) % 100);
- }
-
- // First of all we check if the CPUID command is available
- checkForCPUID();
-
- // Figure out if this machine is little or big endian.
- {
- int32 a = 1;
- if (*(uint8*)&a == 1) {
- _machineEndian = G3D_LITTLE_ENDIAN;
- } else {
- _machineEndian = G3D_BIG_ENDIAN;
- }
- }
-
-# ifdef G3D_NOT_OSX_PPC
- // Process the CPUID information
- if (g_cpuInfo.m_hasCPUID) {
- // We read the standard CPUID level 0x00000000 which should
- // be available on every x86 processor. This fills out
- // a string with the processor vendor tag.
- unsigned int eaxreg = 0, ebxreg = 0, ecxreg = 0, edxreg = 0;
-
- CALL_CPUID(0x00, eaxreg, ebxreg, ecxreg, edxreg);
-
- // Then we connect the single register values to the vendor string
- *((unsigned int*) g_cpuInfo.m_cpuVendorStr) = ebxreg;
- *((unsigned int*) (g_cpuInfo.m_cpuVendorStr + 4)) = edxreg;
- *((unsigned int*) (g_cpuInfo.m_cpuVendorStr + 8)) = ecxreg;
- g_cpuInfo.m_cpuVendorStr[12] = '\0';
-
- // We can also read the max. supported standard CPUID level
- maxSupportedCPUIDLevel = eaxreg & 0xFFFF;
-
- // Then we read the ext. CPUID level 0x80000000
- CALL_CPUID(0x80000000, eaxreg, ebxreg, ecxreg, edxreg);
-
- // ...to check the max. supported extended CPUID level
- maxSupportedExtendedLevel = eaxreg;
-
- // Then we switch to the specific processor vendors.
- // Fill out _cpuArch based on this information. It will
- // be overwritten by the next block of code on Windows,
- // but on Linux will stand.
- switch (ebxreg) {
- case 0x756E6547: // GenuineIntel
- strcpy(_cpuArchCstr, "Intel Processor");
- break;
-
- case 0x68747541: // AuthenticAMD
- strcpy(_cpuArchCstr, "AMD Processor");
- break;
-
- case 0x69727943: // CyrixInstead
- strcpy(_cpuArchCstr, "Cyrix Processor");
- break;
-
- default:
- strcpy(_cpuArchCstr, "Unknown Processor Vendor");
- break;
- }
- }
- #endif // G3D_NOT_OSX_PPC
-
- #ifdef G3D_WIN32
- bool success = RegistryUtil::readInt32
- ("HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "~MHz", g_cpuInfo.m_cpuSpeed);
-
- SYSTEM_INFO systemInfo;
- GetSystemInfo(&systemInfo);
- char* arch;
- switch (systemInfo.wProcessorArchitecture) {
- case PROCESSOR_ARCHITECTURE_INTEL:
- arch = "Intel";
- break;
-
- case PROCESSOR_ARCHITECTURE_MIPS:
- arch = "MIPS";
- break;
-
- case PROCESSOR_ARCHITECTURE_ALPHA:
- arch = "Alpha";
- break;
-
- case PROCESSOR_ARCHITECTURE_PPC:
- arch = "Power PC";
- break;
-
- default:
- arch = "Unknown";
- }
-
- uint32 maxAddr = (uint32)systemInfo.lpMaximumApplicationAddress;
- sprintf(_cpuArchCstr, "%d x %d-bit %s processor",
- systemInfo.dwNumberOfProcessors,
- (int)(::log((double)maxAddr) / ::log(2.0) + 2.0),
- arch);
- // _CPUSpeed / (1024.0 * 1024));
-
- OSVERSIONINFO osVersionInfo;
- osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- success = GetVersionEx(&osVersionInfo) != 0;
-
- if (success) {
- sprintf(_operatingSystemCstr, "Windows %d.%d build %d Platform %d %s",
- osVersionInfo.dwMajorVersion,
- osVersionInfo.dwMinorVersion,
- osVersionInfo.dwBuildNumber,
- osVersionInfo.dwPlatformId,
- osVersionInfo.szCSDVersion);
- } else {
- strcpy(_operatingSystemCstr, "Windows");
- }
-
- #elif defined(G3D_LINUX)
-
- {
- // Shell out to the 'uname' command
- FILE* f = popen("uname -a", "r");
-
- int len = 100;
- char* r = (char*)::malloc(len * sizeof(char));
- fgets(r, len, f);
- // Remove trailing newline
- if (r[strlen(r) - 1] == '\n') {
- r[strlen(r) - 1] = '\0';
- }
- fclose(f);
-
- strcpy(_operatingSystemCstr, r);
- ::free(r);
- }
-
- #elif defined(G3D_OSX)
-
- // Operating System:
- SInt32 macVersion;
- Gestalt(gestaltSystemVersion, &macVersion);
-
- int major = (macVersion >> 8) & 0xFF;
- int minor = (macVersion >> 4) & 0xF;
- int revision = macVersion & 0xF;
-
- sprintf(_operatingSystemCstr, "OS X %x.%x.%x", major, minor, revision);
-
- // Clock Cycle Timing Information:
- Gestalt('pclk', &System::m_OSXCPUSpeed);
- g_cpuInfo.m_cpuSpeed = iRound((double)m_OSXCPUSpeed / (1024 * 1024));
- m_secondsPerNS = 1.0 / 1.0e9;
-
- // System Architecture:
- const NXArchInfo* pInfo = NXGetLocalArchInfo();
-
- if (pInfo) {
- strcpy(_cpuArchCstr, pInfo->description);
-
- switch (pInfo->cputype) {
- case CPU_TYPE_POWERPC:
- switch(pInfo->cpusubtype){
- case CPU_SUBTYPE_POWERPC_750:
- case CPU_SUBTYPE_POWERPC_7400:
- case CPU_SUBTYPE_POWERPC_7450:
- strcpy(g_cpuInfo.m_cpuVendorStr, "Motorola");
- break;
- case CPU_SUBTYPE_POWERPC_970:
- strcpy(g_cpuInfo.m_cpuVendorStr, "IBM");
- break;
- }
- break;
-
- case CPU_TYPE_I386:
- strcpy(g_cpuInfo.m_cpuVendorStr, "Intel");
- break;
- }
- }
- #endif
-
- initTime();
-
- getStandardProcessorExtensions();
-}
-
-static void checkForCPUID() {
- unsigned int bitChanged = 0;
-
- // We've to check if we can toggle the flag register bit 21.
- // If we can't the processor does not support the CPUID command.
-
-#if defined(_MSC_VER)
- __asm {
- push eax
- push ebx
- pushfd
- pushfd
- pop eax
- mov ebx, eax
- xor eax, 0x00200000
- push eax
- popfd
- pushfd
- pop eax
- popfd
- xor eax, ebx
- mov bitChanged, eax
- pop ebx
- pop eax
- }
-#elif defined(__GNUC__) && defined(i386) && !defined(G3D_OSX_INTEL)
- // 32-bit g++
- __asm__ (
- "pushfl # Get original EFLAGS \n"
- "pushfl \n"
- "popl %%eax \n"
- "movl %%eax, %%ecx \n"
- "xorl $0x200000, %%eax # Flip ID bit in EFLAGS \n"
- "pushl %%eax # Save new EFLAGS value on stack \n"
- "popfl # Replace current EFLAGS value \n"
- "pushfl # Get new EFLAGS \n"
- "popl %%eax # Store new EFLAGS in EAX \n"
- "popfl \n"
- "xorl %%ecx, %%eax # Can not toggle ID bit, \n"
- "movl %%eax, %0 # We have CPUID support \n"
- : "=m" (bitChanged)
- : // No inputs
- : "%eax", "%ecx"
- );
-#elif defined(__GNUC__) && defined(__x86_64__) && !defined(G3D_OSX_INTEL)
- // x86_64 has SSE and CPUID
-
- bitChanged = 1;
-#else
- // Unknown architecture
- bitChanged = 0;
-#endif
-
- g_cpuInfo.m_hasCPUID = ((bitChanged == 0) ? false : true);
-}
-
-void getStandardProcessorExtensions() {
-#if !defined(G3D_OSX) || defined(G3D_OSX_INTEL)
- if (! g_cpuInfo.m_hasCPUID) {
- return;
- }
-
- unsigned int eaxreg = 0, ebxreg = 0, ecxreg = 0;
- unsigned int features = 0;
-
- // http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf
- // call cpuid with function 0x01 in EAX
-
- // Invoking CPUID with '1' in EAX fills out edx with a bit string.
- // The bits of this value indicate the presence or absence of
- // useful processor features.
- CALL_CPUID(0x01, eaxreg, ebxreg, ecxreg, features);
-
- #define checkBit(var, bit) ((var & (1 << bit)) ? true : false)
-
- g_cpuInfo.m_hasRDTSC = checkBit(features, 16);
- g_cpuInfo.m_hasMMX = checkBit(features, 23);
- g_cpuInfo.m_hasSSE = checkBit(features, 25);
- g_cpuInfo.m_hasSSE2 = checkBit(features, 26);
- g_cpuInfo.m_hasSSE3 = checkBit(ecxreg, 0);
-
- if (maxSupportedExtendedLevel >= 0x80000001) {
- // function 0x80000001 changes bit 31 of edx to 3dnow support flag
- CALL_CPUID(0x80000001, eaxreg, ebxreg, ecxreg, features);
- g_cpuInfo.m_has3DNOW = checkBit(features, 31);
- } else {
- g_cpuInfo.m_has3DNOW = false;
- }
-
- #undef checkBit
-#endif
-}
-
-#if defined(SSE)
-
-// Copy in 128 bytes chunks, where each chunk contains 8*float32x4 = 8 * 4 * 4 bytes = 128 bytes
-//
-//
-void memcpySSE2(void* dst, const void* src, int nbytes) {
- int remainingBytes = nbytes;
-
- if (nbytes > 128) {
-
- // Number of chunks
- int N = nbytes / 128;
-
- float* restrict d = (float*)dst;
- const float* restrict s = (const float*)src;
-
- // Finish when the destination pointer has moved 8N elements
- float* stop = d + (N * 8 * 4);
-
- while (d < stop) {
- // Inner loop unrolled 8 times
- const __m128 r0 = _mm_loadu_ps(s);
- const __m128 r1 = _mm_loadu_ps(s + 4);
- const __m128 r2 = _mm_loadu_ps(s + 8);
- const __m128 r3 = _mm_loadu_ps(s + 12);
- const __m128 r4 = _mm_loadu_ps(s + 16);
- const __m128 r5 = _mm_loadu_ps(s + 20);
- const __m128 r6 = _mm_loadu_ps(s + 24);
- const __m128 r7 = _mm_loadu_ps(s + 28);
-
- _mm_storeu_ps(d, r0);
- _mm_storeu_ps(d + 4, r1);
- _mm_storeu_ps(d + 8, r2);
- _mm_storeu_ps(d + 12, r3);
- _mm_storeu_ps(d + 16, r4);
- _mm_storeu_ps(d + 20, r5);
- _mm_storeu_ps(d + 24, r6);
- _mm_storeu_ps(d + 28, r7);
-
- s += 32;
- d += 32;
- }
-
- remainingBytes -= N * 8 * 4 * 4;
- }
-
- if (remainingBytes > 0) {
- // Memcpy the rest
- memcpy((uint8*)dst + (nbytes - remainingBytes), (const uint8*)src + (nbytes - remainingBytes), remainingBytes);
- }
-}
-#else
-
- // Fall back to memcpy
- void memcpySSE2(void *dst, const void *src, int nbytes) {
- memcpy(dst, src, nbytes);
- }
-
-#endif
-
-#if defined(G3D_WIN32) && defined(SSE)
-/** Michael Herf's fast memcpy */
-void memcpyMMX(void* dst, const void* src, int nbytes) {
- int remainingBytes = nbytes;
-
- if (nbytes > 64) {
- _asm {
- mov esi, src
- mov edi, dst
- mov ecx, nbytes
- shr ecx, 6 // 64 bytes per iteration
-
- loop1:
- movq mm1, 0[ESI] // Read in source data
- movq mm2, 8[ESI]
- movq mm3, 16[ESI]
- movq mm4, 24[ESI]
- movq mm5, 32[ESI]
- movq mm6, 40[ESI]
- movq mm7, 48[ESI]
- movq mm0, 56[ESI]
-
- movntq 0[EDI], mm1 // Non-temporal stores
- movntq 8[EDI], mm2
- movntq 16[EDI], mm3
- movntq 24[EDI], mm4
- movntq 32[EDI], mm5
- movntq 40[EDI], mm6
- movntq 48[EDI], mm7
- movntq 56[EDI], mm0
-
- add esi, 64
- add edi, 64
- dec ecx
- jnz loop1
-
- emms
- }
- remainingBytes -= ((nbytes >> 6) << 6);
- }
-
- if (remainingBytes > 0) {
- // Memcpy the rest
- memcpy((uint8*)dst + (nbytes - remainingBytes), (const uint8*)src + (nbytes - remainingBytes), remainingBytes);
- }
-}
-
-#else
- // Fall back to memcpy
- void memcpyMMX(void *dst, const void *src, int nbytes) {
- memcpy(dst, src, nbytes);
- }
-
-#endif
-
-
-void System::memcpy(void* dst, const void* src, size_t numBytes) {
- if (System::hasSSE2() && System::hasMMX()) {
- G3D::memcpyMMX(dst, src, numBytes);
- } else if (System::hasSSE() && System::hasMMX()) {
- G3D::memcpyMMX(dst, src, numBytes);
- } else {
- ::memcpy(dst, src, numBytes);
- }
-}
-
-
-/** Michael Herf's fastest memset. n32 must be filled with the same
- character repeated. */
-#if defined(G3D_WIN32) && defined(SSE)
-
-// On x86 processors, use MMX
-void memfill(void *dst, int n32, unsigned long i) {
-
- int originalSize = i;
- int bytesRemaining = i;
-
- if (i > 16) {
-
- bytesRemaining = i % 16;
- i -= bytesRemaining;
- __asm {
- movq mm0, n32
- punpckldq mm0, mm0
- mov edi, dst
-
- loopwrite:
-
- movntq 0[edi], mm0
- movntq 8[edi], mm0
-
- add edi, 16
- sub i, 16
- jg loopwrite
-
- emms
- }
- }
-
- if (bytesRemaining > 0) {
- ::memset((uint8*)dst + (originalSize - bytesRemaining), n32, bytesRemaining);
- }
-}
-
-#else
-
-// For non x86 processors, we fall back to the standard memset
-void memfill(void *dst, int n32, unsigned long i) {
- ::memset(dst, n32, i);
-}
-
-#endif
-
-
-void System::memset(void* dst, uint8 value, size_t numBytes) {
- if (System::hasSSE() && System::hasMMX()) {
- uint32 v = value;
- v = v + (v << 8) + (v << 16) + (v << 24);
- G3D::memfill(dst, v, numBytes);
- } else {
- ::memset(dst, value, numBytes);
- }
-}
-
-
-std::string& System::appName() {
- static std::string n = filenameBase(currentProgramFilename());
- return n;
-}
-
-
-std::string System::currentProgramFilename() {
- char filename[2048];
-
- #ifdef G3D_WIN32
- {
- GetModuleFileNameA(NULL, filename, sizeof(filename));
- }
- #else
- {
- int ret = readlink("/proc/self/exe", filename, sizeof(filename));
-
- // In case of an error, leave the handling up to the caller
- if (ret == -1) {
- return "";
- }
-
- debugAssert((int)sizeof(filename) > ret);
-
- // Ensure proper NULL termination
- filename[ret] = 0;
- }
- #endif
-
- return filename;
-}
-
-
-void System::sleep(RealTime t) {
-
- // Overhead of calling this function.
- static const RealTime OVERHEAD = .000006;
-
- RealTime now = time();
- RealTime wakeupTime = now + t - OVERHEAD;
-
- RealTime remainingTime = wakeupTime - now;
- RealTime sleepTime = 0;
-
- while (remainingTime > 0) {
-
-
- if (remainingTime > 0.001) {
- // Safe to use Sleep with a time... sleep for half the remaining time
- sleepTime = max(remainingTime * .5, 0.0005);
- } else if (remainingTime > 0.0001) {
- // Safe to use Sleep with a zero time;
- // causes the program to yield only
- // the current time slice, and then return.
- sleepTime = 0;
- } else {
- // Not safe to use Sleep; busy wait
- sleepTime = -1;
- }
-
- if (sleepTime >= 0) {
- #ifdef G3D_WIN32
- // Translate to milliseconds
- Sleep((int)(sleepTime * 1e3));
- #else
- // Translate to microseconds
- usleep((int)(sleepTime * 1e6));
- #endif
- }
-
- now = time();
- remainingTime = wakeupTime - now;
- }
-}
-
-
-void System::consoleClearScreen() {
- #ifdef G3D_WIN32
- system("cls");
- #else
- system("clear");
- #endif
-}
-
-
-bool System::consoleKeyPressed() {
- #ifdef G3D_WIN32
-
- return _kbhit() != 0;
-
- #else
-
- static const int STDIN = 0;
- static bool initialized = false;
-
- if (! initialized) {
- // Use termios to turn off line buffering
- termios term;
- tcgetattr(STDIN, &term);
- term.c_lflag &= ~ICANON;
- tcsetattr(STDIN, TCSANOW, &term);
- setbuf(stdin, NULL);
- initialized = true;
- }
-
- #ifdef G3D_LINUX
-
- int bytesWaiting;
- ioctl(STDIN, FIONREAD, &bytesWaiting);
- return bytesWaiting;
-
- #else
-
- timeval timeout;
- fd_set rdset;
-
- FD_ZERO(&rdset);
- FD_SET(STDIN, &rdset);
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
-
- return select(STDIN + 1, &rdset, NULL, NULL, &timeout);
- #endif
- #endif
-}
-
-
-int System::consoleReadKey() {
- #ifdef G3D_WIN32
- return _getch();
- #else
- char c;
- read(0, &c, 1);
- return c;
- #endif
-}
-
-
-void initTime() {
- #ifdef G3D_WIN32
- if (QueryPerformanceFrequency(&_counterFrequency)) {
- QueryPerformanceCounter(&_start);
- }
-
- struct _timeb t;
- _ftime(&t);
-
- realWorldGetTickTime0 = (RealTime)t.time - t.timezone * G3D::MINUTE + (t.dstflag ? G3D::HOUR : 0);
-
- #else
- gettimeofday(&_start, NULL);
- // "sse" = "seconds since epoch". The time
- // function returns the seconds since the epoch
- // GMT (perhaps more correctly called UTC).
- time_t gmt = time(NULL);
-
- // No call to free or delete is needed, but subsequent
- // calls to asctime, ctime, mktime, etc. might overwrite
- // local_time_vals.
- tm* localTimeVals = localtime(&gmt);
-
- time_t local = gmt;
-
- if (localTimeVals) {
- // tm_gmtoff is already corrected for daylight savings.
- local = local + localTimeVals->tm_gmtoff;
- }
-
- realWorldGetTickTime0 = local;
- #endif
-}
-
-
-RealTime System::time() {
- init();
- #ifdef G3D_WIN32
- LARGE_INTEGER now;
- QueryPerformanceCounter(&now);
-
- return ((RealTime)(now.QuadPart - _start.QuadPart) /
- _counterFrequency.QuadPart) + realWorldGetTickTime0;
- #else
- // Linux resolution defaults to 100Hz.
- // There is no need to do a separate RDTSC call as gettimeofday
- // actually uses RDTSC when on systems that support it, otherwise
- // it uses the system clock.
- struct timeval now;
- gettimeofday(&now, NULL);
-
- return (now.tv_sec - _start.tv_sec) +
- (now.tv_usec - _start.tv_usec) / 1e6
- + realWorldGetTickTime0;
- #endif
-}
-
-
-////////////////////////////////////////////////////////////////
-
-#define REALPTR_TO_USERPTR(x) ((uint8*)(x) + sizeof (void *))
-#define USERPTR_TO_REALPTR(x) ((uint8*)(x) - sizeof (void *))
-#define REALBLOCK_SIZE(x) ((x) + sizeof (void *))
-
-class BufferPool {
-public:
-
- /** Only store buffers up to these sizes (in bytes) in each pool->
- Different pools have different management strategies.
-
- A large block is preallocated for tiny buffers; they are used with
- tremendous frequency. Other buffers are allocated as demanded.
- Tiny buffers are 128 bytes long because that seems to align well with
- cache sizes on many machines.
- */
- enum {tinyBufferSize = 128, smallBufferSize = 1024, medBufferSize = 4096};
-
- /**
- Most buffers we're allowed to store.
- 128000 * 128 = 16 MB (preallocated)
- 2048 * 1024 = 2 MB (allocated on demand)
- 1024 * 4096 = 4 MB (allocated on demand)
- */
- enum {maxTinyBuffers = 128000, maxSmallBuffers = 2048, maxMedBuffers = 1024};
-
-private:
-
- class MemBlock {
- public:
- void* ptr;
- size_t bytes;
-
- inline MemBlock() : ptr(NULL), bytes(0) {}
- inline MemBlock(void* p, size_t b) : ptr(p), bytes(b) {}
- };
-
- MemBlock smallPool[maxSmallBuffers];
- int smallPoolSize;
-
- MemBlock medPool[maxMedBuffers];
- int medPoolSize;
-
- /** The tiny pool is a single block of storage into which all tiny
- objects are allocated. This provides better locality for
- small objects and avoids the search time, since all tiny
- blocks are exactly the same size. */
- void* tinyPool[maxTinyBuffers];
- int tinyPoolSize;
-
- /** Pointer to the data in the tiny pool */
- void* tinyHeap;
-
-# ifdef G3D_WIN32
- CRITICAL_SECTION mutex;
-# else
- pthread_mutex_t mutex;
-# endif
-
- /** Provide synchronization between threads */
- void lock() {
-# ifdef G3D_WIN32
- EnterCriticalSection(&mutex);
-# else
- pthread_mutex_lock(&mutex);
-# endif
- }
-
- void unlock() {
-# ifdef G3D_WIN32
- LeaveCriticalSection(&mutex);
-# else
- pthread_mutex_unlock(&mutex);
-# endif
- }
-
- /**
- Malloc out of the tiny heap. Returns NULL if allocation failed.
- */
- inline void* tinyMalloc(size_t bytes) {
- // Note that we ignore the actual byte size
- // and create a constant size block.
- (void)bytes;
- assert(tinyBufferSize >= bytes);
-
- void* ptr = NULL;
-
- if (tinyPoolSize > 0) {
- --tinyPoolSize;
-
- // Return the old last pointer from the freelist
- ptr = tinyPool[tinyPoolSize];
-
-# ifdef G3D_DEBUG
- if (tinyPoolSize > 0) {
- assert(tinyPool[tinyPoolSize - 1] != ptr);
- // "System::malloc heap corruption detected: "
- // "the last two pointers on the freelist are identical (during tinyMalloc).");
- }
-# endif
-
- // NULL out the entry to help detect corruption
- tinyPool[tinyPoolSize] = NULL;
- }
-
- return ptr;
- }
-
- /** Returns true if this is a pointer into the tiny heap. */
- bool inTinyHeap(void* ptr) {
- return
- (ptr >= tinyHeap) &&
- (ptr < (uint8*)tinyHeap + maxTinyBuffers * tinyBufferSize);
- }
-
- void tinyFree(void* ptr) {
- assert(ptr);
- assert(tinyPoolSize < maxTinyBuffers);
- // "Tried to free a tiny pool buffer when the tiny pool freelist is full.");
-
-# ifdef G3D_DEBUG
- if (tinyPoolSize > 0) {
- void* prevOnHeap = tinyPool[tinyPoolSize - 1];
- assert(prevOnHeap != ptr);
-// "System::malloc heap corruption detected: "
-// "the last two pointers on the freelist are identical (during tinyFree).");
- }
-# endif
-
- assert(tinyPool[tinyPoolSize] == NULL);
-
- // Put the pointer back into the free list
- tinyPool[tinyPoolSize] = ptr;
- ++tinyPoolSize;
-
- }
-
- void flushPool(MemBlock* pool, int& poolSize) {
- for (int i = 0; i < poolSize; ++i) {
- ::free(pool[i].ptr);
- pool[i].ptr = NULL;
- pool[i].bytes = 0;
- }
- poolSize = 0;
- }
-
-
- /** Allocate out of a specific pool-> Return NULL if no suitable
- memory was found.
-
- */
- void* malloc(MemBlock* pool, int& poolSize, size_t bytes) {
-
- // OPT: find the smallest block that satisfies the request.
-
- // See if there's something we can use in the buffer pool->
- // Search backwards since usually we'll re-use the last one.
- for (int i = (int)poolSize - 1; i >= 0; --i) {
- if (pool[i].bytes >= bytes) {
- // We found a suitable entry in the pool->
-
- // No need to offset the pointer; it is already offset
- void* ptr = pool[i].ptr;
-
- // Remove this element from the pool
- --poolSize;
- pool[i] = pool[poolSize];
-
- return ptr;
- }
- }
-
- return NULL;
- }
-
-public:
-
- /** Count of memory allocations that have occurred. */
- int totalMallocs;
- int mallocsFromTinyPool;
- int mallocsFromSmallPool;
- int mallocsFromMedPool;
-
- /** Amount of memory currently allocated (according to the application).
- This does not count the memory still remaining in the buffer pool,
- but does count extra memory required for rounding off to the size
- of a buffer.
- Primarily useful for detecting leaks.*/
- // TODO: make me an atomic int!
- volatile int bytesAllocated;
-
- BufferPool() {
- totalMallocs = 0;
-
- mallocsFromTinyPool = 0;
- mallocsFromSmallPool = 0;
- mallocsFromMedPool = 0;
-
- bytesAllocated = true;
-
- tinyPoolSize = 0;
- tinyHeap = NULL;
-
- smallPoolSize = 0;
-
- medPoolSize = 0;
-
-
- // Initialize the tiny heap as a bunch of pointers into one
- // pre-allocated buffer.
- tinyHeap = ::malloc(maxTinyBuffers * tinyBufferSize);
- for (int i = 0; i < maxTinyBuffers; ++i) {
- tinyPool[i] = (uint8*)tinyHeap + (tinyBufferSize * i);
- }
- tinyPoolSize = maxTinyBuffers;
-
-# ifdef G3D_WIN32
- InitializeCriticalSection(&mutex);
-# else
- pthread_mutex_init(&mutex, NULL);
-# endif
- }
-
-
- ~BufferPool() {
- ::free(tinyHeap);
-# ifdef G3D_WIN32
- DeleteCriticalSection(&mutex);
-# else
- // No destruction on pthreads
-# endif
- }
-
-
- void* realloc(void* ptr, size_t bytes) {
- if (ptr == NULL) {
- return malloc(bytes);
- }
-
- if (inTinyHeap(ptr)) {
- if (bytes <= tinyBufferSize) {
- // The old pointer actually had enough space.
- return ptr;
- } else {
- // Free the old pointer and malloc
-
- void* newPtr = malloc(bytes);
- System::memcpy(newPtr, ptr, tinyBufferSize);
- tinyFree(ptr);
- return newPtr;
-
- }
- } else {
- // In one of our heaps.
-
- // See how big the block really was
- size_t realSize = *(uint32*)USERPTR_TO_REALPTR(ptr);
- if (bytes <= realSize) {
- // The old block was big enough.
- return ptr;
- }
-
- // Need to reallocate
- void* newPtr = malloc(bytes);
- System::memcpy(newPtr, ptr, realSize);
- free(ptr);
- return newPtr;
- }
- }
-
-
- void* malloc(size_t bytes) {
- lock();
- ++totalMallocs;
-
- if (bytes <= tinyBufferSize) {
-
- void* ptr = tinyMalloc(bytes);
-
- if (ptr) {
- ++mallocsFromTinyPool;
- unlock();
- return ptr;
- }
-
- }
-
- // Failure to allocate a tiny buffer is allowed to flow
- // through to a small buffer
- if (bytes <= smallBufferSize) {
-
- void* ptr = malloc(smallPool, smallPoolSize, bytes);
-
- if (ptr) {
- ++mallocsFromSmallPool;
- unlock();
- return ptr;
- }
-
- } else if (bytes <= medBufferSize) {
- // Note that a small allocation failure does *not* fall
- // through into a medium allocation because that would
- // waste the medium buffer's resources.
-
- void* ptr = malloc(medPool, medPoolSize, bytes);
-
- if (ptr) {
- ++mallocsFromMedPool;
- unlock();
- debugAssertM(ptr != NULL, "BufferPool::malloc returned NULL");
- return ptr;
- }
- }
-
- bytesAllocated += REALBLOCK_SIZE(bytes);
- unlock();
-
- // Heap allocate
-
- // Allocate 4 extra bytes for our size header (unfortunate,
- // since malloc already added its own header).
- void* ptr = ::malloc(REALBLOCK_SIZE(bytes));
-
- if (ptr == NULL) {
- // Flush memory pools to try and recover space
- flushPool(smallPool, smallPoolSize);
- flushPool(medPool, medPoolSize);
- ptr = ::malloc(REALBLOCK_SIZE(bytes));
- }
-
- if (ptr == NULL) {
- if ((System::outOfMemoryCallback != NULL) &&
- (System::outOfMemoryCallback(REALBLOCK_SIZE(bytes), true) == true)) {
- // Re-attempt the malloc
- ptr = ::malloc(REALBLOCK_SIZE(bytes));
- }
- }
-
- if (ptr == NULL) {
- if (System::outOfMemoryCallback != NULL) {
- // Notify the application
- System::outOfMemoryCallback(REALBLOCK_SIZE(bytes), false);
- }
-# ifdef G3D_DEBUG
- debugPrintf("::malloc(%d) returned NULL\n", REALBLOCK_SIZE(bytes));
-# endif
- debugAssertM(ptr != NULL,
- "::malloc returned NULL. Either the "
- "operating system is out of memory or the "
- "heap is corrupt.");
- return NULL;
- }
-
- *(uint32*)ptr = bytes;
-
- return REALPTR_TO_USERPTR(ptr);
- }
-
-
- void free(void* ptr) {
- if (ptr == NULL) {
- // Free does nothing on null pointers
- return;
- }
-
- assert(isValidPointer(ptr));
-
- if (inTinyHeap(ptr)) {
- lock();
- tinyFree(ptr);
- unlock();
- return;
- }
-
- uint32 bytes = *(uint32*)USERPTR_TO_REALPTR(ptr);
-
- lock();
- if (bytes <= smallBufferSize) {
- if (smallPoolSize < maxSmallBuffers) {
- smallPool[smallPoolSize] = MemBlock(ptr, bytes);
- ++smallPoolSize;
- unlock();
- return;
- }
- } else if (bytes <= medBufferSize) {
- if (medPoolSize < maxMedBuffers) {
- medPool[medPoolSize] = MemBlock(ptr, bytes);
- ++medPoolSize;
- unlock();
- return;
- }
- }
- bytesAllocated -= REALBLOCK_SIZE(bytes);
- unlock();
-
- // Free; the buffer pools are full or this is too big to store.
- ::free(USERPTR_TO_REALPTR(ptr));
- }
-
- std::string performance() const {
- if (totalMallocs > 0) {
- int pooled = mallocsFromTinyPool +
- mallocsFromSmallPool +
- mallocsFromMedPool;
-
- int total = totalMallocs;
-
- return format("malloc performance: %5.1f%% <= %db, %5.1f%% <= %db, "
- "%5.1f%% <= %db, %5.1f%% > %db",
- 100.0 * mallocsFromTinyPool / total,
- BufferPool::tinyBufferSize,
- 100.0 * mallocsFromSmallPool / total,
- BufferPool::smallBufferSize,
- 100.0 * mallocsFromMedPool / total,
- BufferPool::medBufferSize,
- 100.0 * (1.0 - (double)pooled / total),
- BufferPool::medBufferSize);
- } else {
- return "No System::malloc calls made yet.";
- }
- }
-
- std::string status() const {
- return format("preallocated shared buffers: %5d/%d x %db",
- maxTinyBuffers - tinyPoolSize, maxTinyBuffers, tinyBufferSize);
- }
-};
-
-// Dynamically allocated because we need to ensure that
-// the buffer pool is still around when the last global variable
-// is deallocated.
-static BufferPool* bufferpool = NULL;
-
-std::string System::mallocPerformance() {
-#ifndef NO_BUFFERPOOL
- return bufferpool->performance();
-#else
- return "NO_BUFFERPOOL";
-#endif
-}
-
-std::string System::mallocStatus() {
-#ifndef NO_BUFFERPOOL
- return bufferpool->status();
-#else
- return "NO_BUFFERPOOL";
-#endif
-}
-
-
-void System::resetMallocPerformanceCounters() {
-#ifndef NO_BUFFERPOOL
- bufferpool->totalMallocs = 0;
- bufferpool->mallocsFromMedPool = 0;
- bufferpool->mallocsFromSmallPool = 0;
- bufferpool->mallocsFromTinyPool = 0;
-#endif
-}
-
-
-#ifndef NO_BUFFERPOOL
-inline void initMem() {
- // Putting the test here ensures that the system is always
- // initialized, even when globals are being allocated.
- static bool initialized = false;
- if (! initialized) {
- bufferpool = new BufferPool();
- initialized = true;
- }
-}
-#endif
-
-
-void* System::malloc(size_t bytes) {
-#ifndef NO_BUFFERPOOL
- initMem();
- return bufferpool->malloc(bytes);
-#else
- return ::malloc(bytes);
-#endif
-}
-
-void* System::calloc(size_t n, size_t x) {
-#ifndef NO_BUFFERPOOL
- void* b = System::malloc(n * x);
- debugAssertM(b != NULL, "System::malloc returned NULL");
- debugAssertM(isValidHeapPointer(b), "System::malloc returned an invalid pointer");
- System::memset(b, 0, n * x);
- return b;
-#else
- return ::calloc(n, x);
-#endif
-}
-
-
-void* System::realloc(void* block, size_t bytes) {
-#ifndef NO_BUFFERPOOL
- initMem();
- return bufferpool->realloc(block, bytes);
-#else
- return ::realloc(block, bytes);
-#endif
-}
-
-
-void System::free(void* p) {
-#ifndef NO_BUFFERPOOL
- bufferpool->free(p);
-#else
- return ::free(p);
-#endif
-}
-
-
-void* System::alignedMalloc(size_t bytes, size_t alignment) {
-
- alwaysAssertM(isPow2(alignment), "alignment must be a power of 2");
-
- // We must align to at least a word boundary.
- alignment = iMax(alignment, sizeof(void *));
-
- // Pad the allocation size with the alignment size and the
- // size of the redirect pointer.
- size_t totalBytes = bytes + alignment + sizeof(void*);
-
- size_t truePtr = (size_t)System::malloc(totalBytes);
-
- if (truePtr == 0) {
- // malloc returned NULL
- return NULL;
- }
-
- debugAssert(isValidHeapPointer((void*)truePtr));
- #ifdef G3D_WIN32
- // The blocks we return will not be valid Win32 debug heap
- // pointers because they are offset
- // debugAssert(_CrtIsValidPointer((void*)truePtr, totalBytes, TRUE) );
- #endif
-
- // The return pointer will be the next aligned location (we must at least
- // leave space for the redirect pointer, however).
- size_t alignedPtr = truePtr + sizeof(void*);
-
- // 2^n - 1 has the form 1111... in binary.
- uint32 bitMask = (alignment - 1);
-
- // Advance forward until we reach an aligned location.
- while ((alignedPtr & bitMask) != 0) {
- alignedPtr += sizeof(void*);
- }
-
- debugAssert(alignedPtr - truePtr + bytes <= totalBytes);
-
- // Immediately before the aligned location, write the true array location
- // so that we can free it correctly.
- size_t* redirectPtr = (size_t *)(alignedPtr - sizeof(void *));
- redirectPtr[0] = truePtr;
-
- debugAssert(isValidHeapPointer((void*)truePtr));
-
- #ifdef G3D_WIN32
- debugAssert( _CrtIsValidPointer((void*)alignedPtr, bytes, TRUE) );
- #endif
- return (void *)alignedPtr;
-}
-
-
-void System::alignedFree(void* _ptr) {
- if (_ptr == NULL) {
- return;
- }
-
- size_t alignedPtr = (size_t)_ptr;
-
- // Back up one word from the pointer the user passed in.
- // We now have a pointer to a pointer to the true start
- // of the memory block.
- size_t* redirectPtr = (size_t*)(alignedPtr - sizeof(void *));
-
- // Dereference that pointer so that ptr = true start
- void* truePtr = (void*)redirectPtr[0];
-
- debugAssert(isValidHeapPointer((void*)truePtr));
- System::free(truePtr);
-}
-
-
-void System::setEnv(const std::string& name, const std::string& value) {
- std::string cmd = name + "=" + value;
-# ifdef G3D_WIN32
- _putenv(cmd.c_str());
-# else
- // Many linux implementations of putenv expect char*
- putenv(const_cast<char*>(cmd.c_str()));
-# endif
-}
-
-const char* System::getEnv(const std::string& name) {
- return getenv(name.c_str());
-}
-
-static void var(TextOutput& t, const std::string& name, const std::string& val) {
- t.writeSymbols(name,"=");
- t.writeString(val);
- t.writeNewline();
-}
-
-
-static void var(TextOutput& t, const std::string& name, const bool val) {
- t.writeSymbols(name, "=", val ? "Yes" : "No");
- t.writeNewline();
-}
-
-
-static void var(TextOutput& t, const std::string& name, const int val) {
- t.writeSymbols(name,"=");
- t.writeNumber(val);
- t.writeNewline();
-}
-
-void System::describeSystem(
- std::string& s) {
-
- TextOutput t;
- describeSystem(t);
- t.commitString(s);
-}
-
-void System::describeSystem(
- TextOutput& t) {
-
- t.writeSymbols("App", "{");
- t.writeNewline();
- t.pushIndent();
- var(t, "Name", System::currentProgramFilename());
- char cwd[1024];
- getcwd(cwd, 1024);
- var(t, "cwd", std::string(cwd));
- t.popIndent();
- t.writeSymbols("}");
- t.writeNewline();
- t.writeNewline();
-
- t.writeSymbols("OS", "{");
- t.writeNewline();
- t.pushIndent();
- var(t, "Name", System::operatingSystem());
- t.popIndent();
- t.writeSymbols("}");
- t.writeNewline();
- t.writeNewline();
-
- t.writeSymbols("CPU", "{");
- t.writeNewline();
- t.pushIndent();
- var(t, "Vendor", System::cpuVendor());
- var(t, "Architecture", System::cpuArchitecture());
- var(t, "hasCPUID", System::hasCPUID());
- var(t, "hasMMX", System::hasMMX());
- var(t, "hasSSE", System::hasSSE());
- var(t, "hasSSE2", System::hasSSE2());
- var(t, "hasSSE3", System::hasSSE3());
- var(t, "has3DNow", System::has3DNow());
- var(t, "hasRDTSC", System::hasRDTSC());
- t.popIndent();
- t.writeSymbols("}");
- t.writeNewline();
- t.writeNewline();
-
- t.writeSymbols("G3D", "{");
- t.writeNewline();
- t.pushIndent();
- var(t, "Link version", G3D_VER);
- var(t, "Compile version", System::version());
- t.popIndent();
- t.writeSymbols("}");
- t.writeNewline();
- t.writeNewline();
-}
-
-
-int System::cpuSpeedMHz() {
- return g_cpuInfo.m_cpuSpeed;
-}
-
-
-void System::setClipboardText(const std::string& s) {
-# ifdef G3D_WIN32
- if (OpenClipboard(NULL)) {
- HGLOBAL hMem = GlobalAlloc(GHND | GMEM_DDESHARE, s.size() + 1);
- if (hMem) {
- char *pMem = (char*)GlobalLock(hMem);
- strcpy(pMem, s.c_str());
- GlobalUnlock(hMem);
-
- EmptyClipboard();
- SetClipboardData(CF_TEXT, hMem);
- }
-
- CloseClipboard();
- GlobalFree(hMem);
- }
-# endif
-}
-
-
-std::string System::getClipboardText() {
- std::string s;
-
-# ifdef G3D_WIN32
- if (OpenClipboard(NULL)) {
- HANDLE h = GetClipboardData(CF_TEXT);
-
- if (h) {
- char* temp = (char*)GlobalLock(h);
- if (temp) {
- s = temp;
- }
- temp = NULL;
- GlobalUnlock(h);
- }
- CloseClipboard();
- }
-# endif
- return s;
-}
-
-
-std::string System::currentDateString() {
- time_t t1;
- ::time(&t1);
- tm* t = localtime(&t1);
- return format("%d-%02d-%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
-}
-
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/TextInput.cpp b/externals/g3dlite/G3D.lib/source/TextInput.cpp
deleted file mode 100644
index d5dc14fb6a0..00000000000
--- a/externals/g3dlite/G3D.lib/source/TextInput.cpp
+++ /dev/null
@@ -1,988 +0,0 @@
-/**
- @file TextInput.cpp
-
- @author Morgan McGuire, graphics3d.com
-
- @cite Based on a lexer written by Aaron Orenstein.
-
- @created 2001-11-27
- @edited 2008-07-14
- */
-
-#include "G3D/fileutils.h"
-#include "G3D/TextInput.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/stringutils.h"
-
-#ifdef _MSC_VER
-# pragma warning (push)
-// conversion from 'int' to 'char', possible loss of data (TODO: fix underlying problems)
-# pragma warning (disable: 4244)
-#endif
-
-namespace G3D {
-
-double Token::number() const {
- if (_type == NUMBER) {
- std::string s = toLower(_string);
- if (s == "-1.#ind00") {
- return nan();
- }
-
- if (s == "1.#inf00") {
- return inf();
- }
-
- if (s == "-1.#inf00") {
- return -inf();
- }
-
- double n;
- if ((_string.length() > 2) &&
- (_string[0] == '0') &&
- (_string[1] == 'x')) {
- // Hex
- uint32 i;
- sscanf(_string.c_str(), "%x", &i);
- n = i;
- } else {
- sscanf(_string.c_str(), "%lg", &n);
- }
- return n;
- } else {
- return 0.0;
- }
-}
-
-
-TextInput::Settings::Settings ()
- : cComments(true), cppComments(true), escapeSequencesInStrings(true),
- otherCommentCharacter('\0'), otherCommentCharacter2('\0'),
- signedNumbers(true), singleQuotedStrings(true), sourceFileName(),
- startingLineNumberOffset(0), msvcSpecials(true), proofSymbols(false),
- caseSensitive(true)
-{
- trueSymbols.insert("true");
- falseSymbols.insert("false");
-}
-
-
-Token TextInput::peek() {
- if (stack.size() == 0) {
- Token t = nextToken();
- push(t);
- }
-
- return stack.front();
-}
-
-
-int TextInput::peekLineNumber() {
- return peek().line();
-}
-
-
-int TextInput::peekCharacterNumber() {
- return peek().character();
-}
-
-
-Token TextInput::read() {
- if (stack.size() > 0) {
- Token t = stack.front();
- stack.pop_front();
- return t;
- } else {
- return nextToken();
- }
-}
-
-static void toUpper(Set<std::string>& set) {
- Array<std::string> symbols;
- set.getMembers(symbols);
- set.clear();
- for (int i = 0; i < symbols.size(); ++i) {
- set.insert(toUpper(symbols[i]));
- }
-}
-
-void TextInput::init() {
- currentCharOffset = 0;
- charNumber = 1;
- lineNumber = 1 + options.startingLineNumberOffset;
-
- if (! options.caseSensitive) {
- // Convert true and false symbols to all uppercase for fast comparisons
- toUpper(options.trueSymbols);
- toUpper(options.falseSymbols);
- }
-}
-
-
-void TextInput::push(const Token& t) {
- stack.push_front(t);
-}
-
-
-bool TextInput::hasMore() {
- return (peek()._type != Token::END);
-}
-
-
-int TextInput::eatInputChar() {
- // Don't go off the end
- if (currentCharOffset >= (unsigned int)buffer.length()) {
- return EOF;
- }
-
- unsigned char c = buffer[currentCharOffset];
- ++currentCharOffset;
-
- // update lineNumber and charNumber to reflect the location of the *next*
- // character which will be read.
- //
- // We update even for CR because the user is allowed to do arbitrarily
- // stupid things, like put a bunch of literal CRs inside a quoted string.
- //
- // We eat all whitespace between tokens, so they should never see a
- // lineNumber that points to a CR. However, if they have some kind of
- // syntax error in a token that appears *after* a quoted string
- // containing CRs, they should get a correct character number.
-
- // TODO: http://sourceforge.net/tracker/index.php?func=detail&aid=1341266&group_id=76879&atid=548565
-
- if (c == '\n') {
- ++lineNumber;
- charNumber = 1;
- } else {
- ++charNumber;
- }
-
- return c;
-}
-
-int TextInput::peekInputChar(unsigned int distance) {
- // Don't go off the end
- if ((currentCharOffset + distance) >= (unsigned int)buffer.length()) {
- return EOF;
- }
-
- unsigned char c = buffer[currentCharOffset + distance];
- return c;
-}
-
-
-Token TextInput::nextToken() {
- Token t;
-
- t._line = lineNumber;
- t._character = charNumber;
- t._type = Token::END;
- t._extendedType = Token::END_TYPE;
-
- int c = peekInputChar();
- if (c == EOF) {
- return t;
- }
-
- bool whitespaceDone = false;
- while (! whitespaceDone) {
- whitespaceDone = true;
-
- // Consume whitespace
- while (isWhiteSpace(c)) {
- c = eatAndPeekInputChar();
- }
-
- int c2 = peekInputChar(1);
- if ((options.cppComments && c == '/' && c2 == '/')
- || (options.otherCommentCharacter != '\0'
- && c == options.otherCommentCharacter)
- || (options.otherCommentCharacter2 != '\0'
- && c == options.otherCommentCharacter2)) {
-
- // Single line comment, consume to newline or EOF.
-
- do {
- c = eatAndPeekInputChar();
- } while (! isNewline(c) && c != EOF);
-
- // There is whitespace after the comment (in particular, the
- // newline that terminates the comment). There might also be
- // whitespace at the start of the next line.
- whitespaceDone = false;
-
- } else if (options.cComments && (c == '/') && (c2 == '*')) {
-
- // consume both start-comment chars, can't let the trailing one
- // help close the comment.
- eatInputChar();
- eatInputChar();
-
- // Multi-line comment, consume to end-marker or EOF.
- c = peekInputChar();
- c2 = peekInputChar(1);
- while (! ((c == '*') && (c2 == '/')) && (c != EOF)) {
- eatInputChar();
- c = c2;
- c2 = peekInputChar(1);
- }
- eatInputChar(); // eat closing '*'
- eatInputChar(); // eat closing '/'
-
- c = peekInputChar();
-
- // May be whitespace after comment.
- whitespaceDone = false;
- }
-
- } // while (! whitespaceDone)
-
- t._line = lineNumber;
- t._character = charNumber;
-
- // handle EOF
- if (c == EOF) {
- return t;
- }
-
- // Extended ASCII parses as itself, except for EOF
- if (c > 127 && c < 255) {
- t._type = Token::SYMBOL;
- t._extendedType = Token::SYMBOL_TYPE;
- t._string = c;
- c = eatAndPeekInputChar();
- }
-
-
- // Perform appropriate setup for a symbol (including setting up the token
- // string to start with c), eat the input character, and overwrite
- // 'c' with the peeked next input character.
-#define SETUP_SYMBOL(c) \
- { \
- t._type = Token::SYMBOL; \
- t._extendedType = Token::SYMBOL_TYPE; \
- t._string = c; \
- c = eatAndPeekInputChar(); \
- }
-
- switch (c) {
-
- case '@': // Simple symbols -> just themselves.
- case '(':
- case ')':
- case ',':
- case ';':
- case '{':
- case '}':
- case '[':
- case ']':
- case '#':
- case '$':
- case '?':
- case '%':
- SETUP_SYMBOL(c);
- return t;
-
- case '-': // negative number, -, --, -=, or ->
- SETUP_SYMBOL(c);
-
- switch (c) {
- case '>': // ->
- case '-': // --
- case '=': // -=
- t._string += c;
- eatInputChar();
- return t;
- }
-
- if (options.signedNumbers
- && (isDigit(c) || (c == '.' && isDigit(peekInputChar(1))))) {
-
- // Negative number. 'c' is still the first digit, and is
- // the next input char.
-
- goto numLabel;
- }
-
- // plain -
- return t;
-
- case '+': // positive number, +, ++, or +=
- SETUP_SYMBOL(c);
-
- switch (c) {
- case '+': // ++
- case '=': // +=
- t._string += c;
- eatInputChar();
- return t;
- }
-
- if (options.signedNumbers
- && (isDigit(c) || (c == '.' && isDigit(peekInputChar(1))))) {
-
- // Positive number. 'c' is still the first digit, and is
- // the next input char.
-
- goto numLabel;
- }
-
- return t;
-
- case ':': // : or :: or ::> or ::= or := or :>
- SETUP_SYMBOL(c);
-
- if (c == ':') {
- t._string += c;
- eatInputChar();
-
- if (options.proofSymbols) {
- c = peekInputChar(0);
-
- if ((c == '>') || (c == '=')) {
- t._string += c;
- eatInputChar();
- }
- }
- }
- else if (options.proofSymbols && (c == '=' || c == '>')) {
- t._string += c;
- eatInputChar();
- }
- return t;
-
- case '=': // = or == or =>
- SETUP_SYMBOL(c);
-
- if (c == '=') {
- t._string += c;
- eatInputChar();
- return t;
- } else if (options.proofSymbols && (c == '>')) {
- t._string += c;
- eatInputChar();
- return t;
- }
- return t;
-
- case '*': // * or *=
- case '/': // / or /=
- case '!': // ! or !=
- case '~': // ~ or ~=
- case '^': // ^ or ^=
- SETUP_SYMBOL(c);
-
- if (c == '=') {
- t._string += c;
- eatInputChar();
- return t;
- }
- return t;
-
- case '>': // >, >>,or >=
- case '<': // <<, <<, or <= or <- or <:
- case '|': // ||, ||, or |= or |-
- case '&': // &, &&, or &=
- {
- int orig_c = c;
- SETUP_SYMBOL(c);
-
- if ((c == '=') || (orig_c == c)) {
- t._string += c;
- eatInputChar();
- return t;
- } else if (options.proofSymbols) {
- if ((orig_c == '<') && (c == '-')) {
- t._string += c;
- eatInputChar();
- } else if ((orig_c == '|') && (c == '-')) {
- t._string += c;
- eatInputChar();
- } else if ((orig_c == '<') && (c == ':')) {
- t._string += c;
-
- c = eatAndPeekInputChar();
-
- if (c == ':') {
- t._string += c;
- eatInputChar();
- }
- }
- }
- }
- return t;
-
- case '\\': // backslash or escaped comment char.
- SETUP_SYMBOL(c);
-
- if ((options.otherCommentCharacter != '\0'
- && c == options.otherCommentCharacter)
- || (options.otherCommentCharacter2 != '\0'
- && c == options.otherCommentCharacter2)) {
-
- // escaped comment character. Return the raw comment
- // char (no backslash).
-
- t._string = c;
- eatInputChar();
- return t;
- }
- return t;
-
- case '.': // number, ., .., or ...
- if (isDigit(peekInputChar(1))) {
- // We're parsing a float that began without a leading zero
- goto numLabel;
- }
-
- SETUP_SYMBOL(c);
-
- if (c == '.') { // .. or ...
- t._string += c;
- c = eatAndPeekInputChar();
-
- if (c == '.') { // ...
- t._string += c;
- eatInputChar();
- }
- return t;
- }
-
- return t;
-
- } // switch (c)
-
-#undef SETUP_SYMBOL
-
-numLabel:
- if (isDigit(c) || (c == '.')) {
-
- // A number. Note-- single dots have been
- // parsed already, so a . indicates a number
- // less than 1 in floating point form.
-
- // [0-9]*(\.[0-9]) or [0-9]+ or 0x[0-9,A-F]+
-
- if (t._string != "-") {
- // If we picked up a leading "-" sign above, keep it,
- // otherwise drop the string parsed thus far
- t._string = "";
- }
- t._type = Token::NUMBER;
- if (c == '.') {
- t._extendedType = Token::FLOATING_POINT_TYPE;
- } else {
- t._extendedType = Token::INTEGER_TYPE;
- }
-
- if ((c == '0') && (peekInputChar(1) == 'x')) {
- // Hex number
- t._string += "0x";
-
- // skip the 0x
- eatInputChar();
- eatInputChar();
-
- c = peekInputChar();
- while (isDigit(c) || ((c >= 'A') && (c <= 'F')) || ((c >= 'a') && (c <= 'f'))) {
- t._string += c;
- c = eatAndPeekInputChar();
- }
-
- } else {
- // Non-hex number
-
- // Read the part before the decimal.
- while (isDigit(c)) {
- t._string += c;
- c = eatAndPeekInputChar();
- }
-
- // True if we are reading a floating-point special type
- bool isSpecial = false;
-
- // Read the decimal, if one exists
- if (c == '.') {
- t._extendedType = Token::FLOATING_POINT_TYPE;
-
- // The '.' character was a decimal point, not the start of a
- // method or range operator
- t._string += c;
- c = eatAndPeekInputChar();
-
- // Floating point specials (msvc format only)
- if (options.msvcSpecials && (c == '#')) {
- isSpecial = true;
- // We are reading a floating point special value
- // of the form -1.#IND00, -1.#INF00, or 1.#INF00
- c = eatAndPeekInputChar();
- char test = c;
- if (! options.caseSensitive) {
- test = toupper(c);
- }
- if (test != 'I') {
- throw BadMSVCSpecial
- (
- "Incorrect floating-point special (inf or nan) "
- "format.",
- t.line(), charNumber);
- }
- c = eatAndPeekInputChar();
- test = c;
- if (! options.caseSensitive) {
- test = toupper(c);
- }
- if (test != 'N') {
- throw BadMSVCSpecial
- (
- "Incorrect floating-point special (inf or nan) "
- "format.",
- t.line(), charNumber);
- }
- t._string += "#IN";
- c = eatAndPeekInputChar();
- test = c;
- if (! options.caseSensitive) {
- test = toupper(c);
- }
- if ((test != 'F') && (test != 'D')) {
- throw BadMSVCSpecial
- (
- "Incorrect floating-point special (inf or nan) "
- "format.",
- t.line(), charNumber);
- }
- t._string += c;
- for (int j = 0; j < 2; ++j) {
- c = eatAndPeekInputChar();
- if (c != '0') {
- throw BadMSVCSpecial
- (
- "Incorrect floating-point special (inf or"
- "nan) format.",
- t.line(), charNumber);
- }
- t._string += (char)c;
- }
-
- } else {
-
- // Read the part after the decimal
- while (isDigit((char)c)) {
- t._string += (char)c;
- c = eatAndPeekInputChar();
- }
- }
- }
-
- if (! isSpecial && ((c == 'e') || (c == 'E'))) {
- // Read exponent
- t._extendedType = Token::FLOATING_POINT_TYPE;
- t._string += c;
-
- c = eatAndPeekInputChar();
- if ((c == '-') || (c == '+')) {
- t._string += c;
- c = eatAndPeekInputChar();
- }
-
- while (isDigit(c)) {
- t._string += c;
- c = eatAndPeekInputChar();
- }
- }
- }
- return t;
-
- } else if (isLetter(c) || (c == '_')) {
- // Identifier or keyword
- // [A-Za-z_][A-Za-z_0-9]*
-
- t._type = Token::SYMBOL;
- t._extendedType = Token::SYMBOL_TYPE;
- t._string = "";
- do {
- t._string += c;
- c = eatAndPeekInputChar();
- } while (isLetter(c) || isDigit(c) || (c == '_'));
-
- // See if this symbol is actually a boolean
- if ((options.trueSymbols.size() > 0) || (options.falseSymbols.size() > 0)) {
- std::string str = t._string;
- if (! options.caseSensitive) {
- str = toUpper(str);
- }
- if (options.trueSymbols.contains(str)) {
- t._type = Token::BOOLEAN;
- t._extendedType = Token::BOOLEAN_TYPE;
- t._bool = true;
- } else if (options.falseSymbols.contains(str)) {
- t._type = Token::BOOLEAN;
- t._extendedType = Token::BOOLEAN_TYPE;
- t._bool = false;
- }
- }
-
- return t;
-
- } else if (c == '\"') {
-
- // Discard the double-quote.
- eatInputChar();
-
- // Double quoted string
- parseQuotedString('\"', t);
- return t;
-
- } else if (c == '\'') {
-
- // Discard the single-quote.
- eatInputChar();
-
- if (options.singleQuotedStrings) {
- // Single quoted string
- parseQuotedString('\'', t);
- } else {
- t._string = c;
- t._type = Token::SYMBOL;
- t._extendedType = Token::SYMBOL_TYPE;
- }
- return t;
-
- } // end of special case tokens
-
- if (c == EOF) {
- t._type = Token::END;
- t._extendedType = Token::END_TYPE;
- t._string = "";
- return t;
- }
-
- // Some unknown token
- debugAssertM(false,
- format("Unrecognized token type beginning with character '%c' (ASCII %d)",
- c, c));
- return t;
-}
-
-
-void TextInput::parseQuotedString(unsigned char delimiter, Token& t) {
-
- t._type = Token::STRING;
-
- if (delimiter == '\'') {
- t._extendedType = Token::SINGLE_QUOTED_TYPE;
- } else {
- t._extendedType = Token::DOUBLE_QUOTED_TYPE;
- }
-
- while (true) {
- // We're definitely going to consume the next input char, so we get
- // it right now. This makes the condition handling below a bit easier.
- int c = eatInputChar();
-
- if (c == EOF) {
- // END inside a quoted string. (We finish the string.)
- break;
- }
-
- if (options.escapeSequencesInStrings && (c == '\\')) {
- // An escaped character. We're definitely going to consume it,
- // so we get it (and consume it) now.
-
- c = eatInputChar();
-
- switch (c) {
- case 'r':
- t._string += '\r';
- break;
- case 'n':
- t._string += '\n';
- break;
- case 't':
- t._string += '\t';
- break;
- case '0':
- t._string += '\0';
- break;
-
- case '\\':
- case '\"':
- case '\'':
- t._string += (char)c;
- break;
-
- default:
- if (((c == options.otherCommentCharacter) &&
- (options.otherCommentCharacter != '\0')) ||
- ((c == options.otherCommentCharacter2) &&
- (options.otherCommentCharacter2 != '\0'))) {
- t._string += c;
- }
- // otherwise, some illegal escape sequence; skip it.
- break;
-
- } // switch
-
- } else if (c == delimiter) {
- // End of the string. Already consumed the character.
- break;
- } else {
- // All other chars, go on to the string. Already consumed the
- // character.
- t._string += (char)c;
- }
-
- }
-}
-
-bool TextInput::readBoolean() {
- Token t(read());
-
- if (t._type == Token::BOOLEAN) {
- return t.boolean();
- }
-
- // Push initial token back, and throw an error. We intentionally
- // indicate that the wrong type is the type of the initial token.
- // Logically, the number started there.
- push(t);
- throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
- Token::BOOLEAN, t._type);
-}
-
-double TextInput::readNumber() {
- Token t(read());
-
- if (t._type == Token::NUMBER) {
- return t.number();
- }
-
- // Even if signedNumbers is disabled, readNumber attempts to
- // read a signed number, so we handle that case here.
- if (! options.signedNumbers
- && (t._type == Token::SYMBOL)
- && ((t._string == "-")
- || (t._string == "+"))) {
-
- Token t2(read());
-
- if ((t2._type == Token::NUMBER)
- && (t2._character == t._character + 1)) {
-
- if (t._string == "-") {
- return -t2.number();
- } else {
- return t2.number();
- }
- }
-
- // push back the second token.
- push(t2);
- }
-
- // Push initial token back, and throw an error. We intentionally
- // indicate that the wrong type is the type of the initial token.
- // Logically, the number started there.
- push(t);
- throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
- Token::NUMBER, t._type);
-}
-
-
-Token TextInput::readStringToken() {
- Token t(read());
-
- if (t._type == Token::STRING) { // fast path
- return t;
- }
-
- push(t);
- throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
- Token::STRING, t._type);
-}
-
-std::string TextInput::readString() {
- return readStringToken()._string;
-}
-
-void TextInput::readString(const std::string& s) {
- Token t(readStringToken());
-
- if (t._string == s) { // fast path
- return;
- }
-
- push(t);
- throw WrongString(options.sourceFileName, t.line(), t.character(),
- s, t._string);
-}
-
-
-Token TextInput::readSymbolToken() {
- Token t(read());
-
- if (t._type == Token::SYMBOL) { // fast path
- return t;
- }
-
- push(t);
- throw WrongTokenType(options.sourceFileName, t.line(), t.character(),
- Token::SYMBOL, t._type);
-}
-
-
-std::string TextInput::readSymbol() {
- return readSymbolToken()._string;
-}
-
-void TextInput::readSymbol(const std::string& symbol) {
- Token t(readSymbolToken());
-
- if (t._string == symbol) { // fast path
- return;
- }
-
- push(t);
- throw WrongSymbol(options.sourceFileName, t.line(), t.character(),
- symbol, t._string);
-}
-
-
-TextInput::TextInput(const std::string& filename, const Settings& opt) : options(opt) {
- init();
- std::string input = readWholeFile(filename);
-
- if (options.sourceFileName.empty()) {
- options.sourceFileName = filename;
- }
- int n = input.size();
- buffer.resize(n);
- System::memcpy(buffer.getCArray(), input.c_str(), n);
-}
-
-
-TextInput::TextInput(FS fs, const std::string& str, const Settings& opt) : options(opt) {
- (void)fs;
- init();
- if (options.sourceFileName.empty()) {
- if (str.length() < 14) {
- options.sourceFileName = std::string("\"") + str + "\"";
- } else {
- options.sourceFileName = std::string("\"") + str.substr(0, 10) + "...\"";
- }
- }
- buffer.resize(str.length()); // we don't bother copying trailing NUL.
- System::memcpy(buffer.getCArray(), str.c_str(), buffer.size());
-}
-
-
-const std::string& TextInput::filename() const {
- return options.sourceFileName;
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-
-TextInput::TokenException::TokenException(
- const std::string& src,
- int ln,
- int ch) : sourceFile(src), line(ln), character(ch) {
-
- message = format("%s(%d) : ", sourceFile.c_str(), line);
-}
-
-///////////////////////////////////////////////////////////////////////////////////
-
-static const char* tokenTypeToString(Token::Type t) {
- switch (t) {
- case Token::SYMBOL:
- return "Token::SYMBOL";
- case Token::STRING:
- return "Token::STRING";
- case Token::NUMBER:
- return "Token::NUMBER";
- case Token::END:
- return "Token::END";
- default:
- debugAssertM(false, "Fell through switch");
- return "?";
- }
-}
-
-TextInput::WrongTokenType::WrongTokenType(
- const std::string& src,
- int ln,
- int ch,
- Token::Type e,
- Token::Type a) :
- TokenException(src, ln, ch), expected(e), actual(a) {
-
- message += format("Expected token of type %s, found type %s.",
- tokenTypeToString(e), tokenTypeToString(a));
-}
-
-
-TextInput::BadMSVCSpecial::BadMSVCSpecial(
- const std::string& src,
- int ln,
- int ch) :
- TokenException(src, ln, ch) {
-}
-
-
-TextInput::WrongSymbol::WrongSymbol(
- const std::string& src,
- int ln,
- int ch,
- const std::string& e,
- const std::string& a) :
- TokenException(src, ln, ch), expected(e), actual(a) {
-
- message += format("Expected symbol '%s', found symbol '%s'.",
- e.c_str(), a.c_str());
-}
-
-
-TextInput::WrongString::WrongString(
- const std::string& src,
- int ln,
- int ch,
- const std::string& e,
- const std::string& a) :
- TokenException(src, ln, ch), expected(e), actual(a) {
-
- message += format("Expected string '%s', found string '%s'.",
- e.c_str(), a.c_str());
-}
-
-
-void deserialize(bool& b, TextInput& ti) {
- b = ti.readSymbol() == "true";
-}
-
-
-void deserialize(int& b, TextInput& ti) {
- b = iRound(ti.readNumber());
-}
-
-
-void deserialize(uint8& b, TextInput& ti) {
- b = (uint8)iRound(ti.readNumber());
-}
-
-
-void deserialize(double& b, TextInput& ti) {
- b = ti.readNumber();
-}
-
-
-void deserialize(float& b, TextInput& ti) {
- b = (float)ti.readNumber();
-}
-
-} // namespace
-
-#ifdef _MSC_VER
-# pragma warning (pop)
-#endif
diff --git a/externals/g3dlite/G3D.lib/source/TextOutput.cpp b/externals/g3dlite/G3D.lib/source/TextOutput.cpp
deleted file mode 100644
index f7a40d9798b..00000000000
--- a/externals/g3dlite/G3D.lib/source/TextOutput.cpp
+++ /dev/null
@@ -1,452 +0,0 @@
-/**
- @file TextOutput.cpp
-
- @maintainer Morgan McGuire, morgan@graphics3d.com
- @created 2004-06-21
- @edited 2006-08-14
-
- Copyright 2000-2006, Morgan McGuire.
- All rights reserved.
- */
-
-#include "G3D/TextOutput.h"
-#include "G3D/Log.h"
-#include "G3D/fileutils.h"
-
-namespace G3D {
-
-TextOutput::TextOutput(const TextOutput::Settings& opt) :
- startingNewLine(true),
- currentColumn(0),
- inDQuote(false),
- filename(""),
- indentLevel(0)
-{
- setOptions(opt);
-}
-
-
-TextOutput::TextOutput(const std::string& fil, const TextOutput::Settings& opt) :
- startingNewLine(true),
- currentColumn(0),
- inDQuote(false),
- filename(fil),
- indentLevel(0)
-{
-
- setOptions(opt);
-}
-
-
-void TextOutput::setIndentLevel(int i) {
- indentLevel = i;
-
- // If there were more pops than pushes, don't let that take us below 0 indent.
- // Don't ever indent more than the number of columns.
- indentSpaces =
- iClamp(option.spacesPerIndent * indentLevel,
- 0,
- option.numColumns - 1);
-}
-
-
-void TextOutput::setOptions(const Settings& _opt) {
- option = _opt;
-
- debugAssert(option.numColumns > 1);
-
- setIndentLevel(indentLevel);
-
- newline = (option.newlineStyle == Settings::NEWLINE_WINDOWS) ? "\r\n" : "\n";
-}
-
-
-void TextOutput::pushIndent() {
- setIndentLevel(indentLevel + 1);
-}
-
-
-void TextOutput::popIndent() {
- setIndentLevel(indentLevel - 1);
-}
-
-
-static std::string escape(const std::string& string) {
- std::string result = "";
-
- for (std::string::size_type i = 0; i < string.length(); ++i) {
- char c = string.at(i);
- switch (c) {
- case '\0':
- result += "\\0";
- break;
-
- case '\r':
- result += "\\r";
- break;
-
- case '\n':
- result += "\\n";
- break;
-
- case '\t':
- result += "\\t";
- break;
-
- case '\\':
- result += "\\\\";
- break;
-
- default:
- result += c;
- }
- }
-
- return result;
-}
-
-void TextOutput::writeString(const std::string& string) {
- // Convert special characters to escape sequences
- this->printf("\"%s\"", escape(string).c_str());
-}
-
-
-void TextOutput::writeBoolean(bool b) {
- this->printf("%s ", b ? option.trueSymbol.c_str() : option.falseSymbol.c_str());
-}
-
-void TextOutput::writeNumber(double n) {
- this->printf("%f ", n);
-}
-
-
-void TextOutput::writeNumber(int n) {
- this->printf("%d ", n);
-}
-
-
-void TextOutput::writeSymbol(const std::string& string) {
- if (string.size() > 0) {
- // TODO: check for legal symbols?
- this->printf("%s ", string.c_str());
- }
-}
-
-void TextOutput::writeSymbols(
- const std::string& a,
- const std::string& b,
- const std::string& c,
- const std::string& d,
- const std::string& e,
- const std::string& f) {
-
- writeSymbol(a);
- writeSymbol(b);
- writeSymbol(c);
- writeSymbol(d);
- writeSymbol(e);
- writeSymbol(f);
-}
-
-
-void TextOutput::printf(const std::string formatString, ...) {
- va_list argList;
- va_start(argList, formatString);
- this->vprintf(formatString.c_str(), argList);
- va_end(argList);
-}
-
-
-void TextOutput::printf(const char* formatString, ...) {
- va_list argList;
- va_start(argList, formatString);
- this->vprintf(formatString, argList);
- va_end(argList);
-}
-
-
-void TextOutput::convertNewlines(const std::string& in, std::string& out) {
- // TODO: can be significantly optimized in cases where
- // single characters are copied in order by walking through
- // the array and copying substrings as needed.
-
- if (option.convertNewlines) {
- out = "";
- for (uint32 i = 0; i < in.size(); ++i) {
- if (in[i] == '\n') {
- // Unix newline
- out += newline;
- } else if ((in[i] == '\r') && (i + 1 < in.size()) && (in[i + 1] == '\n')) {
- // Windows newline
- out += newline;
- ++i;
- } else {
- out += in[i];
- }
- }
- } else {
- out = in;
- }
-}
-
-
-void TextOutput::writeNewline() {
- for (uint32 i = 0; i < newline.size(); ++i) {
- indentAppend(newline[i]);
- }
-}
-
-
-void TextOutput::writeNewlines(int numLines) {
- for (int i = 0; i < numLines; ++i) {
- writeNewline();
- }
-}
-
-
-void TextOutput::wordWrapIndentAppend(const std::string& str) {
- // TODO: keep track of the last space character we saw so we don't
- // have to always search.
-
- if ((option.wordWrap == Settings::WRAP_NONE) ||
- (currentColumn + (int)str.size() <= option.numColumns)) {
- // No word-wrapping is needed
-
- // Add one character at a time.
- // TODO: optimize for strings without newlines to add multiple
- // characters.
- for (uint32 i = 0; i < str.size(); ++i) {
- indentAppend(str[i]);
- }
- return;
- }
-
- // Number of columns to wrap against
- int cols = option.numColumns - indentSpaces;
-
- // Copy forward until we exceed the column size,
- // and then back up and try to insert newlines as needed.
- for (uint32 i = 0; i < str.size(); ++i) {
-
- indentAppend(str[i]);
- if ((str[i] == '\r') && (i + 1 < str.size()) && (str[i + 1] == '\n')) {
- // \r\n, we need to hit the \n to enter word wrapping.
- ++i;
- indentAppend(str[i]);
- }
-
- if (currentColumn >= cols) {
- debugAssertM(str[i] != '\n' && str[i] != '\r',
- "Should never enter word-wrapping on a newline character");
-
- // True when we're allowed to treat a space as a space.
- bool unquotedSpace = option.allowWordWrapInsideDoubleQuotes || ! inDQuote;
-
- // Cases:
- //
- // 1. Currently in a series of spaces that ends with a newline
- // strip all spaces and let the newline
- // flow through.
- //
- // 2. Currently in a series of spaces that does not end with a newline
- // strip all spaces and replace them with single newline
- //
- // 3. Not in a series of spaces
- // search backwards for a space, then execute case 2.
-
- // Index of most recent space
- uint32 lastSpace = data.size() - 1;
-
- // How far back we had to look for a space
- uint32 k = 0;
- uint32 maxLookBackward = currentColumn - indentSpaces;
-
- // Search backwards (from current character), looking for a space.
- while ((k < maxLookBackward) &&
- (lastSpace > 0) &&
- (! ((data[lastSpace] == ' ') && unquotedSpace))) {
- --lastSpace;
- ++k;
-
- if ((data[lastSpace] == '\"') && !option.allowWordWrapInsideDoubleQuotes) {
- unquotedSpace = ! unquotedSpace;
- }
- }
-
- if (k == maxLookBackward) {
- // We couldn't find a series of spaces
-
- if (option.wordWrap == Settings::WRAP_ALWAYS) {
- // Strip the last character we wrote, force a newline,
- // and replace the last character;
- data.pop();
- writeNewline();
- indentAppend(str[i]);
- } else {
- // Must be Settings::WRAP_WITHOUT_BREAKING
- //
- // Don't write the newline; we'll come back to
- // the word wrap code after writing another character
- }
- } else {
- // We found a series of spaces. If they continue
- // to the new string, strip spaces off both. Otherwise
- // strip spaces from data only and insert a newline.
-
- // Find the start of the spaces. firstSpace is the index of the
- // first non-space, looking backwards from lastSpace.
- uint32 firstSpace = lastSpace;
- while ((k < maxLookBackward) &&
- (firstSpace > 0) &&
- (data[firstSpace] == ' ')) {
- --firstSpace;
- ++k;
- }
-
- if (k == maxLookBackward) {
- ++firstSpace;
- }
-
- if (lastSpace == (uint32)data.size() - 1) {
- // Spaces continued up to the new string
- data.resize(firstSpace + 1);
- writeNewline();
-
- // Delete the spaces from the new string
- while ((i < str.size() - 1) && (str[i + 1] == ' ')) {
- ++i;
- }
- } else {
- // Spaces were somewhere in the middle of the old string.
- // replace them with a newline.
-
- // Copy over the characters that should be saved
- Array<char> temp;
- for (uint32 j = lastSpace + 1; j < (uint32)data.size(); ++j) {
- char c = data[j];
-
- if (c == '\"') {
- // Undo changes to quoting (they will be re-done
- // when we paste these characters back on).
- inDQuote = !inDQuote;
- }
- temp.append(c);
- }
-
- // Remove those characters and replace with a newline.
- data.resize(firstSpace + 1);
- writeNewline();
-
- // Write them back
- for (uint32 j = 0; j < (uint32)temp.size(); ++j) {
- indentAppend(temp[j]);
- }
-
- // We are now free to continue adding from the
- // new string, which may or may not begin with spaces.
-
- } // if spaces included new string
- } // if hit indent
- } // if line exceeded
- } // iterate over str
-}
-
-
-void TextOutput::indentAppend(char c) {
-
- if (startingNewLine) {
- for (int j = 0; j < indentSpaces; ++j) {
- data.push(' ');
- }
- startingNewLine = false;
- currentColumn = indentSpaces;
- }
-
- data.push(c);
-
- // Don't increment the column count on return character
- // newline is taken care of below.
- if (c != '\r') {
- ++currentColumn;
- }
-
- if (c == '\"') {
- inDQuote = ! inDQuote;
- }
-
- startingNewLine = (c == '\n');
- if (startingNewLine) {
- currentColumn = 0;
- }
-}
-
-
-void TextOutput::vprintf(const char* formatString, va_list argPtr) {
- std::string str = vformat(formatString, argPtr);
-
- std::string clean;
- convertNewlines(str, clean);
- wordWrapIndentAppend(clean);
-}
-
-
-void TextOutput::commit(bool flush) {
- std::string p = filenamePath(filename);
- if (! fileExists(p, false)) {
- createDirectory(p);
- }
-
- FILE* f = fopen(filename.c_str(), "wb");
- debugAssert(f);
- fwrite(data.getCArray(), 1, data.size(), f);
- if (flush) {
- fflush(f);
- }
- fclose(f);
-}
-
-
-void TextOutput::commitString(std::string& out) {
- // Null terminate
- data.push('\0');
- out = data.getCArray();
- data.pop();
-}
-
-
-std::string TextOutput::commitString() {
- std::string str;
- commitString(str);
- return str;
-}
-
-
-
-/////////////////////////////////////////////////////////////////////
-
-void serialize(const float& b, TextOutput& to) {
- to.writeNumber(b);
-}
-
-
-void serialize(const bool& b, TextOutput& to) {
- to.writeSymbol(b ? "true" : "false");
-}
-
-
-void serialize(const int& b, TextOutput& to) {
- to.writeNumber(b);
-}
-
-
-void serialize(const uint8& b, TextOutput& to) {
- to.writeNumber(b);
-}
-
-
-void serialize(const double& b, TextOutput& to) {
- to.writeNumber(b);
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/ThreadSet.cpp b/externals/g3dlite/G3D.lib/source/ThreadSet.cpp
deleted file mode 100644
index 59060892247..00000000000
--- a/externals/g3dlite/G3D.lib/source/ThreadSet.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-#include "G3D/ThreadSet.h"
-
-namespace G3D {
-
-int ThreadSet::size() const {
- ThreadSet* me = const_cast<ThreadSet*>(this);
- me->m_lock.lock();
- int s = m_thread.size();
- me->m_lock.unlock();
- return s;
-}
-
-
-int ThreadSet::numStarted() const {
- ThreadSet* me = const_cast<ThreadSet*>(this);
- me->m_lock.lock();
- int count = 0;
- for (int i = 0; i < m_thread.size(); ++i) {
- if (m_thread[i]->started()) {
- ++count;
- }
- }
- me->m_lock.unlock();
- return count;
-}
-
-
-void ThreadSet::start() const {
- ThreadSet* me = const_cast<ThreadSet*>(this);
- me->m_lock.lock();
- for (int i = 0; i < m_thread.size(); ++i) {
- if (! m_thread[i]->started()) {
- m_thread[i]->start();
- }
- }
- me->m_lock.unlock();
-}
-
-
-void ThreadSet::terminate() const {
- ThreadSet* me = const_cast<ThreadSet*>(this);
- me->m_lock.lock();
- for (int i = 0; i < m_thread.size(); ++i) {
- if (m_thread[i]->started()) {
- m_thread[i]->terminate();
- }
- }
- me->m_lock.unlock();
-}
-
-
-void ThreadSet::waitForCompletion() const {
- ThreadSet* me = const_cast<ThreadSet*>(this);
- me->m_lock.lock();
- for (int i = 0; i < m_thread.size(); ++i) {
- if (m_thread[i]->started()) {
- m_thread[i]->waitForCompletion();
- }
- }
- me->m_lock.unlock();
-}
-
-
-int ThreadSet::removeCompleted() {
- m_lock.lock();
- for (int i = 0; i < m_thread.size(); ++i) {
- if (m_thread[i]->completed()) {
- m_thread.fastRemove(i);
- --i;
- }
- }
-
- int s = m_thread.size();
- m_lock.unlock();
- return s;
-}
-
-
-void ThreadSet::clear() {
- m_lock.lock();
- m_thread.clear();
- m_lock.unlock();
-}
-
-
-int ThreadSet::insert(const ThreadRef& t) {
- m_lock.lock();
- bool found = false;
- for (int i = 0; i < m_thread.size() && ! found; ++i) {
- found = (m_thread[i] == t);
- }
- if (! found) {
- m_thread.append(t);
- }
- int s = m_thread.size();
- m_lock.unlock();
- return s;
-}
-
-
-bool ThreadSet::remove(const ThreadRef& t) {
- m_lock.lock();
- bool found = false;
- for (int i = 0; i < m_thread.size() && ! found; ++i) {
- found = (m_thread[i] == t);
- if (found) {
- m_thread.fastRemove(i);
- }
- }
- m_lock.unlock();
- return found;
-}
-
-
-bool ThreadSet::contains(const ThreadRef& t) const {
- ThreadSet* me = const_cast<ThreadSet*>(this);
- me->m_lock.lock();
- bool found = false;
- for (int i = 0; i < m_thread.size() && ! found; ++i) {
- found = (m_thread[i] == t);
- }
- me->m_lock.unlock();
- return found;
-}
-
-
-ThreadSet::Iterator ThreadSet::begin() {
- return m_thread.begin();
-}
-
-
-ThreadSet::Iterator ThreadSet::end() {
- return m_thread.end();
-}
-
-
-ThreadSet::ConstIterator ThreadSet::begin() const {
- return m_thread.begin();
-}
-
-
-ThreadSet::ConstIterator ThreadSet::end() const {
- return m_thread.end();
-}
-
-
-} // namespace G3D
diff --git a/externals/g3dlite/G3D.lib/source/Triangle.cpp b/externals/g3dlite/G3D.lib/source/Triangle.cpp
deleted file mode 100644
index ad264b1f72a..00000000000
--- a/externals/g3dlite/G3D.lib/source/Triangle.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- @file Triangle.cpp
-
- @maintainer Morgan McGuire, graphics3d.com
-
- @created 2001-04-06
- @edited 2006-01-20
-
- Copyright 2000-2006, Morgan McGuire.
- All rights reserved.
- */
-
-#include "G3D/platform.h"
-#include "G3D/Triangle.h"
-#include "G3D/Plane.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/debugAssert.h"
-#include "G3D/AABox.h"
-
-namespace G3D {
-
-
-void Triangle::init(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
-
- _plane = Plane(v0, v1, v2);
- _vertex[0] = v0;
- _vertex[1] = v1;
- _vertex[2] = v2;
-
- static int next[] = {1,2,0};
-
- for (int i = 0; i < 3; ++i) {
- const Vector3& e = _vertex[next[i]] - _vertex[i];
- edgeMagnitude[i] = e.magnitude();
-
- if (edgeMagnitude[i] == 0) {
- edgeDirection[i] = Vector3::zero();
- } else {
- edgeDirection[i] = e / (float)edgeMagnitude[i];
- }
- }
-
- _edge01 = _vertex[1] - _vertex[0];
- _edge02 = _vertex[2] - _vertex[0];
-
- _primaryAxis = _plane.normal().primaryAxis();
- _area = 0.5f * edgeDirection[0].cross(edgeDirection[2]).magnitude() * (edgeMagnitude[0] * edgeMagnitude[2]);
- //0.5f * (_vertex[1] - _vertex[0]).cross(_vertex[2] - _vertex[0]).dot(_plane.normal());
-}
-
-
-Triangle::Triangle() {
- init(Vector3::zero(), Vector3::zero(), Vector3::zero());
-}
-
-
-Triangle::Triangle(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
- init(v0, v1, v2);
-}
-
-
-Triangle::~Triangle() {
-}
-
-
-Triangle::Triangle(class BinaryInput& b) {
- deserialize(b);
-}
-
-
-void Triangle::serialize(class BinaryOutput& b) {
- _vertex[0].serialize(b);
- _vertex[1].serialize(b);
- _vertex[2].serialize(b);
-}
-
-
-void Triangle::deserialize(class BinaryInput& b) {
- _vertex[0].deserialize(b);
- _vertex[1].deserialize(b);
- _vertex[2].deserialize(b);
- init(_vertex[0], _vertex[1], _vertex[2]);
-}
-
-
-float Triangle::area() const {
- return _area;
-}
-
-
-const Vector3& Triangle::normal() const {
- return _plane.normal();
-}
-
-
-const Plane& Triangle::plane() const {
- return _plane;
-}
-
-
-Vector3 Triangle::center() const {
- return (_vertex[0] + _vertex[1] + _vertex[2]) / 3.0;
-}
-
-Vector3 Triangle::randomPoint() const {
- // Choose a random point in the parallelogram
-
- float s = uniformRandom();
- float t = uniformRandom();
-
- if (t > 1.0f - s) {
- // Outside the triangle; reflect about the
- // diagonal of the parallelogram
- t = 1.0f - t;
- s = 1.0f - s;
- }
-
- return _edge01 * s + _edge02 * t + _vertex[0];
-}
-
-
-void Triangle::getBounds(AABox& out) const {
- Vector3 lo = _vertex[0];
- Vector3 hi = lo;
-
- for (int i = 1; i < 3; ++i) {
- lo = lo.min(_vertex[i]);
- hi = hi.max(_vertex[i]);
- }
-
- out = AABox(lo, hi);
-}
-
-} // G3D
diff --git a/externals/g3dlite/G3D.lib/source/UprightFrame.cpp b/externals/g3dlite/G3D.lib/source/UprightFrame.cpp
deleted file mode 100644
index 78b2c0bb0bb..00000000000
--- a/externals/g3dlite/G3D.lib/source/UprightFrame.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- @file UprightFrame.cpp
- Box class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-05-02
- @edited 2007-05-05
-*/
-
-#include "G3D/UprightFrame.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-UprightFrame::UprightFrame(const CoordinateFrame& cframe) {
- Vector3 look = cframe.lookVector();
-
- yaw = G3D::pi() + atan2(look.x, look.z);
- pitch = asin(look.y);
-
- translation = cframe.translation;
-}
-
-
-CoordinateFrame UprightFrame::toCoordinateFrame() const {
- CoordinateFrame cframe;
-
- Matrix3 P(Matrix3::fromAxisAngle(Vector3::unitX(), pitch));
- Matrix3 Y(Matrix3::fromAxisAngle(Vector3::unitY(), yaw));
-
- cframe.rotation = Y * P;
- cframe.translation = translation;
-
- return cframe;
-}
-
-
-UprightFrame UprightFrame::operator+(const UprightFrame& other) const {
- return UprightFrame(translation + other.translation, pitch + other.pitch, yaw + other.yaw);
-}
-
-
-UprightFrame UprightFrame::operator*(const float k) const {
- return UprightFrame(translation * k, pitch * k, yaw * k);
-}
-
-
-void UprightFrame::unwrapYaw(UprightFrame* a, int N) {
- // Use the first point to establish the wrapping convention
- for (int i = 1; i < N; ++i) {
- const float prev = a[i - 1].yaw;
- float& cur = a[i].yaw;
-
- // No two angles should be more than pi (i.e., 180-degrees) apart.
- if (abs(cur - prev) > G3D::pi()) {
- // These angles must have wrapped at zero, causing them
- // to be interpolated the long way.
-
- // Find canonical [0, 2pi] versions of these numbers
- float p = wrap(prev, twoPi());
- float c = wrap(cur, twoPi());
-
- // Find the difference -pi < diff < pi between the current and previous values
- float diff = c - p;
- if (diff < -G3D::pi()) {
- diff += twoPi();
- } else if (diff > G3D::pi()) {
- diff -= twoPi();
- }
-
- // Offset the current from the previous by the difference
- // between them.
- cur = prev + diff;
- }
- }
-}
-
-
-void UprightFrame::serialize(class BinaryOutput& b) const {
- translation.serialize(b);
- b.writeFloat32(pitch);
- b.writeFloat32(yaw);
-}
-
-
-void UprightFrame::deserialize(class BinaryInput& b) {
- translation.deserialize(b);
- pitch = b.readFloat32();
- yaw = b.readFloat32();
-}
-
-
-void UprightSpline::serialize(class BinaryOutput& b) const {
- b.writeBool8(cyclic);
-
- b.writeInt32(control.size());
- for (int i = 0; i < control.size(); ++i) {
- control[i].serialize(b);
- }
- b.writeInt32(time.size());
- for (int i = 0; i < time.size(); ++i) {
- b.writeFloat32(time[i]);
- }
-}
-
-
-void UprightSpline::deserialize(class BinaryInput& b) {
- cyclic = b.readBool8();
-
- control.resize(b.readInt32());
- for (int i = 0; i < control.size(); ++i) {
- control[i].deserialize(b);
- }
-
- if (b.hasMore()) {
- time.resize(b.readInt32());
- for (int i = 0; i < time.size(); ++i) {
- time[i] = b.readFloat32();
- }
- debugAssert(time.size() == control.size());
- } else {
- // Import legacy path
- time.resize(control.size());
- for (int i = 0; i < time.size(); ++i) {
- time[i] = i;
- }
- }
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Vector2.cpp b/externals/g3dlite/G3D.lib/source/Vector2.cpp
deleted file mode 100644
index 6b7f96a764e..00000000000
--- a/externals/g3dlite/G3D.lib/source/Vector2.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- @file Vector2.cpp
-
- 2D vector class, used for texture coordinates primarily.
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @cite Portions based on Dave Eberly'x Magic Software Library
- at http://www.magic-software.com
-
- @created 2001-06-02
- @edited 2006-01-16
- */
-
-#include "G3D/platform.h"
-#include <stdlib.h>
-#include "G3D/Vector2.h"
-#include "G3D/g3dmath.h"
-#include "G3D/format.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/TextInput.h"
-#include "G3D/TextOutput.h"
-
-namespace G3D {
-
-const Vector2& Vector2::zero() {
- static Vector2 v(0, 0);
- return v;
-}
-
-const Vector2& Vector2::unitX() {
- static Vector2 v(1, 0);
- return v;
-}
-
-const Vector2& Vector2::unitY() {
- static Vector2 v(0, 1);
- return v;
-}
-
-const Vector2& Vector2::inf() {
- static Vector2 v((float)G3D::inf(), (float)G3D::inf());
- return v;
-}
-
-
-const Vector2& Vector2::nan() {
- static Vector2 v((float)G3D::nan(), (float)G3D::nan());
- return v;
-}
-
-
-const Vector2& Vector2::minFinite() {
- static Vector2 v(-FLT_MAX, -FLT_MAX);
- return v;
-}
-
-
-const Vector2& Vector2::maxFinite() {
- static Vector2 v(FLT_MAX, FLT_MAX);
- return v;
-}
-
-
-size_t Vector2::hashCode() const {
- unsigned int xhash = (*(int*)(void*)(&x));
- unsigned int yhash = (*(int*)(void*)(&y));
-
- return xhash + (yhash * 37);
-}
-
-
-Vector2::Vector2(BinaryInput& b) {
- deserialize(b);
-}
-
-
-void Vector2::deserialize(BinaryInput& b) {
- x = b.readFloat32();
- y = b.readFloat32();
-}
-
-
-void Vector2::serialize(BinaryOutput& b) const {
- b.writeFloat32(x);
- b.writeFloat32(y);
-}
-
-
-void Vector2::deserialize(TextInput& t) {
- t.readSymbol("(");
- x = (float)t.readNumber();
- t.readSymbol(",");
- y = (float)t.readNumber();
- t.readSymbol(")");
-}
-
-
-void Vector2::serialize(TextOutput& t) const {
- t.writeSymbol("(");
- t.writeNumber(x);
- t.writeSymbol(",");
- t.writeNumber(y);
- t.writeSymbol(")");
-}
-
-//----------------------------------------------------------------------------
-
-Vector2 Vector2::random() {
- Vector2 result;
-
- do {
- result = Vector2(uniformRandom(-1, 1), uniformRandom(-1, 1));
-
- } while (result.squaredLength() >= 1.0f);
-
- result.unitize();
-
- return result;
-}
-
-//----------------------------------------------------------------------------
-Vector2 Vector2::operator/ (float fScalar) const {
- Vector2 kQuot;
-
- if ( fScalar != 0.0f ) {
- float fInvScalar = 1.0f / fScalar;
- kQuot.x = fInvScalar * x;
- kQuot.y = fInvScalar * y;
- return kQuot;
- } else {
- return Vector2::inf();
- }
-}
-
-//----------------------------------------------------------------------------
-Vector2& Vector2::operator/= (float fScalar) {
- if (fScalar != 0.0f) {
- float fInvScalar = 1.0f / fScalar;
- x *= fInvScalar;
- y *= fInvScalar;
- } else {
- x = (float)G3D::inf();
- y = (float)G3D::inf();
- }
-
- return *this;
-}
-
-//----------------------------------------------------------------------------
-float Vector2::unitize (float fTolerance) {
- float fLength = length();
-
- if (fLength > fTolerance) {
- float fInvLength = 1.0f / fLength;
- x *= fInvLength;
- y *= fInvLength;
- } else {
- fLength = 0.0;
- }
-
- return fLength;
-}
-
-//----------------------------------------------------------------------------
-
-std::string Vector2::toString() const {
- return G3D::format("(%g, %g)", x, y);
-}
-
-// 2-char swizzles
-
-Vector2 Vector2::xx() const { return Vector2 (x, x); }
-Vector2 Vector2::yx() const { return Vector2 (y, x); }
-Vector2 Vector2::xy() const { return Vector2 (x, y); }
-Vector2 Vector2::yy() const { return Vector2 (y, y); }
-
-// 3-char swizzles
-
-Vector3 Vector2::xxx() const { return Vector3 (x, x, x); }
-Vector3 Vector2::yxx() const { return Vector3 (y, x, x); }
-Vector3 Vector2::xyx() const { return Vector3 (x, y, x); }
-Vector3 Vector2::yyx() const { return Vector3 (y, y, x); }
-Vector3 Vector2::xxy() const { return Vector3 (x, x, y); }
-Vector3 Vector2::yxy() const { return Vector3 (y, x, y); }
-Vector3 Vector2::xyy() const { return Vector3 (x, y, y); }
-Vector3 Vector2::yyy() const { return Vector3 (y, y, y); }
-
-// 4-char swizzles
-
-Vector4 Vector2::xxxx() const { return Vector4 (x, x, x, x); }
-Vector4 Vector2::yxxx() const { return Vector4 (y, x, x, x); }
-Vector4 Vector2::xyxx() const { return Vector4 (x, y, x, x); }
-Vector4 Vector2::yyxx() const { return Vector4 (y, y, x, x); }
-Vector4 Vector2::xxyx() const { return Vector4 (x, x, y, x); }
-Vector4 Vector2::yxyx() const { return Vector4 (y, x, y, x); }
-Vector4 Vector2::xyyx() const { return Vector4 (x, y, y, x); }
-Vector4 Vector2::yyyx() const { return Vector4 (y, y, y, x); }
-Vector4 Vector2::xxxy() const { return Vector4 (x, x, x, y); }
-Vector4 Vector2::yxxy() const { return Vector4 (y, x, x, y); }
-Vector4 Vector2::xyxy() const { return Vector4 (x, y, x, y); }
-Vector4 Vector2::yyxy() const { return Vector4 (y, y, x, y); }
-Vector4 Vector2::xxyy() const { return Vector4 (x, x, y, y); }
-Vector4 Vector2::yxyy() const { return Vector4 (y, x, y, y); }
-Vector4 Vector2::xyyy() const { return Vector4 (x, y, y, y); }
-Vector4 Vector2::yyyy() const { return Vector4 (y, y, y, y); }
-
-
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/Vector2int16.cpp b/externals/g3dlite/G3D.lib/source/Vector2int16.cpp
deleted file mode 100644
index 04efee2b4b7..00000000000
--- a/externals/g3dlite/G3D.lib/source/Vector2int16.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- @file Vector2int16.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-08-09
- @edited 2006-01-29
- */
-
-#include "G3D/platform.h"
-#include "G3D/g3dmath.h"
-#include "G3D/Vector2int16.h"
-#include "G3D/Vector2.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-
-namespace G3D {
-
-Vector2int16::Vector2int16(const class Vector2& v) {
- x = (int16)iFloor(v.x + 0.5);
- y = (int16)iFloor(v.y + 0.5);
-}
-
-
-Vector2int16::Vector2int16(class BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Vector2int16::serialize(class BinaryOutput& bo) const {
- bo.writeInt16(x);
- bo.writeInt16(y);
-}
-
-
-void Vector2int16::deserialize(class BinaryInput& bi) {
- x = bi.readInt16();
- y = bi.readInt16();
-}
-
-
-Vector2int16 Vector2int16::clamp(const Vector2int16& lo, const Vector2int16& hi) {
- return Vector2int16(iClamp(x, lo.x, hi.x), iClamp(y, lo.y, hi.y));
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Vector3.cpp b/externals/g3dlite/G3D.lib/source/Vector3.cpp
deleted file mode 100644
index bc52640d297..00000000000
--- a/externals/g3dlite/G3D.lib/source/Vector3.cpp
+++ /dev/null
@@ -1,493 +0,0 @@
-/**
- @file Vector3.cpp
-
- 3D vector class
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
-
- @created 2001-06-02
- @edited 2006-01-30
- */
-
-#include <limits>
-#include <stdlib.h>
-#include "G3D/Vector3.h"
-#include "G3D/g3dmath.h"
-#include "G3D/stringutils.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/TextInput.h"
-#include "G3D/TextOutput.h"
-#include "G3D/Vector3int16.h"
-#include "G3D/Matrix3.h"
-#include "G3D/Vector2.h"
-#include "G3D/Vector4int8.h"
-
-namespace G3D {
-
-Vector3 Vector3::dummy;
-
-
-Vector3::Vector3(const Vector4int8& v) : x(v.x / 127.0f), y(v.y / 127.0f), z(v.z / 127.0f) {}
-
-Vector3::Vector3(const class Vector2& v, float _z) : x(v.x), y(v.y), z(_z) {
-}
-
-
-Vector3::Axis Vector3::primaryAxis() const {
-
- Axis a = X_AXIS;
-
- double nx = abs(x);
- double ny = abs(y);
- double nz = abs(z);
-
- if (nx > ny) {
- if (nx > nz) {
- a = X_AXIS;
- } else {
- a = Z_AXIS;
- }
- } else {
- if (ny > nz) {
- a = Y_AXIS;
- } else {
- a = Z_AXIS;
- }
- }
-
- return a;
-}
-
-
-size_t Vector3::hashCode() const {
- unsigned int xhash = (*(int*)(void*)(&x));
- unsigned int yhash = (*(int*)(void*)(&y));
- unsigned int zhash = (*(int*)(void*)(&z));
-
- return xhash + (yhash * 37) + (zhash * 101);
-}
-
-std::ostream& operator<<(std::ostream& os, const Vector3& v) {
- return os << v.toString();
-}
-
-
-//----------------------------------------------------------------------------
-
-double frand() {
- return rand() / (double) RAND_MAX;
-}
-
-Vector3::Vector3(TextInput& t) {
- deserialize(t);
-}
-
-Vector3::Vector3(BinaryInput& b) {
- deserialize(b);
-}
-
-
-Vector3::Vector3(const class Vector3int16& v) {
- x = v.x;
- y = v.y;
- z = v.z;
-}
-
-
-void Vector3::deserialize(BinaryInput& b) {
- x = b.readFloat32();
- y = b.readFloat32();
- z = b.readFloat32();
-}
-
-
-void Vector3::deserialize(TextInput& t) {
- t.readSymbol("(");
- x = (float)t.readNumber();
- t.readSymbol(",");
- y = (float)t.readNumber();
- t.readSymbol(",");
- z = (float)t.readNumber();
- t.readSymbol(")");
-}
-
-
-void Vector3::serialize(TextOutput& t) const {
- t.writeSymbol("(");
- t.writeNumber(x);
- t.writeSymbol(",");
- t.writeNumber(y);
- t.writeSymbol(",");
- t.writeNumber(z);
- t.writeSymbol(")");
-}
-
-
-void Vector3::serialize(BinaryOutput& b) const {
- b.writeFloat32(x);
- b.writeFloat32(y);
- b.writeFloat32(z);
-}
-
-
-Vector3 Vector3::random() {
- Vector3 result;
-
- do {
- result = Vector3(uniformRandom(-1.0, 1.0),
- uniformRandom(-1.0, 1.0),
- uniformRandom(-1.0, 1.0));
- } while (result.squaredMagnitude() >= 1.0f);
-
- result.unitize();
-
- return result;
-}
-
-//----------------------------------------------------------------------------
-Vector3 Vector3::operator/ (float fScalar) const {
- Vector3 kQuot;
-
- if ( fScalar != 0.0 ) {
- float fInvScalar = 1.0f / fScalar;
- kQuot.x = fInvScalar * x;
- kQuot.y = fInvScalar * y;
- kQuot.z = fInvScalar * z;
- return kQuot;
- } else {
- return Vector3::inf();
- }
-}
-
-//----------------------------------------------------------------------------
-Vector3& Vector3::operator/= (float fScalar) {
- if (fScalar != 0.0) {
- float fInvScalar = 1.0f / fScalar;
- x *= fInvScalar;
- y *= fInvScalar;
- z *= fInvScalar;
- } else {
- x = (float)G3D::inf();
- y = (float)G3D::inf();
- z = (float)G3D::inf();
- }
-
- return *this;
-}
-
-//----------------------------------------------------------------------------
-float Vector3::unitize (float fTolerance) {
- float fMagnitude = magnitude();
-
- if (fMagnitude > fTolerance) {
- float fInvMagnitude = 1.0f / fMagnitude;
- x *= fInvMagnitude;
- y *= fInvMagnitude;
- z *= fInvMagnitude;
- } else {
- fMagnitude = 0.0f;
- }
-
- return fMagnitude;
-}
-
-//----------------------------------------------------------------------------
-
-Vector3 Vector3::reflectAbout(const Vector3& normal) const {
-
- Vector3 out;
-
- Vector3 N = normal.direction();
-
- // 2 * normal.dot(this) * normal - this
- return N * 2 * this->dot(N) - *this;
-}
-
-//----------------------------------------------------------------------------
-Vector3 Vector3::cosRandom(const Vector3& normal) {
- double e1 = G3D::uniformRandom(0, 1);
- double e2 = G3D::uniformRandom(0, 1);
-
- // Angle from normal
- double theta = acos(sqrt(e1));
-
- // Angle about normal
- double phi = 2 * pi() * e2;
-
- // Make a coordinate system
- Vector3 U = normal.direction();
- Vector3 V = Vector3::unitX();
-
- if (abs(U.dot(V)) > .9) {
- V = Vector3::unitY();
- }
-
- Vector3 W = U.cross(V).direction();
- V = W.cross(U);
-
- // Convert to rectangular form
- return cos(theta) * U + sin(theta) * (cos(phi) * V + sin(phi) * W);
-}
-//----------------------------------------------------------------------------
-
-Vector3 Vector3::hemiRandom(const Vector3& normal) {
- Vector3 V = Vector3::random();
-
- if (V.dot(normal) < 0) {
- return -V;
- } else {
- return V;
- }
-}
-
-//----------------------------------------------------------------------------
-
-Vector3 Vector3::reflectionDirection(const Vector3& normal) const {
- return -reflectAbout(normal).direction();
-}
-
-//----------------------------------------------------------------------------
-
-Vector3 Vector3::refractionDirection(
- const Vector3& normal,
- float iInside,
- float iOutside) const {
-
- // From pg. 24 of Henrik Wann Jensen. Realistic Image Synthesis
- // Using Photon Mapping. AK Peters. ISBN: 1568811470. July 2001.
-
- // Invert the directions from Wann Jensen's formulation
- // and normalize the vectors.
- const Vector3 W = -direction();
- Vector3 N = normal.direction();
-
- float h1 = iOutside;
- float h2 = iInside;
-
- if (normal.dot(*this) > 0.0f) {
- h1 = iInside;
- h2 = iOutside;
- N = -N;
- }
-
- const float hRatio = h1 / h2;
- const float WdotN = W.dot(N);
-
- float det = 1.0f - (float)square(hRatio) * (1.0f - (float)square(WdotN));
-
- if (det < 0) {
- // Total internal reflection
- return Vector3::zero();
- } else {
- return -hRatio * (W - WdotN * N) - N * sqrt(det);
- }
-}
-
-//----------------------------------------------------------------------------
-void Vector3::orthonormalize (Vector3 akVector[3]) {
- // If the input vectors are v0, v1, and v2, then the Gram-Schmidt
- // orthonormalization produces vectors u0, u1, and u2 as follows,
- //
- // u0 = v0/|v0|
- // u1 = (v1-(u0*v1)u0)/|v1-(u0*v1)u0|
- // u2 = (v2-(u0*v2)u0-(u1*v2)u1)/|v2-(u0*v2)u0-(u1*v2)u1|
- //
- // where |A| indicates length of vector A and A*B indicates dot
- // product of vectors A and B.
-
- // compute u0
- akVector[0].unitize();
-
- // compute u1
- float fDot0 = akVector[0].dot(akVector[1]);
- akVector[1] -= akVector[0] * fDot0;
- akVector[1].unitize();
-
- // compute u2
- float fDot1 = akVector[1].dot(akVector[2]);
- fDot0 = akVector[0].dot(akVector[2]);
- akVector[2] -= akVector[0] * fDot0 + akVector[1] * fDot1;
- akVector[2].unitize();
-}
-
-//----------------------------------------------------------------------------
-void Vector3::generateOrthonormalBasis (Vector3& rkU, Vector3& rkV,
- Vector3& rkW, bool bUnitLengthW) {
- if ( !bUnitLengthW )
- rkW.unitize();
-
- if ( G3D::abs(rkW.x) >= G3D::abs(rkW.y)
- && G3D::abs(rkW.x) >= G3D::abs(rkW.z) ) {
- rkU.x = -rkW.y;
- rkU.y = + rkW.x;
- rkU.z = 0.0;
- } else {
- rkU.x = 0.0;
- rkU.y = + rkW.z;
- rkU.z = -rkW.y;
- }
-
- rkU.unitize();
- rkV = rkW.cross(rkU);
-}
-
-//----------------------------------------------------------------------------
-
-std::string Vector3::toString() const {
- return G3D::format("(%g, %g, %g)", x, y, z);
-}
-
-
-//----------------------------------------------------------------------------
-
-Matrix3 Vector3::cross() const {
- return Matrix3( 0, -z, y,
- z, 0, -x,
- -y, x, 0);
-}
-
-
-void serialize(const Vector3::Axis& a, class BinaryOutput& bo) {
- bo.writeUInt8((uint8)a);
-}
-
-void deserialize(Vector3::Axis& a, class BinaryInput& bi) {
- a = (Vector3::Axis)bi.readUInt8();
-}
-
-//----------------------------------------------------------------------------
-// 2-char swizzles
-
-Vector2 Vector3::xx() const { return Vector2 (x, x); }
-Vector2 Vector3::yx() const { return Vector2 (y, x); }
-Vector2 Vector3::zx() const { return Vector2 (z, x); }
-Vector2 Vector3::xy() const { return Vector2 (x, y); }
-Vector2 Vector3::yy() const { return Vector2 (y, y); }
-Vector2 Vector3::zy() const { return Vector2 (z, y); }
-Vector2 Vector3::xz() const { return Vector2 (x, z); }
-Vector2 Vector3::yz() const { return Vector2 (y, z); }
-Vector2 Vector3::zz() const { return Vector2 (z, z); }
-
-// 3-char swizzles
-
-Vector3 Vector3::xxx() const { return Vector3 (x, x, x); }
-Vector3 Vector3::yxx() const { return Vector3 (y, x, x); }
-Vector3 Vector3::zxx() const { return Vector3 (z, x, x); }
-Vector3 Vector3::xyx() const { return Vector3 (x, y, x); }
-Vector3 Vector3::yyx() const { return Vector3 (y, y, x); }
-Vector3 Vector3::zyx() const { return Vector3 (z, y, x); }
-Vector3 Vector3::xzx() const { return Vector3 (x, z, x); }
-Vector3 Vector3::yzx() const { return Vector3 (y, z, x); }
-Vector3 Vector3::zzx() const { return Vector3 (z, z, x); }
-Vector3 Vector3::xxy() const { return Vector3 (x, x, y); }
-Vector3 Vector3::yxy() const { return Vector3 (y, x, y); }
-Vector3 Vector3::zxy() const { return Vector3 (z, x, y); }
-Vector3 Vector3::xyy() const { return Vector3 (x, y, y); }
-Vector3 Vector3::yyy() const { return Vector3 (y, y, y); }
-Vector3 Vector3::zyy() const { return Vector3 (z, y, y); }
-Vector3 Vector3::xzy() const { return Vector3 (x, z, y); }
-Vector3 Vector3::yzy() const { return Vector3 (y, z, y); }
-Vector3 Vector3::zzy() const { return Vector3 (z, z, y); }
-Vector3 Vector3::xxz() const { return Vector3 (x, x, z); }
-Vector3 Vector3::yxz() const { return Vector3 (y, x, z); }
-Vector3 Vector3::zxz() const { return Vector3 (z, x, z); }
-Vector3 Vector3::xyz() const { return Vector3 (x, y, z); }
-Vector3 Vector3::yyz() const { return Vector3 (y, y, z); }
-Vector3 Vector3::zyz() const { return Vector3 (z, y, z); }
-Vector3 Vector3::xzz() const { return Vector3 (x, z, z); }
-Vector3 Vector3::yzz() const { return Vector3 (y, z, z); }
-Vector3 Vector3::zzz() const { return Vector3 (z, z, z); }
-
-// 4-char swizzles
-
-Vector4 Vector3::xxxx() const { return Vector4 (x, x, x, x); }
-Vector4 Vector3::yxxx() const { return Vector4 (y, x, x, x); }
-Vector4 Vector3::zxxx() const { return Vector4 (z, x, x, x); }
-Vector4 Vector3::xyxx() const { return Vector4 (x, y, x, x); }
-Vector4 Vector3::yyxx() const { return Vector4 (y, y, x, x); }
-Vector4 Vector3::zyxx() const { return Vector4 (z, y, x, x); }
-Vector4 Vector3::xzxx() const { return Vector4 (x, z, x, x); }
-Vector4 Vector3::yzxx() const { return Vector4 (y, z, x, x); }
-Vector4 Vector3::zzxx() const { return Vector4 (z, z, x, x); }
-Vector4 Vector3::xxyx() const { return Vector4 (x, x, y, x); }
-Vector4 Vector3::yxyx() const { return Vector4 (y, x, y, x); }
-Vector4 Vector3::zxyx() const { return Vector4 (z, x, y, x); }
-Vector4 Vector3::xyyx() const { return Vector4 (x, y, y, x); }
-Vector4 Vector3::yyyx() const { return Vector4 (y, y, y, x); }
-Vector4 Vector3::zyyx() const { return Vector4 (z, y, y, x); }
-Vector4 Vector3::xzyx() const { return Vector4 (x, z, y, x); }
-Vector4 Vector3::yzyx() const { return Vector4 (y, z, y, x); }
-Vector4 Vector3::zzyx() const { return Vector4 (z, z, y, x); }
-Vector4 Vector3::xxzx() const { return Vector4 (x, x, z, x); }
-Vector4 Vector3::yxzx() const { return Vector4 (y, x, z, x); }
-Vector4 Vector3::zxzx() const { return Vector4 (z, x, z, x); }
-Vector4 Vector3::xyzx() const { return Vector4 (x, y, z, x); }
-Vector4 Vector3::yyzx() const { return Vector4 (y, y, z, x); }
-Vector4 Vector3::zyzx() const { return Vector4 (z, y, z, x); }
-Vector4 Vector3::xzzx() const { return Vector4 (x, z, z, x); }
-Vector4 Vector3::yzzx() const { return Vector4 (y, z, z, x); }
-Vector4 Vector3::zzzx() const { return Vector4 (z, z, z, x); }
-Vector4 Vector3::xxxy() const { return Vector4 (x, x, x, y); }
-Vector4 Vector3::yxxy() const { return Vector4 (y, x, x, y); }
-Vector4 Vector3::zxxy() const { return Vector4 (z, x, x, y); }
-Vector4 Vector3::xyxy() const { return Vector4 (x, y, x, y); }
-Vector4 Vector3::yyxy() const { return Vector4 (y, y, x, y); }
-Vector4 Vector3::zyxy() const { return Vector4 (z, y, x, y); }
-Vector4 Vector3::xzxy() const { return Vector4 (x, z, x, y); }
-Vector4 Vector3::yzxy() const { return Vector4 (y, z, x, y); }
-Vector4 Vector3::zzxy() const { return Vector4 (z, z, x, y); }
-Vector4 Vector3::xxyy() const { return Vector4 (x, x, y, y); }
-Vector4 Vector3::yxyy() const { return Vector4 (y, x, y, y); }
-Vector4 Vector3::zxyy() const { return Vector4 (z, x, y, y); }
-Vector4 Vector3::xyyy() const { return Vector4 (x, y, y, y); }
-Vector4 Vector3::yyyy() const { return Vector4 (y, y, y, y); }
-Vector4 Vector3::zyyy() const { return Vector4 (z, y, y, y); }
-Vector4 Vector3::xzyy() const { return Vector4 (x, z, y, y); }
-Vector4 Vector3::yzyy() const { return Vector4 (y, z, y, y); }
-Vector4 Vector3::zzyy() const { return Vector4 (z, z, y, y); }
-Vector4 Vector3::xxzy() const { return Vector4 (x, x, z, y); }
-Vector4 Vector3::yxzy() const { return Vector4 (y, x, z, y); }
-Vector4 Vector3::zxzy() const { return Vector4 (z, x, z, y); }
-Vector4 Vector3::xyzy() const { return Vector4 (x, y, z, y); }
-Vector4 Vector3::yyzy() const { return Vector4 (y, y, z, y); }
-Vector4 Vector3::zyzy() const { return Vector4 (z, y, z, y); }
-Vector4 Vector3::xzzy() const { return Vector4 (x, z, z, y); }
-Vector4 Vector3::yzzy() const { return Vector4 (y, z, z, y); }
-Vector4 Vector3::zzzy() const { return Vector4 (z, z, z, y); }
-Vector4 Vector3::xxxz() const { return Vector4 (x, x, x, z); }
-Vector4 Vector3::yxxz() const { return Vector4 (y, x, x, z); }
-Vector4 Vector3::zxxz() const { return Vector4 (z, x, x, z); }
-Vector4 Vector3::xyxz() const { return Vector4 (x, y, x, z); }
-Vector4 Vector3::yyxz() const { return Vector4 (y, y, x, z); }
-Vector4 Vector3::zyxz() const { return Vector4 (z, y, x, z); }
-Vector4 Vector3::xzxz() const { return Vector4 (x, z, x, z); }
-Vector4 Vector3::yzxz() const { return Vector4 (y, z, x, z); }
-Vector4 Vector3::zzxz() const { return Vector4 (z, z, x, z); }
-Vector4 Vector3::xxyz() const { return Vector4 (x, x, y, z); }
-Vector4 Vector3::yxyz() const { return Vector4 (y, x, y, z); }
-Vector4 Vector3::zxyz() const { return Vector4 (z, x, y, z); }
-Vector4 Vector3::xyyz() const { return Vector4 (x, y, y, z); }
-Vector4 Vector3::yyyz() const { return Vector4 (y, y, y, z); }
-Vector4 Vector3::zyyz() const { return Vector4 (z, y, y, z); }
-Vector4 Vector3::xzyz() const { return Vector4 (x, z, y, z); }
-Vector4 Vector3::yzyz() const { return Vector4 (y, z, y, z); }
-Vector4 Vector3::zzyz() const { return Vector4 (z, z, y, z); }
-Vector4 Vector3::xxzz() const { return Vector4 (x, x, z, z); }
-Vector4 Vector3::yxzz() const { return Vector4 (y, x, z, z); }
-Vector4 Vector3::zxzz() const { return Vector4 (z, x, z, z); }
-Vector4 Vector3::xyzz() const { return Vector4 (x, y, z, z); }
-Vector4 Vector3::yyzz() const { return Vector4 (y, y, z, z); }
-Vector4 Vector3::zyzz() const { return Vector4 (z, y, z, z); }
-Vector4 Vector3::xzzz() const { return Vector4 (x, z, z, z); }
-Vector4 Vector3::yzzz() const { return Vector4 (y, z, z, z); }
-Vector4 Vector3::zzzz() const { return Vector4 (z, z, z, z); }
-
-
-
-
-
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/Vector3int16.cpp b/externals/g3dlite/G3D.lib/source/Vector3int16.cpp
deleted file mode 100644
index 8d8bb00bbef..00000000000
--- a/externals/g3dlite/G3D.lib/source/Vector3int16.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- @file Vector3int16.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
-
- @created 2003-04-07
- @edited 2006-01-17
- */
-
-#include "G3D/platform.h"
-#include "G3D/g3dmath.h"
-#include "G3D/Vector3int16.h"
-#include "G3D/Vector3.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/format.h"
-
-namespace G3D {
-
-Vector3int16::Vector3int16(const class Vector3& v) {
- x = (int16)iFloor(v.x + 0.5);
- y = (int16)iFloor(v.y + 0.5);
- z = (int16)iFloor(v.z + 0.5);
-}
-
-
-Vector3int16::Vector3int16(class BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Vector3int16::serialize(class BinaryOutput& bo) const {
- bo.writeInt16(x);
- bo.writeInt16(y);
- bo.writeInt16(z);
-}
-
-
-void Vector3int16::deserialize(class BinaryInput& bi) {
- x = bi.readInt16();
- y = bi.readInt16();
- z = bi.readInt16();
-}
-
-std::string Vector3int16::toString() const {
- return G3D::format("(%d, %d, %d)", x, y, z);
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Vector3int32.cpp b/externals/g3dlite/G3D.lib/source/Vector3int32.cpp
deleted file mode 100644
index 1328ba1aba5..00000000000
--- a/externals/g3dlite/G3D.lib/source/Vector3int32.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- @file Vector3int32.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
-
- @created 2008-07-01
- @edited 2008-07-01
- */
-
-#include "G3D/platform.h"
-#include "G3D/g3dmath.h"
-#include "G3D/Vector3int32.h"
-#include "G3D/Vector3int16.h"
-#include "G3D/Vector3.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/format.h"
-
-namespace G3D {
-
-Vector3int32::Vector3int32(const class Vector3& v) {
- x = (int32)iFloor(v.x + 0.5);
- y = (int32)iFloor(v.y + 0.5);
- z = (int32)iFloor(v.z + 0.5);
-}
-
-
-Vector3int32::Vector3int32(const class Vector3int16& v) {
- x = v.x;
- y = v.y;
- z = v.z;
-}
-
-
-Vector3int32::Vector3int32(class BinaryInput& bi) {
- deserialize(bi);
-}
-
-
-void Vector3int32::serialize(class BinaryOutput& bo) const {
- bo.writeInt32(x);
- bo.writeInt32(y);
- bo.writeInt32(z);
-}
-
-
-void Vector3int32::deserialize(class BinaryInput& bi) {
- x = bi.readInt32();
- y = bi.readInt32();
- z = bi.readInt32();
-}
-
-std::string Vector3int32::toString() const {
- return G3D::format("(%d, %d, %d)", x, y, z);
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/Vector4.cpp b/externals/g3dlite/G3D.lib/source/Vector4.cpp
deleted file mode 100644
index f562f2d6877..00000000000
--- a/externals/g3dlite/G3D.lib/source/Vector4.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/**
- @file Vector4.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2001-07-09
- @edited 2007-02-29
- */
-
-#include <stdlib.h>
-#include <limits>
-#include "G3D/Vector4.h"
-#include "G3D/Color4.h"
-#include "G3D/g3dmath.h"
-#include "G3D/stringutils.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include "G3D/Vector4int8.h"
-#include "G3D/Matrix4.h"
-
-namespace G3D {
-
-Vector4::Vector4(const Vector4int8& v) : x(v.x / 127.0f), y(v.y / 127.0f), z(v.z / 127.0f), w(v.w / 127.0f) {
-}
-
-size_t Vector4::hashCode() const {
- unsigned int xhash = (*(int*)(void*)(&x));
- unsigned int yhash = (*(int*)(void*)(&y));
- unsigned int zhash = (*(int*)(void*)(&z));
- unsigned int whash = (*(int*)(void*)(&w));
-
- return xhash + (yhash * 37) + (zhash * 101) + (whash * 241);
-}
-
-
-Vector4::Vector4(const class Color4& c) {
- x = c.r;
- y = c.g;
- z = c.b;
- w = c.a;
-}
-
-
-Vector4::Vector4(const Vector2& v1, const Vector2& v2) {
- x = v1.x;
- y = v1.y;
- z = v2.x;
- w = v2.y;
-}
-
-
-Vector4::Vector4(const Vector2& v1, float fz, float fw) {
- x = v1.x;
- y = v1.y;
- z = fz;
- w = fw;
-}
-
-Vector4::Vector4(BinaryInput& b) {
- deserialize(b);
-}
-
-
-void Vector4::deserialize(BinaryInput& b) {
- x = b.readFloat32();
- y = b.readFloat32();
- z = b.readFloat32();
- w = b.readFloat32();
-}
-
-
-void Vector4::serialize(BinaryOutput& b) const {
- b.writeFloat32(x);
- b.writeFloat32(y);
- b.writeFloat32(z);
- b.writeFloat32(w);
-}
-
-//----------------------------------------------------------------------------
-
-Vector4 Vector4::operator*(const Matrix4& M) const {
- Vector4 result;
- for (int i = 0; i < 4; ++i) {
- result[i] = 0.0f;
- for (int j = 0; j < 4; ++j) {
- result[i] += (*this)[j] * M[j][i];
- }
- }
- return result;
-}
-
-
-Vector4 Vector4::operator/ (float fScalar) const {
- Vector4 kQuot;
-
- if ( fScalar != 0.0 ) {
- float fInvScalar = 1.0f / fScalar;
- kQuot.x = fInvScalar * x;
- kQuot.y = fInvScalar * y;
- kQuot.z = fInvScalar * z;
- kQuot.w = fInvScalar * w;
- return kQuot;
- } else {
- return Vector4::inf();
- }
-}
-
-//----------------------------------------------------------------------------
-Vector4& Vector4::operator/= (float fScalar) {
- if (fScalar != 0.0f) {
- float fInvScalar = 1.0f / fScalar;
- x *= fInvScalar;
- y *= fInvScalar;
- z *= fInvScalar;
- w *= fInvScalar;
- } else {
- *this = Vector4::inf();
- }
-
- return *this;
-}
-
-
-//----------------------------------------------------------------------------
-
-std::string Vector4::toString() const {
- return G3D::format("(%g, %g, %g, %g)", x, y, z, w);
-}
-// 2-char swizzles
-
-Vector2 Vector4::xx() const { return Vector2 (x, x); }
-Vector2 Vector4::yx() const { return Vector2 (y, x); }
-Vector2 Vector4::zx() const { return Vector2 (z, x); }
-Vector2 Vector4::wx() const { return Vector2 (w, x); }
-Vector2 Vector4::xy() const { return Vector2 (x, y); }
-Vector2 Vector4::yy() const { return Vector2 (y, y); }
-Vector2 Vector4::zy() const { return Vector2 (z, y); }
-Vector2 Vector4::wy() const { return Vector2 (w, y); }
-Vector2 Vector4::xz() const { return Vector2 (x, z); }
-Vector2 Vector4::yz() const { return Vector2 (y, z); }
-Vector2 Vector4::zz() const { return Vector2 (z, z); }
-Vector2 Vector4::wz() const { return Vector2 (w, z); }
-Vector2 Vector4::xw() const { return Vector2 (x, w); }
-Vector2 Vector4::yw() const { return Vector2 (y, w); }
-Vector2 Vector4::zw() const { return Vector2 (z, w); }
-Vector2 Vector4::ww() const { return Vector2 (w, w); }
-
-// 3-char swizzles
-
-Vector3 Vector4::xxx() const { return Vector3 (x, x, x); }
-Vector3 Vector4::yxx() const { return Vector3 (y, x, x); }
-Vector3 Vector4::zxx() const { return Vector3 (z, x, x); }
-Vector3 Vector4::wxx() const { return Vector3 (w, x, x); }
-Vector3 Vector4::xyx() const { return Vector3 (x, y, x); }
-Vector3 Vector4::yyx() const { return Vector3 (y, y, x); }
-Vector3 Vector4::zyx() const { return Vector3 (z, y, x); }
-Vector3 Vector4::wyx() const { return Vector3 (w, y, x); }
-Vector3 Vector4::xzx() const { return Vector3 (x, z, x); }
-Vector3 Vector4::yzx() const { return Vector3 (y, z, x); }
-Vector3 Vector4::zzx() const { return Vector3 (z, z, x); }
-Vector3 Vector4::wzx() const { return Vector3 (w, z, x); }
-Vector3 Vector4::xwx() const { return Vector3 (x, w, x); }
-Vector3 Vector4::ywx() const { return Vector3 (y, w, x); }
-Vector3 Vector4::zwx() const { return Vector3 (z, w, x); }
-Vector3 Vector4::wwx() const { return Vector3 (w, w, x); }
-Vector3 Vector4::xxy() const { return Vector3 (x, x, y); }
-Vector3 Vector4::yxy() const { return Vector3 (y, x, y); }
-Vector3 Vector4::zxy() const { return Vector3 (z, x, y); }
-Vector3 Vector4::wxy() const { return Vector3 (w, x, y); }
-Vector3 Vector4::xyy() const { return Vector3 (x, y, y); }
-Vector3 Vector4::yyy() const { return Vector3 (y, y, y); }
-Vector3 Vector4::zyy() const { return Vector3 (z, y, y); }
-Vector3 Vector4::wyy() const { return Vector3 (w, y, y); }
-Vector3 Vector4::xzy() const { return Vector3 (x, z, y); }
-Vector3 Vector4::yzy() const { return Vector3 (y, z, y); }
-Vector3 Vector4::zzy() const { return Vector3 (z, z, y); }
-Vector3 Vector4::wzy() const { return Vector3 (w, z, y); }
-Vector3 Vector4::xwy() const { return Vector3 (x, w, y); }
-Vector3 Vector4::ywy() const { return Vector3 (y, w, y); }
-Vector3 Vector4::zwy() const { return Vector3 (z, w, y); }
-Vector3 Vector4::wwy() const { return Vector3 (w, w, y); }
-Vector3 Vector4::xxz() const { return Vector3 (x, x, z); }
-Vector3 Vector4::yxz() const { return Vector3 (y, x, z); }
-Vector3 Vector4::zxz() const { return Vector3 (z, x, z); }
-Vector3 Vector4::wxz() const { return Vector3 (w, x, z); }
-Vector3 Vector4::xyz() const { return Vector3 (x, y, z); }
-Vector3 Vector4::yyz() const { return Vector3 (y, y, z); }
-Vector3 Vector4::zyz() const { return Vector3 (z, y, z); }
-Vector3 Vector4::wyz() const { return Vector3 (w, y, z); }
-Vector3 Vector4::xzz() const { return Vector3 (x, z, z); }
-Vector3 Vector4::yzz() const { return Vector3 (y, z, z); }
-Vector3 Vector4::zzz() const { return Vector3 (z, z, z); }
-Vector3 Vector4::wzz() const { return Vector3 (w, z, z); }
-Vector3 Vector4::xwz() const { return Vector3 (x, w, z); }
-Vector3 Vector4::ywz() const { return Vector3 (y, w, z); }
-Vector3 Vector4::zwz() const { return Vector3 (z, w, z); }
-Vector3 Vector4::wwz() const { return Vector3 (w, w, z); }
-Vector3 Vector4::xxw() const { return Vector3 (x, x, w); }
-Vector3 Vector4::yxw() const { return Vector3 (y, x, w); }
-Vector3 Vector4::zxw() const { return Vector3 (z, x, w); }
-Vector3 Vector4::wxw() const { return Vector3 (w, x, w); }
-Vector3 Vector4::xyw() const { return Vector3 (x, y, w); }
-Vector3 Vector4::yyw() const { return Vector3 (y, y, w); }
-Vector3 Vector4::zyw() const { return Vector3 (z, y, w); }
-Vector3 Vector4::wyw() const { return Vector3 (w, y, w); }
-Vector3 Vector4::xzw() const { return Vector3 (x, z, w); }
-Vector3 Vector4::yzw() const { return Vector3 (y, z, w); }
-Vector3 Vector4::zzw() const { return Vector3 (z, z, w); }
-Vector3 Vector4::wzw() const { return Vector3 (w, z, w); }
-Vector3 Vector4::xww() const { return Vector3 (x, w, w); }
-Vector3 Vector4::yww() const { return Vector3 (y, w, w); }
-Vector3 Vector4::zww() const { return Vector3 (z, w, w); }
-Vector3 Vector4::www() const { return Vector3 (w, w, w); }
-
-// 4-char swizzles
-
-Vector4 Vector4::xxxx() const { return Vector4 (x, x, x, x); }
-Vector4 Vector4::yxxx() const { return Vector4 (y, x, x, x); }
-Vector4 Vector4::zxxx() const { return Vector4 (z, x, x, x); }
-Vector4 Vector4::wxxx() const { return Vector4 (w, x, x, x); }
-Vector4 Vector4::xyxx() const { return Vector4 (x, y, x, x); }
-Vector4 Vector4::yyxx() const { return Vector4 (y, y, x, x); }
-Vector4 Vector4::zyxx() const { return Vector4 (z, y, x, x); }
-Vector4 Vector4::wyxx() const { return Vector4 (w, y, x, x); }
-Vector4 Vector4::xzxx() const { return Vector4 (x, z, x, x); }
-Vector4 Vector4::yzxx() const { return Vector4 (y, z, x, x); }
-Vector4 Vector4::zzxx() const { return Vector4 (z, z, x, x); }
-Vector4 Vector4::wzxx() const { return Vector4 (w, z, x, x); }
-Vector4 Vector4::xwxx() const { return Vector4 (x, w, x, x); }
-Vector4 Vector4::ywxx() const { return Vector4 (y, w, x, x); }
-Vector4 Vector4::zwxx() const { return Vector4 (z, w, x, x); }
-Vector4 Vector4::wwxx() const { return Vector4 (w, w, x, x); }
-Vector4 Vector4::xxyx() const { return Vector4 (x, x, y, x); }
-Vector4 Vector4::yxyx() const { return Vector4 (y, x, y, x); }
-Vector4 Vector4::zxyx() const { return Vector4 (z, x, y, x); }
-Vector4 Vector4::wxyx() const { return Vector4 (w, x, y, x); }
-Vector4 Vector4::xyyx() const { return Vector4 (x, y, y, x); }
-Vector4 Vector4::yyyx() const { return Vector4 (y, y, y, x); }
-Vector4 Vector4::zyyx() const { return Vector4 (z, y, y, x); }
-Vector4 Vector4::wyyx() const { return Vector4 (w, y, y, x); }
-Vector4 Vector4::xzyx() const { return Vector4 (x, z, y, x); }
-Vector4 Vector4::yzyx() const { return Vector4 (y, z, y, x); }
-Vector4 Vector4::zzyx() const { return Vector4 (z, z, y, x); }
-Vector4 Vector4::wzyx() const { return Vector4 (w, z, y, x); }
-Vector4 Vector4::xwyx() const { return Vector4 (x, w, y, x); }
-Vector4 Vector4::ywyx() const { return Vector4 (y, w, y, x); }
-Vector4 Vector4::zwyx() const { return Vector4 (z, w, y, x); }
-Vector4 Vector4::wwyx() const { return Vector4 (w, w, y, x); }
-Vector4 Vector4::xxzx() const { return Vector4 (x, x, z, x); }
-Vector4 Vector4::yxzx() const { return Vector4 (y, x, z, x); }
-Vector4 Vector4::zxzx() const { return Vector4 (z, x, z, x); }
-Vector4 Vector4::wxzx() const { return Vector4 (w, x, z, x); }
-Vector4 Vector4::xyzx() const { return Vector4 (x, y, z, x); }
-Vector4 Vector4::yyzx() const { return Vector4 (y, y, z, x); }
-Vector4 Vector4::zyzx() const { return Vector4 (z, y, z, x); }
-Vector4 Vector4::wyzx() const { return Vector4 (w, y, z, x); }
-Vector4 Vector4::xzzx() const { return Vector4 (x, z, z, x); }
-Vector4 Vector4::yzzx() const { return Vector4 (y, z, z, x); }
-Vector4 Vector4::zzzx() const { return Vector4 (z, z, z, x); }
-Vector4 Vector4::wzzx() const { return Vector4 (w, z, z, x); }
-Vector4 Vector4::xwzx() const { return Vector4 (x, w, z, x); }
-Vector4 Vector4::ywzx() const { return Vector4 (y, w, z, x); }
-Vector4 Vector4::zwzx() const { return Vector4 (z, w, z, x); }
-Vector4 Vector4::wwzx() const { return Vector4 (w, w, z, x); }
-Vector4 Vector4::xxwx() const { return Vector4 (x, x, w, x); }
-Vector4 Vector4::yxwx() const { return Vector4 (y, x, w, x); }
-Vector4 Vector4::zxwx() const { return Vector4 (z, x, w, x); }
-Vector4 Vector4::wxwx() const { return Vector4 (w, x, w, x); }
-Vector4 Vector4::xywx() const { return Vector4 (x, y, w, x); }
-Vector4 Vector4::yywx() const { return Vector4 (y, y, w, x); }
-Vector4 Vector4::zywx() const { return Vector4 (z, y, w, x); }
-Vector4 Vector4::wywx() const { return Vector4 (w, y, w, x); }
-Vector4 Vector4::xzwx() const { return Vector4 (x, z, w, x); }
-Vector4 Vector4::yzwx() const { return Vector4 (y, z, w, x); }
-Vector4 Vector4::zzwx() const { return Vector4 (z, z, w, x); }
-Vector4 Vector4::wzwx() const { return Vector4 (w, z, w, x); }
-Vector4 Vector4::xwwx() const { return Vector4 (x, w, w, x); }
-Vector4 Vector4::ywwx() const { return Vector4 (y, w, w, x); }
-Vector4 Vector4::zwwx() const { return Vector4 (z, w, w, x); }
-Vector4 Vector4::wwwx() const { return Vector4 (w, w, w, x); }
-Vector4 Vector4::xxxy() const { return Vector4 (x, x, x, y); }
-Vector4 Vector4::yxxy() const { return Vector4 (y, x, x, y); }
-Vector4 Vector4::zxxy() const { return Vector4 (z, x, x, y); }
-Vector4 Vector4::wxxy() const { return Vector4 (w, x, x, y); }
-Vector4 Vector4::xyxy() const { return Vector4 (x, y, x, y); }
-Vector4 Vector4::yyxy() const { return Vector4 (y, y, x, y); }
-Vector4 Vector4::zyxy() const { return Vector4 (z, y, x, y); }
-Vector4 Vector4::wyxy() const { return Vector4 (w, y, x, y); }
-Vector4 Vector4::xzxy() const { return Vector4 (x, z, x, y); }
-Vector4 Vector4::yzxy() const { return Vector4 (y, z, x, y); }
-Vector4 Vector4::zzxy() const { return Vector4 (z, z, x, y); }
-Vector4 Vector4::wzxy() const { return Vector4 (w, z, x, y); }
-Vector4 Vector4::xwxy() const { return Vector4 (x, w, x, y); }
-Vector4 Vector4::ywxy() const { return Vector4 (y, w, x, y); }
-Vector4 Vector4::zwxy() const { return Vector4 (z, w, x, y); }
-Vector4 Vector4::wwxy() const { return Vector4 (w, w, x, y); }
-Vector4 Vector4::xxyy() const { return Vector4 (x, x, y, y); }
-Vector4 Vector4::yxyy() const { return Vector4 (y, x, y, y); }
-Vector4 Vector4::zxyy() const { return Vector4 (z, x, y, y); }
-Vector4 Vector4::wxyy() const { return Vector4 (w, x, y, y); }
-Vector4 Vector4::xyyy() const { return Vector4 (x, y, y, y); }
-Vector4 Vector4::yyyy() const { return Vector4 (y, y, y, y); }
-Vector4 Vector4::zyyy() const { return Vector4 (z, y, y, y); }
-Vector4 Vector4::wyyy() const { return Vector4 (w, y, y, y); }
-Vector4 Vector4::xzyy() const { return Vector4 (x, z, y, y); }
-Vector4 Vector4::yzyy() const { return Vector4 (y, z, y, y); }
-Vector4 Vector4::zzyy() const { return Vector4 (z, z, y, y); }
-Vector4 Vector4::wzyy() const { return Vector4 (w, z, y, y); }
-Vector4 Vector4::xwyy() const { return Vector4 (x, w, y, y); }
-Vector4 Vector4::ywyy() const { return Vector4 (y, w, y, y); }
-Vector4 Vector4::zwyy() const { return Vector4 (z, w, y, y); }
-Vector4 Vector4::wwyy() const { return Vector4 (w, w, y, y); }
-Vector4 Vector4::xxzy() const { return Vector4 (x, x, z, y); }
-Vector4 Vector4::yxzy() const { return Vector4 (y, x, z, y); }
-Vector4 Vector4::zxzy() const { return Vector4 (z, x, z, y); }
-Vector4 Vector4::wxzy() const { return Vector4 (w, x, z, y); }
-Vector4 Vector4::xyzy() const { return Vector4 (x, y, z, y); }
-Vector4 Vector4::yyzy() const { return Vector4 (y, y, z, y); }
-Vector4 Vector4::zyzy() const { return Vector4 (z, y, z, y); }
-Vector4 Vector4::wyzy() const { return Vector4 (w, y, z, y); }
-Vector4 Vector4::xzzy() const { return Vector4 (x, z, z, y); }
-Vector4 Vector4::yzzy() const { return Vector4 (y, z, z, y); }
-Vector4 Vector4::zzzy() const { return Vector4 (z, z, z, y); }
-Vector4 Vector4::wzzy() const { return Vector4 (w, z, z, y); }
-Vector4 Vector4::xwzy() const { return Vector4 (x, w, z, y); }
-Vector4 Vector4::ywzy() const { return Vector4 (y, w, z, y); }
-Vector4 Vector4::zwzy() const { return Vector4 (z, w, z, y); }
-Vector4 Vector4::wwzy() const { return Vector4 (w, w, z, y); }
-Vector4 Vector4::xxwy() const { return Vector4 (x, x, w, y); }
-Vector4 Vector4::yxwy() const { return Vector4 (y, x, w, y); }
-Vector4 Vector4::zxwy() const { return Vector4 (z, x, w, y); }
-Vector4 Vector4::wxwy() const { return Vector4 (w, x, w, y); }
-Vector4 Vector4::xywy() const { return Vector4 (x, y, w, y); }
-Vector4 Vector4::yywy() const { return Vector4 (y, y, w, y); }
-Vector4 Vector4::zywy() const { return Vector4 (z, y, w, y); }
-Vector4 Vector4::wywy() const { return Vector4 (w, y, w, y); }
-Vector4 Vector4::xzwy() const { return Vector4 (x, z, w, y); }
-Vector4 Vector4::yzwy() const { return Vector4 (y, z, w, y); }
-Vector4 Vector4::zzwy() const { return Vector4 (z, z, w, y); }
-Vector4 Vector4::wzwy() const { return Vector4 (w, z, w, y); }
-Vector4 Vector4::xwwy() const { return Vector4 (x, w, w, y); }
-Vector4 Vector4::ywwy() const { return Vector4 (y, w, w, y); }
-Vector4 Vector4::zwwy() const { return Vector4 (z, w, w, y); }
-Vector4 Vector4::wwwy() const { return Vector4 (w, w, w, y); }
-Vector4 Vector4::xxxz() const { return Vector4 (x, x, x, z); }
-Vector4 Vector4::yxxz() const { return Vector4 (y, x, x, z); }
-Vector4 Vector4::zxxz() const { return Vector4 (z, x, x, z); }
-Vector4 Vector4::wxxz() const { return Vector4 (w, x, x, z); }
-Vector4 Vector4::xyxz() const { return Vector4 (x, y, x, z); }
-Vector4 Vector4::yyxz() const { return Vector4 (y, y, x, z); }
-Vector4 Vector4::zyxz() const { return Vector4 (z, y, x, z); }
-Vector4 Vector4::wyxz() const { return Vector4 (w, y, x, z); }
-Vector4 Vector4::xzxz() const { return Vector4 (x, z, x, z); }
-Vector4 Vector4::yzxz() const { return Vector4 (y, z, x, z); }
-Vector4 Vector4::zzxz() const { return Vector4 (z, z, x, z); }
-Vector4 Vector4::wzxz() const { return Vector4 (w, z, x, z); }
-Vector4 Vector4::xwxz() const { return Vector4 (x, w, x, z); }
-Vector4 Vector4::ywxz() const { return Vector4 (y, w, x, z); }
-Vector4 Vector4::zwxz() const { return Vector4 (z, w, x, z); }
-Vector4 Vector4::wwxz() const { return Vector4 (w, w, x, z); }
-Vector4 Vector4::xxyz() const { return Vector4 (x, x, y, z); }
-Vector4 Vector4::yxyz() const { return Vector4 (y, x, y, z); }
-Vector4 Vector4::zxyz() const { return Vector4 (z, x, y, z); }
-Vector4 Vector4::wxyz() const { return Vector4 (w, x, y, z); }
-Vector4 Vector4::xyyz() const { return Vector4 (x, y, y, z); }
-Vector4 Vector4::yyyz() const { return Vector4 (y, y, y, z); }
-Vector4 Vector4::zyyz() const { return Vector4 (z, y, y, z); }
-Vector4 Vector4::wyyz() const { return Vector4 (w, y, y, z); }
-Vector4 Vector4::xzyz() const { return Vector4 (x, z, y, z); }
-Vector4 Vector4::yzyz() const { return Vector4 (y, z, y, z); }
-Vector4 Vector4::zzyz() const { return Vector4 (z, z, y, z); }
-Vector4 Vector4::wzyz() const { return Vector4 (w, z, y, z); }
-Vector4 Vector4::xwyz() const { return Vector4 (x, w, y, z); }
-Vector4 Vector4::ywyz() const { return Vector4 (y, w, y, z); }
-Vector4 Vector4::zwyz() const { return Vector4 (z, w, y, z); }
-Vector4 Vector4::wwyz() const { return Vector4 (w, w, y, z); }
-Vector4 Vector4::xxzz() const { return Vector4 (x, x, z, z); }
-Vector4 Vector4::yxzz() const { return Vector4 (y, x, z, z); }
-Vector4 Vector4::zxzz() const { return Vector4 (z, x, z, z); }
-Vector4 Vector4::wxzz() const { return Vector4 (w, x, z, z); }
-Vector4 Vector4::xyzz() const { return Vector4 (x, y, z, z); }
-Vector4 Vector4::yyzz() const { return Vector4 (y, y, z, z); }
-Vector4 Vector4::zyzz() const { return Vector4 (z, y, z, z); }
-Vector4 Vector4::wyzz() const { return Vector4 (w, y, z, z); }
-Vector4 Vector4::xzzz() const { return Vector4 (x, z, z, z); }
-Vector4 Vector4::yzzz() const { return Vector4 (y, z, z, z); }
-Vector4 Vector4::zzzz() const { return Vector4 (z, z, z, z); }
-Vector4 Vector4::wzzz() const { return Vector4 (w, z, z, z); }
-Vector4 Vector4::xwzz() const { return Vector4 (x, w, z, z); }
-Vector4 Vector4::ywzz() const { return Vector4 (y, w, z, z); }
-Vector4 Vector4::zwzz() const { return Vector4 (z, w, z, z); }
-Vector4 Vector4::wwzz() const { return Vector4 (w, w, z, z); }
-Vector4 Vector4::xxwz() const { return Vector4 (x, x, w, z); }
-Vector4 Vector4::yxwz() const { return Vector4 (y, x, w, z); }
-Vector4 Vector4::zxwz() const { return Vector4 (z, x, w, z); }
-Vector4 Vector4::wxwz() const { return Vector4 (w, x, w, z); }
-Vector4 Vector4::xywz() const { return Vector4 (x, y, w, z); }
-Vector4 Vector4::yywz() const { return Vector4 (y, y, w, z); }
-Vector4 Vector4::zywz() const { return Vector4 (z, y, w, z); }
-Vector4 Vector4::wywz() const { return Vector4 (w, y, w, z); }
-Vector4 Vector4::xzwz() const { return Vector4 (x, z, w, z); }
-Vector4 Vector4::yzwz() const { return Vector4 (y, z, w, z); }
-Vector4 Vector4::zzwz() const { return Vector4 (z, z, w, z); }
-Vector4 Vector4::wzwz() const { return Vector4 (w, z, w, z); }
-Vector4 Vector4::xwwz() const { return Vector4 (x, w, w, z); }
-Vector4 Vector4::ywwz() const { return Vector4 (y, w, w, z); }
-Vector4 Vector4::zwwz() const { return Vector4 (z, w, w, z); }
-Vector4 Vector4::wwwz() const { return Vector4 (w, w, w, z); }
-Vector4 Vector4::xxxw() const { return Vector4 (x, x, x, w); }
-Vector4 Vector4::yxxw() const { return Vector4 (y, x, x, w); }
-Vector4 Vector4::zxxw() const { return Vector4 (z, x, x, w); }
-Vector4 Vector4::wxxw() const { return Vector4 (w, x, x, w); }
-Vector4 Vector4::xyxw() const { return Vector4 (x, y, x, w); }
-Vector4 Vector4::yyxw() const { return Vector4 (y, y, x, w); }
-Vector4 Vector4::zyxw() const { return Vector4 (z, y, x, w); }
-Vector4 Vector4::wyxw() const { return Vector4 (w, y, x, w); }
-Vector4 Vector4::xzxw() const { return Vector4 (x, z, x, w); }
-Vector4 Vector4::yzxw() const { return Vector4 (y, z, x, w); }
-Vector4 Vector4::zzxw() const { return Vector4 (z, z, x, w); }
-Vector4 Vector4::wzxw() const { return Vector4 (w, z, x, w); }
-Vector4 Vector4::xwxw() const { return Vector4 (x, w, x, w); }
-Vector4 Vector4::ywxw() const { return Vector4 (y, w, x, w); }
-Vector4 Vector4::zwxw() const { return Vector4 (z, w, x, w); }
-Vector4 Vector4::wwxw() const { return Vector4 (w, w, x, w); }
-Vector4 Vector4::xxyw() const { return Vector4 (x, x, y, w); }
-Vector4 Vector4::yxyw() const { return Vector4 (y, x, y, w); }
-Vector4 Vector4::zxyw() const { return Vector4 (z, x, y, w); }
-Vector4 Vector4::wxyw() const { return Vector4 (w, x, y, w); }
-Vector4 Vector4::xyyw() const { return Vector4 (x, y, y, w); }
-Vector4 Vector4::yyyw() const { return Vector4 (y, y, y, w); }
-Vector4 Vector4::zyyw() const { return Vector4 (z, y, y, w); }
-Vector4 Vector4::wyyw() const { return Vector4 (w, y, y, w); }
-Vector4 Vector4::xzyw() const { return Vector4 (x, z, y, w); }
-Vector4 Vector4::yzyw() const { return Vector4 (y, z, y, w); }
-Vector4 Vector4::zzyw() const { return Vector4 (z, z, y, w); }
-Vector4 Vector4::wzyw() const { return Vector4 (w, z, y, w); }
-Vector4 Vector4::xwyw() const { return Vector4 (x, w, y, w); }
-Vector4 Vector4::ywyw() const { return Vector4 (y, w, y, w); }
-Vector4 Vector4::zwyw() const { return Vector4 (z, w, y, w); }
-Vector4 Vector4::wwyw() const { return Vector4 (w, w, y, w); }
-Vector4 Vector4::xxzw() const { return Vector4 (x, x, z, w); }
-Vector4 Vector4::yxzw() const { return Vector4 (y, x, z, w); }
-Vector4 Vector4::zxzw() const { return Vector4 (z, x, z, w); }
-Vector4 Vector4::wxzw() const { return Vector4 (w, x, z, w); }
-Vector4 Vector4::xyzw() const { return Vector4 (x, y, z, w); }
-Vector4 Vector4::yyzw() const { return Vector4 (y, y, z, w); }
-Vector4 Vector4::zyzw() const { return Vector4 (z, y, z, w); }
-Vector4 Vector4::wyzw() const { return Vector4 (w, y, z, w); }
-Vector4 Vector4::xzzw() const { return Vector4 (x, z, z, w); }
-Vector4 Vector4::yzzw() const { return Vector4 (y, z, z, w); }
-Vector4 Vector4::zzzw() const { return Vector4 (z, z, z, w); }
-Vector4 Vector4::wzzw() const { return Vector4 (w, z, z, w); }
-Vector4 Vector4::xwzw() const { return Vector4 (x, w, z, w); }
-Vector4 Vector4::ywzw() const { return Vector4 (y, w, z, w); }
-Vector4 Vector4::zwzw() const { return Vector4 (z, w, z, w); }
-Vector4 Vector4::wwzw() const { return Vector4 (w, w, z, w); }
-Vector4 Vector4::xxww() const { return Vector4 (x, x, w, w); }
-Vector4 Vector4::yxww() const { return Vector4 (y, x, w, w); }
-Vector4 Vector4::zxww() const { return Vector4 (z, x, w, w); }
-Vector4 Vector4::wxww() const { return Vector4 (w, x, w, w); }
-Vector4 Vector4::xyww() const { return Vector4 (x, y, w, w); }
-Vector4 Vector4::yyww() const { return Vector4 (y, y, w, w); }
-Vector4 Vector4::zyww() const { return Vector4 (z, y, w, w); }
-Vector4 Vector4::wyww() const { return Vector4 (w, y, w, w); }
-Vector4 Vector4::xzww() const { return Vector4 (x, z, w, w); }
-Vector4 Vector4::yzww() const { return Vector4 (y, z, w, w); }
-Vector4 Vector4::zzww() const { return Vector4 (z, z, w, w); }
-Vector4 Vector4::wzww() const { return Vector4 (w, z, w, w); }
-Vector4 Vector4::xwww() const { return Vector4 (x, w, w, w); }
-Vector4 Vector4::ywww() const { return Vector4 (y, w, w, w); }
-Vector4 Vector4::zwww() const { return Vector4 (z, w, w, w); }
-Vector4 Vector4::wwww() const { return Vector4 (w, w, w, w); }
-
-
-}; // namespace
diff --git a/externals/g3dlite/G3D.lib/source/Vector4int8.cpp b/externals/g3dlite/G3D.lib/source/Vector4int8.cpp
deleted file mode 100644
index 29ca0d678fc..00000000000
--- a/externals/g3dlite/G3D.lib/source/Vector4int8.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- @file Vector4int8.cpp
-
- Homogeneous vector class.
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2007-02-09
- @edited 2007-02-09
-
- Copyright 2000-2007, Morgan McGuire.
- All rights reserved.
- */
-
-#include "G3D/platform.h"
-#include "G3D/Vector4int8.h"
-#include "G3D/Vector3.h"
-#include "G3D/Vector4.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/BinaryOutput.h"
-#include <string>
-
-namespace G3D {
-
-Vector4int8::Vector4int8(const Vector4& source) {
- x = iClamp(iRound(source.x), -128, 127);
- y = iClamp(iRound(source.y), -128, 127);
- z = iClamp(iRound(source.z), -128, 127);
- w = iClamp(iRound(source.w), -128, 127);
-}
-
-Vector4int8::Vector4int8(const Vector3& source, int8 w) : w(w) {
- x = iClamp(iRound(source.x), -128, 127);
- y = iClamp(iRound(source.y), -128, 127);
- z = iClamp(iRound(source.z), -128, 127);
-}
-
-Vector4int8::Vector4int8(class BinaryInput& b) {
- deserialize(b);
-}
-
-void Vector4int8::serialize(class BinaryOutput& b) const {
- // Intentionally write individual bytes to avoid endian issues
- b.writeInt8(x);
- b.writeInt8(y);
- b.writeInt8(z);
- b.writeInt8(w);
-}
-
-void Vector4int8::deserialize(class BinaryInput& b) {
- x = b.readInt8();
- y = b.readInt8();
- z = b.readInt8();
- w = b.readInt8();
-}
-
-} // namespace G3D
-
diff --git a/externals/g3dlite/G3D.lib/source/WinMain.cpp b/externals/g3dlite/G3D.lib/source/WinMain.cpp
deleted file mode 100644
index 94653de4d43..00000000000
--- a/externals/g3dlite/G3D.lib/source/WinMain.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- Dervied from SDL_main.c, which was placed in the public domain by Sam Lantinga 4/13/98
-
- The WinMain function -- calls your program's main() function
-*/
-
-#include "G3D/platform.h"
-
-#ifdef G3D_WIN32
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <cctype>
-
-#ifdef main
-# ifndef _WIN32_WCE_EMULATION
-# undef main
-# endif /* _WIN32_WCE_EMULATION */
-#endif /* main */
-
-#if defined(_WIN32_WCE) && _WIN32_WCE < 300
-/* seems to be undefined in Win CE although in online help */
-#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t'))
-#endif /* _WIN32_WCE < 300 */
-
-// Turn off the G3D for loop scoping for C++
-#ifdef for
-# undef for
-#endif
-
-extern int main(int argc, const char** argv);
-
-/* Parse a command line buffer into arguments */
-static int ParseCommandLine(char *cmdline, char **argv) {
- char *bufp;
- int argc;
-
- argc = 0;
- for (bufp = cmdline; *bufp;) {
- /* Skip leading whitespace */
- while (isspace(*bufp)) {
- ++bufp;
- }
- /* Skip over argument */
- if (*bufp == '"') {
- ++bufp;
- if (*bufp) {
- if (argv) {
- argv[argc] = bufp;
- }
- ++argc;
- }
- /* Skip over word */
- while (*bufp && (*bufp != '"')) {
- ++bufp;
- }
- } else {
- if (*bufp) {
- if (argv) {
- argv[argc] = bufp;
- }
- ++argc;
- }
- /* Skip over word */
- while (*bufp && !isspace(*bufp)) {
- ++bufp;
- }
- }
- if (*bufp) {
- if (argv) {
- *bufp = '\0';
- }
- ++bufp;
- }
- }
- if (argv) {
- argv[argc] = NULL;
- }
- return (argc);
-}
-
-/* Show an error message */
-static void ShowError(const char *title, const char *message) {
-/* If USE_MESSAGEBOX is defined, you need to link with user32.lib */
-#ifdef USE_MESSAGEBOX
- MessageBox(NULL, message, title, MB_ICONEXCLAMATION | MB_OK);
-#else
- fprintf(stderr, "%s: %s\n", title, message);
-#endif
-}
-
-/* Pop up an out of memory message, returns to Windows */
-static BOOL OutOfMemory(void) {
- ShowError("Fatal Error", "Out of memory - aborting");
- return FALSE;
-}
-
-
-int WINAPI G3D_WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {
- char **argv;
- int argc;
- int status;
- char *cmdline;
-# ifdef _WIN32_WCE
- wchar_t *bufp;
- int nLen;
-# else
- char *bufp;
- size_t nLen;
-# endif
-
-#ifdef _WIN32_WCE
-#error WinCE not supported
- /*
- nLen = wcslen(szCmdLine) + 128 + 1;
- bufp = SDL_stack_alloc(wchar_t, nLen * 2);
- wcscpy(bufp, TEXT("\""));
- GetModuleFileName(NULL, bufp + 1, 128 - 3);
- wcscpy(bufp + wcslen(bufp), TEXT("\" "));
- wcsncpy(bufp + wcslen(bufp), szCmdLine, nLen - wcslen(bufp));
- nLen = wcslen(bufp) + 1;
- cmdline = SDL_stack_alloc(char, nLen);
- if (cmdline == NULL) {
- return OutOfMemory();
- }
- WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL);
- */
-#else
- /* Grab the command line */
- bufp = GetCommandLineA();
- nLen = strlen(bufp) + 1;
- cmdline = (char*)malloc(sizeof(char) * nLen);
- if (cmdline == NULL) {
- return OutOfMemory();
- }
- strncpy(cmdline, bufp, nLen);
-#endif
-
- /* Parse it into argv and argc */
- argc = ParseCommandLine(cmdline, NULL);
- argv = (char**)malloc(sizeof(char*) * (argc + 1));
- if (argv == NULL) {
- return OutOfMemory();
- }
- ParseCommandLine(cmdline, argv);
-
- /* Run the main program */
- status = main(argc, (const char**)argv);
- free(argv);
- free(cmdline);
-
- return status;
-}
-
-#endif // if Win32
diff --git a/externals/g3dlite/G3D.lib/source/debugAssert.cpp b/externals/g3dlite/G3D.lib/source/debugAssert.cpp
deleted file mode 100644
index 4b24546a661..00000000000
--- a/externals/g3dlite/G3D.lib/source/debugAssert.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/**
- @file debugAssert.cpp
-
- Windows implementation of assertion routines.
-
- @maintainer Morgan McGuire, graphics3d.com
-
- @created 2001-08-26
- @edited 2006-02-02
- */
-
-#include "G3D/debugAssert.h"
-#include "G3D/platform.h"
-#ifdef G3D_WIN32
- #include <tchar.h>
-#endif
-#include "G3D/format.h"
-#include "G3D/prompt.h"
-#include <string>
-#include "G3D/debugPrintf.h"
-#include "G3D/Log.h"
-
-#include <cstdlib>
-
-#ifdef _MSC_VER
- // disable: "C++ exception handler used"
-# pragma warning (push)
-# pragma warning (disable : 4530)
-#endif
-
-using namespace std;
-
-namespace G3D { namespace _internal {
-
-ConsolePrintHook _consolePrintHook;
-AssertionHook _debugHook = _handleDebugAssert_;
-AssertionHook _failureHook = _handleErrorCheck_;
-
-#ifdef G3D_LINUX
- Display* x11Display = NULL;
- Window x11Window = 0;
-#endif
-
-
-#ifdef G3D_WIN32
-static void postToClipboard(const char *text) {
- if (OpenClipboard(NULL)) {
- HGLOBAL hMem = GlobalAlloc(GHND | GMEM_DDESHARE, strlen(text) + 1);
- if (hMem) {
- char *pMem = (char*)GlobalLock(hMem);
- strcpy(pMem, text);
- GlobalUnlock(hMem);
-
- EmptyClipboard();
- SetClipboardData(CF_TEXT, hMem);
- }
-
- CloseClipboard();
- GlobalFree(hMem);
- }
-}
-#endif
-
-/**
- outTitle should be set before the call
- */
-static void createErrorMessage(
- const char* expression,
- const std::string& message,
- const char* filename,
- int lineNumber,
- std::string& outTitle,
- std::string& outMessage) {
-
- std::string le = "";
- const char* newline = "\n";
-
- #ifdef G3D_WIN32
- newline = "\r\n";
-
- // The last error value. (Which is preserved across the call).
- DWORD lastErr = GetLastError();
-
- // The decoded message from FormatMessage
- LPTSTR formatMsg = NULL;
-
- if (NULL == formatMsg) {
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_IGNORE_INSERTS |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- lastErr,
- 0,
- (LPTSTR)&formatMsg,
- 0,
- NULL);
- }
-
- // Make sure the message got translated into something.
- LPTSTR realLastErr;
- if (NULL != formatMsg) {
- realLastErr = formatMsg;
- } else {
- realLastErr = _T("Last error code does not exist.");
- }
-
- if (lastErr != 0) {
- le = G3D::format("Last Error (0x%08X): %s\r\n\r\n", lastErr, (LPCSTR)realLastErr);
- }
-
- // Get rid of the allocated memory from FormatMessage.
- if (NULL != formatMsg) {
- LocalFree((LPVOID)formatMsg);
- }
-
- char modulePath[MAX_PATH];
- GetModuleFileNameA(NULL, modulePath, MAX_PATH);
-
- const char* moduleName = strrchr(modulePath, '\\');
- outTitle = outTitle + string(" - ") + string(moduleName ? (moduleName + 1) : modulePath);
-
- #endif
-
- // Build the message.
- outMessage =
- G3D::format("%s%s%sExpression: %s%s%s:%d%s%s%s",
- message.c_str(), newline, newline, expression, newline,
- filename, lineNumber, newline, newline, le.c_str());
-}
-
-
-bool _handleDebugAssert_(
- const char* expression,
- const std::string& message,
- const char* filename,
- int lineNumber,
- bool& ignoreAlways,
- bool useGuiPrompt) {
-
- std::string dialogTitle = "Assertion Failure";
- std::string dialogText = "";
- createErrorMessage(expression, message, filename, lineNumber, dialogTitle, dialogText);
-
- #ifdef G3D_WIN32
- DWORD lastErr = GetLastError();
- postToClipboard(dialogText.c_str());
- debugPrintf("\n%s\n", dialogText.c_str());
- #endif
-
- const int cBreak = 0;
- const int cIgnore = 1;
- const int cIgnoreAlways = 2;
- const int cAbort = 3;
-
- static const char* choices[] = {"Debug", "Ignore", "Ignore Always", "Exit"};
-
- // Log the error
- Log::common()->print(std::string("\n**************************\n\n") + dialogTitle + "\n" + dialogText);
-
- int result = G3D::prompt(dialogTitle.c_str(), dialogText.c_str(), (const char**)choices, 4, useGuiPrompt);
-
-# ifdef G3D_WIN32
- // Put the incoming last error back.
- SetLastError(lastErr);
-# endif
-
- switch (result) {
- // -1 shouldn't actually occur because it means
- // that we're in release mode.
- case -1:
- case cBreak:
- return true;
- break;
-
- case cIgnore:
- return false;
- break;
-
- case cIgnoreAlways:
- ignoreAlways = true;
- return false;
- break;
-
- case cAbort:
- exit(-1);
- break;
- }
-
- // Should never get here
- return false;
-}
-
-
-bool _handleErrorCheck_(
- const char* expression,
- const std::string& message,
- const char* filename,
- int lineNumber,
- bool& ignoreAlways,
- bool useGuiPrompt) {
-
- (void)ignoreAlways;
-
- std::string dialogTitle = "Critical Error";
- std::string dialogText = "";
-
- createErrorMessage(expression, message, filename, lineNumber, dialogTitle, dialogText);
-
- // Log the error
- Log::common()->print(std::string("\n**************************\n\n") + dialogTitle + "\n" + dialogText);
- #ifdef G3D_WIN32
- DWORD lastErr = GetLastError();
- postToClipboard(dialogText.c_str());
- debugPrintf("\n%s\n", dialogText.c_str());
- #endif
-
- static const char* choices[] = {"Ok"};
-
- std::string m =
- std::string("An internal error has occured in your program and it will now close. Details about the error have been reported in \"") +
- Log::getCommonLogFilename() + "\".";
-
- int result = G3D::prompt("Error", m.c_str(), (const char**)choices, 1, useGuiPrompt);
- (void)result;
-
- return true;
-}
-
-
-#ifdef G3D_WIN32
-static HCURSOR oldCursor;
-static RECT oldCursorRect;
-static POINT oldCursorPos;
-static int oldShowCursorCount;
-#endif
-
-void _releaseInputGrab_() {
- #ifdef G3D_WIN32
-
- GetCursorPos(&oldCursorPos);
-
- // Stop hiding the cursor if the application hid it.
- oldShowCursorCount = ShowCursor(true) - 1;
-
- if (oldShowCursorCount < -1) {
- for (int c = oldShowCursorCount; c < -1; ++c) {
- ShowCursor(true);
- }
- }
-
- // Set the default cursor in case the application
- // set the cursor to NULL.
- oldCursor = GetCursor();
- SetCursor(LoadCursor(NULL, IDC_ARROW));
-
- // Allow the cursor full access to the screen
- GetClipCursor(&oldCursorRect);
- ClipCursor(NULL);
-
- #elif defined(G3D_LINUX)
- if (x11Display != NULL) {
- XUngrabPointer(x11Display, CurrentTime);
- XUngrabKeyboard(x11Display, CurrentTime);
- if (x11Window != 0) {
- //XUndefineCursor(x11Display, x11Window);
- // TODO: Note that we leak this cursor; it should be
- // freed in the restore code.
- Cursor c = XCreateFontCursor(x11Display, 68);
- XDefineCursor(x11Display, x11Window, c);
- }
- XSync(x11Display, false);
- XAllowEvents(x11Display, AsyncPointer, CurrentTime);
- XFlush(x11Display);
- }
- #elif defined(G3D_OSX)
- // TODO: OS X
- #endif
-}
-
-
-void _restoreInputGrab_() {
- #ifdef G3D_WIN32
-
- // Restore the old clipping region
- ClipCursor(&oldCursorRect);
-
- SetCursorPos(oldCursorPos.x, oldCursorPos.y);
-
- // Restore the old cursor
- SetCursor(oldCursor);
-
- // Restore old visibility count
- if (oldShowCursorCount < 0) {
- for (int c = 0; c > oldShowCursorCount; --c) {
- ShowCursor(false);
- }
- }
-
- #elif defined(G3D_LINUX)
- // TODO: Linux
- #elif defined(G3D_OSX)
- // TODO: OS X
- #endif
-}
-
-
-}; // internal namespace
-
-void setAssertionHook(AssertionHook hook) {
- G3D::_internal::_debugHook = hook;
-}
-
-AssertionHook assertionHook() {
- return G3D::_internal::_debugHook;
-}
-
-void setFailureHook(AssertionHook hook) {
- G3D::_internal::_failureHook = hook;
-}
-
-AssertionHook failureHook() {
- return G3D::_internal::_failureHook;
-}
-
-
-void setConsolePrintHook(ConsolePrintHook h) {
- G3D::_internal::_consolePrintHook = h;
-}
-
-ConsolePrintHook consolePrintHook() {
- return G3D::_internal::_consolePrintHook;
-}
-
-
-std::string __cdecl debugPrint(const std::string& s) {
-# ifdef G3D_WIN32
- const int MAX_STRING_LEN = 1024;
-
- // Windows can't handle really long strings sent to
- // the console, so we break the string.
- if (s.size() < MAX_STRING_LEN) {
- OutputDebugStringA(s.c_str());
- } else {
- for (unsigned int i = 0; i < s.size(); i += MAX_STRING_LEN) {
- std::string sub = s.substr(i, MAX_STRING_LEN);
- OutputDebugStringA(sub.c_str());
- }
- }
-# else
- fprintf(stderr, "%s", s.c_str());
- fflush(stderr);
-# endif
-
- return s;
-}
-
-std::string __cdecl debugPrintf(const char* fmt ...) {
- va_list argList;
- va_start(argList, fmt);
- std::string s = G3D::vformat(fmt, argList);
- va_end(argList);
-
- return debugPrint(consolePrint(s));
-}
-
-std::string consolePrint(const std::string& s) {
- FILE* L = Log::common()->getFile();
- fprintf(L, "%s", s.c_str());
-
- if (consolePrintHook()) {
- consolePrintHook()(s);
- }
-
- fflush(L);
- return s;
-}
-
-
-std::string __cdecl consolePrintf(const char* fmt ...) {
- va_list argList;
- va_start(argList, fmt);
- std::string s = G3D::vformat(fmt, argList);
- va_end(argList);
-
- return consolePrint(s);
-}
-
-} // namespace
-
-#ifdef _MSC_VER
-# pragma warning (pop)
-#endif
diff --git a/externals/g3dlite/G3D.lib/source/fileutils.cpp b/externals/g3dlite/G3D.lib/source/fileutils.cpp
deleted file mode 100644
index 3a5e8c715c8..00000000000
--- a/externals/g3dlite/G3D.lib/source/fileutils.cpp
+++ /dev/null
@@ -1,1092 +0,0 @@
-/**
- @file fileutils.cpp
-
- @author Morgan McGuire, graphics3d.com
-
- @author 2002-06-06
- @edited 2008-01-20
- */
-
-#include "G3D/platform.h"
-#include "G3D/fileutils.h"
-#include "G3D/BinaryInput.h"
-#include "G3D/g3dmath.h"
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <zip/zip.h>
-#include <zip/unzip.h>
-#include "G3D/stringutils.h"
-#include "G3D/Set.h"
-
-#include <cstring>
-
-#ifdef G3D_WIN32
- // Needed for _getcwd
- #include <direct.h>
- #include <io.h>
-#else
- #include <dirent.h>
- #include <fnmatch.h>
- #include <unistd.h>
- #define _getcwd getcwd
-#endif
-#include <stdio.h>
-#include "G3D/BinaryOutput.h"
-
-#ifdef G3D_WIN32
- //for _mkdir and _stat
-# include <direct.h>
-#else
-# define _stat stat
-#endif
-
-
-namespace G3D {
-
-namespace _internal {
- Set<std::string> currentFilesUsed;
-}
-
-std::string pathConcat(const std::string& dirname, const std::string& file) {
- // Ensure that the directory ends in a slash
- if ((dirname.size() != 0) &&
- (dirname[dirname.size() - 1] != '/') &&
- (dirname[dirname.size() - 1] != '\\') &&
- (dirname[dirname.size() - 1] != ':')) {
- return dirname + '/' + file;
- } else {
- return dirname + file;
- }
-}
-
-std::string resolveFilename(const std::string& filename) {
- if (filename.size() >= 1) {
- if ((filename[0] == '/') || (filename[0] == '\\')) {
- // Already resolved
- return filename;
- } else {
-
- #ifdef G3D_WIN32
- if ((filename.size() >= 2) && (filename[1] == ':')) {
- // There is a drive spec on the front.
- if ((filename.size() >= 3) && ((filename[2] == '\\') ||
- (filename[2] == '/'))) {
- // Already fully qualified
- return filename;
- } else {
- // The drive spec is relative to the
- // working directory on that drive.
- debugAssertM(false, "Files of the form d:path are"
- " not supported (use a fully qualified"
- " name).");
- return filename;
- }
- }
- #endif
- }
- }
-
- char buffer[1024];
-
- // Prepend the working directory.
- _getcwd(buffer, 1024);
-
- return format("%s/%s", buffer, filename.c_str());
-}
-
-bool zipfileExists(const std::string& filename) {
- std::string outZipfile;
- std::string outInternalFile;
- return zipfileExists(filename, outZipfile, outInternalFile);
-}
-
-std::string readWholeFile(
- const std::string& filename) {
-
- _internal::currentFilesUsed.insert(filename);
-
- std::string s;
-
- debugAssert(filename != "");
- if (fileExists(filename, false)) {
-
- int64 length = fileLength(filename);
-
- char* buffer = (char*)System::alignedMalloc(length + 1, 16);
- debugAssert(buffer);
- FILE* f = fopen(filename.c_str(), "rb");
- debugAssert(f);
- int ret = fread(buffer, 1, length, f);
- debugAssert(ret == length);(void)ret;
- fclose(f);
-
- buffer[length] = '\0';
- s = std::string(buffer);
-
- System::alignedFree(buffer);
-
- } else if (zipfileExists(filename)) {
-
- void* zipBuffer;
- size_t length;
- zipRead(filename, zipBuffer, length);
-
- char* buffer = (char*)System::alignedMalloc(length + 1, 16);
- System::memcpy(buffer,zipBuffer, length + 1);
- zipClose(zipBuffer);
-
- buffer[length] = '\0';
- s = std::string(buffer);
- System::alignedFree(buffer);
- } else {
- debugAssertM(false, filename + " not found");
- }
-
- return s;
-}
-
-
-void zipRead(const std::string& file,
- void*& data,
- size_t& length) {
- std::string zip, desiredFile;
-
- if (zipfileExists(file, zip, desiredFile)) {
- unzFile f = unzOpen(zip.c_str());
- {
- unzLocateFile(f, desiredFile.c_str(), 2);
- unz_file_info info;
- unzGetCurrentFileInfo(f, &info, NULL, 0, NULL, 0, NULL, 0);
- length = info.uncompressed_size;
- // sets machines up to use MMX, if they want
- data = System::alignedMalloc(length, 16);
- unzOpenCurrentFile(f);
- {
- int test = unzReadCurrentFile(f, data, length);
- debugAssertM((size_t)test == length,
- desiredFile + " was corrupt because it unzipped to the wrong size.");
- (void)test;
- }
- unzCloseCurrentFile(f);
- }
- unzClose(f);
- } else {
- data = NULL;
- }
-}
-
-
-void zipClose(void* data) {
- System::alignedFree(data);
-}
-
-
-int64 fileLength(const std::string& filename) {
- struct _stat st;
- int result = _stat(filename.c_str(), &st);
-
- if (result == -1) {
- std::string zip, contents;
- if(zipfileExists(filename, zip, contents)){
- int64 requiredMem;
-
- unzFile f = unzOpen(zip.c_str());
- {
- unzLocateFile(f, contents.c_str(), 2);
- unz_file_info info;
- unzGetCurrentFileInfo(f, &info, NULL, 0, NULL, 0, NULL, 0);
- requiredMem = info.uncompressed_size;
- }
- unzClose(f);
- return requiredMem;
- } else {
- return -1;
- }
- }
-
- return st.st_size;
-}
-
-/** Used by robustTmpfile. Returns nonzero if fread, fwrite, and fseek all
-succeed on the file.
- @author Morgan McGuire, morgan@graphics3d.com */
-static int isFileGood(FILE* f) {
-
- int x, n, result;
-
- /* Must be a valid file handle */
- if (f == NULL) {
- return 0;
- }
-
- /* Try to write */
- x = 1234;
- n = fwrite(&x, sizeof(int), 1, f);
-
- if (n != 1) {
- return 0;
- }
-
- /* Seek back to the beginning */
- result = fseek(f, 0, SEEK_SET);
- if (result != 0) {
- return 0;
- }
-
- /* Read */
- n = fread(&x, sizeof(int), 1, f);
- if (n != 1) {
- return 0;
- }
-
- /* Seek back to the beginning again */
- fseek(f, 0, SEEK_SET);
-
- return 1;
-}
-
-FILE* createTempFile() {
- FILE* t = NULL;
-
-//# ifdef G3D_WIN32
- t = tmpfile();
-//# else
-// // On Unix, tmpfile generates a warning for any code that links against it.
-// const char* tempfilename = "/tmp/g3dtemp.XXXXXXXX";
-// mktemp(tempfilename);
-// t = fopen(tempfilename, "w");
-//# endif
-
-# ifdef _WIN32
- char* n = NULL;
-# endif
- char name[256];
-
- if (isFileGood(t)) {
- return t;
- }
-
-# ifdef G3D_WIN32
- /* tmpfile failed; try the tmpnam routine */
- t = fopen(tmpnam(NULL), "w+");
- if (isFileGood(t)) {
- return t;
- }
-
- n = _tempnam("c:/tmp/", "t");
- /* Try to create something in C:\tmp */
- t = fopen(n, "w+");
- if (isFileGood(t)) {
- return t;
- }
-
- /* Try c:\temp */
- n = _tempnam("c:/temp/", "t");
- t = fopen(n, "w+");
- if (isFileGood(t)) {
- return t;
- }
-
- /* try the current directory */
- n = _tempnam("./", "t");
- t = fopen(n, "w+");
- if (isFileGood(t)) {
- return t;
- }
-
- sprintf(name, "%s/tmp%d", "c:/temp", rand());
- t = fopen(name, "w+");
- if (isFileGood(t)) {
- return t;
- }
-
- /* Try some hardcoded paths */
- sprintf(name, "%s/tmp%d", "c:/tmp", rand());
- t = fopen(name, "w+");
- if (isFileGood(t)) {
- return t;
- }
-# else
- sprintf(name, "%s/tmp%d", "/tmp", rand());
- t = fopen(name, "w+");
- if (isFileGood(t)) {
- return t;
- }
-#endif
-
- sprintf(name, "tmp%d", rand());
- t = fopen(name, "w+");
- if (isFileGood(t)) {
- return t;
- }
-
- fprintf(stderr, "Unable to create a temporary file; robustTmpfile returning NULL\n");
-
- return NULL;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-void writeWholeFile(
- const std::string& filename,
- const std::string& str,
- bool flush) {
-
- // Make sure the directory exists.
- std::string root, base, ext, path;
- Array<std::string> pathArray;
- parseFilename(filename, root, pathArray, base, ext);
-
- path = root + stringJoin(pathArray, '/');
- if (! fileExists(path, false)) {
- createDirectory(path);
- }
-
- FILE* file = fopen(filename.c_str(), "wb");
-
- debugAssert(file);
-
- fwrite(str.c_str(), str.size(), 1, file);
-
- if (flush) {
- fflush(file);
- }
- fclose(file);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- Creates the directory (which may optionally end in a /)
- and any parents needed to reach it.
- */
-void createDirectory(
- const std::string& dir) {
-
- if (dir == "") {
- return;
- }
-
- std::string d;
-
- // Add a trailing / if there isn't one.
- switch (dir[dir.size() - 1]) {
- case '/':
- case '\\':
- d = dir;
- break;
-
- default:
- d = dir + "/";
- }
-
- // If it already exists, do nothing
- if (fileExists(d.substr(0, d.size() - 1)), false) {
- return;
- }
-
- // Parse the name apart
- std::string root, base, ext;
- Array<std::string> path;
-
- std::string lead;
- parseFilename(d, root, path, base, ext);
- debugAssert(base == "");
- debugAssert(ext == "");
-
- // Begin with an extra period so "c:\" becomes "c:\.\" after
- // appending a path and "c:" becomes "c:.\", not root: "c:\"
- std::string p = root + ".";
-
- // Create any intermediate that doesn't exist
- for (int i = 0; i < path.size(); ++i) {
- p += "/" + path[i];
- if (! fileExists(p, false)) {
- // Windows only requires one argument to mkdir,
- // where as unix also requires the permissions.
-# ifndef G3D_WIN32
- mkdir(p.c_str(), 0777);
-# else
- _mkdir(p.c_str());
-# endif
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool fileExists(
- const std::string& filename,
- const bool lookInZipfiles) {
-
- if (filename == "") {
- return true;
- }
-
-
- // Useful for debugging
- //char curdir[1024]; _getcwd(curdir, 1024);
-
- struct _stat st;
- int ret = _stat(filename.c_str(), &st);
-
- // _stat returns zero on success
- bool exists = (ret == 0);
-
- if (exists) {
- // Exists
- return true;
- } else if (lookInZipfiles) {
- // Does not exist standalone, but might exist in a zipfile
-
- // These output arguments will be ignored
- std::string zipDir, internalPath;
- return zipfileExists(filename, zipDir, internalPath);
- } else {
- // Does not exist
- return false;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-/* Helper methods for zipfileExists()*/
-// Given a string (the drive) and an array (the path), computes the directory
-static void _zip_resolveDirectory(std::string& completeDir, const std::string& drive, const Array<std::string>& path, const int length){
- completeDir = drive;
- int tempLength;
- // if the given length is longer than the array, we correct it
- if(length > path.length()){
- tempLength = path.length();
- } else{
- tempLength = length;
- }
-
- for(int t = 0; t < tempLength; ++t){
- if(t > 0){
- completeDir += "/";
- }
- completeDir += path[t];
- }
-}
-
-
-// assumes that zipDir references a .zip file
-static bool _zip_zipContains(const std::string& zipDir, const std::string& desiredFile){
- unzFile f = unzOpen(zipDir.c_str());
- //the last parameter, an int, determines case sensitivity:
- //1 is sensitive, 2 is not, 0 is default
- int test = unzLocateFile(f, desiredFile.c_str(), 2);
- unzClose(f);
- if(test == UNZ_END_OF_LIST_OF_FILE){
- return false;
- }
- return true;
-}
-
-
-// If no zipfile exists, outZipfile and outInternalFile are unchanged
-bool zipfileExists(const std::string& filename, std::string& outZipfile,
- std::string& outInternalFile){
- if (fileExists(filename, false)) {
- // Not inside a zipfile if the file itself exists
- return false;
- } else {
- Array<std::string> path;
- std::string drive, base, ext, zipfile, infile;
- parseFilename(filename, drive, path, base, ext);
-
- // Put the filename back together
- if ((base != "") && (ext != "")) {
- infile = base + "." + ext;
- } else {
- infile = base + ext;
- }
-
- // Remove "." from path
- for (int i = 0; i < path.length(); ++i) {
- if (path[i] == ".") {
- path.remove(i);
- --i;
- }
- }
-
- // Remove ".." from path
- for (int i = 1; i < path.length(); ++i) {
- if ((path[i] == "..") && (i > 0) && (path[i - 1] != "..")) {
- // Remove both i and i - 1
- path.remove(i - 1, 2);
- i -= 2;
- }
- }
-
- // Walk the path backwards, accumulating pieces onto the infile until
- // we find a zipfile that contains it
- for (int t = 0; t < path.length(); ++t){
- _zip_resolveDirectory(zipfile, drive, path, path.length() - t);
- if (t > 0) {
- infile = path[path.length() - t] + "/" + infile;
- }
-
- if (fileExists(zipfile, false)) {
- // test if it actually is a zipfile
- // if not, return false, a bad
- // directory structure has been given,
- // not a .zip
- if (isZipfile(zipfile)){
-
- if (_zip_zipContains(zipfile, infile)){
- outZipfile = zipfile;
- outInternalFile = infile;
- return true;
- } else {
- return false;
- }
- } else {
- // the directory structure was valid but did not point to a .zip
- return false;
- }
- }
-
- }
- }
-
- // not a valid directory structure ever,
- // obviously no .zip was found within the path
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-std::string generateFilenameBase(const std::string& prefix) {
- Array<std::string> exist;
-
- // Note "template" is a reserved word in C++
- std::string templat = prefix + System::currentDateString();
- getFiles(templat + "*", exist);
-
- // Remove extensions
- for (int i = 0; i < exist.size(); ++i) {
- exist[i] = filenameBase(exist[i]);
- }
-
- int num = 0;
- std::string result;
- templat += "_%03d";
- do {
- result = format(templat.c_str(), num);
- ++num;
- } while (exist.contains(result));
-
- return result;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void copyFile(
- const std::string& source,
- const std::string& dest) {
-
- #ifdef G3D_WIN32
- CopyFileA(source.c_str(), dest.c_str(), FALSE);
- #else
- // TODO: don't use BinaryInput and BinaryOutput
- // Read it all in, then dump it out
- BinaryInput in(source, G3D_LITTLE_ENDIAN);
- BinaryOutput out(dest, G3D_LITTLE_ENDIAN);
- out.writeBytes(in.getCArray(), in.size());
- out.commit(false);
- #endif
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-void parseFilename(
- const std::string& filename,
- std::string& root,
- Array<std::string>& path,
- std::string& base,
- std::string& ext) {
-
- std::string f = filename;
-
- root = "";
- path.clear();
- base = "";
- ext = "";
-
- if (f == "") {
- // Empty filename
- return;
- }
-
- // See if there is a root/drive spec.
- if ((f.size() >= 2) && (f[1] == ':')) {
-
- if ((f.size() > 2) && isSlash(f[2])) {
-
- // e.g. c:\foo
- root = f.substr(0, 3);
- f = f.substr(3, f.size() - 3);
-
- } else {
-
- // e.g. c:foo
- root = f.substr(2);
- f = f.substr(2, f.size() - 2);
-
- }
-
- } else if ((f.size() >= 2) & isSlash(f[0]) && isSlash(f[1])) {
-
- // e.g. //foo
- root = f.substr(0, 2);
- f = f.substr(2, f.size() - 2);
-
- } else if (isSlash(f[0])) {
-
- root = f.substr(0, 1);
- f = f.substr(1, f.size() - 1);
-
- }
-
- // Pull the extension off
- {
- // Find the period
- size_t i = f.rfind('.');
-
- if (i != std::string::npos) {
- // Make sure it is after the last slash!
- size_t j = iMax(f.rfind('/'), f.rfind('\\'));
- if ((j == std::string::npos) || (i > j)) {
- ext = f.substr(i + 1, f.size() - i - 1);
- f = f.substr(0, i);
- }
- }
- }
-
- // Pull the basename off
- {
- // Find the last slash
- size_t i = iMax(f.rfind('/'), f.rfind('\\'));
-
- if (i == std::string::npos) {
-
- // There is no slash; the basename is the whole thing
- base = f;
- f = "";
-
- } else if ((i != std::string::npos) && (i < f.size() - 1)) {
-
- base = f.substr(i + 1, f.size() - i - 1);
- f = f.substr(0, i);
-
- }
- }
-
- // Parse what remains into path.
- size_t prev, cur = 0;
-
- while (cur < f.size()) {
- prev = cur;
-
- // Allow either slash
- size_t i = f.find('/', prev + 1);
- size_t j = f.find('\\', prev + 1);
- if (i == std::string::npos) {
- i = f.size();
- }
-
- if (j == std::string::npos) {
- j = f.size();
- }
-
- cur = iMin(i, j);
-
- if (cur == std::string::npos) {
- cur = f.size();
- }
-
- path.append(f.substr(prev, cur - prev));
- ++cur;
- }
-}
-
-
-/**
- Helper for getFileList and getDirectoryList.
-
- @param wantFiles If false, returns the directories, otherwise
- returns the files.
- @param includePath If true, the names include paths
- */
-static void getFileOrDirListNormal
-(
- const std::string& filespec,
- Array<std::string>& files,
- bool wantFiles,
- bool includePath) {
-
- bool test = wantFiles ? true : false;
-
- std::string path = "";
-
- // Find the place where the path ends and the file-spec begins
- size_t i = filespec.rfind('/');
- size_t j = filespec.rfind('\\');
-
- // Drive letters on Windows can separate a path
- size_t k = filespec.rfind(':');
-
- if (((j != std::string::npos) && (j > i)) ||
- (i == std::string::npos)) {
- i = j;
- }
-
- if (((k != std::string::npos) && (k > i)) ||
- (i == std::string::npos)) {
- i = k;
- }
-
- // If there is a path, pull it off
- if (i != std::string::npos) {
- path = filespec.substr(0, i + 1);
- }
-
- std::string prefix = path;
-
- if (path.size() > 0) {
- // Strip the trailing character
- path = path.substr(0, path.size() - 1);
- }
-
-# ifdef G3D_WIN32
- {
- struct _finddata_t fileinfo;
-
- long handle = _findfirst(filespec.c_str(), &fileinfo);
- int result = handle;
-
- while (result != -1) {
- if ((((fileinfo.attrib & _A_SUBDIR) == 0) == test) &&
- strcmp(fileinfo.name, ".") &&
- strcmp(fileinfo.name, "..")) {
-
- if (includePath) {
- files.append(prefix + fileinfo.name);
- } else {
- files.append(fileinfo.name);
- }
- }
-
- result = _findnext(handle, &fileinfo);
- }
- }
-# else
- {
- if (path == "") {
- // Empty paths don't work on Unix
- path = ".";
- }
-
- // Unix implementation
- DIR* dir = opendir(path.c_str());
-
- if (dir != NULL) {
- struct dirent* entry = readdir(dir);
-
- while (entry != NULL) {
-
- // Exclude '.' and '..'
- if ((strcmp(entry->d_name, ".") != 0) &&
- (strcmp(entry->d_name, "..") != 0)) {
-
- // Form a name with a path
- std::string filename = prefix + entry->d_name;
- // See if this is a file or a directory
- struct _stat st;
- bool exists = _stat(filename.c_str(), &st) != -1;
-
- if (exists &&
-
- // Make sure it has the correct type
- (((st.st_mode & S_IFDIR) == 0) == test) &&
-
- // Make sure it matches the wildcard
- (fnmatch(filespec.c_str(),
- filename.c_str(),
- FNM_PATHNAME) == 0)) {
-
- if (includePath) {
- files.append(filename);
- } else {
- files.append(entry->d_name);
- }
- }
- }
-
- entry = readdir(dir);
- }
- closedir(dir);
- }
- }
-# endif
-}
-
-/**
-
- c:/temp/foo.zip/plainsky\\*
-" path "
- "prefix "
-
- @param path The zipfile name (no trailing slash)
- @param prefix Directory inside the zipfile. No leading slash, must have trailing slash if non-empty.
- @param file Name inside the zipfile that we are testing to see if it matches prefix + "*"
- */
-static void _zip_addEntry(const std::string& path,
- const std::string& prefix,
- const std::string& file,
- Set<std::string>& files,
- bool wantFiles,
- bool includePath) {
-
- // Make certain we are within the desired parent folder (prefix)
- if (beginsWith(file, prefix)) {
- // validityTest was prefix/file
-
- // Extract everything to the right of the prefix
- std::string s = file.substr(prefix.length());
-
- if (s == "") {
- // This was the name of the prefix
- return;
- }
-
- // See if there are any slashes
- size_t slashPos = s.find('/');
-
- bool add = false;
-
- if (slashPos == std::string::npos) {
- // No slashes, so s must be a file
- add = wantFiles;
- } else if (! wantFiles) {
- // Not all zipfiles list directories as explicit entries.
- // Because of this, if we're looking for directories and see
- // any path longer than prefix, we must add the subdirectory.
- // The Set will fix duplicates for us.
- s = s.substr(0, slashPos);
- add = true;
- }
-
- if (add) {
- if (includePath) {
- files.insert(path + "/" + prefix + s);
- } else {
- files.insert(s);
- }
- }
- }
-}
-
-
-static void getFileOrDirListZip(const std::string& path,
- const std::string& prefix,
- Array<std::string>& files,
- bool wantFiles,
- bool includePath){
- unzFile f = unzOpen(path.c_str());
-
- enum {MAX_STRING_LENGTH=1024};
- char filename[MAX_STRING_LENGTH];
- Set<std::string> fileSet;
-
- do {
-
- // prefix is valid, either "" or a subfolder
- unzGetCurrentFileInfo(f, NULL, filename, MAX_STRING_LENGTH, NULL, 0, NULL, 0);
- _zip_addEntry(path, prefix, filename, fileSet, wantFiles, includePath);
-
- } while (unzGoToNextFile(f) != UNZ_END_OF_LIST_OF_FILE);
-
- unzClose(f);
-
- fileSet.getMembers(files);
-}
-
-
-static void determineFileOrDirList(
- const std::string& filespec,
- Array<std::string>& files,
- bool wantFiles,
- bool includePath) {
-
- // if it is a .zip, prefix will specify the folder within
- // whose contents we want to see
- std::string prefix = "";
- std::string path = filenamePath(filespec);
-
- if ((path.size() > 0) && isSlash(path[path.size() - 1])) {
- // Strip the trailing slash
- path = path.substr(0, path.length() -1);
- }
-
- if (fileExists(path, false)) {
- if (isZipfile(path)) {
- // .zip should only work if * is specified as the Base + Ext
- // Here, we have been asked for the root's contents
- debugAssertM(filenameBaseExt(filespec) == "*", "Can only call getFiles/getDirs on zipfiles using '*' wildcard");
- getFileOrDirListZip(path, prefix, files, wantFiles, includePath);
- } else {
- // It is a normal directory
- getFileOrDirListNormal(filespec, files, wantFiles, includePath);
- }
- } else if (zipfileExists(filenamePath(filespec), path, prefix)) {
- // .zip should only work if * is specified as the Base + Ext
- // Here, we have been asked for the contents of a folder within the .zip
- debugAssertM(filenameBaseExt(filespec) == "*", "Can only call getFiles/getDirs on zipfiles using '*' wildcard");
- getFileOrDirListZip(path, prefix, files, wantFiles, includePath);
- }
-}
-
-
-void getFiles(
- const std::string& filespec,
- Array<std::string>& files,
- bool includePath) {
-
- determineFileOrDirList(filespec, files, true, includePath);
-}
-
-
-void getDirs(
- const std::string& filespec,
- Array<std::string>& files,
- bool includePath) {
-
- determineFileOrDirList(filespec, files, false, includePath);
-}
-
-
-std::string filenameBaseExt(const std::string& filename) {
- int i = filename.rfind("/");
- int j = filename.rfind("\\");
-
- if ((j > i) && (j >= 0)) {
- i = j;
- }
-
-# ifdef G3D_WIN32
- j = filename.rfind(":");
- if ((i == -1) && (j >= 0)) {
- i = j;
- }
-# endif
-
- if (i == -1) {
- return filename;
- } else {
- return filename.substr(i + 1, filename.length() - i);
- }
-}
-
-
-std::string filenameBase(const std::string& s) {
- std::string drive;
- std::string base;
- std::string ext;
- Array<std::string> path;
-
- parseFilename(s, drive, path, base, ext);
- return base;
-}
-
-
-std::string filenameExt(const std::string& filename) {
- int i = filename.rfind(".");
- if (i >= 0) {
- return filename.substr(i + 1, filename.length() - i);
- } else {
- return "";
- }
-}
-
-
-std::string filenamePath(const std::string& filename) {
- int i = filename.rfind("/");
- int j = filename.rfind("\\");
-
- if ((j > i) && (j >= 0)) {
- i = j;
- }
-
-# ifdef G3D_WIN32
- j = filename.rfind(":");
- if ((i == -1) && (j >= 0)) {
- i = j;
- }
-# endif
-
- if (i == -1) {
- return "";
- } else {
- return filename.substr(0, i+1);
- }
-}
-
-
-bool isZipfile(const std::string& filename) {
-
- FILE* f = fopen(filename.c_str(), "r");
- if (f == NULL) {
- return false;
- }
- uint8 header[4];
- fread(header, 4, 1, f);
-
- const uint8 zipHeader[4] = {0x50, 0x4b, 0x03, 0x04};
- for (int i = 0; i < 4; ++i) {
- if (header[i] != zipHeader[i]) {
- fclose(f);
- return false;
- }
- }
-
- fclose(f);
- return true;
-}
-
-
-bool isDirectory(const std::string& filename) {
- struct _stat st;
- bool exists = _stat(filename.c_str(), &st) != -1;
- return exists && ((st.st_mode & S_IFDIR) != 0);
-}
-
-
-bool filenameContainsWildcards(const std::string& filename) {
- return (filename.find('*') != std::string::npos) || (filename.find('?') != std::string::npos);
-}
-
-
-bool fileIsNewer(const std::string& src, const std::string& dst) {
- struct _stat sts;
- bool sexists = _stat(src.c_str(), &sts) != -1;
-
- struct _stat dts;
- bool dexists = _stat(dst.c_str(), &dts) != -1;
-
- return sexists && ((! dexists) || (sts.st_mtime > dts.st_mtime));
-}
-
-
-Array<std::string> filesUsed() {
- Array<std::string> f;
- _internal::currentFilesUsed.getMembers(f);
- return f;
-}
-
-}
-
-#ifndef G3D_WIN32
- #undef _stat
-#endif
diff --git a/externals/g3dlite/G3D.lib/source/filter.cpp b/externals/g3dlite/G3D.lib/source/filter.cpp
deleted file mode 100644
index f6c0467820f..00000000000
--- a/externals/g3dlite/G3D.lib/source/filter.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- @file filter.cpp
-
- @author Morgan McGuire, matrix@graphics3d.com
- @created 2007-03-01
- @edited 2007-03-01
-
- Copyright 2000-2007, Morgan McGuire.
- All rights reserved.
- */
-#include "G3D/filter.h"
-
-namespace G3D {
-
-void gaussian1D(Array<float>& coeff, int N, float std) {
- coeff.resize(N);
- float sum = 0.0f;
- for (int i = 0; i < N; ++i) {
- float x = i - (N - 1) / 2.0f;
- float p = -square(x / std) / 2.0f;
- float y = exp(p);
- coeff[i] = y;
- sum += y;
- }
-
- for (int i = 0; i < N; ++i) {
- coeff[i] /= sum;
- }
-}
-
-
-} // namespace
diff --git a/externals/g3dlite/G3D.lib/source/format.cpp b/externals/g3dlite/G3D.lib/source/format.cpp
deleted file mode 100644
index d9d1b516393..00000000000
--- a/externals/g3dlite/G3D.lib/source/format.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/**
- @file format.cpp
-
- @author Morgan McGuire, graphics3d.com
-
- @created 2000-09-09
- @edited 2006-08-14
-*/
-
-#include "G3D/format.h"
-#include "G3D/platform.h"
-#include "G3D/System.h"
-
-#ifdef _MSC_VER
- // disable: "C++ exception handler used"
-# pragma warning (push)
-# pragma warning (disable : 4530)
-#endif // _MSC_VER
-
-// If your platform does not have vsnprintf, you can find a
-// implementation at http://www.ijs.si/software/snprintf/
-
-namespace G3D {
-
-std::string __cdecl format(const char* fmt,...) {
- va_list argList;
- va_start(argList,fmt);
- std::string result = vformat(fmt, argList);
- va_end(argList);
-
- return result;
-}
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1300)
-// Both MSVC seems to use the non-standard vsnprintf
-// so we are using vscprintf to determine buffer size, however
-// only MSVC7 and up headers include vscprintf for some reason.
-std::string vformat(const char *fmt, va_list argPtr) {
- // We draw the line at a 1MB string.
- const int maxSize = 1000000;
-
- // If the string is less than 161 characters,
- // allocate it on the stack because this saves
- // the malloc/free time.
- const int bufSize = 161;
- char stackBuffer[bufSize];
-
- // MSVC does not support va_copy
- int actualSize = _vscprintf(fmt, argPtr) + 1;
-
- if (actualSize > bufSize) {
-
- // Now use the heap.
- char* heapBuffer = NULL;
-
- if (actualSize < maxSize) {
-
- heapBuffer = (char*)System::malloc(maxSize + 1);
- _vsnprintf(heapBuffer, maxSize, fmt, argPtr);
- heapBuffer[maxSize] = '\0';
- } else {
- heapBuffer = (char*)System::malloc(actualSize);
- vsprintf(heapBuffer, fmt, argPtr);
- }
-
- std::string formattedString(heapBuffer);
- System::free(heapBuffer);
- return formattedString;
- } else {
-
- vsprintf(stackBuffer, fmt, argPtr);
- return std::string(stackBuffer);
- }
-}
-
-#elif defined(_MSC_VER) && (_MSC_VER < 1300)
-
-std::string vformat(const char *fmt, va_list argPtr) {
- // We draw the line at a 1MB string.
- const int maxSize = 1000000;
-
- // If the string is less than 161 characters,
- // allocate it on the stack because this saves
- // the malloc/free time.
- const int bufSize = 161;
- char stackBuffer[bufSize];
-
- // MSVC6 doesn't support va_copy, however it also seems to compile
- // correctly if we just pass our argument list along. Note that
- // this whole code block is only compiled if we're on MSVC6 anyway
- int actualWritten = _vsnprintf(stackBuffer, bufSize, fmt, argPtr);
-
- // Not a big enough buffer, bufSize characters written
- if (actualWritten == -1) {
-
- int heapSize = 512;
- double powSize = 1.0;
- char* heapBuffer = (char*)System::malloc(heapSize);
-
- while ((_vsnprintf(heapBuffer, heapSize, fmt, argPtr) == -1) &&
- (heapSize < maxSize)) {
-
- heapSize = iCeil(heapSize * ::pow((double)2.0, powSize++));
- heapBuffer = (char*)System::realloc(heapBuffer, heapSize);
- }
-
- heapBuffer[heapSize-1] = '\0';
-
- std::string heapString(heapBuffer);
- System::free(heapBuffer);
-
- return heapString;
- } else {
-
- return std::string(stackBuffer);
- }
-}
-
-#else
-
-// glibc 2.1 has been updated to the C99 standard
-std::string vformat(const char* fmt, va_list argPtr) {
- // If the string is less than 161 characters,
- // allocate it on the stack because this saves
- // the malloc/free time. The number 161 is chosen
- // to support two lines of text on an 80 character
- // console (plus the null terminator).
- const int bufSize = 161;
- char stackBuffer[bufSize];
-
- va_list argPtrCopy;
- va_copy(argPtrCopy, argPtr);
- int numChars = vsnprintf(stackBuffer, bufSize, fmt, argPtrCopy);
- va_end(argPtrCopy);
-
- if (numChars >= bufSize) {
- // We didn't allocate a big enough string.
- char* heapBuffer = (char*)System::malloc((numChars + 1) * sizeof(char));
-
- debugAssert(heapBuffer);
- int numChars2 = vsnprintf(heapBuffer, numChars + 1, fmt, argPtr);
- debugAssert(numChars2 == numChars);
- (void)numChars2;
-
- std::string result(heapBuffer);
-
- System::free(heapBuffer);
-
- return result;
-
- } else {
-
- return std::string(stackBuffer);
-
- }
-}
-
-#endif
-
-} // namespace
-
-#ifdef _MSC_VER
-# pragma warning (pop)
-#endif
diff --git a/externals/g3dlite/G3D.lib/source/g3dmath.cpp b/externals/g3dlite/G3D.lib/source/g3dmath.cpp
deleted file mode 100644
index 95c9e16cc24..00000000000
--- a/externals/g3dlite/G3D.lib/source/g3dmath.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- @file g3dmath.cpp
-
- @author Morgan McGuire, graphics3d.com
-
- @created 2001-06-02
- @edited 2004-02-24
- */
-
-#include "G3D/g3dmath.h"
-#include <stdlib.h>
-
-namespace G3D {
-
-float gaussRandom(float mean, float stdev) {
-
- // Using Box-Mueller method from http://www.taygeta.com/random/gaussian.html
- // Modified to specify standard deviation and mean of distribution
- float w, x1, x2;
-
- // Loop until w is less than 1 so that log(w) is negative
- do {
- x1 = uniformRandom(-1.0, 1.0);
- x2 = uniformRandom(-1.0, 1.0);
-
- w = float(square(x1) + square(x2));
- } while (w > 1.0f);
-
- // Transform to gassian distribution
- // Multiply by sigma (stdev ^ 2) and add mean.
- return x2 * (float)square(stdev) * sqrtf((-2.0f * logf(w) ) / w) + mean;
-}
-
-
-int highestBit(uint32 x) {
- // Binary search.
- int base = 0;
-
- if (x & 0xffff0000) {
- base = 16;
- x >>= 16;
- }
- if (x & 0x0000ff00) {
- base += 8;
- x >>= 8;
- }
- if (x & 0x000000f0) {
- base += 4;
- x >>= 4;
- }
-
- static const int lut[] = {-1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3};
- return base + lut[x];
-}
-
-
-int iRandom(int low, int high) {
- int r = iFloor(low + (high - low + 1) * (double)rand() / RAND_MAX);
-
- // There is a *very small* chance of generating
- // a number larger than high.
- if (r > high) {
- return high;
- } else {
- return r;
- }
-}
-
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/license.cpp b/externals/g3dlite/G3D.lib/source/license.cpp
deleted file mode 100644
index b362ad3f45f..00000000000
--- a/externals/g3dlite/G3D.lib/source/license.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- @file license.cpp
-
- @author Morgan McGuire, graphics3d.com
-
- @created 2004-04-15
- @edited 2004-04-15
-*/
-
-#include "G3D/format.h"
-#include <string>
-
-namespace G3D {
-
-std::string license() {
- return format(
-
-"This software is based in part on the PNG Reference Library which is\n"
-"Copyright (c) 2004 Glenn Randers-Pehrson\n\n"
-"This software is based in part on the work of the Independent JPEG Group.\n\n"
-"This software is based on part on the FFmpeg libavformat and libavcodec libraries\n"
-"(\"FFmpeg\", http://ffmpeg.mplayerhq.hu), which are included under the terms of the\n"
-"GNU Lesser General Public License (LGPL), (http://www.gnu.org/copyleft/lesser.html).\n\n"
-"%s"
-"This program uses the G3D Library (http://g3d-cpp.sf.net), which\n"
-"is licensed under the \"BSD\" Open Source license. The Graphics3D library\n"
-"source code is Copyright © 2000-2008, Morgan McGuire, All rights reserved.\n"
-"The BSD license requires the following statement regarding G3D:\n"
-"\n"
-"Redistribution and use in source and binary forms, with or without\n"
-"modification, are permitted provided that the following conditions\n"
-"are met:\n"
-"\n"
-"Redistributions of source code must retain the above copyright\n"
-"notice, this list of conditions and the following disclaimer.\n"
-"\n"
-"Redistributions in binary form must reproduce the above copyright\n"
-"notice, this list of conditions and the following disclaimer in the\n"
-"documentation and/or other materials provided with the distribution.\n"
-"\n"
-"Neither the name of Morgan McGuire, Brown University, Williams College, nor the names\n"
-"of the G3D contributors may be used to endorse or promote products derived\n"
-"from this software without specific prior written permission.\n"
-"\n"
-"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
-"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
-"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
-"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
-"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
-"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
-"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
-"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
-"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
-"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
-"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
-"\n\n"
-"G3D VERSION %d\n",
-
-#ifdef G3D_WIN32
- "" // Win32 doesn't use SDL
-#else
- "This software uses the Simple DirectMedia Layer library (\"SDL\",\n"
- "http://www.libsdl.org), which is included under the terms of the\n"
- "GNU Lesser General Public License, (http://www.gnu.org/copyleft/lesser.html).\n\n"
-#endif
-,
-G3D_VER);
-}
-
-}
diff --git a/externals/g3dlite/G3D.lib/source/prompt.cpp b/externals/g3dlite/G3D.lib/source/prompt.cpp
deleted file mode 100644
index 1fb3bd4cfee..00000000000
--- a/externals/g3dlite/G3D.lib/source/prompt.cpp
+++ /dev/null
@@ -1,716 +0,0 @@
-/**
- @file prompt.cpp
-
- @author Morgan McGuire, morgan@graphics3d.com
- @cite Windows dialog interface by Max McGuire, mmcguire@ironlore.com
- @cite Font setting code by Kurt Miller, kurt@flipcode.com
-
- @created 2000-08-26
- @edited 2005-01-14
- */
-
-#include "G3D/prompt.h"
-#include "G3D/platform.h"
-
-#include <stdio.h>
-
-#ifdef G3D_WIN32
-# include <sstream>
-# include <conio.h>
-#else
-# define _getch getchar
-#endif
-
-#ifdef G3D_OSX
-# include <Carbon/Carbon.h>
-#endif
-
-namespace G3D {
-
-#ifdef G3D_WIN32
-
-namespace _internal {
-/**
- Generic Win32 dialog facility.
- @author Max McGuire
- */
-class DialogTemplate {
-public:
-
- DialogTemplate(LPCSTR caption, DWORD style,
- int x, int y, int w, int h,
- LPCSTR font = NULL, WORD fontSize = 8) {
-
- usedBufferLength = sizeof(DLGTEMPLATE);
- totalBufferLength = usedBufferLength;
-
- dialogTemplate = (DLGTEMPLATE*)malloc(totalBufferLength);
-
- dialogTemplate->style = style;
-
- if (font != NULL) {
- dialogTemplate->style |= DS_SETFONT;
- }
-
- dialogTemplate->x = (short)x;
- dialogTemplate->y = (short)y;
- dialogTemplate->cx = (short)w;
- dialogTemplate->cy = (short)h;
- dialogTemplate->cdit = 0;
-
- dialogTemplate->dwExtendedStyle = 0;
-
- // The dialog box doesn't have a menu or a special class
- AppendData("\0", 2);
- AppendData("\0", 2);
-
- // Add the dialog's caption to the template
-
- AppendString(caption);
-
- if (font != NULL) {
- AppendData(&fontSize, sizeof(WORD));
- AppendString(font);
- }
- }
-
- void AddComponent(LPCSTR type, LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
-
- DLGITEMTEMPLATE item;
-
- item.style = style;
- item.x = (short)x;
- item.y = (short)y;
- item.cx = (short)w;
- item.cy = (short)h;
- item.id = id;
-
- item.dwExtendedStyle = exStyle;
-
- AppendData(&item, sizeof(DLGITEMTEMPLATE));
-
- AppendString(type);
- AppendString(caption);
-
- WORD creationDataLength = 0;
- AppendData(&creationDataLength, sizeof(WORD));
-
- // Increment the component count
- dialogTemplate->cdit++;
-
- }
-
-
- void AddButton(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
-
- AddStandardComponent(0x0080, caption, style, exStyle, x, y, w, h, id);
-
- WORD creationDataLength = 0;
- AppendData(&creationDataLength, sizeof(WORD));
-
- }
-
-
- void AddEditBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
-
- AddStandardComponent(0x0081, caption, style, exStyle, x, y, w, h, id);
-
- WORD creationDataLength = 0;
- AppendData(&creationDataLength, sizeof(WORD));
-
- }
-
-
- void AddStatic(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
-
- AddStandardComponent(0x0082, caption, style, exStyle, x, y, w, h, id);
-
- WORD creationDataLength = 0;
- AppendData(&creationDataLength, sizeof(WORD));
-
- }
-
-
- void AddListBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
-
- AddStandardComponent(0x0083, caption, style, exStyle, x, y, w, h, id);
-
- WORD creationDataLength = sizeof(WORD) + 5 * sizeof(WCHAR);
- AppendData(&creationDataLength, sizeof(WORD));
-
- AppendString("TEST");
-
- }
-
-
- void AddScrollBar(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
-
- AddStandardComponent(0x0084, caption, style, exStyle, x, y, w, h, id);
-
- WORD creationDataLength = 0;
- AppendData(&creationDataLength, sizeof(WORD));
-
- }
-
-
- void AddComboBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y, int w, int h, WORD id) {
-
- AddStandardComponent(0x0085, caption, style, exStyle, x, y, w, h, id);
-
- WORD creationDataLength = 0;
- AppendData(&creationDataLength, sizeof(WORD));
-
- }
-
-
- /**
- *
- * Returns a pointer to the Win32 dialog template which the object
- * represents. This pointer may become invalid if additional components
- * are added to the template.
- *
- */
- operator const DLGTEMPLATE*() const {
- return dialogTemplate;
- }
-
- virtual ~DialogTemplate() {
- free(dialogTemplate);
- }
-
-protected:
-
- void AddStandardComponent(WORD type, LPCSTR caption, DWORD style, DWORD exStyle,
- int x, int y, int w, int h, WORD id, LPSTR font = NULL, WORD fontSize = 8) {
-
- DLGITEMTEMPLATE item;
-
- // DWORD align the beginning of the component data
-
- AlignData(sizeof(DWORD));
-
- item.style = style;
- if (font != NULL) {
- item.style |= DS_SETFONT;
- }
- item.x = (short)x;
- item.y = (short)y;
- item.cx = (short)w;
- item.cy = (short)h;
- item.id = id;
-
- item.dwExtendedStyle = exStyle;
-
- AppendData(&item, sizeof(DLGITEMTEMPLATE));
-
- WORD preType = 0xFFFF;
-
- AppendData(&preType, sizeof(WORD));
- AppendData(&type, sizeof(WORD));
-
- AppendString(caption);
-
- if (font != NULL) {
- AppendData(&fontSize, sizeof(WORD));
- AppendString(font);
- }
-
- // Increment the component count
- dialogTemplate->cdit++;
- }
-
-
- void AlignData(int size) {
-
- int paddingSize = usedBufferLength % size;
-
- if (paddingSize != 0) {
- EnsureSpace(paddingSize);
- usedBufferLength += paddingSize;
- }
-
- }
-
- void AppendString(LPCSTR string) {
-
- int length = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0);
-
- WCHAR* wideString = (WCHAR*)malloc(sizeof(WCHAR) * length);
- MultiByteToWideChar(CP_ACP, 0, string, -1, wideString, length);
-
- AppendData(wideString, length * sizeof(WCHAR));
- free(wideString);
-
- }
-
- void AppendData(const void* data, int dataLength) {
-
- EnsureSpace(dataLength);
-
- memcpy((char*)dialogTemplate + usedBufferLength, data, dataLength);
- usedBufferLength += dataLength;
-
- }
-
- void EnsureSpace(int length) {
- if (length + usedBufferLength > totalBufferLength) {
- totalBufferLength += length * 2;
-
- void* newBuffer = malloc(totalBufferLength);
- memcpy(newBuffer, dialogTemplate, usedBufferLength);
-
- free(dialogTemplate);
- dialogTemplate = (DLGTEMPLATE*)newBuffer;
- }
- }
-
-private:
-
- DLGTEMPLATE* dialogTemplate;
-
- int totalBufferLength;
- int usedBufferLength;
-
-};
-
-
-struct PromptParams {
- const char* message;
- const char* title;
-};
-
-/**
- * Constants for controls.
- */
-#define IDC_MESSAGE 1000
-#define IDC_BUTTON0 2000
-
-INT_PTR CALLBACK PromptDlgProc(HWND hDlg, UINT msg,
- WPARAM wParam, LPARAM lParam) {
- switch(msg) {
- case WM_INITDIALOG:
- {
- PromptParams *params = (PromptParams*)lParam;
- ::SetWindowTextA(::GetDlgItem(hDlg, IDC_MESSAGE), params->message);
-
- ::SetFocus(::GetDlgItem(hDlg, IDC_BUTTON0));
-
- SetWindowTextA(hDlg, params->title);
-
- HFONT hfont =
- CreateFontA(16, 0, 0, 0, FW_NORMAL,
- FALSE, FALSE, FALSE,
- ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
- PROOF_QUALITY, FIXED_PITCH | FF_MODERN, "Courier New");
-
- SendDlgItemMessage(hDlg, IDC_MESSAGE, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE,0));
-
-
- break;
- }
- case WM_COMMAND:
- {
- int choiceNumber = LOWORD(wParam) - IDC_BUTTON0;
- if ((choiceNumber >= 0) && (choiceNumber < 10)) {
- EndDialog(hDlg, choiceNumber);
- return TRUE;
- }
- }
-
- break;
-
- case WM_NCDESTROY:
- // Under SDL 1.2.6 we get a NCDESTROY message for no reason and the
- // window is immediately closed. This is here to debug the problem.
- (void)0;
- break;
-
- }
-
- return FALSE;
-}
-
-}; // namespace _internal
-
-
-using namespace _internal;
-
-/**
- * Show a dialog prompt.
- */
-static int guiPrompt(
- const char* windowTitle,
- const char* prompt,
- const char** choice,
- int numChoices) {
-
- int width = 280;
- int height = 128;
-
- const int buttonSpacing = 2;
- const int buttonWidth =
- (width - buttonSpacing * 2 -
- buttonSpacing * (numChoices - 1)) / numChoices;
- const int buttonHeight = 13;
-
-
- DialogTemplate dialogTemplate(
- windowTitle,
- WS_CAPTION | DS_CENTER | WS_SYSMENU,
- 10, 10, width, height,
- "Tahoma");
-
- dialogTemplate.AddEditBox(
- "Edit", WS_VISIBLE | ES_READONLY | ES_OEMCONVERT | ES_MULTILINE | WS_TABSTOP, WS_EX_STATICEDGE,
- 2, 2, width - 4, height - buttonHeight - 7, IDC_MESSAGE);
-
- int i;
- for (i = 0; i < numChoices; i++) {
-
- int x = buttonSpacing + i * (buttonWidth + buttonSpacing);
- int y = height - buttonHeight - buttonSpacing;
-
- dialogTemplate.AddButton(choice[i], WS_VISIBLE | WS_TABSTOP, 0,
- x, y, buttonWidth, buttonHeight, IDC_BUTTON0 + (WORD)i);
-
- }
-
- // Convert all single \n characters to \r\n for proper printing
- int strLen = 0;
- const char* pStr = prompt;
-
- while (*pStr != '\0') {
- if ((*pStr == '\n') && (pStr != prompt)) {
- if (*(pStr - 1) != '\r') {
- ++strLen;
- }
- }
- ++strLen;
- ++pStr;
- }
-
- char* newStr = (char*)malloc(strLen + 1);
-
- const char* pStr2 = prompt;
- char* pNew = newStr;
-
- while (*pStr2 != '\0') {
- if ((*pStr2 == '\n') && (pStr2 != prompt)) {
- if (*(pStr2 - 1) != '\r') {
- *pNew = '\r';
- ++pNew;
- }
- }
- *pNew = *pStr2;
- ++pNew;
- ++pStr2;
- }
-
- *pNew = '\0';
-
- PromptParams params;
- params.message = newStr;;
- params.title = windowTitle;
-
- HMODULE module = GetModuleHandle(0);
- int ret = DialogBoxIndirectParam(module, dialogTemplate, NULL, (DLGPROC) PromptDlgProc, (DWORD)&params);
-
- free(newStr);
-
- /*
- For debugging when DialogBoxIndirectParam fails:
-
- // The last error value. (Which is preserved across the call).
- DWORD lastErr = GetLastError();
-
- // The decoded message from FormatMessage
- LPTSTR formatMsg = NULL;
-
- if (NULL == formatMsg) {
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_IGNORE_INSERTS |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- lastErr,
- 0,
- (LPTSTR)&formatMsg,
- 0,
- NULL);
- }
-
- // Make sure the message got translated into something.
- LPTSTR realLastErr;
- if (NULL != formatMsg) {
- realLastErr = formatMsg;
- } else {
- realLastErr = "Last error code does not exist.";
- }
-
- // Get rid of the allocated memory from FormatMessage.
- if (NULL != formatMsg) {
- LocalFree((LPVOID)formatMsg);
- }
- */
-
- return ret;
-}
-
-#endif
-
-
-/**
- * Show a prompt on stdout
- */
-static int textPrompt(
- const char* windowTitle,
- const char* prompt,
- const char** choice,
- int numChoices) {
-
- printf("\n___________________________________________________\n");
- printf("%s\n", windowTitle);
- printf("%s", prompt);
-
- if (numChoices > 10) {
- numChoices = 10;
- }
-
- int c = -1;
- if (numChoices > 1) {
- printf("\n");
- printf("Choose an option by number:");
-
- while ((c < 0) || (c >= numChoices)) {
- printf("\n");
-
- for (int i = 0; i < numChoices; i++) {
- if (numChoices <= 3) {
- printf(" (%d) %s ", i, choice[i]);
- } else {
- printf(" (%d) %s\n", i, choice[i]);
- }
- }
-
- printf("\n> ");
- c = _getch() - '0';
-
- if ((c < 0) || (c >= numChoices)) {
- printf("'%d' is not a valid choice.", c);
- } else {
- printf("%d", c);
- }
- }
-
- } else if (numChoices == 1) {
-
- printf("\nPress any key for '%s'...", choice[0]);
- _getch();
- c = 0;
-
- } else {
-
- printf("\nPress any key...");
- _getch();
- c = 0;
- }
-
- printf("\n___________________________________________________\n");
- return c;
-}
-
-#ifdef G3D_OSX
-
-// See http://developer.apple.com/documentation/Carbon/Reference/Carbon_Event_Manager_Ref/index.html
-
-#define CARBON_COMMANDID_START 128
-#define CARBON_BUTTON_SPACING 12
-#define CARBON_BUTTON_HEIGHT 20
-#define CARBON_BUTTON_MINWIDTH 69
-#define CARBON_WINDOW_PADDING 20
-
-struct CallbackData {
- WindowRef refWindow;
-
- /** Index of this particular button */
- int myIndex;
-
- /** Buttons store their index into here when pressed. */
- int* whichButton;
-};
-
-/**
- Assumes that userData is a pointer to a carbon_evt_data_t.
-
- */
-static pascal OSStatus DoCommandEvent(EventHandlerCallRef handlerRef, EventRef event, void* userData) {
- // See http://developer.apple.com/documentation/Carbon/Conceptual/HandlingWindowsControls/index.html
-
- CallbackData& callbackData = *(CallbackData*)userData;
-
-# pragma unused(handlerRef)
-
- callbackData.whichButton[0] = callbackData.myIndex;
-
- // If we get here we can close the window
- QuitAppModalLoopForWindow(callbackData.refWindow);
-
- // Return noErr to indicate that we handled the event
- return noErr;
-}
-
-static int guiPrompt
-(const char* windowTitle,
- const char* prompt,
- const char** choice,
- int numChoices) {
-
- WindowRef window;
-
- int iNumButtonRows = 0;
- int iButtonWidth = -1;
- OSStatus err = noErr;
-
- // Determine number of rows of buttons
- while (iButtonWidth < CARBON_BUTTON_MINWIDTH) {
- ++iNumButtonRows;
- iButtonWidth =
- (550 - (CARBON_WINDOW_PADDING*2 +
- (CARBON_BUTTON_SPACING*numChoices))) /
- (numChoices/iNumButtonRows);
- }
-
- // Window Variables
- Rect rectWin = {0, 0, 200 + ((iNumButtonRows-1) * (CARBON_BUTTON_HEIGHT+CARBON_BUTTON_SPACING)), 550}; // top, left, bottom, right
- CFStringRef szWindowTitle = CFStringCreateWithCString(kCFAllocatorDefault, windowTitle, kCFStringEncodingUTF8);
-
- window = NULL;
-
- err = CreateNewWindow(kMovableAlertWindowClass, kWindowStandardHandlerAttribute|kWindowCompositingAttribute, &rectWin, &window);
- err = SetWindowTitleWithCFString(window, szWindowTitle);
- err = SetThemeWindowBackground(window, kThemeBrushAlertBackgroundActive, false);
- assert(err == noErr);
-
- // Event Handler Variables
- EventTypeSpec buttonSpec[] = {{ kEventClassControl, kEventControlHit }, { kEventClassCommand, kEventCommandProcess }};
- EventHandlerUPP buttonHandler = NewEventHandlerUPP(DoCommandEvent);
-
- // Static Text Variables
- Rect rectStatic = {20, 20, 152, 530};
- CFStringRef szStaticText = CFStringCreateWithCString(kCFAllocatorDefault, prompt, kCFStringEncodingUTF8);
- ControlRef refStaticText = NULL;
- err = CreateStaticTextControl(window, &rectStatic, szStaticText, NULL, &refStaticText);
-
- // Button Variables
- Rect bounds[numChoices];
- CFStringRef caption[numChoices];
- ControlRef button[numChoices];
-
- int whichButton=-1;
- CallbackData callbackData[numChoices];
-
- // Create the Buttons and assign event handlers
- for (int i = 0; i < numChoices; ++i) {
- bounds[i].top = 160 + ((CARBON_BUTTON_HEIGHT+CARBON_BUTTON_SPACING)*(i%iNumButtonRows));
- bounds[i].right = 530 - ((iButtonWidth+CARBON_BUTTON_SPACING)*(i/iNumButtonRows));
- bounds[i].left = bounds[i].right - iButtonWidth;
- bounds[i].bottom = bounds[i].top + CARBON_BUTTON_HEIGHT;
-
- // Convert the button captions to Apple strings
- caption[i] = CFStringCreateWithCString(kCFAllocatorDefault, choice[i], kCFStringEncodingUTF8);
-
- err = CreatePushButtonControl(window, &bounds[i], caption[i], &button[i]);
- assert(err == noErr);
-
- err = SetControlCommandID(button[i], CARBON_COMMANDID_START + i);
- assert(err == noErr);
-
- callbackData[i].refWindow = window;
- callbackData[i].myIndex = i;
- callbackData[i].whichButton = &whichButton;
-
- err = InstallControlEventHandler(button[i], buttonHandler,
- GetEventTypeCount(buttonSpec), buttonSpec,
- &callbackData[i], NULL);
- assert(err == noErr);
- }
-
- // Show Dialog
- err = RepositionWindow(window, NULL, kWindowCenterOnMainScreen);
- ShowWindow(window);
- BringToFront(window);
- err = ActivateWindow(window, true);
-
- // Hack to get our window/process to the front...
- ProcessSerialNumber psn = { 0, kCurrentProcess};
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
- SetFrontProcess (&psn);
-
- // Run in Modal State
- err = RunAppModalLoopForWindow(window);
-
- // Dispose of Button Related Data
- for (int i = 0; i < numChoices; ++i) {
- // Dispose of controls
- DisposeControl(button[i]);
-
- // Release CFStrings
- CFRelease(caption[i]);
- }
-
- // Dispose of Other Controls
- DisposeControl(refStaticText);
-
- // Dispose of Event Handlers
- DisposeEventHandlerUPP(buttonHandler);
-
- // Dispose of Window
- DisposeWindow(window);
-
- // Release CFStrings
- CFRelease(szWindowTitle);
- CFRelease(szStaticText);
-
- // Return Selection
- return whichButton;
-}
-
-#endif
-
-int prompt(
- const char* windowTitle,
- const char* prompt,
- const char** choice,
- int numChoices,
- bool useGui) {
-
- #ifdef G3D_WIN32
- if (useGui) {
- // Build the message box
- return guiPrompt(windowTitle, prompt, choice, numChoices);
- }
- #endif
-
- #ifdef G3D_OSX
- if (useGui){
- //Will default to text prompt if numChoices > 4
- return guiPrompt(windowTitle, prompt, choice, numChoices);
- }
- #endif
- return textPrompt(windowTitle, prompt, choice, numChoices);
-}
-
-
-void msgBox(
- const std::string& message,
- const std::string& title) {
-
- const char *choice[] = {"Ok"};
- prompt(title.c_str(), message.c_str(), choice, 1, true);
-}
-
-#ifndef G3D_WIN32
- #undef _getch
-#endif
-
-};// namespace
-
diff --git a/externals/g3dlite/G3D.lib/source/stringutils.cpp b/externals/g3dlite/G3D.lib/source/stringutils.cpp
deleted file mode 100644
index a21fc1f377c..00000000000
--- a/externals/g3dlite/G3D.lib/source/stringutils.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/**
- @file stringutils.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
- @created 2000-09-09
- @edited 2008-01-10
-*/
-
-#include "G3D/platform.h"
-#include "G3D/stringutils.h"
-#include "G3D/BinaryInput.h"
-#include <algorithm>
-
-namespace G3D {
-
-#ifdef _MSC_VER
- // disable: "C++ exception handler used"
-# pragma warning (push)
-# pragma warning (disable : 4530)
-#endif
-#ifdef G3D_WIN32
- const char* NEWLINE = "\r\n";
-#else
- const char* NEWLINE = "\n";
- static bool iswspace(int ch) { return (ch==' ' || ch=='\t' || ch=='\n'); }
-#endif
-
-bool beginsWith(
- const std::string& test,
- const std::string& pattern) {
-
- if (test.size() >= pattern.size()) {
- for (int i = 0; i < (int)pattern.size(); ++i) {
- if (pattern[i] != test[i]) {
- return false;
- }
- }
- return true;
- } else {
- return false;
- }
-}
-
-
-bool endsWith(
- const std::string& test,
- const std::string& pattern) {
-
- if (test.size() >= pattern.size()) {
- int te = test.size() - 1;
- int pe = pattern.size() - 1;
- for (int i = pattern.size() - 1; i >= 0; --i) {
- if (pattern[pe - i] != test[te - i]) {
- return false;
- }
- }
- return true;
- } else {
- return false;
- }
-}
-
-
-std::string wordWrap(
- const std::string& input,
- int numCols) {
-
- std::string output;
- size_t c = 0;
- int len;
-
- // Don't make lines less than this length
- int minLength = numCols / 4;
- size_t inLen = input.size();
-
- bool first = true;
- while (c < inLen) {
- if (first) {
- first = false;
- } else {
- output += NEWLINE;
- }
-
- if ((int)inLen - (int)c - 1 < numCols) {
- // The end
- output += input.substr(c, inLen - c);
- break;
- }
-
- len = numCols;
-
- // Look at character c + numCols, see if it is a space.
- while ((len > minLength) &&
- (input[c + len] != ' ')) {
- len--;
- }
-
- if (len == minLength) {
- // Just crop
- len = numCols;
-
- }
-
- output += input.substr(c, len);
- c += len;
- if (c < input.size()) {
- // Collapse multiple spaces.
- while ((input[c] == ' ') && (c < input.size())) {
- c++;
- }
- }
- }
-
- return output;
-}
-
-
-int stringCompare(
- const std::string& s1,
- const std::string& s2) {
-
- return stringPtrCompare(&s1, &s2);
-}
-
-
-int stringPtrCompare(
- const std::string* s1,
- const std::string* s2) {
-
- return s1->compare(*s2);
-}
-
-
-std::string toUpper(const std::string& x) {
- std::string result = x;
- std::transform(result.begin(), result.end(), result.begin(), toupper);
- return result;
-}
-
-
-std::string toLower(const std::string& x) {
- std::string result = x;
- std::transform(result.begin(), result.end(), result.begin(), tolower);
- return result;
-}
-
-
-Array<std::string> stringSplit(
- const std::string& x,
- char splitChar) {
-
- Array<std::string> out;
-
- // Pointers to the beginning and end of the substring
- const char* start = x.c_str();
- const char* stop = start;
-
- while ((stop = strchr(start, splitChar))) {
- out.append(std::string(start, stop - start));
- start = stop + 1;
- }
-
- // Append the last one
- out.append(std::string(start));
-
- return out;
-}
-
-
-std::string stringJoin(
- const Array<std::string>& a,
- char joinChar) {
-
- std::string out;
-
- for (int i = 0; i < (int)a.size() - 1; ++i) {
- out += a[i] + joinChar;
- }
-
- if (a.size() > 0) {
- return out + a.last();
- } else {
- return out;
- }
-}
-
-
-std::string stringJoin(
- const Array<std::string>& a,
- const std::string& joinStr) {
-
- std::string out;
-
- for (int i = 0; i < (int)a.size() - 1; ++i) {
- out += a[i] + joinStr;
- }
-
- if (a.size() > 0) {
- return out + a.last();
- } else {
- return out;
- }
-}
-
-
-std::string trimWhitespace(
- const std::string& s) {
-
- size_t left = 0;
-
- // Trim from left
- while ((left < s.length()) && iswspace(s[left])) {
- ++left;
- }
-
- int right = s.length() - 1;
- // Trim from right
- while ((right > (int)left) && iswspace(s[right])) {
- --right;
- }
-
- return s.substr(left, right - left + 1);
-}
-
-}; // namespace
-
-#undef NEWLINE
-#ifdef _MSC_VER
-# pragma warning (pop)
-#endif
diff --git a/externals/g3dlite/G3D.lib/source/uint128.cpp b/externals/g3dlite/G3D.lib/source/uint128.cpp
deleted file mode 100644
index 450009a5cff..00000000000
--- a/externals/g3dlite/G3D.lib/source/uint128.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- @file uint128.cpp
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
- @author Kyle Whitson
-
- @created 2008-07-17
- @edited 2008-07-17
- */
-
-#include "G3D/uint128.h"
-
-namespace G3D {
-
-/** Adds two 64-bit integers, placing the result and the overflow into 64-bit integers.*/
-static void addAndCarry(const uint64& _a, const uint64& _b, uint64& carry, uint64& result) {
-
- // Break each number into 4 32-bit chunks. Since we are using uints, right-shifting will fill with zeros.
- // This eliminates the need to and with 0xFFFFFFFF.
- uint32 a [2] = {_a & 0xFFFFFFFF, _a >> 32};
- uint32 b [2] = {_b & 0xFFFFFFFF, _b >> 32};
-
- uint64 tmp = uint64(a[0]) + b[0];
-
- result = tmp & 0xFFFFFFFF;
- uint32 c = tmp >> 32;
-
- tmp = uint64(c) + a[1] + b[1];
- result += tmp << 32;
- carry = (tmp >> 32);
-}
-
-/** Multiplies two unsigned 64-bit integers, placing the result into one 64-bit int and the overflow into another.*/
-void multiplyAndCarry(const uint64& _a, const uint64& _b, uint64& carry, uint64& result) {
-
- // Break each number into 4 32-bit chunks. Since we are using uints, right-shifting will fill with zeros.
- // This eliminates the need to and with 0xFFFFFFFF.
- uint32 a [2] = {_a & 0xFFFFFFFF, _a >> 32};
- uint32 b [2] = {_b & 0xFFFFFFFF, _b >> 32};
-
- uint64 prod [2][2];
- for(int i = 0; i < 2; ++i) {
- for(int j = 0; j < 2; ++j) {
- prod[i][j] = uint64(a[i]) * b[j];
- }
- }
-
- // The product of the low bits of a and b will always fit into the result
- result = prod[0][0];
-
- // The product of the high bits of a and b will never fit into the result
- carry = prod[1][1];
-
- // The high 32 bits of prod[0][1] and prod[1][0] will never fit into the result
- carry += prod[0][1] >> 32;
- carry += prod[1][0] >> 32;
-
- uint64 tmp;
- addAndCarry(result, (prod[0][1] << 32), tmp, result);
- carry += tmp;
- addAndCarry(result, (prod[1][0] << 32), tmp, result);
- carry += tmp;
-}
-
-
-uint128::uint128(const uint64& hi, const uint64& lo) : hi(hi), lo(lo) {
-}
-
-uint128::uint128(const uint64& lo) : hi(0), lo(lo) {
-}
-
-uint128& uint128::operator+=(const uint128& x) {
-
- G3D::uint64 carry;
- addAndCarry(lo, x.lo, carry, lo);
-
- // Adding the carry will change hi. Save the old hi bits in case this == x.
- const uint64 xHi = x.hi;
- hi += carry;
- hi += xHi;
- return *this;
-}
-
-uint128& uint128::operator*=(const uint128& x) {
-
- // The low bits will get overwritten when doing the multiply, so back up both (in case &x == this)
- const uint64 oldLo = lo;
- const uint64 oldXLo = x.lo;
-
- G3D::uint64 carry;
- multiplyAndCarry(oldLo, oldXLo, carry, lo);
-
- // Overflow doesn't matter here because the result is going into hi - any overflow will exceed the capacity of a 128-bit number
- // Note: hi * x.hi will always overflow, since (x * 2^64) * (y * 2^64) = x*y*(2^128). The largest number expressable in 128 bits is
- // 2^128 - 1.
- hi = carry + (oldLo * x.hi) + (hi * oldXLo);
-
- return *this;
-}
-
-uint128& uint128::operator^=(const uint128& x) {
- hi ^= x.hi;
- lo ^= x.lo;
- return *this;
-}
-
-uint128& uint128::operator&=(const uint128& x) {
- hi &= x.hi;
- lo &= x.lo;
- return *this;
-}
-
-uint128& uint128::operator|=(const uint128& x) {
- hi |= x.hi;
- lo |= x.lo;
- return *this;
-}
-
-bool uint128::operator==(const uint128& x) {
- return (hi == x.hi) && (lo == x.lo);
-}
-
-uint128& uint128::operator>>=(const int x) {
-
- //Before shifting, mask out the bits that will be shifted out of hi.
- //Put a 1 in the first bit that will not be lost in the shift, then subtract 1 to get the mask.
- uint64 mask = ((uint64)1L << x) - 1;
- uint64 tmp = hi & mask;
- hi >>= x;
-
- //Shift lo and add the bits shifted down from hi
- lo = (lo >> x) + (tmp << (64 - x));
-
- return *this;
-}
-
-uint128& uint128::operator<<=(const int x) {
-
- //Before shifting, mask out the bits that will be shifted out of lo.
- //Put a 1 in the last bit that will be lost in the shift, then subtract 1 to get the logical inverse of the mask.
- //A bitwise NOT will then produce the correct mask.
- uint64 mask = ~((((uint64)1L) << (64 - x)) - 1);
- uint64 tmp = lo & mask;
- lo <<= x;
-
- //Shift hi and add the bits shifted up from lo
- hi = (hi << x) + (tmp >> (64 - x));
-
- return *this;
-}
-
-uint128 uint128::operator&(const uint128& x) {
- return uint128(hi & x.hi, lo & x.lo);
-}
-}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/AABox.h b/externals/g3dlite/G3D/AABox.h
index 76c5d6d5195..2e8da1f6098 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/AABox.h
+++ b/externals/g3dlite/G3D/AABox.h
@@ -3,12 +3,12 @@
Axis-aligned box class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2004-01-10
- @edited 2006-02-10
+ @edited 2009-02-10
- Copyright 2000-2006, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -28,6 +28,7 @@ namespace G3D {
*/
class AABox {
private:
+ friend class Intersect;
/** Optional argument placeholder */
static int dummy;
@@ -79,9 +80,13 @@ public:
hi = hi.max(a);
}
- void serialize(class BinaryOutput& b) const;
+ void serialize(class BinaryOutput& b) const;
+
+ void deserialize(class BinaryInput& b);
- void deserialize(class BinaryInput& b);
+ inline bool isFinite() const {
+ return lo.isFinite() && hi.isFinite();
+ }
inline const Vector3& low() const {
return lo;
@@ -94,29 +99,15 @@ public:
/**
The largest possible finite box.
*/
- static inline const AABox& maxFinite() {
- static const AABox b = AABox(Vector3::minFinite(),
- Vector3::maxFinite());
- return b;
- }
+ static const AABox& maxFinite();
/** A large finite box. This is smaller than FLT_MAX
because it leaves room to add boxes together. */
- static inline const AABox& large() {
- static const AABox b = AABox(Vector3::minFinite() * 0.5f,
- Vector3::maxFinite() * 0.5f);
- return b;
- }
+ static const AABox& large();
- static inline const AABox& inf() {
- static const AABox b = AABox(-Vector3::inf(), Vector3::inf());
- return b;
- }
+ static const AABox& inf();
- static inline const AABox& zero() {
- static const AABox b = AABox(Vector3::zero(), Vector3::zero());
- return b;
- }
+ static const AABox& zero();
/**
Returns the centroid of the box.
diff --git a/externals/g3dlite/G3D/Any.h b/externals/g3dlite/G3D/Any.h
new file mode 100644
index 00000000000..49701202ca9
--- /dev/null
+++ b/externals/g3dlite/G3D/Any.h
@@ -0,0 +1,570 @@
+/**
+ @file Any.h
+
+ @author Morgan McGuire, Shawn Yarbrough, and Corey Taylor
+ @maintainer Morgan McGuire
+
+ @created 2006-06-11
+ @edited 2009-12-16
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Any_h
+#define G3D_Any_h
+
+#include "G3D/platform.h"
+#include "G3D/Table.h"
+#include "G3D/Array.h"
+#include "G3D/AtomicInt32.h"
+#include <string>
+
+// needed for Token
+#include "G3D/TextInput.h"
+
+#ifdef verify
+#undef verify
+#endif
+
+namespace G3D {
+
+class TextOutput;
+
+/**
+\brief Easy loading and saving of human-readable configuration files.
+
+Encodes typed, structured data and can serialize it to a human
+readable format that is very similar to the Python language's data
+syntax. Well-suited for quickly creating human-readable file formats,
+especially since deserialization and serialization preserve comments and
+an Any can tell you what file and line it came from.
+
+The class is designed so that copying Anys generally is fast, even if
+it is a large array or table. This is because data is shared between
+copies until it is mutated, at which point an actual copy occurs.
+
+\section Example
+Sample File:
+<pre>
+{
+ shape = "round",
+
+ # in meters
+ radius = 3.7,
+
+ position = Vector3(1.0, -1.0, 0.0),
+ texture = { format = "RGB8", size = (320, 200)}
+}
+</pre>
+
+Sample code using:
+<pre>
+Any x;
+x.load("ball.txt");
+if (x["shape"].string() == "round") {
+ x["density"] = 3;
+}
+x.save("ball.txt");
+</pre>
+
+The custom serialization format was chosen to be terse, easy for
+humans to read, and easy for machines to parse. It was specifically
+chosen over formats like XML, YAML, JSON, S-expressions, and Protocol
+Buffers, although there is no reason you could not write readers and
+writers for G3D::Any that support those.
+
+G3D::Any assumes that structures do not contain cycles; it is an
+error to create a structure like:
+
+<pre>
+Any x(Any::ARRAY);
+x.array().append(x); // don't do this!
+</pre>
+
+although no exception will be thrown at runtime during that append.
+
+
+\section Parsing
+
+The primary use of Any is to create your own text file formats.
+The Vector3 constructor is a good example of how to use the Any::verify
+methods to provide good error checking while parsing such formats:
+
+<pre>
+Vector3::Vector3(const Any& any) {
+ any.verifyName("Vector3");
+ any.verifyType(Any::TABLE, Any::ARRAY);
+ any.verifySize(3);
+
+ if (any.type() == Any::ARRAY) {
+ x = any[0];
+ y = any[1];
+ z = any[2];
+ } else {
+ // Table
+ x = any["x"];
+ y = any["y"];
+ z = any["z"];
+ }
+}
+</pre>
+
+\section BNF
+Serialized format BNF:
+
+<pre>
+identifier ::= (letter | "_") (letter | digit | "_")*
+identifier-op ::= "::" | "->" | "."
+
+identifier-exp ::= [identifier-op] identifier (identifier-op identifier)*
+
+comment ::= "#" <any characters> "\n"
+separator ::= "," | ";"
+
+number ::= <legal C printf number format>
+string ::= <legal C double-quoted string; backslashes must be escaped>
+boolean ::= "True" | "False"
+none ::= "None"
+array ::= "(" [value ("," value)*] ")"
+pair ::= (identifier | string) "=" value
+table ::= "{" [pair (separator pair)*] "}"
+named-array ::= identifier-exp tuple
+named-table ::= identifier-exp dict
+
+value ::= [comment] (none | number | boolean | string | array | table | named-array | named-table)
+</pre>
+
+Except for single-line comments, whitespace is not significant.
+All parsing is case-insensitive.
+
+The deserializer allows the substitution of [] for () when writing
+tuples and ";" for ",".
+
+The serializer indents four spaces for each level of nesting.
+Tables are written with the keys in alphabetic order.
+*/
+class Any {
+public:
+
+ enum Type {NONE, BOOLEAN, NUMBER, STRING, ARRAY, TABLE};
+
+ static std::string toString(Type t);
+
+ /** Where an Any came from in a file. Useful for throwing parsing errors */
+ class Source {
+ public:
+ std::string filename;
+ int line;
+ int character;
+
+ Source() : line(0), character(0) {}
+
+ void set(const TextInput& ti, const Token& t) {
+ filename = ti.filename();
+ line = t.line();
+ character = t.character();
+ }
+ };
+
+ typedef Array<Any> AnyArray;
+ typedef Table<std::string, Any> AnyTable;
+
+private:
+
+ /** Called from deserialize() */
+ static void deserializeComment(TextInput& ti, Token& token, std::string& comment);
+
+ /** NONE, BOOLEAN, and NUMBER are stored directly in the Any */
+ union SimpleValue {
+ bool b;
+ double n;
+
+ inline SimpleValue() : n(0.0) {}
+ inline SimpleValue(bool x) : b(x) {}
+ inline SimpleValue(double x) : n(x) {}
+ };
+
+ class Data {
+ public:
+ /** ARRAY, TABLE, or STRING value only. NULL otherwise. */
+ union Value {
+ std::string* s;
+ Array<Any>* a;
+ AnyTable* t;
+ inline Value() : s(NULL) {}
+ };
+
+ // Needed so that the destructor knows what is in Value
+ // and can call its destructor.
+ Type type;
+
+ /** Always points to memory that is allocated with the Data, so
+ the destructor does not delete this. */
+ Value value;
+
+ std::string comment;
+
+ std::string name;
+
+ /** For STRING, ARRAY and TABLE types, m_value is shared between
+ multiple instances. Mutation is allowed only if the reference
+ count is exactly 1, otherwise the mutating instance must copy
+ the value. This is not used for other types.
+ */
+ AtomicInt32 referenceCount;
+
+ Source source;
+
+ private:
+
+ /** Called by create() */
+ inline Data(Type t) : type(t), referenceCount(1) {}
+
+ /** Called by destroy */
+ ~Data();
+
+ public:
+
+ /** Clones the argument */
+ static Data* create(const Data* d);
+ static Data* create(Type t);
+
+ /** Free d, invoking its destructor and freeing the memory for
+ the value. */
+ static void destroy(Data* d);
+
+ };
+
+ /** If not empty, this Any was created from operator[] on a table
+ and perhaps was not intended to exist. The name is needed to
+ format the error message if it is read from before it is
+ written to.
+
+ The source of a placeholder object is that of the parent
+ object until it is written.
+ */
+ std::string m_placeholderName;
+
+ Type m_type;
+ SimpleValue m_simpleValue;
+ mutable Data* m_data;
+
+ /** Called before every read operation to ensure that this object
+ is not a placeholder. */
+ void beforeRead() const;
+
+ /** Called before every write operation to wipe the placeholder
+ status. */
+ void beforeWrite();
+
+ /** Decrements the reference count (if there is one). If the
+ reference count is zero after decrement, calls delete on @a m_data
+ and sets it to NULL.
+ */
+ void dropReference();
+
+ /** Allocate the Data object if it does not exist */
+ void ensureData();
+
+ /** If m_data is not NULL, ensure that it has a unique reference
+ and contains a valid m_data. This has a race condition if two
+ threads are both trying to modify the same Any
+ simultaneously.*/
+ void ensureMutable();
+
+ /** Read an unnamed a TABLE or ARRAY. Token should be the open
+ paren token; it is the next token after the close on
+ return. Called from deserialize().*/
+ void deserializeBody(TextInput& ti, Token& token);
+
+ void deserialize(TextInput& ti, Token& token);
+
+ /** Read the name of a named Array or Table. */
+ static void deserializeName(TextInput& ti, Token& token, std::string& name);
+
+ /** Read until a comma is consumed or a close paren is hit, and
+ return that token. Considers the passed in token to be the first
+ value read. */
+ static void readUntilCommaOrClose(TextInput& ti, Token& token);
+
+ /** Construct an Any that is a proxy for a table fetch from \a data.
+ This proxy can be copied exactly once on return from operator[].*/
+ Any(const std::string& key, Data* data);
+
+ inline bool isPlaceholder() const {
+ return ! m_placeholderName.empty();
+ }
+
+public:
+
+ /** Base class for all Any exceptions.*/
+ class Exception {
+ public:
+ virtual ~Exception() {}
+ };
+
+ /** Thrown by operator[] when a key is not present in a const table. */
+ class KeyNotFound : public ParseError {
+ public:
+ std::string key;
+ };
+
+ /** Thrown by operator[] when an array index is not present. */
+ class IndexOutOfBounds : public Exception {
+ public:
+ int index;
+ int size;
+ inline IndexOutOfBounds() : index(0), size(0) {}
+ inline IndexOutOfBounds(int i, int s) : index(i), size(s) {}
+ };
+
+ /** NONE constructor */
+ Any();
+
+ /** Deserialize */
+ explicit Any(TextInput& t);
+
+ Any(const Any& x);
+
+ /** NUMBER constructor */
+ Any(double x);
+
+#ifdef G3D_32BIT
+ /** NUMBER constructor */
+ Any(int64 x);
+#endif // G3D_32BIT
+
+#if 0
+ /** NUMBER constructor */
+ Any(int32 x);
+#endif // 0
+
+ /** NUMBER constructor */
+ Any(long x);
+
+ /** NUMBER constructor */
+ Any(int x);
+
+ /** NUMBER constructor */
+ Any(short x);
+
+ /** BOOLEAN constructor */
+ Any(bool x);
+
+ /** STRING constructor */
+ Any(const std::string& x);
+
+ /** STRING constructor */
+ Any(const char* x);
+
+ /** \a t must be ARRAY or TABLE */
+ Any(Type t, const std::string& name = "");
+
+ ~Any();
+
+ /** Removes the comment and name */
+ Any& operator=(const Any& x);
+
+ /** Removes the comment and name */
+ Any& operator=(double x);
+
+ /** Removes the comment and name */
+ Any& operator=(int x);
+
+ /** Removes the comment and name */
+ Any& operator=(bool x);
+
+ /** Removes the comment and name */
+ Any& operator=(const std::string& x);
+
+ /** Removes the comment and name */
+ Any& operator=(const char* x);
+
+ /** \a t must be ARRAY, TABLE, or NONE. Removes the comment and name */
+ Any& operator=(Type t);
+
+ Type type() const;
+
+ /** Same as deserialize or load, but operates on a string instead
+ of a stream or file.
+
+ \sa deserialize, load
+ */
+ void parse(const std::string& src);
+
+ std::string unparse() const;
+
+ /** Comments appear before values when they are in serialized form.*/
+ const std::string& comment() const;
+ void setComment(const std::string& c);
+
+ /** True if this is the NONE value */
+ bool isNone() const;
+
+ /** Throws a ParseError exception if this is not a number */
+ double number() const;
+ const std::string& string() const;
+ bool boolean() const;
+
+ /** If this is named ARRAY or TABLE, returns the name. */
+ const std::string& name() const;
+
+ /** \brief Set the name used when serializing an ARRAY or TABLE.
+
+ Only legal for ARRAY or TABLE. The \a name must begin with a letter
+ and contain only letters, numbers, underscores and scope operators.
+
+ <pre>
+ a2z
+ hello
+ Foo::bar
+ color.red
+ this->that
+ __x
+ </pre>
+
+
+ The scope operators "::", "->", and
+ ".", may have spaces around them. The name may not
+ contain parentheses.
+ */
+ void setName(const std::string& name);
+
+ /** Number of elements if this is an ARRAY or TABLE */
+ int size() const;
+ int length() const;
+
+ /** For an array, returns the ith element */
+ const Any& operator[](int i) const;
+ Any& operator[](int i);
+
+ /** Directly exposes the underlying data structure for an ARRAY. */
+ const Array<Any>& array() const;
+ void append(const Any& v0);
+ void append(const Any& v0, const Any& v1);
+ void append(const Any& v0, const Any& v1, const Any& v2);
+ void append(const Any& v0, const Any& v1, const Any& v2, const Any& v3);
+
+ /** Directly exposes the underlying data structure for table.*/
+ const Table<std::string, Any>& table() const;
+
+ /** For a table, returns the element for \a key. Throws KeyNotFound
+ exception if the element does not exist.
+ */
+ const Any& operator[](const std::string& key) const;
+
+ // Needed to prevent the operator[](int) overload from catching
+ // string literals
+ inline const Any& operator[](const char* key) const {
+ return operator[](std::string(key));
+ }
+
+ /**
+ Fetch an element from a table. This can be used as:
+
+ <pre>
+ a["key"] = value; (create the key if it did not exist)
+ </pre>
+
+ or
+
+ <pre>
+ value = a["key"]; (throw an error if the key did not exist)
+ </pre>
+
+ <b>Note:</b>
+ In order to cause elements to be correctly created in the
+ first case while still providing "key not found" errors in the
+ second case, the Any returned is a special object that delays
+ the actual fetch until the following assignment or method
+ call. This means that in the event of an error, the exception
+ may be thrown from a line other than the actual fetch. Use
+ the Any::get() or the const Any::operator[]() methods to avoid
+ this behavior and ensure error-checking at fetch time.
+ */
+ Any& operator[](const std::string& key);
+
+ /** \copydoc Any::operator[](const std::string&) */
+ inline Any& operator[](const char* key) {
+ return operator[](std::string(key));
+ }
+
+ /** For a table, returns the element for key \a x and \a
+ defaultVal if it does not exist. */
+ const Any& get(const std::string& key, const Any& defaultVal) const;
+
+ /** Returns true if this key is in the TABLE. Illegal to call on an object that is not a TABLE. */
+ bool containsKey(const std::string& key) const;
+
+ /** For a table, assigns the element for key k. */
+ void set(const std::string& key, const Any& val);
+
+ /** for an ARRAY, resizes and returns the last element */
+ Any& next();
+
+
+ /** True if the Anys are exactly equal, ignoring comments. Applies deeply on arrays and tables. */
+ bool operator==(const Any& x) const;
+ bool operator!=(const Any& x) const;
+
+ operator int() const;
+ operator float() const;
+ operator double() const;
+ operator bool() const;
+ operator std::string() const;
+
+ /** Resize to \a n elements, where new elements are NIL
+ It is an error to call this method if this is not an Any::ARRAY */
+ void resize(int n);
+
+ /**
+ Clears all entries.
+ This must be a TABLE or ARRAY */
+ void clear();
+
+ /** Parse from a file.
+ \sa deserialize, parse */
+ void load(const std::string& filename);
+
+ /** Uses the serialize method. */
+ void save(const std::string& filename) const;
+
+ void serialize(TextOutput& to) const;
+ /** Parse from a stream.
+ \sa load, parse */
+ void deserialize(TextInput& ti);
+
+ const Source& source() const;
+
+ /** Throws a ParseError if \a value is false. Useful for quickly
+ creating parse rules in classes that deserialize from Any.
+ */
+ void verify(bool value, const std::string& message = "") const;
+
+ /** Verifies that the name begins with identifier \a n. It may contain
+ identifier operators after this */
+ void verifyName(const std::string& n) const;
+
+ /** Verifies that the type is \a t. */
+ void verifyType(Type t) const;
+
+ /** Throws an exception if the type is not \a t0 or \a t1. */
+ void verifyType(Type t0, Type t1) const;
+
+ /** Verifies that the size is between \a low and \a high, inclusive */
+ void verifySize(int low, int high) const;
+
+ /** Verifies that the size is exactly \a s */
+ void verifySize(int s) const;
+
+private:
+
+ void deserializeTable(TextInput& ti);
+ void deserializeArray(TextInput& ti,const std::string& term);
+
+}; // class Any
+
+} // namespace G3D
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/AnyVal.h b/externals/g3dlite/G3D/AnyVal.h
index 8254dd73c93..8c1bc72f206 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/AnyVal.h
+++ b/externals/g3dlite/G3D/AnyVal.h
@@ -34,6 +34,10 @@ class Rect2D;
class AABox;
/**
+ \deprecated
+ <b>Use the G3D::Any class instead. This is only provided for
+ backwards compatibility to G3D 7.xx.</b>
+
A generic value, useful for defining property trees that can
be loaded from and saved to disk. The values are intentionally
restricted to a small set.
@@ -172,6 +176,8 @@ Table<boost::any> tree;
...
}
</pre>
+
+\deprecated
*/
class AnyVal {
public:
diff --git a/externals/g3dlite/G3D/AreaMemoryManager.h b/externals/g3dlite/G3D/AreaMemoryManager.h
new file mode 100644
index 00000000000..d8d8f710359
--- /dev/null
+++ b/externals/g3dlite/G3D/AreaMemoryManager.h
@@ -0,0 +1,93 @@
+/**
+ @file AreaMemoryManager.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-01-20
+ @edited 2009-05-29
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+
+#ifndef G3D_AreaMemoryManager_h
+#define G3D_AreaMemoryManager_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/Array.h"
+#include "G3D/MemoryManager.h"
+
+namespace G3D {
+
+/**
+ \brief Allocates memory in large blocks and then frees it as an area.
+
+ Useful for ensuring cache coherence and for reducing the time cost of
+ multiple allocations and deallocations.
+
+ <b>Not threadsafe</b>
+ */
+class AreaMemoryManager : public MemoryManager {
+private:
+
+ class Buffer {
+ private:
+ uint8* m_first;
+ size_t m_size;
+ size_t m_used;
+
+ public:
+
+ Buffer(size_t size);
+
+ ~Buffer();
+
+ /** Returns NULL if out of space */
+ void* alloc(size_t s);
+ };
+
+ size_t m_sizeHint;
+
+ /** The underlying array is stored in regular MemoryManager heap memory */
+ Array<Buffer*> m_bufferArray;
+
+ AreaMemoryManager(size_t sizeHint);
+
+public:
+
+ typedef ReferenceCountedPointer<AreaMemoryManager> Ref;
+
+ /**
+ \param sizeHint Total amount of memory expected to be allocated.
+ The allocator will allocate memory from the system in increments
+ of this size.
+ */
+ static AreaMemoryManager::Ref create(size_t sizeHint = 10 * 1024 * 1024);
+
+ /** Invokes deallocateAll. */
+ ~AreaMemoryManager();
+
+ size_t bytesAllocated() const;
+
+ /** Allocates memory out of the buffer pool.
+ @param s must be no larger than sizeHint */
+ virtual void* alloc(size_t s);
+
+ /** Ignored. */
+ virtual void free(void* x);
+
+ virtual bool isThreadsafe() const;
+
+ /** Deletes all previously allocated memory. Because delete is not
+ invoked on objects in this memory, it is not safe to simply
+ free memory containing C++ objects that expect their destructors
+ to be called. */
+ void deallocateAll();
+};
+
+typedef AreaMemoryManager CoherentAllocator;
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Array.h b/externals/g3dlite/G3D/Array.h
index ae4eea8ab40..cc9e1d9dd01 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Array.h
+++ b/externals/g3dlite/G3D/Array.h
@@ -5,18 +5,19 @@
@cite Portions written by Aaron Orenstein, a@orenstein.name
@created 2001-03-11
- @edited 2008-07-09
+ @edited 2009-05-29
- Copyright 2000-2008, Morgan McGuire, morgan@cs.williams.edu
+ Copyright 2000-2009, Morgan McGuire, http://graphics.cs.williams.edu
All rights reserved.
*/
-#ifndef G3D_ARRAY_H
-#define G3D_ARRAY_H
+#ifndef G3D_Array_h
+#define G3D_Array_h
#include "G3D/platform.h"
#include "G3D/debug.h"
#include "G3D/System.h"
+#include "G3D/MemoryManager.h"
#ifdef G3D_DEBUG
// For formatting error messages
# include "G3D/format.h"
@@ -47,7 +48,7 @@ const int SORT_INCREASING = 1;
const int SORT_DECREASING = -1;
/**
- Dynamic 1D array.
+ \brief Dynamic 1D array tuned for performance.
Objects must have a default constructor (constructor that
takes no arguments) in order to be used with this template.
@@ -57,20 +58,15 @@ const int SORT_DECREASING = -1;
Do not use with objects that overload placement <code>operator new</code>,
since the speed of Array is partly due to pooled allocation.
- If SSE is defined Arrays allocate the first element aligned to
- 16 bytes.
-
-
Array is highly optimized compared to std::vector.
Array operations are less expensive than on std::vector and for large
amounts of data, Array consumes only 1.5x the total size of the
data, while std::vector consumes 2.0x. The default
array takes up zero heap space. The first resize (or append)
operation grows it to a reasonable internal size so it is efficient
- to append to small arrays. Memory is allocated using
- System::alignedMalloc, which produces pointers aligned to 16-byte
- boundaries for use with SSE instructions and uses pooled storage for
- fast allocation. When Array needs to copy
+ to append to small arrays.
+
+ Then Array needs to copy
data internally on a resize operation it correctly invokes copy
constructors of the elements (the MSVC6 implementation of
std::vector uses realloc, which can create memory leaks for classes
@@ -90,23 +86,29 @@ const int SORT_DECREASING = -1;
is empty.
Do not subclass an Array.
+
+ \sa G3D::SmallArray
*/
template <class T, int MIN_ELEMENTS = 10, size_t MIN_BYTES = 32>
class Array {
private:
/** 0...num-1 are initialized elements, num...numAllocated-1 are not */
- T* data;
+ T* data;
+
+ int num;
+ int numAllocated;
- int num;
- int numAllocated;
+ MemoryManager::Ref m_memoryManager;
- void init(int n, int a) {
- debugAssert(n <= a);
+ /** \param n Number of elements
+ */
+ void init(int n, const MemoryManager::Ref& m) {
+ m_memoryManager = m;
debugAssert(n >= 0);
this->num = 0;
this->numAllocated = 0;
data = NULL;
- if (a > 0) {
+ if (n > 0) {
resize(n);
} else {
data = NULL;
@@ -114,7 +116,7 @@ private:
}
void _copy(const Array &other) {
- init(other.num, other.num);
+ init(other.num, MemoryManager::create());
for (int i = 0; i < num; i++) {
data[i] = other.data[i];
}
@@ -148,7 +150,8 @@ private:
// elements are actually revealed to the application. They
// will be constructed in the resize() method.
- data = (T*)System::alignedMalloc(sizeof(T) * numAllocated, 16);
+ data = (T*)m_memoryManager->alloc(sizeof(T) * numAllocated);
+ alwaysAssertM(data, "Memory manager returned NULL: out of memory?");
// Call the copy constructors
{const int N = G3D::min(oldNum, numAllocated);
@@ -171,8 +174,7 @@ private:
ptr->~T();
}}
-
- System::alignedFree(oldData);
+ m_memoryManager->free(oldData);
}
public:
@@ -236,23 +238,60 @@ public:
return data;
}
- /** Creates a zero length array (no heap allocation occurs until resize). */
- Array() {
- init(0, 0);
- }
+ /** Creates a zero length array (no heap allocation occurs until resize). */
+ Array() : num(0) {
+ init(0, MemoryManager::create());
+ debugAssert(num >= 0);
+ }
+
+
+ /** Creates an array containing v0. */
+ Array(const T& v0) {
+ init(1, MemoryManager::create());
+ (*this)[0] = v0;
+ }
+
+ /** Creates an array containing v0 and v1. */
+ Array(const T& v0, const T& v1) {
+ init(2, MemoryManager::create());
+ (*this)[0] = v0;
+ (*this)[1] = v1;
+ }
+
+ /** Creates an array containing v0...v2. */
+ Array(const T& v0, const T& v1, const T& v2) {
+ init(3, MemoryManager::create());
+ (*this)[0] = v0;
+ (*this)[1] = v1;
+ (*this)[2] = v2;
+ }
+
+ /** Creates an array containing v0...v3. */
+ Array(const T& v0, const T& v1, const T& v2, const T& v3) {
+ init(4, MemoryManager::create());
+ (*this)[0] = v0;
+ (*this)[1] = v1;
+ (*this)[2] = v2;
+ (*this)[3] = v3;
+ }
+
+ /** Creates an array containing v0...v4. */
+ Array(const T& v0, const T& v1, const T& v2, const T& v3, const T& v4) {
+ init(5, MemoryManager::create());
+ (*this)[0] = v0;
+ (*this)[1] = v1;
+ (*this)[2] = v2;
+ (*this)[3] = v3;
+ (*this)[4] = v4;
+ }
- /**
- Creates an array of size.
- */
- Array(int size) {
- init(size, size);
- }
/**
Copy constructor
*/
- Array(const Array& other) {
+ Array(const Array& other) : num(0) {
_copy(other);
+ debugAssert(num >= 0);
}
/**
@@ -268,14 +307,13 @@ public:
(data + i)->~T();
}
- System::alignedFree(data);
+ m_memoryManager->free(data);
// Set to 0 in case this Array is global and gets referenced during app exit
data = NULL;
num = 0;
numAllocated = 0;
}
-
/**
Removes all elements. Use resize(0, false) or fastClear if you want to
remove all elements without deallocating the underlying array
@@ -285,6 +323,12 @@ public:
resize(0, shrink);
}
+ void clearAndSetMemoryManager(const MemoryManager::Ref& m) {
+ clear();
+ debugAssert(data == NULL);
+ m_memoryManager = m;
+ }
+
/** resize(0, false)
@deprecated*/
void fastClear() {
@@ -295,10 +339,11 @@ public:
Assignment operator.
*/
Array& operator=(const Array& other) {
- resize(other.num);
- for (int i = 0; i < num; ++i) {
+ debugAssert(num >= 0);
+ resize(other.num); for (int i = 0; i < num; ++i) {
data[i] = other[i];
}
+ debugAssert(num >= 0);
return *this;
}
@@ -310,6 +355,10 @@ public:
return *this;
}
+ inline MemoryManager::Ref memoryManager() const {
+ return m_memoryManager;
+ }
+
/**
Number of elements in the array.
*/
@@ -336,12 +385,6 @@ public:
resize(size() - 1, shrinkIfNecessary);
}
- /** Resizes without shrinking the underlying array. Same as resize(n, false).
- @deprecated*/
- void fastResize(int n) {
- resize(n, false);
- }
-
/**
Inserts at the specified index and shifts all other elements up by one.
@@ -358,28 +401,34 @@ public:
/** @param shrinkIfNecessary if false, memory will never be
reallocated when the array shrinks. This makes resizing much
- faster but can waste memory. */
- void resize(int n, bool shrinkIfNecessary = true) {
- int oldNum = num;
- num = n;
-
- // Call the destructors on newly hidden elements if there are any
- for (int i = num; i < oldNum; ++i) {
- (data + i)->~T();
- }
+ faster but can waste memory.
+ */
+ void resize(int n, bool shrinkIfNecessary = true) {
+ debugAssert(n >= 0);
+ if (num == n) {
+ return;
+ }
- // Once allocated, always maintain MIN_ELEMENTS elements or 32 bytes, whichever is higher.
- static const int minSize = G3D::max(MIN_ELEMENTS, (int)(MIN_BYTES / sizeof(T)));
+ int oldNum = num;
+ num = n;
- if ((MIN_ELEMENTS == 0) && (MIN_BYTES == 0) && (n == 0) && shrinkIfNecessary) {
- // Deallocate the array completely
- numAllocated = 0;
- System::alignedFree(data);
- data = NULL;
- return;
- }
+ // Call the destructors on newly hidden elements if there are any
+ for (int i = num; i < oldNum; ++i) {
+ (data + i)->~T();
+ }
+
+ // Once allocated, always maintain MIN_ELEMENTS elements or 32 bytes, whichever is higher.
+ const int minSize = std::max(MIN_ELEMENTS, (int)(MIN_BYTES / sizeof(T)));
- if (num > numAllocated) {
+ if ((MIN_ELEMENTS == 0) && (MIN_BYTES == 0) && (n == 0) && shrinkIfNecessary) {
+ // Deallocate the array completely
+ numAllocated = 0;
+ m_memoryManager->free(data);
+ data = NULL;
+ return;
+ }
+
+ if (num > numAllocated) {
// Grow the underlying array
if (numAllocated == 0) {
@@ -403,7 +452,7 @@ public:
float growFactor = 3.0;
- size_t oldSizeBytes = numAllocated * sizeof(T);
+ int oldSizeBytes = numAllocated * sizeof(T);
if (oldSizeBytes > 400000) {
// Avoid bloat
growFactor = 1.5;
@@ -621,6 +670,24 @@ public:
return (*this)[0];
}
+ /**
+ "The member function returns a reference to the last element of the controlled sequence,
+ which must be non-empty."
+ For compatibility with std::vector.
+ */
+ T& back() {
+ return (*this)[size()-1];
+ }
+
+ /**
+ "The member function returns a reference to the last element of the controlled sequence,
+ which must be non-empty."
+ For compatibility with std::vector.
+ */
+ const T& back() const {
+ return (*this)[size()-1];
+ }
+
/**
Removes the last element and returns it. By default, shrinks the underlying array.
*/
@@ -763,6 +830,19 @@ public:
/**
Returns the index of (the first occurance of) an index or -1 if
+ not found. Searches from the right.
+ */
+ int rfindIndex(const T& value) const {
+ for (int i = num -1 ; i >= 0; --i) {
+ if (data[i] == value) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ Returns the index of (the first occurance of) an index or -1 if
not found.
*/
int findIndex(const T& value) const {
@@ -851,12 +931,26 @@ public:
return elem1->x < elem2->x;
}
</PRE>
+
+ or a functor, e.g.,
+ <pre>
+bool
+less_than_functor::operator()( const double& lhs, const double& rhs ) const
+{
+return( lhs < rhs? true : false );
+}
+</pre>
*/
- void sort(bool (__cdecl *lessThan)(const T& elem1, const T& elem2)) {
+ // void sort(bool (__cdecl *lessThan)(const T& elem1, const T& elem2)) {
+ // std::sort(data, data + num, lessThan);
+ //}
+ template<class LessThan>
+ void sort(const LessThan& lessThan) {
+ // Using std::sort, which according to http://www.open-std.org/JTC1/SC22/WG21/docs/D_4.cpp
+ // was 2x faster than qsort for arrays around size 2000 on intel core2 with gcc
std::sort(data, data + num, lessThan);
}
-
/**
Sorts the array in increasing order using the > or < operator. To
invoke this method on Array<T>, T must override those operator.
diff --git a/externals/g3dlite/G3D.lib/include/G3D/AtomicInt32.h b/externals/g3dlite/G3D/AtomicInt32.h
index 9d58e02efe5..2d63f998355 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/AtomicInt32.h
+++ b/externals/g3dlite/G3D/AtomicInt32.h
@@ -1,7 +1,7 @@
/**
@file AtomicInt32.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2005-09-01
@edited 2006-06-21
@@ -13,7 +13,7 @@
#include "G3D/g3dmath.h"
#if defined(G3D_OSX)
- #include <libkern/OSAtomic.h>
+# include <libkern/OSAtomic.h>
#endif
namespace G3D {
@@ -31,7 +31,7 @@ private:
# if defined(G3D_WIN32)
volatile long m_value;
# elif defined(G3D_OSX)
- int32_t m_value;
+ int32_t m_value;
# else
volatile int32 m_value;
# endif
@@ -85,9 +85,9 @@ public:
# elif defined(G3D_OSX)
- int32 old = m_value;
- OSAtomicAdd32(x, &m_value);
- return old;
+ int32 old = m_value;
+ OSAtomicAdd32(x, &m_value);
+ return old;
# endif
}
@@ -105,7 +105,7 @@ public:
add(1);
# elif defined(G3D_OSX)
// Note: returns the newly incremented value
- OSAtomicIncrement32(&m_value);
+ OSAtomicIncrement32(&m_value);
# endif
}
@@ -124,7 +124,7 @@ public:
: "memory", "cc");
return nz;
# elif defined(G3D_OSX)
- // Note: returns the newly decremented value
+ // Note: returns the newly decremented value
return OSAtomicDecrement32(&m_value);
# endif
}
@@ -138,24 +138,22 @@ public:
Otherwise, no operation is performed.
Under VC6 the sign bit may be lost.
-
*/
int32 compareAndSet(const int32 comperand, const int32 exchange) {
# if defined(G3D_WIN32)
return InterlockedCompareExchange(&m_value, exchange, comperand);
-# elif defined(G3D_LINUX) || defined(G3D_FREEBSD)
+# elif defined(G3D_LINUX) || defined(G3D_FREEBSD) || defined(G3D_OSX)
+ // Based on Apache Portable Runtime
+ // http://koders.com/c/fid3B6631EE94542CDBAA03E822CA780CBA1B024822.aspx
int32 ret;
asm volatile ("lock; cmpxchgl %1, %2"
: "=a" (ret)
: "r" (exchange), "m" (m_value), "0"(comperand)
: "memory", "cc");
return ret;
-# elif defined(G3D_OSX)
- int32 old = m_value;
-
- OSAtomicCompareAndSwap32(comperand, exchange, &m_value);
- return old;
+ // Note that OSAtomicCompareAndSwap32 does not return a useful value for us
+ // so it can't satisfy the cmpxchgl contract.
# endif
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/BinaryFormat.h b/externals/g3dlite/G3D/BinaryFormat.h
index 53f0c144bf6..f6719a1c540 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/BinaryFormat.h
+++ b/externals/g3dlite/G3D/BinaryFormat.h
@@ -1,6 +1,6 @@
/**
@file BinaryFormat.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@author 2005-06-03
@edited 2005-06-03
diff --git a/externals/g3dlite/G3D.lib/include/G3D/BinaryInput.h b/externals/g3dlite/G3D/BinaryInput.h
index c0ab9052402..1dac93ea55e 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/BinaryInput.h
+++ b/externals/g3dlite/G3D/BinaryInput.h
@@ -6,12 +6,12 @@
@created 2001-08-09
@edited 2006-07-19
- Copyright 2000-2007, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_BINARYINPUT_H
-#define G3D_BINARYINPUT_H
+#ifndef G3D_BinaryInput_h
+#define G3D_BinaryInput_h
#ifdef _MSC_VER
// Disable conditional expression is constant, which occurs incorrectly on inlined functions
diff --git a/externals/g3dlite/G3D.lib/include/G3D/BinaryOutput.h b/externals/g3dlite/G3D/BinaryOutput.h
index d81ec56a67b..d81ec56a67b 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/BinaryOutput.h
+++ b/externals/g3dlite/G3D/BinaryOutput.h
diff --git a/externals/g3dlite/G3D.lib/include/G3D/BoundsTrait.h b/externals/g3dlite/G3D/BoundsTrait.h
index 31525dab73b..15e1418010c 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/BoundsTrait.h
+++ b/externals/g3dlite/G3D/BoundsTrait.h
@@ -1,10 +1,10 @@
/**
@file BoundsTrait.h
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2008-10-01
@edited 2008-10-01
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Box.h b/externals/g3dlite/G3D/Box.h
index 83e06a2f069..82af9125b05 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Box.h
+++ b/externals/g3dlite/G3D/Box.h
@@ -3,7 +3,7 @@
Box class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
@created 2001-06-02
@@ -153,19 +153,21 @@ public:
/**
See AABox::culledBy
*/
- bool culledBy(
- const Array<Plane>& plane,
- int32& cullingPlaneIndex,
- const uint32 testMask,
- uint32& childMask) const;
+ bool culledBy
+ (
+ const Array<Plane>& plane,
+ int32& cullingPlaneIndex,
+ const uint32 testMask,
+ uint32& childMask) const;
/**
Conservative culling test that does not produce a mask for children.
*/
- bool culledBy(
- const Array<Plane>& plane,
- int32& cullingPlaneIndex = dummy,
- const uint32 testMask = -1) const;
+ bool culledBy
+ (
+ const Array<Plane>& plane,
+ int32& cullingPlaneIndex = dummy,
+ const uint32 testMask = -1) const;
bool contains(
const Vector3& point) const;
@@ -174,7 +176,7 @@ public:
float volume() const;
- void getRandomSurfacePoint(Vector3& P, Vector3& N = Vector3::dummy) const;
+ void getRandomSurfacePoint(Vector3& P, Vector3& N = Vector3::ignore()) const;
/**
Uniformly distributed on the interior (includes surface)
diff --git a/externals/g3dlite/G3D/Box2D.h b/externals/g3dlite/G3D/Box2D.h
new file mode 100644
index 00000000000..80accad89dd
--- /dev/null
+++ b/externals/g3dlite/G3D/Box2D.h
@@ -0,0 +1,121 @@
+/**
+ @file Box2D.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2001-06-02
+ @edited 2008-12-27
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_Box2D_h
+#define G3D_Box2D_h
+
+#include "G3D/platform.h"
+#include "G3D/Vector2.h"
+
+namespace G3D {
+
+class CoordinateFrame;
+typedef class CoordinateFrame CFrame;
+class Rect2D;
+typedef class Rect2D AABox2D;
+
+/**
+ 2D oriented box
+ @cite http://www.flipcode.com/archives/2D_OBB_Intersection.shtml
+ */
+class Box2D {
+private:
+ /** Corners of the box, where 0 is the lower left. */
+ Vector2 m_corner[4];
+
+ /** Two edges of the box extended away from corner[0], with length
+ = 1 / extentSquared */
+ Vector2 m_axisin[2];
+
+ /** Two edges of the box extended away from corner[0], with unit length */
+ Vector2 m_axis[2];
+
+ /** Centroid of the box */
+ Vector2 m_center;
+
+ /** origin[a] = m_corner[0].dot(m_axisin[a]); */
+ float origin[2];
+
+ /** Surface area */
+ float m_area;
+
+ Vector2 m_extent;
+
+ /** Returns true if other overlaps one dimension of this. */
+ bool overlaps1Way(const Box2D& other) const;
+
+
+ /** Updates the axes after the m_corners move. Assumes the
+ m_corners actually form a rectangle. */
+ void computeAxes();
+
+public:
+
+ /**
+ @param center World-space center
+ @param w Width along object-space x-axis
+ @param h Height along object-space y-axis
+ @param angle Counter-clockwise angle from object-space x-axis in radians
+ */
+ Box2D(const Vector2& center = Vector2(0, 0), float w = 0, float h = 0, float angle = 0);
+
+ Box2D(const AABox2D& b);
+
+ Box2D(const Vector2& min, const Vector2& max);
+
+ /** Transform @a b by @a frame, discarding the Z components, and
+ compute the new box.*/
+ Box2D(const CFrame& frame, Box2D& b);
+
+ inline bool contains(const Vector2& v) const {
+ // Take to object space:
+ const Vector2& p = v - m_center;
+ float x = p.dot(m_axisin[0]);
+ float y = p.dot(m_axisin[1]);
+
+ // Must be within extent/2 on both axes in object space
+ return (abs(x) <= 0.5f) && (abs(y) <= 0.5f);
+ }
+
+ /** @brief Distance from corner(0) to the next corner along the box's local axis a. */
+ inline const Vector2& extent() const {
+ return m_extent;
+ }
+
+ /** @brief Unit length vector along axis @a a */
+ inline const Vector2& axis(int a) const {
+ debugAssert(a == 0 || a == 1);
+ return m_axis[a];
+ }
+
+ /** @brief Surface area */
+ inline float area() const {
+ return m_area;
+ }
+
+ inline const Vector2& corner(int i) const {
+ debugAssert(i >=0 && i <= 3);
+ return m_corner[i];
+ }
+
+ inline const Vector2& center() const {
+ return m_center;
+ }
+
+ /** Returns true if the intersection of the boxes is non-empty. */
+ inline bool overlaps(const Box2D& other) const {
+ return overlaps1Way(other) && other.overlaps1Way(*this);
+ }
+};
+
+} // G3D
+#endif
diff --git a/externals/g3dlite/G3D/BumpMapPreprocess.h b/externals/g3dlite/G3D/BumpMapPreprocess.h
new file mode 100644
index 00000000000..955f99e61b2
--- /dev/null
+++ b/externals/g3dlite/G3D/BumpMapPreprocess.h
@@ -0,0 +1,61 @@
+/**
+ \file BumpMapPreprocess.h
+
+ \maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ \created 2010-01-28
+ \edited 2010-01-28
+
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
+ */
+
+#ifndef G3D_BumpMapPreprocess_h
+#define G3D_BumpMapPreprocess_h
+
+#include "G3D/platform.h"
+
+namespace G3D {
+class Any;
+
+/**
+Not in the BumpMap class to avoid a circular dependency between Texture and BumpMap.
+G3D::GImage::computeNormalMap().
+*/
+class BumpMapPreprocess {
+public:
+
+ /** If true, the elevations are box filtered after computing normals
+ and before uploading, which produces better results for parallax offset mapping
+ Defaults to false. */
+ bool lowPassFilter;
+
+ /** Height of the maximum ("white") value, in pixels, for the purpose of computing normals.
+ A value of 255 means that a 255 x 255 bump image with a full black-to-white gradient
+ will produce a 45-degree ramp (this also results in "cubic" voxels).
+ A negative value means to set zExtentPixels to -zExtentPixels * max(width, height).
+ The default is -0.02.
+ */
+ float zExtentPixels;
+
+ /** After computing normals, scale the height by |N.z|, a trick that reduces texture swim in steep areas for parallax offset
+ mapping. Defaults to false.*/
+ bool scaleZByNz;
+
+ BumpMapPreprocess() : lowPassFilter(false), zExtentPixels(-0.02f), scaleZByNz(false) {}
+
+ BumpMapPreprocess(const Any& any);
+
+ operator Any() const;
+
+ bool operator==(const BumpMapPreprocess& other) const {
+ return
+ (lowPassFilter == other.lowPassFilter) &&
+ (zExtentPixels == other.zExtentPixels) &&
+ (scaleZByNz == other.scaleZByNz);
+ }
+};
+
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Capsule.h b/externals/g3dlite/G3D/Capsule.h
index 237dcdab69d..baeea3aa82b 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Capsule.h
+++ b/externals/g3dlite/G3D/Capsule.h
@@ -1,7 +1,7 @@
/**
@file Capsule.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-02-07
@edited 2005-08-20
diff --git a/externals/g3dlite/G3D.lib/include/G3D/CollisionDetection.h b/externals/g3dlite/G3D/CollisionDetection.h
index 62f92c18d33..c8fcf5534c2 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/CollisionDetection.h
+++ b/externals/g3dlite/G3D/CollisionDetection.h
@@ -4,17 +4,18 @@
Moving collision detection for simple primitives.
- @author Morgan McGuire, matrix@graphics3d.com
+ @author Morgan McGuire, http://graphics.cs.williams.edu
@cite Spherical collision based on Paul Nettle's
ftp://ftp.3dmaileffects.com/pub/FluidStudios/CollisionDetection/Fluid_Studios_Generic_Collision_Detection_for_Games_Using_Ellipsoids.pdf
and comments by Max McGuire. Ray-sphere intersection by Eric Haines.
Box-Box intersection written by Kevin Egan.
Thanks to Max McGuire of Iron Lore for various bug fixes.
+ Box-Triangle by Tomas Akenine-Moller
@created 2001-11-19
- @edited 2006-01-10
+ @edited 2008-12-19
- Copyright 2000-2006, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -68,17 +69,17 @@ namespace G3D {
<table>
<tr><td></td><td><b>Vector3</b></td><td><b>LineSegment</b></td><td><b>Ray *</b></td><td><b>Line</b></td><td><b>Plane</b></td><td><b>Triangle</b></td><td><b>Sphere</b></td><td><b>Cylinder</b></td><td><b>Capsule</b></td><td><b>AABox</b></td><td><b>Box</b></td></tr>
- <tr><td><b>Vector3</b></td><td>Vector3::operator== Vector3::fuzzyEq G3D::distance</td><td bgcolor=#C0C0C0 colspan=10 ></td></tr>
- <tr><td><b>LineSegment</b></td><td>LineSegment::closestPoint LineSegment::distance CollisionDetection::closestPointOnLineSegment</td><td></td><td bgcolor=#C0C0C0 colspan=9 ></td></tr>
+ <tr><td><b>Vector3</b></td><td>\link Vector3::operator== V3::==\endlink \link Vector3::fuzzyEq V3::fuzzy \endlink \link G3D::distance distance \endlink</td><td bgcolor=#C0C0C0 colspan=10 ></td></tr>
+ <tr><td><b>LineSegment</b></td><td>\link LineSegment::closestPoint LS::closestPoint\endlink \link LineSegment::distance LS::distance\endlink \link CollisionDetection::closestPointOnLineSegment CD\endlink</td><td></td><td bgcolor=#C0C0C0 colspan=9 ></td></tr>
<tr><td><b>Ray *</b></td><td>Ray::closestPoint Ray::distance</td><td></td><td></td><td bgcolor=#C0C0C0 colspan=8 ></td></tr>
- <tr><td><b>Line</b></td><td>Line::closestPoint Line::distance</td><td></td><td>CollisionDetection::closestPointsBetweenLineAndLine</td><td></td><td bgcolor=#C0C0C0 colspan=7 ></td></tr>
+ <tr><td><b>Line</b></td><td>Line::closestPoint Line::distance</td><td></td><td>\link CollisionDetection::closestPointsBetweenLineAndLine CD\endlink</td><td></td><td bgcolor=#C0C0C0 colspan=7 ></td></tr>
<tr><td><b>Plane</b></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=6 ></td></tr>
<tr><td><b>Triangle</b></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=5 ></td></tr>
- <tr><td><b>Sphere</b></td><td>Sphere::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=4 ></td></tr>
+ <tr><td><b>Sphere</b></td><td>Sphere::contains</td><td></td><td>\link CollisionDetection::collisionTimeForMovingPointFixedSphere CD \endlink, \link Ray::intersectionTime R::time\endlink</td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=4 ></td></tr>
<tr><td><b>Cylinder</b></td><td>Cylinder::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=3 ></td></tr>
<tr><td><b>Capsule</b></td><td>Capsule::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=2 ></td></tr>
- <tr><td><b>AABox</b></td><td>AABox::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=1 ></td></tr>
- <tr><td><b>Box</b></td><td>Box::contains</td><td>(treat as Ray)</td><td>CollisionDetection::collisionTimeForMovingPointFixedBox</td><td>(treat as Ray)</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedPlane</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedPlane</td><td>CollisionDetection::penetrationDepthForFixedSphereFixedBox</td><td>None (use OPCODE)</td><td>CollisionDetection::movingSpherePassesThroughFixedBox</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedBox</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedBox</td></tr>
+ <tr><td><b>AABox</b></td><td>AABox::contains</td><td></td><td></td><td></td><td></td><td>\link CollisionDetection::fixedSolidBoxIntersectsFixedTriangle CD\endlink</td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=1 ></td></tr>
+ <tr><td><b>Box</b></td><td>Box::contains</td><td>(treat as Ray)</td><td>\link CollisionDetection::collisionTimeForMovingPointFixedBox CD\endlink</td><td>(treat as Ray)</td><td>\link CollisionDetection::penetrationDepthForFixedBoxFixedPlane CD \endlink</td><td>\link CollisionDetection::penetrationDepthForFixedBoxFixedPlane CD\endlink</td><td>\link CollisionDetection::penetrationDepthForFixedSphereFixedBox CD\endlink</td><td>None (use OPCODE)</td><td>\link CollisionDetection::movingSpherePassesThroughFixedBox CD \endlink</td><td>\link CollisionDetection::penetrationDepthForFixedBoxFixedBox CD\endlink</td><td>\link CollisionDetection::penetrationDepthForFixedBoxFixedBox CD\endlink</td></tr>
</table>
<p>
@@ -86,6 +87,8 @@ namespace G3D {
<i>* Note: Moving collision detection against certain primitives is equivalent to static collision
detection against a bigger primitive. Ray, Line Segment == ``moving Point''; Capsule ==``moving Sphere''; Plane == ``moving Line''</i>
+
+ @deprecated Routines moving to the G3D::Intersect class in G3D 8.0
*/
class CollisionDetection {
private:
@@ -404,11 +407,11 @@ public:
Plane as well as the deepest point of the sphere that penetrates the plane
and the plane normal at that intersection.
- @param sphere Fixed Sphere.
- @param plane Fixed Plane.
- @param contactPoints Sphere point that penetrates the plane.
+ @param sphereA Fixed Sphere.
+ @param planeB Fixed Plane.
+ @param contactPoints Sphere point that penetrates the plane.
[Post Condition]
- @param contactNormals Normal at penetration point. [Post Condition]
+ @param contactNormals Normal at penetration point. [Post Condition]
@return Depth of penetration. If there is no intersection between the
objects then the depth will be a negative value.
@@ -477,8 +480,6 @@ public:
@param v0 Triangle vertex 1.
@param v1 Triangle vertex 2.
@param v2 Triangle vertex 3
- @param location Location of collision. [Post Condition]
- (Infinite vector on no collision)
@return Time til collision. If there is no collision then the return
value will be inf().
@@ -519,7 +520,7 @@ public:
const Vector3& v2,
Vector3& location) {
float t = collisionTimeForMovingPointFixedTriangle(orig, dir, v0, v1, v2);
- if (t < inf()) {
+ if (t < finf()) {
location = orig + dir * t;
}
return t;
@@ -553,7 +554,7 @@ public:
float t = collisionTimeForMovingPointFixedTriangle(
orig, dir, tri.vertex(0), tri.vertex(1), tri.vertex(2));
- if ((t < inf()) && (&location != &ignore)) {
+ if ((t < finf()) && (&location != &ignore)) {
location = orig + dir * t;
normal = tri.normal();
}
@@ -589,21 +590,20 @@ public:
Vector3& location,
Vector3& normal) {
float t = collisionTimeForMovingPointFixedTriangle(orig, dir, v0, v1, v2);
- if (t < inf()) {
+ if (t < finf()) {
location = orig + dir * t;
- normal = (v2 - v0).cross(v1 - v0).direction();
+ normal = (v1 - v0).cross(v2 - v0).direction();
}
return t;
}
/**
- Unlike other methods, does not support an output normal.
If the ray origin is inside the box, returns inf() but inside
is set to true.
<B>Beta API</B>
@cite Andrew Woo, from "Graphics Gems", Academic Press, 1990
- @cite Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500)
+ @cite Optimized code by Pierre Terdiman, 2000 (~20-30% faster on Celeron 500)
@cite Epsilon value added by Klaus Hartmann
@cite http://www.codercorner.com/RayAABB.cpp
*/
@@ -639,6 +639,29 @@ public:
bool& inside = ignoreBool,
Vector3& normal = ignore);
+
+ /**
+ @brief Calculates intersection of a ray and a static
+ Axis-Aligned Box (AABox).
+
+ @note Avoids the sqrt from collisionTimeForMovingPointFixedAABox;
+ early-out branches and operations optimized for Intel Core2 architecture.
+
+ @param invDir 1/dir
+ @param location Location of collision. [Post Condition]
+ @param inside Does the ray originate inside the box? [Post Condition]
+
+ @return True if the ray hits the box
+ */
+ static bool __fastcall rayAABox(
+ const Ray& ray,
+ const Vector3& invDir,
+ const AABox& box,
+ const Vector3& boxCenter,
+ float boundingRadiusSquared,
+ Vector3& location,
+ bool& inside);
+
/**
Calculates time between the intersection of a moving point and a fixed
sphere.
@@ -648,11 +671,12 @@ public:
@param point Moving point.
@param velocity Point's velocity.
- @param Sphere Fixed Sphere.
- @param location Location of collision. [Post Condition]
+ @param sphere Fixed Sphere.
+ @param outLocation Location of collision. [Post Condition]
@param outNormal Sphere's surface normal to collision [Post Condition]
+ \param solid If true, rays inside the sphere immediately intersect (good for collision detection). If false, they hit the opposite side of the sphere (good for ray tracing).
- @return Time til collision. If there is no collision then the return
+ @return Time until collision. If there is no collision then the return
value will be inf().
*/
static float collisionTimeForMovingPointFixedSphere(
@@ -660,7 +684,8 @@ public:
const Vector3& velocity,
const class Sphere& sphere,
Vector3& outLocation,
- Vector3& outNormal = ignore);
+ Vector3& outNormal = ignore,
+ bool solid = false);
/**
Calculates time between the intersection of a moving point and a fixed
@@ -721,7 +746,7 @@ public:
@param point Moving point.
@param velocity Point's velocity.
@param capsule Fixed capsule.
- @param location Location of collision. [Post Condition]
+ @param outLocation Location of collision. [Post Condition]
@param outNormal Capsule's surface normal to collision [Post Condition]
@return Time til collision. If there is no collision then the return
@@ -741,7 +766,7 @@ public:
@param sphere Moving sphere.
@param velocity Sphere's velocity.
@param plane Fixed Plane.
- @param location Location of collision -- not center position of sphere
+ @param outLocation Location of collision -- not center position of sphere
at the collision time. [Post Condition]
@param outNormal Box's surface normal to collision [Post Condition]
@@ -787,7 +812,7 @@ public:
@param v1 Rectangle vertex 2.
@param v2 Rectangle vertex 3
@param v3 Rectangle vertex 4.
- @param location Location of collision -- not center position of sphere
+ @param outLocation Location of collision -- not center position of sphere
at the collision time. [Post Condition]
@param outNormal Box's surface normal to collision [Post Condition]
@@ -828,29 +853,29 @@ public:
Vector3& outLocation,
Vector3& outNormal = ignore);
- /**
- Calculates time between the intersection of a moving sphere and a fixed
- sphere.
-
- @note This won't detect a collision if the sphere is already interpenetrating
- the fixed sphere.
-
- @param movingSphere Moving sphere.
- @param velocity Sphere's velocity.
- @param fixedSphere Fixed Sphere.
- @param location Location of collision -- not center position of sphere
- at the collision time. [Post Condition]
- @param outNormal Sphere's surface normal to collision [Post Condition]
+ /** Calculates time between the intersection of a moving sphere
+ and a fixed sphere.
- @return Time til collision. If there is no collision then the return
- value will be inf().
- */
- static float collisionTimeForMovingSphereFixedSphere(
- const class Sphere& sphere,
- const Vector3& velocity,
- const class Sphere& fixedSphere,
- Vector3& outLocation,
- Vector3& outNormal = ignore);
+ If they are already interpenetrating, returns 0 and @a
+ location is the closest point on the surface of the fixed sphere
+ to the center of the moving sphere.
+
+ @param sphere Moving sphere.
+ @param velocity Sphere's velocity.
+ @param fixedSphere Fixed Sphere.
+ @param outLocation Location of collision -- not center position of sphere
+ at the collision time. [Post Condition]
+ @param outNormal Moving sphere's surface normal to collision [Post Condition]
+
+ @return Time until collision. If there is no collision then the return
+ value will be inf().
+ */
+ static float collisionTimeForMovingSphereFixedSphere(
+ const Sphere& sphere,
+ const Vector3& velocity,
+ const Sphere& fixedSphere,
+ Vector3& outLocation,
+ Vector3& outNormal = ignore);
/**
Calculates time between the intersection of a moving sphere and a fixed
@@ -983,13 +1008,11 @@ public:
and direction can be used in this function if already pre-calculated. This
prevents doing the same work twice.
- @param v0 Triangle vertex 0.
- @param v1 Triangle vertex 1.
- @param v2 Triangle vertex 2.
- @param point External point.
- @param edgeIndex The point lies on the edge between v[edgeIndex] and v[(edgeIndex + 1) % 3]
+ @param v Triangle vertices.
+ @param point External point.
+ @param edgeIndex The point lies on the edge between v[edgeIndex] and v[(edgeIndex + 1) % 3]
- @return Closests point to <code>point</code> on the perimeter of the
+ @return Closest point to <code>point</code> on the perimeter of the
triangle.
*/
static Vector3 closestPointOnTrianglePerimeter(
@@ -1109,6 +1132,10 @@ public:
const Sphere& sphere,
const Triangle& triangle);
+ static bool fixedSolidBoxIntersectsFixedTriangle(
+ const AABox& box,
+ const Triangle& triangle);
+
/**
Tests whether a point is inside a rectangle defined by the vertexes
v0, v1, v2, & v3, and the rectangle's plane normal.
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Color1.h b/externals/g3dlite/G3D/Color1.h
index 1958da2b6cd..0f68c84b363 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Color1.h
+++ b/externals/g3dlite/G3D/Color1.h
@@ -3,11 +3,11 @@
Monochrome Color class
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-01-31
- @edited 2008-10-02
+ @edited 2009-03-20
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -47,6 +47,21 @@ public:
inline explicit Color1(float v) : value(v) {
}
+ inline bool isZero() const {
+ return value == 0.0f;
+ }
+
+ inline bool isOne() const {
+ return value == 1.0f;
+ }
+
+ static const Color1& one();
+
+ static const Color1& zero();
+
+ /** Returns the value three times */
+ class Color3 rgb() const;
+
Color1 (const class Color1uint8& other);
void serialize(class BinaryOutput& bo) const;
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Color1uint8.h b/externals/g3dlite/G3D/Color1uint8.h
index ffaa2d43ac4..092099d0d17 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Color1uint8.h
+++ b/externals/g3dlite/G3D/Color1uint8.h
@@ -18,12 +18,6 @@
namespace G3D {
-#if defined(G3D_WIN32)
- // Switch to tight alignment
- #pragma pack(push, 1)
-#endif
-
-
/**
Represents a Color1 as a packed integer. Convenient
for creating unsigned int vertex arrays.
@@ -58,6 +52,7 @@ let s = 1/256
</PRE>
and the intervals are all the same size, thus giving equal precision to all values.
*/
+G3D_BEGIN_PACKED_CLASS(1)
class Color1uint8 {
private:
// Hidden operators
@@ -91,17 +86,6 @@ public:
}
}
-
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- __attribute((aligned(1)))
-#endif
-
-;
-
-#ifdef G3D_WIN32
- #pragma pack(pop)
-#endif
-
+G3D_END_PACKED_CLASS(1)
}
-
#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Color3.h b/externals/g3dlite/G3D/Color3.h
index b8d0f94829a..bffe434fc27 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Color3.h
+++ b/externals/g3dlite/G3D/Color3.h
@@ -3,19 +3,19 @@
Color class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Portions based on Dave Eberly's Magic Software Library
at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
@created 2001-06-02
- @edited 2008-07-17
+ @edited 2009-04-28
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_COLOR3_H
-#define G3D_COLOR3_H
+#ifndef G3D_Color3_h
+#define G3D_Color3_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
@@ -24,6 +24,7 @@
#include <string>
namespace G3D {
+class Any;
/**
Do not subclass-- this implementation makes assumptions about the
@@ -43,6 +44,18 @@ public:
*/
Color3();
+ /** \param any Must be in one of the following forms:
+ - Color3(#, #, #)
+ - Color3::fromARGB(#)
+ - Color3{r = #, g = #, b = #)
+ - Color3::one()
+ - Color3::zero()
+ */
+ Color3(const Any& any);
+
+ /** Converts the Color3 to an Any. */
+ operator Any() const;
+
explicit Color3(class BinaryInput& bi);
Color3(float r, float g, float b);
@@ -52,6 +65,11 @@ public:
explicit Color3(const float value[3]);
+ /** Returns this color */
+ const Color3& rgb() const {
+ return *this;
+ }
+
/**
Initialize from another color.
*/
@@ -59,6 +77,16 @@ public:
Color3 (const class Color3uint8& other);
+ inline bool isZero() const {
+ return (r == 0.0f) && (g == 0.0f) && (b == 0.0f);
+ }
+
+ inline bool isOne() const {
+ return (r == 1.0f) && (g == 1.0f) && (b == 1.0f);
+ }
+
+ bool isFinite() const;
+
/**
Initialize from an HTML-style color (e.g. 0xFF0000 == RED)
*/
@@ -68,6 +96,22 @@ public:
Does not include white, black, or gray. */
static const Color3& wheelRandom();
+ /** Generate colors according to the ANSI color set, mod 16.
+ \sa pastelMap */
+ static Color3 ansiMap(uint32 i);
+
+ /**
+ Generate colors using a hash such that adjacent values
+ are unlikely to have similar colors.
+
+ Useful for rendering with
+ stable but arbitrary colors, e.g., when debugging a mesh
+ algorithm.
+
+ \sa ansiMap
+ */
+ static Color3 pastelMap(uint32 i);
+
/**
* Channel value.
*/
@@ -93,9 +137,13 @@ public:
// arithmetic operations
Color3 operator+ (const Color3& rkVector) const;
Color3 operator- (const Color3& rkVector) const;
- Color3 operator* (float fScalar) const;
+ inline Color3 operator* (float s) const {
+ return Color3(r * s, g * s, b * s);
+ }
Color3 operator* (const Color3& rkVector) const;
- Color3 operator/ (float fScalar) const;
+ inline Color3 operator/ (float fScalar) const {
+ return (*this) * (1.0f / fScalar);
+ }
Color3 operator- () const;
// arithmetic updates
@@ -108,14 +156,6 @@ public:
bool fuzzyEq(const Color3& other) const;
bool fuzzyNe(const Color3& other) const;
- inline operator float* () {
- return (float*)this;
- }
-
- operator const float* () const {
- return (float*)this;
- }
-
// vector operations
float length () const;
Color3 direction() const;
@@ -133,11 +173,6 @@ public:
return Color3(::pow(r, other), ::pow(g, other), ::pow(b, other));
}
- /**@return the largest component */
- inline float max() const {
- return G3D::max(G3D::max(r, g), b);
- }
-
inline Color3 max(const Color3& other) const {
return Color3(G3D::max(r, other.r), G3D::max(g, other.g), G3D::max(b, other.b));
}
@@ -146,6 +181,16 @@ public:
return Color3(G3D::min(r, other.r), G3D::min(g, other.g), G3D::min(b, other.b));
}
+ /** Smallest element */
+ inline float min() const {
+ return G3D::min(G3D::min(r, g), b);
+ }
+
+ /** Largest element */
+ inline float max() const {
+ return G3D::max(G3D::max(r, g), b);
+ }
+
inline Color3 lerp(const Color3& other, float a) const {
return (*this) + (other - *this) * a;
@@ -293,11 +338,6 @@ inline Color3 Color3::operator- (const Color3& rkVector) const {
}
//----------------------------------------------------------------------------
-inline Color3 Color3::operator* (float fScalar) const {
- return Color3(fScalar*r, fScalar*g, fScalar*b);
-}
-
-//----------------------------------------------------------------------------
inline Color3 Color3::operator* (const Color3& rkVector) const {
return Color3(r * rkVector.r, g * rkVector.g, b * rkVector.b);
}
@@ -377,6 +417,8 @@ inline Color3 Color3::unitCross (const Color3& rkVector) const {
kCross.unitize();
return kCross;
}
+
+
} // namespace
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Color3uint8.h b/externals/g3dlite/G3D/Color3uint8.h
index 20e225a0734..bd4b00d7fd6 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Color3uint8.h
+++ b/externals/g3dlite/G3D/Color3uint8.h
@@ -30,10 +30,7 @@ namespace G3D {
but Vector3(1,1,1) == Vector3int16(1,1,1).
*/
-#if defined(G3D_WIN32)
- // Switch to tight alignment
- #pragma pack(push, 1)
-#endif
+G3D_BEGIN_PACKED_CLASS(1)
class Color3uint8 {
private:
@@ -85,9 +82,18 @@ public:
// WARNING. These member functions rely on
// (1) Color3 not having virtual functions
// (2) the data packed in a 3*sizeof(uint8) memory block
- G3D::uint8& operator[] (int i) const;
- operator G3D::uint8* ();
- operator const G3D::uint8* () const;
+ uint8& operator[] (int i) const {
+ debugAssert((unsigned int)i < 3);
+ return ((uint8*)this)[i];
+ }
+
+ operator uint8* () {
+ return (G3D::uint8*)this;
+ }
+
+ operator const uint8* () const {
+ return (uint8*)this;
+ }
bool operator==(const Color3uint8& other) const {
return (other.r == r) && (other.g == g) && (other.b == b);
@@ -97,31 +103,8 @@ public:
return (other.r != r) && (other.g != g) && (other.b != b);
}
}
+G3D_END_PACKED_CLASS(1)
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- __attribute((aligned(1)))
-#endif
-
-;
-
-#ifdef G3D_WIN32
- #pragma pack(pop)
-#endif
-
-
-inline G3D::uint8& Color3uint8::operator[] (int i) const {
- debugAssert((unsigned int)i < 3);
- return ((G3D::uint8*)this)[i];
-}
-
-//----------------------------------------------------------------------------
-inline Color3uint8::operator G3D::uint8* () {
- return (G3D::uint8*)this;
-}
-
-inline Color3uint8::operator const G3D::uint8* () const {
- return (G3D::uint8*)this;
-}
-}
+} // namespace G3D
#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Color4.h b/externals/g3dlite/G3D/Color4.h
index 6b1b3b4c4bb..d8858abbce2 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Color4.h
+++ b/externals/g3dlite/G3D/Color4.h
@@ -3,19 +3,19 @@
Color class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Portions based on Dave Eberly's Magic Software Library
at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
@created 2002-06-25
- @edited 2008-07-16
+ @edited 2009-11-15
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_COLOR4_H
-#define G3D_COLOR4_H
+#ifndef G3D_Color4_h
+#define G3D_Color4_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
@@ -24,6 +24,8 @@
namespace G3D {
+class Any;
+
/**
Do not subclass-- this implementation makes assumptions about the
memory layout.
@@ -38,6 +40,16 @@ private:
public:
+ /** \param any Must be in one of the following forms:
+ - Color4(#, #, #, #)
+ - Color4::fromARGB(#)
+ - Color4{r = #, g = #, b = #, a = #)
+ */
+ Color4(const Any& any);
+
+ /** Converts the Color4 to an Any. */
+ operator Any() const;
+
/**
* Does not initialize fields.
*/
@@ -51,14 +63,10 @@ public:
Color4(const class Vector4& v);
- /**
- * Initialize from G3D::Reals.
- */
Color4(float r, float g, float b, float a = 1.0);
-
- /**
- * Initialize from array of G3D::Reals.
- */
+
+ static const Color4& one();
+
Color4(float value[4]);
/**
@@ -66,6 +74,15 @@ public:
*/
Color4(const Color4& other);
+
+ inline bool isZero() const {
+ return (r == 0.0f) && (g == 0.0f) && (b == 0.0f) && (a == 0.0f);
+ }
+
+ inline bool isOne() const {
+ return (r == 1.0f) && (g == 1.0f) && (b == 1.0f) && (a == 1.0f);
+ }
+
void serialize(class BinaryOutput& bo) const;
void deserialize(class BinaryInput& bi);
@@ -89,8 +106,6 @@ public:
// (1) Color4 not having virtual functions
// (2) the data packed in a 3*sizeof(float) memory block
float& operator[] (int i) const;
- operator float* ();
- operator const float* () const;
// assignment and comparison
Color4& operator= (const Color4& rkVector);
@@ -102,6 +117,9 @@ public:
Color4 operator+ (const Color4& rkVector) const;
Color4 operator- (const Color4& rkVector) const;
Color4 operator* (float fScalar) const;
+ inline Color4 operator* (const Color4& k) const {
+ return Color4(r*k.r, g*k.g, b*k.b, a * k.a);
+ }
Color4 operator/ (float fScalar) const;
Color4 operator- () const;
friend Color4 operator* (double fScalar, const Color4& rkVector);
@@ -141,6 +159,11 @@ public:
static const Color4& clear();
static const Color4& inf();
+ static const Color4& nan();
+
+ inline bool isFinite() const {
+ return G3D::isFinite(r) && G3D::isFinite(g) && G3D::isFinite(b) && G3D::isFinite(a);
+ }
inline Color3 bgr() const {
return Color3(b, g, r);
@@ -209,15 +232,6 @@ inline float& Color4::operator[] (int i) const {
}
//----------------------------------------------------------------------------
-inline Color4::operator float* () {
- return (float*)this;
-}
-
-inline Color4::operator const float* () const {
- return (float*)this;
-}
-
-//----------------------------------------------------------------------------
inline bool Color4::fuzzyEq(const Color4& other) const {
Color4 dif = (*this - other);
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Color4uint8.h b/externals/g3dlite/G3D/Color4uint8.h
index 7804a6e1e51..ab8c0729276 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Color4uint8.h
+++ b/externals/g3dlite/G3D/Color4uint8.h
@@ -31,12 +31,7 @@ namespace G3D {
but Vector3(1,1,1) == Vector3int16(1,1,1).
*/
-
-#ifdef G3D_WIN32
- // Switch to tight alignment
- #pragma pack(push, 1)
-#endif
-
+G3D_BEGIN_PACKED_CLASS(1)
class Color4uint8 {
private:
// Hidden operators
@@ -79,9 +74,17 @@ public:
// WARNING. These member functions rely on
// (1) Color4uint8 not having virtual functions
// (2) the data packed in a 3*sizeof(uint8) memory block
- G3D::uint8& operator[] (int i) const;
- operator G3D::uint8* ();
- operator const G3D::uint8* () const;
+ uint8& operator[] (int i) const {
+ return ((uint8*)this)[i];
+ }
+
+ operator uint8* () {
+ return (uint8*)this;
+ }
+
+ operator const uint8* () const {
+ return (uint8*)this;
+ }
inline Color3uint8 bgr() const {
@@ -105,29 +108,8 @@ public:
}
}
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- __attribute((aligned(1)))
-#endif
-;
-
-#ifdef G3D_WIN32
- #pragma pack(pop)
-#endif
-
-
-inline G3D::uint8& Color4uint8::operator[] (int i) const {
- return ((G3D::uint8*)this)[i];
-}
+G3D_END_PACKED_CLASS(1)
-//----------------------------------------------------------------------------
-inline Color4uint8::operator G3D::uint8* () {
- return (G3D::uint8*)this;
-}
-
-inline Color4uint8::operator const G3D::uint8* () const {
- return (G3D::uint8*)this;
-}
-
-}
+} // namespace G3D
#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Cone.h b/externals/g3dlite/G3D/Cone.h
index c09b9b6846c..d801a9b348f 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Cone.h
+++ b/externals/g3dlite/G3D/Cone.h
@@ -3,7 +3,7 @@
Cone class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
@created 2001-06-02
diff --git a/externals/g3dlite/G3D.lib/include/G3D/ConvexPolyhedron.h b/externals/g3dlite/G3D/ConvexPolyhedron.h
index 6ae9ba136ff..a6fdd62cf90 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/ConvexPolyhedron.h
+++ b/externals/g3dlite/G3D/ConvexPolyhedron.h
@@ -1,7 +1,7 @@
/**
@file ConvexPolyhedron.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-11-11
@edited 2006-04-10
@@ -32,41 +32,42 @@ public:
class ConvexPolygon {
private:
- friend class ConvexPolyhedron;
+ friend class ConvexPolyhedron;
Array<Vector3> _vertex;
public:
ConvexPolygon() {}
+ ConvexPolygon(const Vector3& v0, const Vector3& v1, const Vector3& v2);
ConvexPolygon(const Array<Vector3>& __vertex);
virtual ~ConvexPolygon() {}
/**
Counter clockwise winding order.
*/
- inline const Vector3& vertex(int i) const {
- return _vertex[i];
- }
-
- inline void setVertex(int i, const Vector3& v) {
- _vertex[i] = v;
- }
-
- /**
- Zero vertices indicates an empty polygon (zero area).
- */
- inline int numVertices() const {
- return _vertex.size();
- }
-
- inline void setNumVertices(int n) {
- _vertex.resize(n);
- }
-
+ inline const Vector3& vertex(int i) const {
+ return _vertex[i];
+ }
+
+ inline void setVertex(int i, const Vector3& v) {
+ _vertex[i] = v;
+ }
+
/**
- O(n) in the number of edges
- */
+ Zero vertices indicates an empty polygon (zero area).
+ */
+ inline int numVertices() const {
+ return _vertex.size();
+ }
+
+ inline void setNumVertices(int n) {
+ _vertex.resize(n);
+ }
+
+ /**
+ O(n) in the number of edges
+ */
bool isEmpty() const;
/**
@@ -81,16 +82,16 @@ public:
void cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below, DirectedEdge& newEdge);
void cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below);
- /**
- When a cut plane grazes a vertex in the polygon, two near-identical vertices may be created.
- The closeness of these two points can cause a number of problems, such as ConvexPolygon::normal()
- returning an infinite vector. It should be noted, however, that not all applications are
- sensitive to near-identical vertices.
-
- removeDuplicateVertices() detects and eliminates redundant vertices.
- */
- void removeDuplicateVertices();
-
+ /**
+ When a cut plane grazes a vertex in the polygon, two near-identical vertices may be created.
+ The closeness of these two points can cause a number of problems, such as ConvexPolygon::normal()
+ returning an infinite vector. It should be noted, however, that not all applications are
+ sensitive to near-identical vertices.
+
+ removeDuplicateVertices() detects and eliminates redundant vertices.
+ */
+ void removeDuplicateVertices();
+
/**
O(n) in the number of edges
*/
diff --git a/externals/g3dlite/G3D.lib/include/G3D/CoordinateFrame.h b/externals/g3dlite/G3D/CoordinateFrame.h
index 705c6c93ae2..7ed4d0acc65 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/CoordinateFrame.h
+++ b/externals/g3dlite/G3D/CoordinateFrame.h
@@ -1,17 +1,17 @@
/**
@file CoordinateFrame.h
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-03-04
- @edited 2008-07-14
+ @edited 2009-04-29
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_COORDINATEFRAME_H
-#define G3D_COORDINATEFRAME_H
+#ifndef G3D_CFrame_h
+#define G3D_CFrame_h
#include "G3D/platform.h"
#include "G3D/Vector3.h"
@@ -24,7 +24,15 @@
#include <cstdarg>
#include <assert.h>
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
+#endif
+
+
namespace G3D {
+class Any;
/**
A rigid body RT (rotation-translation) transformation.
@@ -56,6 +64,16 @@ public:
/** Takes object space points to world space. */
Vector3 translation;
+ /** \param any Must be in one of the following forms:
+ - CFrame((matrix3 expr), (vector3 expr))
+ - CFrame::fromXYZYPRDegrees(#, #, #, #, #, #)
+ - CFrame { rotation = (matrix3 expr), translation = (vector3 expr) }
+ */
+ CoordinateFrame(const Any& any);
+
+ /** Converts the CFrame to an Any. */
+ operator Any() const;
+
inline bool operator==(const CoordinateFrame& other) const {
return (translation == other.translation) && (rotation == other.rotation);
}
@@ -73,9 +91,7 @@ public:
/**
Initializes to the identity coordinate frame.
*/
- inline CoordinateFrame() :
- rotation(Matrix3::identity()), translation(Vector3::zero()) {
- }
+ CoordinateFrame();
CoordinateFrame(const Vector3& _translation) :
rotation(Matrix3::identity()), translation(_translation) {
@@ -143,7 +159,7 @@ public:
object has an inverted heading.
*/
inline float getHeading() const {
- Vector3 look = rotation.getColumn(2);
+ Vector3 look = rotation.column(2);
float angle = -(float) atan2(-look.x, look.z);
return angle;
}
@@ -275,7 +291,7 @@ public:
/** The direction this camera is looking (its negative z axis)*/
inline Vector3 lookVector() const {
- return -rotation.getColumn(2);
+ return -rotation.column(2);
}
/** Returns the ray starting at the camera origin travelling in direction CoordinateFrame::lookVector. */
@@ -283,11 +299,11 @@ public:
/** Up direction for this camera (its y axis). */
inline Vector3 upVector() const {
- return rotation.getColumn(1);
+ return rotation.column(1);
}
inline Vector3 rightVector() const {
- return rotation.getColumn(0);
+ return rotation.column(0);
}
/**
@@ -295,7 +311,7 @@ public:
Useful for strafing motions and building alternative coordinate frames.
*/
inline Vector3 leftVector() const {
- return -rotation.getColumn(0);
+ return -rotation.column(0);
}
/**
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Crypto.h b/externals/g3dlite/G3D/Crypto.h
index f8266b8721b..56c816a4977 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Crypto.h
+++ b/externals/g3dlite/G3D/Crypto.h
@@ -1,7 +1,7 @@
/**
@file Crypto.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2006-03-29
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Cylinder.h b/externals/g3dlite/G3D/Cylinder.h
index c341d29a2b9..85eba77b794 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Cylinder.h
+++ b/externals/g3dlite/G3D/Cylinder.h
@@ -1,7 +1,7 @@
/**
@file Cylinder.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-02-07
@edited 2005-09-26
diff --git a/externals/g3dlite/G3D.lib/include/G3D/EqualsTrait.h b/externals/g3dlite/G3D/EqualsTrait.h
index acf17615b45..349cb5088fb 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/EqualsTrait.h
+++ b/externals/g3dlite/G3D/EqualsTrait.h
@@ -1,10 +1,10 @@
/**
@file EqualsTrait.h
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2008-10-01
@edited 2008-10-01
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
diff --git a/externals/g3dlite/G3D.lib/include/G3D/G3D.h b/externals/g3dlite/G3D/G3D.h
index 42ab18e2c24..5b56b9c71dc 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/G3D.h
+++ b/externals/g3dlite/G3D/G3D.h
@@ -1,20 +1,20 @@
/**
- @file graphics3D.h
+ @file G3D.h
- This header includes all of the graphics3D libraries in
+ This header includes all of the G3D libraries in
appropriate namespaces.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-08-25
- @edited 2008-11-01
+ @edited 2010-01-30
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2010, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_GRAPHICS3D_H
-#define G3D_GRAPHICS3D_H
+#ifndef G3D_G3D_h
+#define G3D_G3D_h
#define NOMINMAX 1
#ifdef min
@@ -25,7 +25,11 @@
#endif
#include "G3D/platform.h"
+#include "G3D/units.h"
+#include "G3D/ParseError.h"
+#include "G3D/Random.h"
#include "G3D/Array.h"
+#include "G3D/SmallArray.h"
#include "G3D/Queue.h"
#include "G3D/Crypto.h"
#include "G3D/format.h"
@@ -45,6 +49,7 @@
#include "G3D/Ray.h"
#include "G3D/Sphere.h"
#include "G3D/Box.h"
+#include "G3D/Box2D.h"
#include "G3D/AABox.h"
#include "G3D/WrapMode.h"
#include "G3D/Cone.h"
@@ -58,11 +63,18 @@
#include "G3D/BinaryInput.h"
#include "G3D/BinaryOutput.h"
#include "G3D/debug.h"
+#include "G3D/g3dfnmatch.h"
#include "G3D/G3DGameUnits.h"
#include "G3D/g3dmath.h"
#include "G3D/uint128.h"
#include "G3D/fileutils.h"
#include "G3D/ReferenceCount.h"
+#include "G3D/Welder.h"
+#include "G3D/GMutex.h"
+#include "G3D/PrecomputedRandom.h"
+#include "G3D/MemoryManager.h"
+#include "G3D/AreaMemoryManager.h"
+#include "G3D/BumpMapPreprocess.h"
template<class T> struct HashTrait< G3D::ReferenceCountedPointer<T> > {
static size_t hashCode(G3D::ReferenceCountedPointer<T> key) { return reinterpret_cast<size_t>( key.pointer() ); }
@@ -70,6 +82,7 @@ template<class T> struct HashTrait< G3D::ReferenceCountedPointer<T> > {
#include "G3D/GImage.h"
#include "G3D/CollisionDetection.h"
+#include "G3D/Intersect.h"
#include "G3D/Log.h"
#include "G3D/serialize.h"
#include "G3D/TextInput.h"
@@ -90,14 +103,13 @@ template<class T> struct HashTrait< G3D::ReferenceCountedPointer<T> > {
#include "G3D/Vector3int32.h"
#include "G3D/Vector4int8.h"
#include "G3D/ConvexPolyhedron.h"
-#include "G3D/Discovery.h"
#include "G3D/MeshAlg.h"
#include "G3D/vectorMath.h"
#include "G3D/Rect2D.h"
#include "G3D/GCamera.h"
#include "G3D/GLight.h"
-#include "G3D/AABSPTree.h"
-#include "G3D/PointAABSPTree.h"
+#include "G3D/KDTree.h"
+#include "G3D/PointKDTree.h"
#include "G3D/TextOutput.h"
#include "G3D/MeshBuilder.h"
#include "G3D/Stopwatch.h"
@@ -105,7 +117,7 @@ template<class T> struct HashTrait< G3D::ReferenceCountedPointer<T> > {
#include "G3D/GThread.h"
#include "G3D/ThreadSet.h"
#include "G3D/RegistryUtil.h"
-#include "G3D/AnyVal.h"
+#include "G3D/Any.h"
#include "G3D/PointHashGrid.h"
#include "G3D/Map2D.h"
#include "G3D/Image1.h"
diff --git a/externals/g3dlite/G3D.lib/include/G3D/G3DAll.h b/externals/g3dlite/G3D/G3DAll.h
index feba3d6d390..1176fe742e7 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/G3DAll.h
+++ b/externals/g3dlite/G3D/G3DAll.h
@@ -4,9 +4,9 @@
Includes all G3D and GLG3D files and uses the G3D namespace.
This requires OpenGL and SDL headers. If you don't want all of this,
- #include <G3D.h> separately.
+ \#include <G3D.h> separately.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-01-01
@edited 2006-08-13
diff --git a/externals/g3dlite/G3D.lib/include/G3D/G3DGameUnits.h b/externals/g3dlite/G3D/G3DGameUnits.h
index bc4c873f290..e2bc2c811e8 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/G3DGameUnits.h
+++ b/externals/g3dlite/G3D/G3DGameUnits.h
@@ -1,7 +1,7 @@
/**
@file G3DGameUnits.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-10-05
@edited 2006-11-10
*/
@@ -25,11 +25,9 @@ typedef double RealTime;
enum AMPM {AM, PM};
+/** \deprecated */
enum {SECOND=1, MINUTE=60, HOUR = 60*60, DAY=24*60*60, SUNRISE=24*60*60/4, SUNSET=24*60*60*3/4, MIDNIGHT=0, METER=1, KILOMETER=1000};
-#define CENTIMETER (0.01)
-#define DECIMETER (0.1)
-
/**
Converts a 12 hour clock time into the number of seconds since
midnight. Note that 12:00 PM is noon and 12:00 AM is midnight.
diff --git a/externals/g3dlite/G3D.lib/include/G3D/GCamera.h b/externals/g3dlite/G3D/GCamera.h
index 4dfa500883b..018fbc85d59 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/GCamera.h
+++ b/externals/g3dlite/G3D/GCamera.h
@@ -1,10 +1,10 @@
/**
@file GCamera.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2005-07-20
- @edited 2007-07-24
+ @edited 2009-04-20
*/
#ifndef G3D_GCamera_H
@@ -20,17 +20,21 @@ namespace G3D {
class Matrix4;
class Rect2D;
+class Any;
/**
Abstraction of a pinhole camera.
- The area a camera sees is called a frustum. It is bounded by the near plane, the far plane, and the sides
- of the view frame projected into the scene. It has the shape of a pyramid with the top cut off.
+ The area a camera sees is called a frustum. It is bounded by the
+ near plane, the far plane, and the sides of the view frame projected
+ into the scene. It has the shape of a pyramid with the top cut off.
- Cameras can project points from 3D to 2D. The "unit" projection matches OpenGL. It maps the entire view frustum
- to a cube of unit radius (i.e., edges of length 2) centered at the origin. The non-unit projection then maps
- that cube to the specified pixel viewport in X and Y and the range [0, 1] in Z. The projection is reversable
- as long as the projected Z value is known.
+ Cameras can project points from 3D to 2D. The "unit" projection
+ matches OpenGL. It maps the entire view frustum to a cube of unit
+ radius (i.e., edges of length 2) centered at the origin. The
+ non-unit projection then maps that cube to the specified pixel
+ viewport in X and Y and the range [0, 1] in Z. The projection is
+ reversable as long as the projected Z value is known.
All viewport arguments are the pixel bounds of the viewport-- e.g.,
RenderDevice::viewport().
@@ -44,16 +48,15 @@ public:
enum FOVDirection {HORIZONTAL, VERTICAL};
private:
-
- /** field of view (in radians) */
- float m_fieldOfView;
+ /** Full field of view (in radians) */
+ float m_fieldOfView;
/** Clipping plane, *not* imaging plane. Negative numbers. */
- float m_nearPlaneZ;
+ float m_nearPlaneZ;
/** Negative */
- float m_farPlaneZ;
+ float m_farPlaneZ;
/** Stores the camera's location and orientation */
CoordinateFrame m_cframe;
@@ -63,6 +66,23 @@ private:
public:
+ /** Must be of the format produced by the Any cast, e.g.,
+
+ <pre>
+ GCamera {
+ coordinateFrame = CFrame::fromXYZYPRDegrees(-13.3f, 8.0f, -1.9f, 246.6f, -3),
+ nearPlaneZ = -0.5,
+ farPlaneZ = -50,
+ fovDirection = "HORIZONTAL",
+ fovAngleDegrees = 90
+ }</pre>
+
+ Missing fields are filled from the default GCamera constructor.
+ */
+ GCamera(const Any& any);
+
+ operator Any() const;
+
class Frustum {
public:
class Face {
@@ -88,6 +108,8 @@ public:
GCamera();
+ GCamera(const Matrix4& proj, const CFrame& frame);
+
virtual ~GCamera();
/** Returns the current coordinate frame */
@@ -96,25 +118,46 @@ public:
}
/** Sets c to the camera's coordinate frame */
- void getCoordinateFrame(CoordinateFrame& c) const;
+ void getCoordinateFrame(CoordinateFrame& c) const;
/** Sets a new coordinate frame for the camera */
- void setCoordinateFrame(const CoordinateFrame& c);
+ void setCoordinateFrame(const CoordinateFrame& c);
- /** Sets P equal to the camera's projection matrix */
+ /** Sets \a P equal to the camera's projection matrix. This is the
+ matrix that maps points to the homogeneous clip cube that
+ varies from -1 to 1 on all axes. The projection matrix does
+ not include the camera transform.
+
+ This is the matrix that a RenderDevice (or OpenGL) uses as the projection matrix.
+ @sa RenderDevice::setProjectionAndCameraMatrix, RenderDevice::setProjectionMatrix, Matrix4::perspectiveProjection
+ */
void getProjectUnitMatrix(const Rect2D& viewport, Matrix4& P) const;
+ /** Sets \a P equal to the matrix that transforms points to pixel
+ coordinates on the given viewport. A point correspoinding to
+ the top-left corner of the viewport in camera space will
+ transform to viewport.x0y0() and the bottom-right to viewport.x1y1(). */
+ void getProjectPixelMatrix(const Rect2D& viewport, Matrix4& P) const;
+
/** Converts projected points from OpenGL standards
- (-1, 1) to normal 3D coordinate standards (0, 1) */
+ (-1, 1) to normal 3D coordinate standards (0, 1)
+
+ \deprecated
+ */ // TODO: Remove
Vector3 convertFromUnitToNormal(const Vector3& in, const Rect2D& viewport) const;
/**
- Sets the vertical field of view, in radians. The
- initial angle is toRadians(55). Must specify the direction of the angle
+ Sets the field of view, in radians. The
+ initial angle is toRadians(55). Must specify
+ the direction of the angle.
+
+ This is the full angle, i.e., from the left side of the
+ viewport to the right side.
*/
void setFieldOfView(float angle, FOVDirection direction);
- /** Returns the current field of view angle and direction */
+ /** Returns the current full field of view angle (from the left side of the
+ viewport to the right side) and direction */
inline void getFieldOfView(float& angle, FOVDirection& direction) const {
angle = m_fieldOfView;
direction = m_direction;
diff --git a/externals/g3dlite/G3D.lib/include/G3D/GImage.h b/externals/g3dlite/G3D/GImage.h
index 12003514d6a..8ae11134fc9 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/GImage.h
+++ b/externals/g3dlite/G3D/GImage.h
@@ -1,5 +1,5 @@
/**
- @file GImage.h
+ \file GImage.h
See G3D::GImage for details.
@@ -11,17 +11,17 @@
@cite PNG compress/decompressor is the <A HREF="http://www.libpng.org/pub/png/libpng.html">libpng library</A>, used in accordance with their license.
@cite PPM code by Morgan McGuire based on http://netpbm.sourceforge.net/doc/ppm.html
- @maintainer Morgan McGuire, morgan@graphics3d.com
- @created 2002-05-27
- @edited 2007-01-31
+ \maintainer Morgan McGuire, http://graphics.cs.williams.edu
- Copyright 2000-2007, Morgan McGuire.
- All rights reserved.
+ \created 2002-05-27
+ \edited 2010-01-04
+ Copyright 2000-2010, Morgan McGuire.
+ All rights reserved.
*/
-#ifndef G3D_GIMAGE_H
-#define G3D_GIMAGE_H
+#ifndef G3D_GImage_h
+#define G3D_GImage_h
#include "G3D/platform.h"
#include <string>
@@ -31,33 +31,38 @@
#include "G3D/Color1uint8.h"
#include "G3D/Color3uint8.h"
#include "G3D/Color4uint8.h"
+#include "G3D/MemoryManager.h"
+#include "G3D/BumpMapPreprocess.h"
namespace G3D {
class BinaryInput;
class BinaryOutput;
+
+
/**
Interface to image compression & file formats.
- Supported formats (decode and encode): Color JPEG, PNG, (Uncompressed)TGA 24, (Uncompressed)TGA 32, BMP 1, BMP 4, BMP 8, BMP 24, PPM (P6), and PPM ASCII (P1, P2, P3).
- 8-bit paletted PCX, 24-bit PCX, and ICO are supported for decoding only.
+ Supported formats (decode and encode): Color JPEG, PNG,
+ (Uncompressed)TGA 24, (Uncompressed)TGA 32, BMP 1, BMP 4, BMP 8, BMP
+ 24, PPM (P6), and PPM ASCII (P1, P2, P3), which includes PPM, PGM,
+ and PBM. 8-bit paletted PCX, 24-bit PCX, and ICO are supported for
+ decoding only.
Sample usage:
- <PRE>
- #include "graphics3D.h"
-
+ \verbatim
// Loading from disk:
- G3D::GImage im1 = G3D::GImage("test.jpg");
+ G3D::GImage im1("test.jpg");
// Loading from memory:
- G3D::GImage im2 = G3D::GImage(data, length);
+ G3D::GImage im2(data, length);
// im.pixel is a pointer to RGB color data. If you want
// an alpha channel, call RGBtoRGBA or RGBtoARGB for
// conversion.
// Saving to memory:
- G3D::GImage im3 = G3D::GImage(width, height);
+ G3D::GImage im3(width, height);
// (Set the pixels of im3...)
uint8* data2;
int len2;
@@ -65,7 +70,7 @@ class BinaryOutput;
// Saving to disk
im3.save("out.jpg");
- </PRE>
+ \endverbatim
The free Image Magick Magick Wand API
(http://www.imagemagick.org/www/api/magick_wand.html) provides a more powerful
@@ -76,7 +81,15 @@ class BinaryOutput;
*/
class GImage {
private:
- uint8* _byte;
+
+ /** Used exclusively for allocating m_byte; this may be an
+ implementation that allocates directly on a GPU.*/
+ MemoryManager::Ref m_memMan;
+ uint8* m_byte;
+
+ int m_channels;
+ int m_width;
+ int m_height;
public:
@@ -91,98 +104,125 @@ public:
std::string filename;
};
- enum Format {JPEG, BMP, TGA, PCX, ICO, PNG, PPM_ASCII, PPM, AUTODETECT, UNKNOWN};
+ /** PGM, PPM, and PBM all come in two versions and are classified as PPM_* files */
+ enum Format {JPEG, BMP, TGA, PCX, ICO, PNG,
+ PPM_BINARY, PGM_BINARY = PPM_BINARY,
+ PPM_ASCII, PGM_ASCII = PPM_ASCII,
+ AUTODETECT, UNKNOWN};
- int width;
- int height;
/**
The number of channels; either 3 (RGB) or 4 (RGBA)
*/
- int channels;
+ inline int channels() const {
+ return m_channels;
+ }
+
+ inline int width() const {
+ return m_width;
+ }
+
+ inline int height() const {
+ return m_height;
+ }
inline const uint8* byte() const {
- return _byte;
+ return m_byte;
}
- /** Returns a pointer to the upper left pixel
- as Color3uint8.
- */
- inline const Color3uint8* pixel3() const {
- debugAssertM(channels == 3, format("Tried to call GImage::pixel3 on an image with %d channels", channels));
- return (Color3uint8*)_byte;
+ /** Returns a pointer to the underlying data, which is stored
+ in row-major order without row padding.
+ e.g., <code>uint8* ptr = image.rawData<uint8>();
+ */
+ template<typename Type>
+ inline const Type* rawData() const {
+ return (Type*)m_byte;
+ }
+
+ /** \copybrief GImage::rawData() const */
+ template<typename Type>
+ inline Type* rawData() {
+ return (Type*)m_byte;
+ }
+
+ inline const Color1uint8* pixel1() const {
+ debugAssertM(m_channels == 1, format("Tried to call GImage::pixel1 on an image with %d channels", m_channels));
+ return (Color1uint8*)m_byte;
+ }
+
+ inline Color1uint8* pixel1() {
+ debugAssertM(m_channels == 1, format("Tried to call GImage::pixel1 on an image with %d channels", m_channels));
+ return (Color1uint8*)m_byte;
}
/** Returns a pointer to the upper left pixel
as Color4uint8.
*/
inline const Color4uint8* pixel4() const {
- debugAssertM(channels == 4, format("Tried to call GImage::pixel4 on an image with %d channels", channels));
- return (Color4uint8*)_byte;
+ debugAssertM(m_channels == 4, format("Tried to call GImage::pixel4 on an image with %d channels", m_channels));
+ return (Color4uint8*)m_byte;
}
- inline const Color1uint8* pixel1() const {
- debugAssertM(channels == 1, format("Tried to call GImage::pixel1 on an image with %d channels", channels));
- return (Color1uint8*)_byte;
+ inline Color4uint8* pixel4() {
+ debugAssert(m_channels == 4);
+ return (Color4uint8*)m_byte;
}
- inline Color1uint8* pixel1() {
- debugAssertM(channels == 1, format("Tried to call GImage::pixel1 on an image with %d channels", channels));
- return (Color1uint8*)_byte;
+ /** Returns a pointer to the upper left pixel
+ as Color3uint8.
+ */
+ inline const Color3uint8* pixel3() const {
+ debugAssertM(m_channels == 3, format("Tried to call GImage::pixel3 on an image with %d channels", m_channels));
+ return (Color3uint8*)m_byte;
+ }
+
+ inline Color3uint8* pixel3() {
+ debugAssert(m_channels == 3);
+ return (Color3uint8*)m_byte;
}
/** Returns the pixel at (x, y), where (0,0) is the upper left. */
inline const Color1uint8& pixel1(int x, int y) const {
- debugAssert(x >= 0 && x < width);
- debugAssert(y >= 0 && y < height);
- return pixel1()[x + y * width];
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel1()[x + y * m_width];
}
/** Returns the pixel at (x, y), where (0,0) is the upper left. */
inline Color1uint8& pixel1(int x, int y) {
- debugAssert(x >= 0 && x < width);
- debugAssert(y >= 0 && y < height);
- return pixel1()[x + y * width];
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel1()[x + y * m_width];
}
/** Returns the pixel at (x, y), where (0,0) is the upper left. */
inline const Color3uint8& pixel3(int x, int y) const {
- debugAssert(x >= 0 && x < width);
- debugAssert(y >= 0 && y < height);
- return pixel3()[x + y * width];
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel3()[x + y * m_width];
}
inline Color3uint8& pixel3(int x, int y) {
- debugAssert(x >= 0 && x < width);
- debugAssert(y >= 0 && y < height);
- return pixel3()[x + y * width];
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel3()[x + y * m_width];
}
/** Returns the pixel at (x, y), where (0,0) is the upper left. */
inline const Color4uint8& pixel4(int x, int y) const {
- debugAssert(x >= 0 && x < width);
- debugAssert(y >= 0 && y < height);
- return pixel4()[x + y * width];
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel4()[x + y * m_width];
}
inline Color4uint8& pixel4(int x, int y) {
- debugAssert(x >= 0 && x < width);
- debugAssert(y >= 0 && y < height);
- return pixel4()[x + y * width];
+ debugAssert(x >= 0 && x < m_width);
+ debugAssert(y >= 0 && y < m_height);
+ return pixel4()[x + y * m_width];
}
inline uint8* byte() {
- return _byte;
- }
-
- inline Color3uint8* pixel3() {
- debugAssert(channels == 3);
- return (Color3uint8*)_byte;
- }
-
- inline Color4uint8* pixel4() {
- debugAssert(channels == 4);
- return (Color4uint8*)_byte;
+ return m_byte;
}
private:
@@ -253,12 +293,23 @@ private:
const GImage& other);
public:
+
+ /** Predicts the image file format of \a filename */
static Format resolveFormat(const std::string& filename);
- GImage() {
- width = height = channels = 0;
- _byte = NULL;
- }
+ void flipHorizontal();
+ void flipVertical();
+ void rotate90CW(int numTimes = 1);
+
+ /**
+ Create an empty image of the given size.
+ \sa load()
+ */
+ GImage(
+ int width = 0,
+ int height = 0,
+ int channels = 3,
+ const MemoryManager::Ref& m = MemoryManager::create());
/**
Load an encoded image from disk and decode it.
@@ -266,7 +317,8 @@ public:
*/
GImage(
const std::string& filename,
- Format format = AUTODETECT);
+ Format format = AUTODETECT,
+ const MemoryManager::Ref& m = MemoryManager::create());
/**
Decodes an image stored in a buffer.
@@ -274,18 +326,12 @@ public:
GImage(
const unsigned char*data,
int length,
- Format format = AUTODETECT);
-
- /**
- Create an empty image of the given size.
- */
- GImage(
- int width,
- int height,
- int channels = 3);
+ Format format = AUTODETECT,
+ const MemoryManager::Ref& m = MemoryManager::create());
GImage(
- const GImage& other);
+ const GImage& other,
+ const MemoryManager::Ref& m = MemoryManager::create());
GImage& operator=(const GImage& other);
@@ -295,22 +341,19 @@ public:
channel of the supplied image. The new GImage is passed
as a reference parameter for speed.
*/
- void insertRedAsAlpha(const GImage& alpha, GImage& output) const;
-
- GImage G3D_DEPRECATED insertRedAsAlpha(const GImage& alpha) const;
+ void insertRedAsAlpha(const GImage& alpha, GImage& output) const;
/**
Returns a new GImage with 3 channels, removing
the alpha channel if there is one. The new GImage
is passed as a reference parameter for speed.
*/
- void stripAlpha(GImage& output) const;
-
- GImage G3D_DEPRECATED stripAlpha() const;
+ void stripAlpha(GImage& output) const;
- /**
- Loads an image from disk (clearing the old one first).
- */
+ /**
+ Loads an image from disk (clearing the old one first),
+ using the existing memory manager.
+ */
void load(
const std::string& filename,
Format format = AUTODETECT);
@@ -326,11 +369,12 @@ public:
virtual ~GImage();
/**
- Resizes the internal buffer to (width x height) with the
- number of channels specified. All data is set to 0 (black).
+ Resizes the internal buffer to (\a width x \a height) with the
+ number of \a channels specified.
+
+ \param zero If true, all data is set to 0 (black).
*/
- void resize(int width, int height, int channels);
-
+ void resize(int width, int height, int channels, bool zero = true);
/**
Copies src sub-image data into dest at a certain offset.
@@ -340,8 +384,15 @@ public:
completely fit within dest at the specified offset. Both
src and dest must have the same number of channels.
*/
- static bool pasteSubImage(GImage & dest, const GImage & src,
- int destX, int destY, int srcX, int srcY, int srcWidth, int srcHeight);
+ static bool pasteSubImage(
+ GImage& dest,
+ const GImage& src,
+ int destX,
+ int destY,
+ int srcX,
+ int srcY,
+ int srcWidth,
+ int srcHeight);
/**
creates dest from src sub-image data.
@@ -380,6 +431,7 @@ public:
/**
The caller must delete the returned buffer.
+ TODO: provide a memory manager
*/
void encode(
Format format,
@@ -395,7 +447,7 @@ public:
/**
Decodes the buffer into this image.
- @format Must be the correct format.
+ @param format Must be the correct format.
*/
void decode(
BinaryInput& input,
@@ -404,7 +456,6 @@ public:
/** Returns the size of this object in bytes */
int sizeInMemory() const;
-
/** Ok for in == out */
static void R8G8B8_to_Y8U8V8(int width, int height, const uint8* in, uint8* out);
@@ -426,6 +477,16 @@ public:
uint8* out,
int numPixels);
+ static void LtoRGB
+ (const uint8* in,
+ uint8* out,
+ int numPixels);
+
+ static void LtoRGBA
+ (const uint8* in,
+ uint8* out,
+ int numPixels);
+
/** Safe for in == out */
static void RGBtoBGR(
const uint8* in,
@@ -483,36 +544,20 @@ public:
return Texture::fromGImage(filename, normal);
</PRE>
- @param lowPassBump If true, a 9x9 filter of 1's is used to low-pass filter the elevations,
- which produces better results for parallax mapping.
-
- @param scaleHeightByNz After computing normals, scale the height by |N.z|, a trick that
- reduces texture swim in steep areas for parallax mapping.
-
- @param whiteHeightInPixels How high should the brightest input value be considered for purposes
- of normal computation, compared to the horizontal and vertical size of a pixel.
- A value of 255 means that a 255 x 255 bump image with a full black-to-white gradient will
- produce a 45-degree ramp (this also results in "cubic" voxels).
- A special (default) value of -1 means scale the effective white height so that it is equal
- to the larger spatial dimension.
*/
static void computeNormalMap(
const class GImage& bump,
class GImage& normal,
- float whiteHeightInPixels = -1.0f,
- bool lowPassBump = false,
- bool scaleHeightByNz = false);
+ const BumpMapPreprocess& preprocess = BumpMapPreprocess());
+
+ static void computeNormalMap
+ (int width,
+ int height,
+ int channels,
+ const uint8* src,
+ GImage& normal,
+ const BumpMapPreprocess& preprocess = BumpMapPreprocess());
- static void computeNormalMap(
- int width,
- int height,
- int channels,
- const uint8* src,
- GImage& normal,
- float whiteHeightInPixels,
- bool lowPassBump,
- bool scaleHeightByNz);
-
/**
Bayer demosaicing using the filter proposed in
@@ -530,19 +575,31 @@ public:
/** Fast conversion; the output has 1/2 the size of the input in each direction. Assumes in != out.
See G3D::BAYER_G8B8_R8G8_to_R8G8B8_MHC for a much better result. */
- static void BAYER_G8B8_R8G8_to_Quarter_R8G8B8(int inWidth, int inHeight, const uint8* in, uint8* out);
+ static void BAYER_G8B8_R8G8_to_Quarter_R8G8B8
+ (int inWidth,
+ int inHeight,
+ const uint8* in,
+ uint8* out);
/** Attempt to undo fast conversion of G3D::BAYER_G8B8_R8G8_to_Quarter_R8G8B8;
the green channel will lose data. Assumes in != out
The input should have size 3 * inWidth * inHeight. The output should have size
2 * inWidth * 2 * inHeight.
*/
- static void Quarter_R8G8B8_to_BAYER_G8B8_R8G8(int inWidth, int inHeight, const uint8* in, uint8* out);
+ static void Quarter_R8G8B8_to_BAYER_G8B8_R8G8
+ (int inWidth,
+ int inHeight,
+ const uint8* in,
+ uint8* out);
/** Overwrites every pixel with one of the two colors in a checkerboard pattern.
The fields used from the two colors depend on the current number of channels in @a im.
*/
- static void makeCheckerboard(GImage& im, int checkerSize = 1, const Color4uint8& color1 = Color4uint8(255,255,255,255), const Color4uint8& color2 = Color4uint8(0,0,0,255));
+ static void makeCheckerboard
+ (GImage& im,
+ int checkerSize = 1,
+ const Color4uint8& color1 = Color4uint8(255,255,255,255),
+ const Color4uint8& color2 = Color4uint8(0,0,0,255));
};
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/GLight.h b/externals/g3dlite/G3D/GLight.h
index b8fa7b54261..3a95f1a8114 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/GLight.h
+++ b/externals/g3dlite/G3D/GLight.h
@@ -1,14 +1,14 @@
/**
@file GLight.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-11-12
- @edited 2006-02-08
+ @edited 2009-11-08
*/
-#ifndef G3D_GLIGHT_H
-#define G3D_GLIGHT_H
+#ifndef G3D_GLight_h
+#define G3D_GLight_h
#include "G3D/platform.h"
#include "G3D/Vector4.h"
@@ -16,6 +16,7 @@
#include "G3D/Color4.h"
namespace G3D {
+class Any;
/**
A light representation that closely follows the OpenGL light format.
@@ -25,12 +26,23 @@ public:
/** World space position (for a directional light, w = 0 */
Vector4 position;
+ /** For a spot or directional light, this is the "right vector" that will be used when constructing
+ a reference frame(). */
+ Vector3 rightDirection;
+
/** Direction in which the light faces, if a spot light. This is the "look vector" of the light source. */
Vector3 spotDirection;
- /** In <B>degrees</B>. 180 = no cutoff (point/dir) >90 = spot light */
+ /** In <B>degrees</B>. 180 = no cutoff (point/dir). Values less than 90 = spot light */
float spotCutoff;
+ /** If true, G3D::SuperShader will render a cone of light large
+ enough to encompass the entire square that bounds the cutoff
+ angle. This produces a square prism instead of a cone of light
+ when used with a G3D::ShadowMap. for an unshadowed light this
+ has no effect.*/
+ bool spotSquare;
+
/** Constant, linear, quadratic */
float attenuation[3];
@@ -40,29 +52,51 @@ public:
/** If false, this light is ignored */
bool enabled;
- /** If false, this light does not create specular highlights (useful when using negative lights). */
+ /** If false, this light does not create specular highlights
+ (useful when using negative lights). */
bool specular;
- /** If false, this light does not create diffuse illumination (useful when rendering a specular-only pass). */
+ /** If false, this light does not create diffuse illumination
+ (useful when rendering a specular-only pass). */
bool diffuse;
GLight();
+
+ /** Accepted forms:
+ - GLight::directional( vector3, color3, [bool, [bool]])
+ - GLight::spot(vector3, vector3, #, color3, [#, [#, [#, [#, [bool, [bool]]]])
+ - GLight::point(vector3, color3, [#, [#, [#, [#, [bool, [bool]]]])
+ - GLight { [all fields] }
+ */
+ GLight(const Any& any);
+
+ /** Converts the Color3 to an Any. */
+ operator Any() const;
/** @param toLight will be normalized */
static GLight directional(const Vector3& toLight, const Color3& color, bool specular = true, bool diffuse = true);
static GLight point(const Vector3& pos, const Color3& color, float constAtt = 1, float linAtt = 0, float quadAtt = 0.5f, bool specular = true, bool diffuse = true);
- /** @param pointDirection Will be normalized. Points in the direction that light propagates.
- @param cutOffAngleDegrees Must be on the range [0, 90]. This is the angle from the point direction
- to the edge of the light cone.
+ /** @param pointDirection Will be normalized. Points in the
+ direction that light propagates.
+
+ @param cutOffAngleDegrees Must be on the range [0, 90]. This
+ is the angle from the point direction to the edge of the light
+ cone. I.e., a value of 45 produces a light with a 90-degree
+ cone of view.
*/
- static GLight spot(const Vector3& pos, const Vector3& pointDirection, float cutOffAngleDegrees, const Color3& color, float constAtt = 1, float linAtt = 0, float quadAtt = 0, bool specular = true, bool diffuse = true);
+ static GLight spot(const Vector3& pos, const Vector3& pointDirection, float cutOffAngleDegrees,
+ const Color3& color, float constAtt = 1, float linAtt = 0, float quadAtt = 0,
+ bool specular = true, bool diffuse = true);
/** Returns the sphere within which this light has some noticable effect. May be infinite.
@param cutoff The value at which the light intensity is considered negligible. */
class Sphere effectSphere(float cutoff = 30.0f / 255) const;
+ /** Computes a reference frame (e.g., for use with G3D::ShadowMap */
+ class CoordinateFrame frame() const;
+
bool operator==(const GLight& other) const;
bool operator!=(const GLight& other) const;
};
diff --git a/externals/g3dlite/G3D/GMutex.h b/externals/g3dlite/G3D/GMutex.h
new file mode 100644
index 00000000000..3469b812736
--- /dev/null
+++ b/externals/g3dlite/G3D/GMutex.h
@@ -0,0 +1,123 @@
+/**
+ @file GMutex.h
+
+ @created 2005-09-22
+ @edited 2009-03-25
+ */
+
+#ifndef G3D_GMutex_h
+#define G3D_GMutex_h
+
+#include "G3D/platform.h"
+#include "G3D/AtomicInt32.h"
+#include "G3D/debugAssert.h"
+#include <string>
+
+#ifndef G3D_WIN32
+# include <pthread.h>
+# include <signal.h>
+#endif
+
+
+namespace G3D {
+
+/**
+ \brief A mutual exclusion lock that busy-waits when locking.
+
+ On a machine with one (significant) thread per processor core,
+ a spinlock may be substantially faster than a mutex.
+
+ \sa G3D::GThread, G3D::GMutex, G3D::AtomicInt32
+ */
+class Spinlock {
+private:
+
+ AtomicInt32 x;
+
+public:
+
+ inline Spinlock() : x(0) {}
+
+ /** Busy waits until the lock is unlocked, then locks it
+ exclusively. Returns true if the lock succeeded on the first
+ try (indicating no contention). */
+ inline bool lock() {
+ bool first = true;
+ while (x.compareAndSet(0, 1) == 1) {
+ first = false;
+# ifdef G3D_WIN32
+ Sleep(0);
+# else
+ usleep(0);
+# endif
+ }
+ return first;
+ }
+
+ inline void unlock() {
+ x.compareAndSet(1, 0);
+ }
+
+};
+
+/**
+ \brief Mutual exclusion lock used for synchronization.
+
+ @sa G3D::GThread, G3D::AtomicInt32, G3D::Spinlock
+*/
+class GMutex {
+private:
+# ifdef G3D_WIN32
+ CRITICAL_SECTION m_handle;
+# else
+ pthread_mutex_t m_handle;
+ pthread_mutexattr_t m_attr;
+# endif
+
+ // Not implemented on purpose, don't use
+ GMutex(const GMutex &mlock);
+ GMutex &operator=(const GMutex &);
+ bool operator==(const GMutex&);
+
+public:
+ GMutex();
+ ~GMutex();
+
+ /** Locks the mutex or blocks until available. */
+ void lock();
+
+ /** Locks the mutex if it not already locked.
+ Returns true if lock successful, false otherwise. */
+ bool tryLock();
+
+ /** Unlocks the mutex. */
+ void unlock();
+};
+
+
+/**
+ Automatically locks while in scope.
+*/
+class GMutexLock {
+private:
+ GMutex* m;
+
+ // Not implemented on purpose, don't use
+ GMutexLock(const GMutexLock &mlock);
+ GMutexLock &operator=(const GMutexLock &);
+ bool operator==(const GMutexLock&);
+
+public:
+ GMutexLock(GMutex* mutex) {
+ m = mutex;
+ m->lock();
+ }
+
+ ~GMutexLock() {
+ m->unlock();
+ }
+};
+
+} // G3D
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/GThread.h b/externals/g3dlite/G3D/GThread.h
index 63f1c235bda..58437efc3fb 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/GThread.h
+++ b/externals/g3dlite/G3D/GThread.h
@@ -32,7 +32,7 @@ typedef ReferenceCountedPointer<class GThread> GThreadRef;
dropping all pointers (and causing deallocation) of a GThread does NOT
stop the underlying process.
- @sa G3D::GMutex, G3D::AtomicInt32
+ @sa G3D::GMutex, G3D::Spinlock, G3D::AtomicInt32
*/
class GThread : public ReferenceCountedObject {
private:
@@ -62,7 +62,14 @@ private:
std::string m_name;
+protected:
+
+ /** Overriden by the thread implementor */
+ virtual void threadMain() = 0;
+
public:
+ typedef ReferenceCountedPointer<class GThread> Ref;
+ enum SpawnBehavior {USE_NEW_THREAD, USE_CURRENT_THREAD};
GThread(const std::string& name);
@@ -71,15 +78,16 @@ public:
/** Constructs a basic GThread without requiring a subclass.
@param proc The global or static function for the threadMain() */
- static GThreadRef create(const std::string& name, void (*proc)(void*), void* param);
-
- /** @deprecated use overload that accepts void* param */
- static GThreadRef create(const std::string& name, void (*proc)());
+ static GThreadRef create(const std::string& name, void (*proc)(void*), void* param = NULL);
/** Starts the thread and executes threadMain(). Returns false if
the thread failed to start (either because it was already started
- or because the OS refused).*/
- bool start();
+ or because the OS refused).
+
+ @param behavior If USE_CURRENT_THREAD, rather than spawning a new thread, this routine
+ runs threadMain on the current thread.
+ */
+ bool start(SpawnBehavior behavior = USE_NEW_THREAD);
/** Terminates the thread without notifying or
waiting for a cancelation point. */
@@ -105,62 +113,6 @@ public:
inline const std::string& name() {
return m_name;
}
-
- /** Overriden by the thread implementor */
- virtual void threadMain() = 0;
-};
-
-
-/**
- Mutual exclusion lock used for synchronization.
- @sa G3D::GThread, G3D::AtomicInt32
-*/
-class GMutex {
-private:
-# ifdef G3D_WIN32
- CRITICAL_SECTION m_handle;
-# else
- pthread_mutex_t m_handle;
-# endif
-
- // Not implemented on purpose, don't use
- GMutex(const GMutex &mlock);
- GMutex &operator=(const GMutex &);
- bool operator==(const GMutex&);
-
-public:
- GMutex();
- ~GMutex();
-
- /** Locks the mutex or blocks until available. */
- void lock();
-
- /** Unlocks the mutex. */
- void unlock();
-};
-
-
-/**
- Automatically locks while in scope.
-*/
-class GMutexLock {
-private:
- GMutex* m;
-
- // Not implemented on purpose, don't use
- GMutexLock(const GMutexLock &mlock);
- GMutexLock &operator=(const GMutexLock &);
- bool operator==(const GMutexLock&);
-
-public:
- GMutexLock(GMutex* mutex) {
- m = mutex;
- m->lock();
- }
-
- ~GMutexLock() {
- m->unlock();
- }
};
diff --git a/externals/g3dlite/G3D.lib/include/G3D/GUniqueID.h b/externals/g3dlite/G3D/GUniqueID.h
index 44ec6e03405..c8b775c2e66 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/GUniqueID.h
+++ b/externals/g3dlite/G3D/GUniqueID.h
@@ -1,6 +1,6 @@
/**
@file GUniqueID.h
- @author Morgan McGuire, morgan@cs.williams.edu
+ @author Morgan McGuire, http://graphics.cs.williams.edu
*/
#ifndef G3D_GUNIQUEID_H
#define G3D_GUNIQUEID_H
diff --git a/externals/g3dlite/G3D.lib/include/G3D/HashTrait.h b/externals/g3dlite/G3D/HashTrait.h
index 702903ff09b..ca35da48643 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/HashTrait.h
+++ b/externals/g3dlite/G3D/HashTrait.h
@@ -1,15 +1,16 @@
/**
@file HashTrait.h
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2008-10-01
- @edited 2008-10-01
- Copyright 2000-2008, Morgan McGuire.
+ @edited 2009-11-01
+
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_HASHTRAIT_H
-#define G3D_HASHTRAIT_H
+#ifndef G3D_HashTrait_h
+#define G3D_HashTrait_h
#include "G3D/platform.h"
#include "G3D/Crypto.h"
@@ -25,14 +26,42 @@ template <typename T> struct HashTrait<T*> {
static size_t hashCode(const void* k) { return reinterpret_cast<size_t>(k); }
};
+#if 0
template <> struct HashTrait <int> {
static size_t hashCode(int k) { return static_cast<size_t>(k); }
};
+#endif
+
+template <> struct HashTrait <G3D::int16> {
+ static size_t hashCode(G3D::int16 k) { return static_cast<size_t>(k); }
+};
+
+template <> struct HashTrait <G3D::uint16> {
+ static size_t hashCode(G3D::uint16 k) { return static_cast<size_t>(k); }
+};
+
+//template <> struct HashTrait <int> {
+// static size_t hashCode(int k) { return static_cast<size_t>(k); }
+//};
+
+template <> struct HashTrait <G3D::int32> {
+ static size_t hashCode(G3D::int32 k) { return static_cast<size_t>(k); }
+};
template <> struct HashTrait <G3D::uint32> {
static size_t hashCode(G3D::uint32 k) { return static_cast<size_t>(k); }
};
+#if 0
+template <> struct HashTrait <long unsigned int> {
+ static size_t hashCode(G3D::uint32 k) { return static_cast<size_t>(k); }
+};
+#endif
+
+template <> struct HashTrait <G3D::int64> {
+ static size_t hashCode(G3D::int64 k) { return static_cast<size_t>(k); }
+};
+
template <> struct HashTrait <G3D::uint64> {
static size_t hashCode(G3D::uint64 k) { return static_cast<size_t>(k); }
};
@@ -42,22 +71,22 @@ template <> struct HashTrait <std::string> {
};
template <> struct HashTrait<G3D::uint128> {
- // Use the FNV-1 hash (http://isthe.com/chongo/tech/comp/fnv/#FNV-1).
+ // Use the FNV-1 hash (http://isthe.com/chongo/tech/comp/fnv/#FNV-1).
static size_t hashCode(G3D::uint128 key) {
static const G3D::uint128 FNV_PRIME_128(1 << 24, 0x159);
- static const G3D::uint128 FNV_OFFSET_128(0xCF470AAC6CB293D2LL, 0xF52F88BF32307F8FLL);
+ static const G3D::uint128 FNV_OFFSET_128(0xCF470AAC6CB293D2ULL, 0xF52F88BF32307F8FULL);
G3D::uint128 hash = FNV_OFFSET_128;
G3D::uint128 mask(0, 0xFF);
- for (int i = 0; i < 16; ++i) {
- hash *= FNV_PRIME_128;
+ for (int i = 0; i < 16; ++i) {
+ hash *= FNV_PRIME_128;
hash ^= (mask & key);
key >>= 8;
- }
-
+ }
+
G3D::uint64 foldedHash = hash.hi ^ hash.lo;
- return static_cast<size_t>((foldedHash >> 32) ^ (foldedHash & 0xFFFFFFFF));
- }
+ return static_cast<size_t>((foldedHash >> 32) ^ (foldedHash & 0xFFFFFFFF));
+ }
};
#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Image1.h b/externals/g3dlite/G3D/Image1.h
index f0850710d2c..711e83f2079 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Image1.h
+++ b/externals/g3dlite/G3D/Image1.h
@@ -1,7 +1,7 @@
/**
@file Image1.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-01-31
@edited 2007-01-31
@@ -29,7 +29,9 @@ class Image1 : public Map2D<Color1, Color1> {
public:
typedef Image1 Type;
- typedef Image1Ref Ref;
+ typedef ReferenceCountedPointer<class Image1> Ref;
+ typedef Color1 Storage;
+ typedef Color1 Compute;
protected:
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Image1uint8.h b/externals/g3dlite/G3D/Image1uint8.h
index 7225ca35db8..f32e022e92a 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Image1uint8.h
+++ b/externals/g3dlite/G3D/Image1uint8.h
@@ -1,7 +1,7 @@
/**
@file Image1uint8.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-01-31
@edited 2007-01-31
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Image3.h b/externals/g3dlite/G3D/Image3.h
index c67669c1c5e..13cb8fa7faf 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Image3.h
+++ b/externals/g3dlite/G3D/Image3.h
@@ -1,7 +1,7 @@
/**
@file Image3.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-01-31
@edited 2007-01-31
@@ -29,7 +29,9 @@ class Image3 : public Map2D<Color3, Color3> {
public:
typedef Image3 Type;
- typedef Image3Ref Ref;
+ typedef ReferenceCountedPointer<class Image3> Ref;
+ typedef Color3 Storage;
+ typedef Color3 Compute;
protected:
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Image3uint8.h b/externals/g3dlite/G3D/Image3uint8.h
index 9ee1ef6678b..d4fdbc169ca 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Image3uint8.h
+++ b/externals/g3dlite/G3D/Image3uint8.h
@@ -1,7 +1,7 @@
/**
@file Image3uint8.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-01-31
@edited 2007-01-31
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Image4.h b/externals/g3dlite/G3D/Image4.h
index 04df43f9527..21d7f1e79b1 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Image4.h
+++ b/externals/g3dlite/G3D/Image4.h
@@ -1,7 +1,7 @@
/**
@file Image4.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-01-31
@edited 2007-01-31
@@ -23,15 +23,21 @@ typedef ReferenceCountedPointer<class Image4> Image4Ref;
/**
RGBA image with 32-bit floating point storage for each channel.
- Whenever a method needs to convert from RGB to ARGB, A=1 is assumed.
+ Whenever a method needs to convert from RGB to RGBA, A=1 is assumed.
- See also G3D::Image4uint8, G3D::GImage.
+ Bilinear interpolation on Image4 is about 8x faster than on
+ Image4uint8 due to the large cost of converting int->float on modern
+ machines.
+
+ @sa G3D::Image4uint8, G3D::GImage.
*/
class Image4 : public Map2D<Color4, Color4> {
public:
typedef Image4 Type;
- typedef Image4Ref Ref;
+ typedef ReferenceCountedPointer<class Image4> Ref;
+ typedef Color4 Storage;
+ typedef Color4 Compute;
protected:
@@ -57,7 +63,7 @@ public:
static Ref fromFile(const std::string& filename, WrapMode wrap = WrapMode::ERROR, GImage::Format fmt = GImage::AUTODETECT);
- static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
+ static Ref fromArray(const class Color1uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
static Ref fromArray(const class Color3uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
static Ref fromArray(const class Color4uint8* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
static Ref fromArray(const class Color1* ptr, int width, int height, WrapMode wrap = WrapMode::ERROR);
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Image4uint8.h b/externals/g3dlite/G3D/Image4uint8.h
index 11daf97c83c..46df6b490b4 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Image4uint8.h
+++ b/externals/g3dlite/G3D/Image4uint8.h
@@ -1,7 +1,7 @@
/**
@file Image4uint8.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-01-31
@edited 2007-01-31
diff --git a/externals/g3dlite/G3D.lib/include/G3D/ImageFormat.h b/externals/g3dlite/G3D/ImageFormat.h
index a1334fb1a5a..7f098322d26 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/ImageFormat.h
+++ b/externals/g3dlite/G3D/ImageFormat.h
@@ -1,10 +1,10 @@
/**
@file ImageFormat.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-05-23
- @edited 2008-07-17
+ @edited 2010-01-01
*/
#ifndef GLG3D_ImageFormat_H
@@ -51,15 +51,26 @@ public:
CODE_RGB16,
CODE_RGB16F,
CODE_RGB32F,
+ CODE_R11G11B10F,
+ CODE_RGB9E5F,
+
+ CODE_RGB8I,
+ CODE_RGB8UI,
CODE_ARGB8,
CODE_BGR8,
+ CODE_RG8,
+ CODE_RG8I,
+ CODE_RG8UI,
+
CODE_RGBA8,
CODE_RGBA16,
CODE_RGBA16F,
CODE_RGBA32F,
+ CODE_RGBA32UI,
+
CODE_BAYER_RGGB8,
CODE_BAYER_GRBG8,
CODE_BAYER_GBRG8,
@@ -81,6 +92,17 @@ public:
CODE_RGBA_DXT3,
CODE_RGBA_DXT5,
+ CODE_SRGB8,
+ CODE_SRGBA8,
+
+ CODE_SL8,
+ CODE_SLA8,
+
+ CODE_SRGB_DXT1,
+ CODE_SRGBA_DXT1,
+ CODE_SRGBA_DXT3,
+ CODE_SRGBA_DXT5,
+
CODE_DEPTH16,
CODE_DEPTH24,
CODE_DEPTH32,
@@ -100,7 +122,8 @@ public:
COLOR_SPACE_NONE,
COLOR_SPACE_RGB,
COLOR_SPACE_HSV,
- COLOR_SPACE_YUV
+ COLOR_SPACE_YUV,
+ COLOR_SPACE_SRGB
};
enum BayerPattern {
@@ -152,7 +175,8 @@ public:
/** Amount of CPU memory per pixel when packed into an array, discounting any end-of-row padding. */
int cpuBitsPerPixel;
- /** Amount of CPU memory per pixel when packed into an array, discounting any end-of-row padding. @deprecated Use cpuBitsPerPixel*/
+ /** Amount of CPU memory per pixel when packed into an array, discounting any end-of-row padding.
+ @deprecated Use cpuBitsPerPixel*/
int packedBitsPerTexel;
/**
@@ -168,7 +192,7 @@ public:
/** @deprecated Use openGLBitsPerPixel */
int hardwareBitsPerTexel;
- /** The OpenGL bytes format of the data buffer used with this texture format, e.g., GL_UNSIGNED_BYTE */
+ /** The OpenGL bytes (type) format of the data buffer used with this texture format, e.g., GL_UNSIGNED_BYTE */
int openGLDataFormat;
/** True if there is no alpha channel for this texture. */
@@ -177,31 +201,34 @@ public:
/** True if the bit depths specified are for float formats. */
bool floatingPoint;
- /** Human readable name of this texture.*/
- std::string name() const;
+ /** Human readable name of this format.*/
+ const std::string& name() const;
+
+ /** Takes the same values that name() returns */
+ static const ImageFormat* fromString(const std::string& s);
private:
- ImageFormat(
- int numComponents,
- bool compressed,
- int glFormat,
- int glBaseFormat,
- int luminanceBits,
- int alphaBits,
- int redBits,
- int greenBits,
- int blueBits,
- int depthBits,
- int stencilBits,
- int hardwareBitsPerTexel,
- int packedBitsPerTexel,
- int glDataFormat,
- bool opaque,
- bool floatingPoint,
- Code code,
- ColorSpace colorSpace,
- BayerPattern bayerPattern = BAYER_PATTERN_NONE);
+ ImageFormat
+ (int numComponents,
+ bool compressed,
+ int glFormat,
+ int glBaseFormat,
+ int luminanceBits,
+ int alphaBits,
+ int redBits,
+ int greenBits,
+ int blueBits,
+ int depthBits,
+ int stencilBits,
+ int hardwareBitsPerTexel,
+ int packedBitsPerTexel,
+ int glDataFormat,
+ bool opaque,
+ bool floatingPoint,
+ Code code,
+ ColorSpace colorSpace,
+ BayerPattern bayerPattern = BAYER_PATTERN_NONE);
public:
@@ -233,6 +260,10 @@ public:
static const ImageFormat* BGR8();
+ static const ImageFormat* RG8();
+ static const ImageFormat* RG8I();
+ static const ImageFormat* RG8UI();
+
static const ImageFormat* RGB5();
static const ImageFormat* RGB5A1();
@@ -256,6 +287,16 @@ public:
static const ImageFormat* RGBA16F();
static const ImageFormat* RGBA32F();
+
+ static const ImageFormat* RGBA32UI();
+
+ static const ImageFormat* R11G11B10F();
+
+ static const ImageFormat* RGB9E5F();
+
+ static const ImageFormat* RGB8I();
+
+ static const ImageFormat* RGB8UI();
static const ImageFormat* RGB_DXT1();
@@ -265,6 +306,22 @@ public:
static const ImageFormat* RGBA_DXT5();
+ static const ImageFormat* SRGB8();
+
+ static const ImageFormat* SRGBA8();
+
+ static const ImageFormat* SL8();
+
+ static const ImageFormat* SLA8();
+
+ static const ImageFormat* SRGB_DXT1();
+
+ static const ImageFormat* SRGBA_DXT1();
+
+ static const ImageFormat* SRGBA_DXT3();
+
+ static const ImageFormat* SRGBA_DXT5();
+
static const ImageFormat* DEPTH16();
static const ImageFormat* DEPTH24();
@@ -318,8 +375,8 @@ public:
enum Value {
NEAREST,
BILINEAR,
- mhc,
- HIGH_QUALITY = mhc
+ MHC,
+ HIGH_QUALITY = MHC
};
private:
diff --git a/externals/g3dlite/G3D/Intersect.h b/externals/g3dlite/G3D/Intersect.h
new file mode 100644
index 00000000000..4a3c8fb4540
--- /dev/null
+++ b/externals/g3dlite/G3D/Intersect.h
@@ -0,0 +1,55 @@
+/**
+ @file Intersect.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-06-29
+ @edited 2009-06-29
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+
+ From the G3D Innovation Engine
+ http://g3d.sf.net
+ */
+#ifndef G3D_Intersect
+#define G3D_Intersect
+
+#include "G3D/platform.h"
+#include "G3D/Ray.h"
+#include "G3D/AABox.h"
+
+namespace G3D {
+
+/**
+ @beta
+ */
+class Intersect {
+public:
+
+ /** \brief Returns true if the intersection of the ray and the solid box is non-empty.
+
+ \cite "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
+ by Martin Eisemann, Thorsten Grosch, Stefan Müller and Marcus Magnor
+ Computer Graphics Lab, TU Braunschweig, Germany and
+ University of Koblenz-Landau, Germany
+ */
+ static bool __fastcall rayAABox(const Ray& ray, const AABox& box);
+
+ /** \brief Returns true if the intersection of the ray and the solid box is non-empty.
+
+ \param time If there is an intersection, set to the time to that intersection. If the ray origin is inside the box,
+ this is a negative value indicating the distance backwards from the ray origin to the first intersection.
+ \a time is not set if there is no intersection.
+
+ \cite Slope-Mul method from "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
+ by Martin Eisemann, Thorsten Grosch, Stefan Müller and Marcus Magnor
+ Computer Graphics Lab, TU Braunschweig, Germany and
+ University of Koblenz-Landau, Germany
+ */
+ static bool __fastcall rayAABox(const Ray& ray, const AABox& box, float& time);
+};
+
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/AABSPTree.h b/externals/g3dlite/G3D/KDTree.h
index 1178fad93c3..4785ef2baea 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/AABSPTree.h
+++ b/externals/g3dlite/G3D/KDTree.h
@@ -1,14 +1,13 @@
/**
- @file AABSPTree.h
+ @file KDTree.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2004-01-11
- @edited 2008-11-19
+ @edited 2009-12-28
- Copyright 2000-2008, Morgan McGuire.
- All rights reserved.
-
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
*/
#ifndef G3D_KDTREE_H
@@ -151,7 +150,7 @@ namespace G3D {
the following functions are all overloaded:
<pre>
- T::T();</CODE> <I>(public constructor of no arguments)</I>
+ T::T(); // public constructor of no arguments
template <> struct HashTrait<T> { static size_t hashCode(int key); };
template<> struct BoundsTrait<T> { static void getBounds(const T& obj, G3D::AABox& out); };
</pre>
@@ -311,6 +310,7 @@ protected:
Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {}
inline int operator()(Handle* ignore, const Handle* handle) const {
+ (void)ignore;
const AABox& box = handle->bounds;
debugAssert(ignore == NULL);
@@ -537,7 +537,7 @@ protected:
void getIntersectingMembers(
const AABox& box,
const Sphere& sphere,
- Array<T>& members,
+ Array<T*>& members,
bool useSphere) const {
// Test all values at this node
@@ -545,7 +545,7 @@ protected:
const AABox& bounds = boundsArray[v];
if (bounds.intersects(box) &&
(! useSphere || bounds.intersects(sphere))) {
- members.append(valueArray[v]->value);
+ members.append(& (valueArray[v]->value));
}
}
@@ -591,10 +591,10 @@ protected:
bool alreadyInsideBounds = false;
bool rayWillHitBounds =
CollisionDetection::collisionLocationForMovingPointFixedAABox(
- ray.origin, ray.direction, splitBounds, location, alreadyInsideBounds);
+ ray.origin(), ray.direction(), splitBounds, location, alreadyInsideBounds);
bool canHitThisNode = (alreadyInsideBounds ||
- (rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance))));
+ (rayWillHitBounds && ((location - ray.origin()).squaredLength() < square(distance))));
return canHitThisNode;
}
@@ -622,10 +622,10 @@ protected:
bool alreadyInsideBounds = false;
bool rayWillHitBounds =
CollisionDetection::collisionLocationForMovingPointFixedAABox(
- ray.origin, ray.direction, bounds, location, alreadyInsideBounds);
+ ray.origin(), ray.direction(), bounds, location, alreadyInsideBounds);
canHitThisObject = (alreadyInsideBounds ||
- (rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance))));
+ (rayWillHitBounds && ((location - ray.origin()).squaredLength() < square(distance))));
}
if (canHitThisObject) {
@@ -646,30 +646,30 @@ protected:
int firstChild = NONE;
int secondChild = NONE;
- if (ray.origin[splitAxis] < splitLocation) {
+ if (ray.origin()[splitAxis] < splitLocation) {
// The ray starts on the small side
firstChild = 0;
- if (ray.direction[splitAxis] > 0) {
+ if (ray.direction()[splitAxis] > 0) {
// The ray will eventually reach the other side
secondChild = 1;
}
- } else if (ray.origin[splitAxis] > splitLocation) {
+ } else if (ray.origin()[splitAxis] > splitLocation) {
// The ray starts on the large side
firstChild = 1;
- if (ray.direction[splitAxis] < 0) {
+ if (ray.direction()[splitAxis] < 0) {
secondChild = 0;
}
} else {
// The ray starts on the splitting plane
- if (ray.direction[splitAxis] < 0) {
+ if (ray.direction()[splitAxis] < 0) {
// ...and goes to the small side
firstChild = 0;
- } else if (ray.direction[splitAxis] > 0) {
+ } else if (ray.direction()[splitAxis] > 0) {
// ...and goes to the large side
firstChild = 1;
}
@@ -680,10 +680,10 @@ protected:
child[firstChild]->intersectRay(ray, intersectCallback, distance, intersectCallbackIsFast);
}
- if (ray.direction[splitAxis] != 0) {
+ if (ray.direction()[splitAxis] != 0) {
// See if there was an intersection before hitting the splitting plane.
// If so, there is no need to look on the far side and recursion terminates.
- float distanceToSplittingPlane = (splitLocation - ray.origin[splitAxis]) / ray.direction[splitAxis];
+ float distanceToSplittingPlane = (splitLocation - ray.origin()[splitAxis]) / ray.direction()[splitAxis];
if (distanceToSplittingPlane > distance) {
// We aren't going to hit anything else before hitting the splitting plane,
// so don't bother looking on the far side of the splitting plane at the other
@@ -1131,6 +1131,15 @@ public:
# endif
}
+
+ /** Clear, set the contents to the values in the array, and then balance */
+ void setContents(const Array<T>& array, int valuesPerNode = 5, int numMeanSplits = 3) {
+ clear();
+ insert(array);
+ balance(valuesPerNode, numMeanSplits);
+ }
+
+
protected:
/**
@@ -1138,7 +1147,7 @@ protected:
*/
static void getIntersectingMembers(
const Array<Plane>& plane,
- Array<T>& members,
+ Array<T*>& members,
Node* node,
uint32 parentMask) {
@@ -1147,7 +1156,7 @@ protected:
if (parentMask == 0) {
// None of these planes can cull anything
for (int v = node->valueArray.size() - 1; v >= 0; --v) {
- members.append(node->valueArray[v]->value);
+ members.append(& (node->valueArray[v]->value));
}
// Iterate through child nodes
@@ -1161,7 +1170,7 @@ protected:
// Test values at this node against remaining planes
for (int v = node->boundsArray.size() - 1; v >= 0; --v) {
if (! node->boundsArray[v].culledBy(plane, dummy, parentMask)) {
- members.append(node->valueArray[v]->value);
+ members.append(&(node->valueArray[v]->value));
}
}
@@ -1184,7 +1193,7 @@ public:
Returns all members inside the set of planes.
@param members The results are appended to this array.
*/
- void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
+ void getIntersectingMembers(const Array<Plane>& plane, Array<T*>& members) const {
if (root == NULL) {
return;
}
@@ -1192,10 +1201,18 @@ public:
getIntersectingMembers(plane, members, root, 0xFFFFFF);
}
+ void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
+ Array<T*> temp;
+ getIntersectingMembers(plane, temp, root, 0xFFFFFF);
+ for (int i = 0; i < temp.size(); ++i) {
+ members.append(*temp[i]);
+ }
+ }
+
/**
Typically used to find all visible
objects inside the view frustum (see also GCamera::getClipPlanes)... i.e. all objects
- <B>not<B> culled by frustum.
+ <B>not</B> culled by frustum.
Example:
<PRE>
@@ -1205,7 +1222,7 @@ public:
</PRE>
@param members The results are appended to this array.
*/
- void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
+ void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T*>& members) const {
Array<Plane> plane;
for (int i = 0; i < frustum.faceArray.size(); ++i) {
@@ -1215,6 +1232,14 @@ public:
getIntersectingMembers(plane, members);
}
+ void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
+ Array<T*> temp;
+ getIntersectingMembers(frustum, temp);
+ for (int i = 0; i < temp.size(); ++i) {
+ members.append(*temp[i]);
+ }
+ }
+
/**
C++ STL style iterator variable. See beginBoxIntersection().
The iterator overloads the -> (dereference) operator, so this
@@ -1355,7 +1380,8 @@ public:
private:
/**
- Post increment (much slower than preincrement!). Intentionally overloaded to preclude accidentally slow code.
+ Post increment (much slower than preincrement!).
+ Intentionally overloaded to preclude accidentally slow code.
*/
BoxIntersectionIterator operator++(int);
/*{
@@ -1405,26 +1431,34 @@ public:
Appends all members whose bounds intersect the box.
See also KDTree::beginBoxIntersection.
*/
- void getIntersectingMembers(const AABox& box, Array<T>& members) const {
+ void getIntersectingMembers(const AABox& box, Array<T*>& members) const {
if (root == NULL) {
return;
}
root->getIntersectingMembers(box, Sphere(Vector3::zero(), 0), members, false);
}
+ void getIntersectingMembers(const AABox& box, Array<T>& members) const {
+ Array<T*> temp;
+ getIntersectingMembers(box, temp);
+ for (int i = 0; i < temp.size(); ++i) {
+ members.append(*temp[i]);
+ }
+ }
+
/**
Invoke a callback for every member along a ray until the closest intersection is found.
@param callback either a function or an instance of a class with an overloaded operator() of the form:
- <code>void callback(const Ray& ray, const T& object, float& distance)</code>. If the ray hits the object
- before travelling distance <code>distance</code>, updates <code>distance</code> with the new distance to
- the intersection, otherwise leaves it unmodified. A common example is:
+ <code>void callback(const Ray& ray, const T& object, float& distance)</code>. If the ray hits the object
+ before travelling distance <code>distance</code>, updates <code>distance</code> with the new distance to
+ the intersection, otherwise leaves it unmodified. A common example is:
- <pre>
- class Entity {
- public:
+ <pre>
+ class Entity {
+ public:
void intersect(const Ray& ray, float& maxDist, Vector3& outLocation, Vector3& outNormal) {
float d = maxDist;
@@ -1455,16 +1489,20 @@ public:
KDTree<Entity*> scene;
Intersection intersection;
- float distance = inf();
+ float distance = finf();
scene.intersectRay(camera.worldRay(x, y), intersection, distance);
</pre>
- @param distance When the method is invoked, this is the maximum distance that the tree should search for an intersection.
- On return, this is set to the distance to the first intersection encountered.
+ @param distance When the method is invoked, this is the maximum
+ distance that the tree should search for an intersection. On
+ return, this is set to the distance to the first intersection
+ encountered.
- @param intersectCallbackIsFast If false, each object's bounds are tested before the intersectCallback is invoked.
- If the intersect callback runs at the same speed or faster than AABox-ray intersection, set this to true.
+ @param intersectCallbackIsFast If false, each object's bounds are
+ tested before the intersectCallback is invoked. If the
+ intersect callback runs at the same speed or faster than
+ AABox-ray intersection, set this to true.
*/
template<typename RayCallback>
void intersectRay(
@@ -1474,7 +1512,6 @@ public:
bool intersectCallbackIsFast = false) const {
root->intersectRay(ray, intersectCallback, distance, intersectCallbackIsFast);
-
}
@@ -1484,7 +1521,7 @@ public:
@param members The results are appended to this array.
*/
- void getIntersectingMembers(const Sphere& sphere, Array<T>& members) const {
+ void getIntersectingMembers(const Sphere& sphere, Array<T*>& members) const {
if (root == NULL) {
return;
}
@@ -1492,7 +1529,14 @@ public:
AABox box;
sphere.getBounds(box);
root->getIntersectingMembers(box, sphere, members, true);
+ }
+ void getIntersectingMembers(const Sphere& sphere, Array<T>& members) const {
+ Array<T*> temp;
+ getIntersectingMembers(sphere, temp);
+ for (int i = 0; i < temp.size(); ++i) {
+ members.append(*temp[i]);
+ }
}
/**
@@ -1522,6 +1566,22 @@ public:
}
+ /** If a value that is EqualsFunc to @a value is present, returns a pointer to the
+ version stored in the data structure, otherwise returns NULL.
+ */
+ const T* getPointer(const T& value) const {
+ // Temporarily create a handle and member
+ Handle h(value);
+ const Member* member = memberTable.getKeyPointer(Member(&h));
+ if (member == NULL) {
+ // Not found
+ return NULL;
+ } else {
+ return &(member->handle->value);
+ }
+ }
+
+
/**
C++ STL style iterator variable. See begin().
Overloads the -> (dereference) operator, so this acts like a pointer
@@ -1601,8 +1661,6 @@ public:
#undef TreeType
};
-/** @deprecated For backwards compatibility */
-#define AABSPTree KDTree
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Line.h b/externals/g3dlite/G3D/Line.h
index ff6dc8d08e7..3579a6becec 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Line.h
+++ b/externals/g3dlite/G3D/Line.h
@@ -3,7 +3,7 @@
Line class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
@edited 2006-02-28
diff --git a/externals/g3dlite/G3D.lib/include/G3D/LineSegment.h b/externals/g3dlite/G3D/LineSegment.h
index 092b0c9ca6d..70210ec7e00 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/LineSegment.h
+++ b/externals/g3dlite/G3D/LineSegment.h
@@ -1,7 +1,7 @@
/**
@file LineSegment.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-02-08
@edited 2008-02-02
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Log.h b/externals/g3dlite/G3D/Log.h
index 19b4b65c82d..d252d0c1a17 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Log.h
+++ b/externals/g3dlite/G3D/Log.h
@@ -1,7 +1,7 @@
/**
@file Log.h
- @maintainer Morgan McGuire, morgan@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Backtrace by Aaron Orenstein
@created 2001-08-04
@edited 2005-11-04
@@ -36,6 +36,9 @@ namespace G3D {
*/
void logPrintf(const char* fmt, ...);
+/** Does not flush the buffer; follow up with a logPrintf to force the flush. */
+void logLazyPrintf(const char* fmt, ...);
+
/**
System log for debugging purposes. The first log opened
is the "common log" and can be accessed with the static
@@ -56,11 +59,6 @@ private:
int stripFromStackBottom;
- /**
- Prints the time & stack trace.
- */
- void printHeader();
-
public:
/**
@@ -93,6 +91,8 @@ public:
void __cdecl printf(const char* fmt, ...) G3D_CHECK_PRINTF_METHOD_ARGS;
void __cdecl vprintf(const char*, va_list argPtr) G3D_CHECK_VPRINTF_METHOD_ARGS;
+ /** Does not flush */
+ void __cdecl lazyvprintf(const char*, va_list argPtr) G3D_CHECK_VPRINTF_METHOD_ARGS;
static Log* common();
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Map2D.h b/externals/g3dlite/G3D/Map2D.h
index 48e2e957a5f..9af9f7242c1 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Map2D.h
+++ b/externals/g3dlite/G3D/Map2D.h
@@ -5,14 +5,15 @@
@maintainer Morgan McGuire, morgan@cs.brown.edu
@created 2004-10-10
- @edited 2007-07-18
+ @edited 2009-03-24
*/
-#ifndef G3D_MAP2D_H
-#define G3D_MAP2D_H
+#ifndef G3D_Map2D_h
+#define G3D_Map2D_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
#include "G3D/Array.h"
+#include "G3D/vectorMath.h"
#include "G3D/Vector2int16.h"
#include "G3D/ReferenceCount.h"
#include "G3D/AtomicInt32.h"
@@ -163,7 +164,7 @@ namespace G3D {
[3, w - 4]. The class does not offer quadratic interpolation because
the interpolation filter could not center over a pixel.
- @author Morgan McGuire, morgan@cs.williams.edu
+ @author Morgan McGuire, http://graphics.cs.williams.edu
*/
template< typename Storage,
typename Compute = typename G3D::_internal::_GetComputeType<Storage>::Type>
@@ -508,7 +509,9 @@ public:
to be at the upper left corner, so <code>image->nearest(x, y) == image(x, y)</code>
*/
inline Compute nearest(float x, float y, WrapMode wrap) const {
- return Compute(get(iRound(x), iRound(y), wrap));
+ int ix = iRound(x);
+ int iy = iRound(y);
+ return Compute(get(ix, iy, wrap));
}
inline Compute nearest(float x, float y) const {
@@ -548,21 +551,22 @@ public:
Guaranteed to match nearest(x, y) at integers. */
Compute bilinear(float x, float y, WrapMode wrap) const {
- int i = iFloor(x);
- int j = iFloor(y);
+ const int i = iFloor(x);
+ const int j = iFloor(y);
- float fX = x - i;
- float fY = y - j;
+ const float fX = x - i;
+ const float fY = y - j;
// Horizontal interpolation, first row
- Compute t0(get(i, j, wrap));
- Compute t1(get(i + 1, j, wrap));
- Compute A = lerp(t0, t1, fX);
+ const Compute& t0 = get(i, j, wrap);
+ const Compute& t1 = get(i + 1, j, wrap);
// Horizontal interpolation, second row
- Compute t2(get(i, j + 1, wrap));
- Compute t3(get(i + 1, j + 1, wrap));
- Compute B = lerp(t2, t3, fX);
+ const Compute& t2 = get(i, j + 1, wrap);
+ const Compute& t3 = get(i + 1, j + 1, wrap);
+
+ const Compute& A = lerp(t0, t1, fX);
+ const Compute& B = lerp(t2, t3, fX);
// Vertical interpolation
return lerp(A, B, fY);
@@ -590,13 +594,11 @@ public:
float fX = x - i;
float fY = y - j;
- // 'static' prevents constructors from being called
- // every time through this loop.
- static Compute vsample[4];
+ Compute vsample[4];
for (int v = 0; v < 4; ++v) {
// Horizontal interpolation
- static Compute hsample[4];
+ Compute hsample[4];
for (int u = 0; u < 4; ++u) {
hsample[u] = Compute(get(i + u - 1, j + v - 1, wrap));
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Matrix.h b/externals/g3dlite/G3D/Matrix.h
index 481af940324..3c5394d9a76 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Matrix.h
+++ b/externals/g3dlite/G3D/Matrix.h
@@ -1,6 +1,6 @@
/**
@file Matrix.h
- @author Morgan McGuire, morgan@cs.williams.edu
+ @author Morgan McGuire, http://graphics.cs.williams.edu
@created 2005-10-23
@edited 2007-07-18
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Matrix2.h b/externals/g3dlite/G3D/Matrix2.h
index eaf4aefa220..eaf4aefa220 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Matrix2.h
+++ b/externals/g3dlite/G3D/Matrix2.h
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Matrix3.h b/externals/g3dlite/G3D/Matrix3.h
index ad09cd3860f..06ec7e67474 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Matrix3.h
+++ b/externals/g3dlite/G3D/Matrix3.h
@@ -3,7 +3,7 @@
3x3 matrix class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Portions based on Dave Eberly's Magic Software Library at <A HREF="http://www.magic-software.com">http://www.magic-software.com</A>
@@ -11,8 +11,8 @@
@edited 2006-04-05
*/
-#ifndef G3D_MATRIX3_H
-#define G3D_MATRIX3_H
+#ifndef G3D_Matrix3_h
+#define G3D_Matrix3_h
#include "G3D/platform.h"
#include "G3D/Vector3.h"
@@ -23,6 +23,14 @@
namespace G3D {
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
+#endif
+
+class Any;
+
/**
3x3 matrix. Do not subclass.
*/
@@ -39,6 +47,10 @@ private:
public:
+ Matrix3(const Any& any);
+
+ operator Any() const;
+
/** Initial values are undefined for performance. See also
Matrix3::zero(), Matrix3::identity(), Matrix3::fromAxisAngle, etc.*/
inline Matrix3() {}
@@ -60,6 +72,9 @@ public:
void serialize(class BinaryOutput& b) const;
void deserialize(class BinaryInput& b);
+ /** Returns true if column(0).cross(column(1)).dot(column(2)) > 0. */
+ bool isRightHanded() const;
+
/**
Sets all elements.
*/
@@ -90,11 +105,6 @@ public:
return (const float*)&elt[0][0];
}
- /** @deprecated */
- Vector3 getColumn (int iCol) const;
- /** @deprecated */
- Vector3 getRow (int iRow) const;
-
Vector3 column(int c) const;
const Vector3& row(int r) const;
@@ -154,6 +164,10 @@ public:
friend Matrix3 operator* (float fScalar, const Matrix3& rkMatrix);
friend Matrix3 operator* (int fScalar, const Matrix3& rkMatrix);
+ Matrix3& operator*= (float k);
+ Matrix3& operator/= (float k);
+
+
private:
/** Multiplication where out != A and out != B */
static void _mul(const Matrix3& A, const Matrix3& B, Matrix3& out);
@@ -213,8 +227,37 @@ public:
void qDUDecomposition (Matrix3& rkQ, Vector3& rkD,
Vector3& rkU) const;
+ /**
+ Polar decomposition of a matrix. Based on pseudocode from Nicholas J
+ Higham, "Computing the Polar Decomposition -- with Applications Siam
+ Journal of Science and Statistical Computing, Vol 7, No. 4, October
+ 1986.
+
+ Decomposes A into R*S, where R is orthogonal and S is symmetric.
+
+ Ken Shoemake's "Matrix animation and polar decomposition"
+ in Proceedings of the conference on Graphics interface '92
+ seems to be better known in the world of graphics, but Higham's version
+ uses a scaling constant that can lead to faster convergence than
+ Shoemake's when the initial matrix is far from orthogonal.
+ */
+ void polarDecomposition(Matrix3 &R, Matrix3 &S) const;
+
+ /**
+ * Matrix norms.
+ */
float spectralNorm () const;
+ float squaredFrobeniusNorm() const;
+
+ float frobeniusNorm() const;
+
+ float l1Norm() const;
+
+ float lInfNorm() const;
+
+ float diffOneNorm(const Matrix3 &y) const;
+
/** matrix must be orthonormal */
void toAxisAngle(Vector3& rkAxis, float& rfRadians) const;
@@ -256,7 +299,7 @@ public:
static void tensorProduct (const Vector3& rkU, const Vector3& rkV,
Matrix3& rkProduct);
- std::string toString() const;
+ std::string toString() const;
static const float EPSILON;
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Matrix4.h b/externals/g3dlite/G3D/Matrix4.h
index 5bb6cecfdf9..9ce87d875b8 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Matrix4.h
+++ b/externals/g3dlite/G3D/Matrix4.h
@@ -3,14 +3,14 @@
4x4 matrix class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-10-02
- @edited 2007-04-05
+ @edited 2009-10-20
*/
-#ifndef G3D_MATRIX4_H
-#define G3D_MATRIX4_H
+#ifndef G3D_Matrix4_h
+#define G3D_Matrix4_h
#ifdef _MSC_VER
// Disable conditional expression is constant, which occurs incorrectly on inlined functions
@@ -25,6 +25,8 @@
namespace G3D {
+class Any;
+
/**
A 4x4 matrix.
@@ -48,6 +50,11 @@ private:
bool operator>=(const Matrix4&) const;
public:
+ /** Must be of the form: <code>Matrix4(#, #, # .... #)</code>*/
+ Matrix4(const Any& any);
+
+ operator Any() const;
+
Matrix4(
float r1c1, float r1c2, float r1c3, float r1c4,
float r2c1, float r2c2, float r2c3, float r2c4,
@@ -80,6 +87,17 @@ public:
static const Matrix4& identity();
static const Matrix4& zero();
+ /** If this is a perspective projection matrix created by
+ Matrix4::perspectiveProjection, extract its parameters. */
+ void getPerspectiveProjectionParameters
+ (float& left,
+ float& right,
+ float& bottom,
+ float& top,
+ float& nearval,
+ float& farval,
+ float updirection = -1.0f) const;
+
inline float* operator[](int r) {
debugAssert(r >= 0);
debugAssert(r < 4);
@@ -111,6 +129,9 @@ public:
Constructs an orthogonal projection matrix from the given parameters.
Near and far are the <b>NEGATIVE</b> of the near and far plane Z values
(to follow OpenGL conventions).
+
+ \param upDirection Use -1.0 for 2D Y increasing downwards (the G3D 8.x default convention),
+ 1.0 for 2D Y increasing upwards (the G3D 7.x default and OpenGL convention)
*/
static Matrix4 orthogonalProjection(
float left,
@@ -118,29 +139,34 @@ public:
float bottom,
float top,
float nearval,
- float farval);
+ float farval,
+ float upDirection = -1.0f);
+
+ /** \param upDirection Use -1.0 for 2D Y increasing downwards (the G3D 8.x default convention),
+ 1.0 for 2D Y increasing upwards (the G3D 7.x default and OpenGL convention)
+ */
static Matrix4 orthogonalProjection(
const class Rect2D& rect,
float nearval,
- float farval);
+ float farval,
+ float upDirection = -1.0f);
+ /** \param upDirection Use -1.0 for 2D Y increasing downwards (the G3D 8.x default convention),
+ 1.0 for 2D Y increasing upwards (the G3D 7.x default and OpenGL convention)
+ */
static Matrix4 perspectiveProjection(
float left,
float right,
float bottom,
float top,
float nearval,
- float farval);
+ float farval,
+ float upDirection = -1.0f);
void setRow(int r, const class Vector4& v);
void setColumn(int c, const Vector4& v);
- /** @deprecated */
- Vector4 getRow(int r) const;
- /** @deprecated */
- Vector4 getColumn(int c) const;
-
const Vector4& row(int r) const;
Vector4 column(int c) const;
@@ -193,6 +219,23 @@ public:
inline static Matrix4 translation(const Vector3& v) {
return Matrix4(Matrix3::identity(), v);
}
+
+ inline static Matrix4 translation(float x, float y, float z) {
+ return Matrix4(Matrix3::identity(), Vector3(x, y, z));
+ }
+
+ /** Create a rotation matrix that rotates \a deg degrees around the Y axis */
+ inline static Matrix4 yawDegrees(float deg) {
+ return Matrix4(Matrix3::fromAxisAngle(Vector3::unitY(), toRadians(deg)));
+ }
+
+ inline static Matrix4 pitchDegrees(float deg) {
+ return Matrix4(Matrix3::fromAxisAngle(Vector3::unitX(), toRadians(deg)));
+ }
+
+ inline static Matrix4 rollDegrees(float deg) {
+ return Matrix4(Matrix3::fromAxisAngle(Vector3::unitZ(), toRadians(deg)));
+ }
};
diff --git a/externals/g3dlite/G3D/MemoryManager.h b/externals/g3dlite/G3D/MemoryManager.h
new file mode 100644
index 00000000000..15bf6d8be43
--- /dev/null
+++ b/externals/g3dlite/G3D/MemoryManager.h
@@ -0,0 +1,93 @@
+/**
+ @file MemoryManager.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2009-04-20
+ @edited 2009-04-20
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_MemoryManager_h
+#define G3D_MemoryManager_h
+
+#include "G3D/platform.h"
+#include "G3D/ReferenceCount.h"
+
+namespace G3D {
+
+/**
+ Abstraction of memory management.
+ Default implementation uses G3D::System::malloc and is threadsafe.
+
+ \sa CRTMemoryManager, AlignedMemoryManager, AreaMemoryManager */
+class MemoryManager : public ReferenceCountedObject {
+protected:
+
+ MemoryManager();
+
+public:
+
+ typedef ReferenceCountedPointer<class MemoryManager> Ref;
+
+ /** Return a pointer to \a s bytes of memory that are unused by
+ the rest of the program. The contents of the memory are
+ undefined */
+ virtual void* alloc(size_t s);
+
+ /** Invoke to declare that this memory will no longer be used by
+ the program. The memory manager is not required to actually
+ reuse or release this memory. */
+ virtual void free(void* ptr);
+
+ /** Returns true if this memory manager is threadsafe (i.e., alloc
+ and free can be called asychronously) */
+ virtual bool isThreadsafe() const;
+
+ /** Return the instance. There's only one instance of the default
+ MemoryManager; it is cached after the first creation. */
+ static MemoryManager::Ref create();
+};
+
+/**
+ Allocates memory on 16-byte boundaries.
+ \sa MemoryManager, CRTMemoryManager, AreaMemoryManager */
+class AlignedMemoryManager : public MemoryManager {
+protected:
+
+ AlignedMemoryManager();
+
+public:
+
+ typedef ReferenceCountedPointer<class AlignedMemoryManager> Ref;
+
+
+ virtual void* alloc(size_t s);
+
+ virtual void free(void* ptr);
+
+ virtual bool isThreadsafe() const;
+
+ static AlignedMemoryManager::Ref create();
+};
+
+
+/** MemoryManager implemented using the C runtime. */
+class CRTMemoryManager : public MemoryManager {
+protected:
+ CRTMemoryManager();
+
+public:
+ typedef ReferenceCountedPointer<class MemoryManager> Ref;
+ virtual void* alloc(size_t s);
+ virtual void free(void* ptr);
+ virtual bool isThreadsafe() const;
+
+ /** There's only one instance of this memory manager; it is
+ cached after the first creation. */
+ static CRTMemoryManager::Ref create();
+};
+
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/MeshAlg.h b/externals/g3dlite/G3D/MeshAlg.h
index be381eff117..1decea10105 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/MeshAlg.h
+++ b/externals/g3dlite/G3D/MeshAlg.h
@@ -3,19 +3,28 @@
Indexed Mesh algorithms.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-09-14
- @edited 2008-07-30
+ @edited 2010-01-18
*/
-#ifndef G3D_MESHALG_H
-#define G3D_MESHALG_H
+#ifndef G3D_MeshAlg_h
+#define G3D_MeshAlg_h
#include "G3D/platform.h"
#include "G3D/Array.h"
#include "G3D/Vector3.h"
#include "G3D/CoordinateFrame.h"
+#include "G3D/SmallArray.h"
+#include "G3D/constants.h"
+#include "G3D/Image1.h"
+
+#ifdef G3D_WIN32
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+#pragma warning (disable : 4127)
+#endif
namespace G3D {
@@ -28,13 +37,14 @@ namespace G3D {
cannot precompute information, etc. Instead of compromising, this
class implements the hard parts of mesh computation and you can write
your own ideal mesh class on top of it.
+
+ \sa G3D::ArticulatedModel, G3D::IFSModel
*/
class MeshAlg {
public:
- enum Primitive {LINES, LINE_STRIP, TRIANGLES, TRIANGLE_STRIP,
- TRIANGLE_FAN, QUADS, QUAD_STRIP, POINTS};
-
+ /** \deprecated */
+ typedef PrimitiveType Primitive;
/** Adjacency information for a vertex.
Does not contain the vertex position or normal,
@@ -56,7 +66,7 @@ public:
Edges may be listed multiple times if they are
degenerate.
*/
- Array<int> edgeIndex;
+ SmallArray<int, 6> edgeIndex;
/**
Returns true if e or ~e is in the edgeIndex list.
@@ -69,7 +79,7 @@ public:
Array of faces containing this vertex. Faces
may be listed multiple times if they are degenerate.
*/
- Array<int> faceIndex;
+ SmallArray<int, 6> faceIndex;
inline bool inFace(int f) const {
debugAssert(f >= 0);
@@ -263,7 +273,7 @@ public:
Computes some basic mesh statistics including: min, max mean and median,
edge lengths; and min, mean, median, and max face area.
- @param vertexGeometry %Vertex positions to use when deciding colocation.
+ @param vertexArray %Vertex positions to use when deciding colocation.
@param indexArray Order to traverse vertices to make triangles
@param minEdgeLength Minimum edge length
@param meanEdgeLength Mean edge length
@@ -287,18 +297,6 @@ public:
double& maxFaceArea);
private:
- /**
- Computes the tangent space basis vectors for
- a counter-clockwise oriented face.
-
- @cite Max McGuire
- */
- static void computeTangentVectors(
- const Vector3& normal,
- const Vector3 position[3],
- const Vector2 texCoord[3],
- Vector3& tangent,
- Vector3& binormal);
/** Helper for weldAdjacency */
static void weldBoundaryEdges(
@@ -446,7 +444,7 @@ public:
Array<Vector3>& newVertexPositions,
Array<int>& toNew,
Array<int>& toOld,
- double radius = G3D::fuzzyEpsilon);
+ double radius = fuzzyEpsilon);
/**
Modifies the face, edge, and vertex arrays in place so that
@@ -481,7 +479,7 @@ public:
Array<Face>& faceArray,
Array<Edge>& edgeArray,
Array<Vertex>& vertexArray,
- double radius = G3D::fuzzyEpsilon);
+ double radius = fuzzyEpsilon);
/**
@@ -521,46 +519,11 @@ public:
@cite The bounding sphere uses the method from J. Ritter. An effcient bounding sphere. In Andrew S. Glassner, editor, Graphics Gems. Academic Press, Boston, MA, 1990.
*/
- static void computeBounds(const Array<Vector3>& vertex, class Box& box, class Sphere& sphere);
+ static void computeBounds(const Array<Vector3>& vertex, class AABox& box, class Sphere& sphere);
/** Computes bounds for a subset of the vertices. It is ok if vertices appear more than once in the index array. */
- static void computeBounds(const Array<Vector3>& vertex, const Array<int>& index, class Box& box, class Sphere& sphere);
-
- /**
- Mutates geometry, texCoord, and indexArray so that the output has collocated vertices collapsed (welded).
-
- @param vertices Input and output
- @param textureCoords Input and output
- @param normals Output only
- @param indices Input and output. This is an array of trilist indices.
- @param oldToNewIndex Output argument
- @param normalSmoothingAngle Varies from 0 (flat shading) to toRadians(180) for extremely smooth shading. Default is toRadians(70)
- */
- static void weld(
- Array<Vector3>& vertices,
- Array<Vector2>& textureCoords,
- Array<Vector3>& normals,
- Array<Array<int>*>& indices,
- float normalSmoothingAngle = toRadians(70.0f),
- float vertexWeldRadius = 0.0001f,
- float textureWeldRadius = 0.0001f,
- float normalWeldRadius = 0.01f);
-
- inline static void weld(
- Array<Vector3>& vertices,
- Array<Vector2>& textureCoords,
- Array<Vector3>& normals,
- Array<int>& indices,
- float normalSmoothingAngle = toRadians(70.0f),
- float vertexWeldRadius = 0.0002f,
- float textureWeldRadius = 0.00001f,
- float normalWeldRadius = 0.00001f) {
-
- Array<Array<int>*> meta;
- meta.append(&indices);
- weld(vertices, textureCoords, normals, meta, normalSmoothingAngle, vertexWeldRadius, textureWeldRadius, normalWeldRadius);
- }
-
+ static void computeBounds(const Array<Vector3>& vertex, const Array<int>& index, class AABox& box, class Sphere& sphere);
+
/**
In debug mode, asserts that the adjacency references between the
face, edge, and vertex array are consistent.
@@ -580,6 +543,7 @@ public:
@param textureScale Lower-right texture coordinate
@param spaceCentered If true, the coordinates generated are centered at the origin before the transformation.
@param twoSided If true, matching top and bottom planes are generated.
+ \param elevation If non-NULL, values from this image are used as elevations. Apply an \a xform to adjust the scale
*/
static void generateGrid(
Array<Vector3>& vertex,
@@ -590,7 +554,8 @@ public:
const Vector2& textureScale = Vector2(1,1),
bool spaceCentered = true,
bool twoSided = true,
- const CoordinateFrame& xform = CoordinateFrame());
+ const CoordinateFrame& xform = CoordinateFrame(),
+ const Image1::Ref& elevation = NULL);
/** Converts quadlist (QUADS),
triangle fan (TRIANGLE_FAN),
@@ -603,15 +568,15 @@ public:
Array<IndexType>& outIndices) {
debugAssert(
- inType == MeshAlg::TRIANGLE_STRIP ||
- inType == MeshAlg::TRIANGLE_FAN ||
- inType == MeshAlg::QUADS ||
- inType == MeshAlg::QUAD_STRIP);
+ inType == PrimitiveType::TRIANGLE_STRIP ||
+ inType == PrimitiveType::TRIANGLE_FAN ||
+ inType == PrimitiveType::QUADS ||
+ inType == PrimitiveType::QUAD_STRIP);
const int inSize = inIndices.size();
switch(inType) {
- case MeshAlg::TRIANGLE_FAN:
+ case PrimitiveType::TRIANGLE_FAN:
{
debugAssert(inSize >= 3);
@@ -627,7 +592,7 @@ public:
break;
}
- case MeshAlg::TRIANGLE_STRIP:
+ case PrimitiveType::TRIANGLE_STRIP:
{
debugAssert(inSize >= 3);
@@ -652,7 +617,7 @@ public:
break;
}
- case MeshAlg::QUADS:
+ case PrimitiveType::QUADS:
{
debugAssert(inIndices.size() >= 4);
@@ -671,7 +636,7 @@ public:
break;
}
- case MeshAlg::QUAD_STRIP:
+ case PrimitiveType::QUAD_STRIP:
{
debugAssert(inIndices.size() >= 4);
diff --git a/externals/g3dlite/G3D.lib/include/G3D/MeshBuilder.h b/externals/g3dlite/G3D/MeshBuilder.h
index 3256c0de823..9920d59d7d3 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/MeshBuilder.h
+++ b/externals/g3dlite/G3D/MeshBuilder.h
@@ -1,7 +1,7 @@
/**
@file MeshBuilder.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-02-27
@edited 2004-10-04
diff --git a/externals/g3dlite/G3D.lib/include/G3D/NetAddress.h b/externals/g3dlite/G3D/NetAddress.h
index 8ed20a06690..8ed20a06690 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/NetAddress.h
+++ b/externals/g3dlite/G3D/NetAddress.h
diff --git a/externals/g3dlite/G3D.lib/include/G3D/NetworkDevice.h b/externals/g3dlite/G3D/NetworkDevice.h
index faffa56d690..ea3290cbc09 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/NetworkDevice.h
+++ b/externals/g3dlite/G3D/NetworkDevice.h
@@ -32,7 +32,7 @@
include the size of the header itself. The minimum message is 9
bytes:a 4-byte type, a 4-byte header equal to "1", and one byte of data.
- @maintainer Morgan McGuire, morgan@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-11-22
@edited 2006-11-25
*/
@@ -162,7 +162,7 @@ uint32 gcchtonl(uint32);
<LI> On the server, invoke G3D::NetListener::waitForConnection.
<LI> On the client, call G3D::NetworkDevice::createReliableConduit.
You will need the server's G3D::NetAddress. Consider using
- G3D::DiscoveryClient to find it via broadcasting.
+ G3D::Discovery::Client to find it via broadcasting.
</OL>
*/
diff --git a/externals/g3dlite/G3D/ParseError.h b/externals/g3dlite/G3D/ParseError.h
new file mode 100644
index 00000000000..f02948e3d29
--- /dev/null
+++ b/externals/g3dlite/G3D/ParseError.h
@@ -0,0 +1,59 @@
+/**
+ @file ParseError.h
+
+ @maintainer Morgan McGuire
+
+ @created 2009-11-15
+ @edited 2009-11-15
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_ParseError_h
+#define G3D_ParseError_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include <string>
+
+namespace G3D {
+
+/** Thrown by TextInput, Any, and other parsers on unexpected input. */
+class ParseError {
+public:
+ enum {UNKNOWN = -1};
+
+ /** Empty means unknown */
+ std::string filename;
+
+ /** For a binary file, the location of the parse error. -1 if unknown.*/
+ int64 byte;
+
+ /** For a text file, the line number is the line number of start of token which caused the exception. 1 is
+ the first line of the file. -1 means unknown. Note that you can use
+ TextInput::Settings::startingLineNumberOffset to shift the effective line
+ number that is reported by that class.
+ */
+ int line;
+
+ /** Character number (in the line) of the start of the token which caused the
+ exception. 1 is the character in the line. May be -1 if unknown.
+ */
+ int character;
+
+ std::string message;
+
+ ParseError() : byte(UNKNOWN), line(UNKNOWN), character(UNKNOWN) {}
+
+ virtual ~ParseError() {}
+
+ ParseError(const std::string& f, int l, int c, const std::string& m) :
+ filename (f), byte(UNKNOWN), line(l), character(c), message(m) {}
+
+ ParseError(const std::string& f, int64 b, const std::string& m) :
+ filename (f), byte(b), line(UNKNOWN), character(UNKNOWN), message(m) {}
+};
+
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/PhysicsFrame.h b/externals/g3dlite/G3D/PhysicsFrame.h
index 44eedb6846e..a5a9305b83e 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/PhysicsFrame.h
+++ b/externals/g3dlite/G3D/PhysicsFrame.h
@@ -1,7 +1,7 @@
/**
@file PhysicsFrame.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-07-08
@edited 2006-01-10
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Plane.h b/externals/g3dlite/G3D/Plane.h
index 1f0b15e0fe4..360bcd2bc75 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Plane.h
+++ b/externals/g3dlite/G3D/Plane.h
@@ -3,7 +3,7 @@
Plane class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
@edited 2004-07-18
diff --git a/externals/g3dlite/G3D.lib/include/G3D/PointHashGrid.h b/externals/g3dlite/G3D/PointHashGrid.h
index 8e9726e82da..0db9e677321 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/PointHashGrid.h
+++ b/externals/g3dlite/G3D/PointHashGrid.h
@@ -1,15 +1,15 @@
/**
@file PointHashGrid.h
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2008-07-01
- @edited 2008-11-02
+ @edited 2009-05-28
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_POINTHASHGRID_H
-#define G3D_POINTHASHGRID_H
+#ifndef G3D_PointHashGrid_h
+#define G3D_PointHashGrid_h
#include "G3D/platform.h"
#include "G3D/EqualsTrait.h"
@@ -20,6 +20,7 @@
#include "G3D/Table.h"
#include "G3D/AABox.h"
#include "G3D/Sphere.h"
+#include "G3D/SmallArray.h"
namespace G3D {
@@ -33,7 +34,7 @@ namespace G3D {
G3D::EqualsTrait, and G3D::HashFunc. overrides are provided for
common G3D classes like G3D::Vector3.
*/
-template<class Value,
+template<class Value,
class PosFunc = PositionTrait<Value>,
class EqualsFunc = EqualsTrait<Value>,
class HashFunc = HashTrait<Vector3int32> >
@@ -64,6 +65,9 @@ private:
/** Extent of a cell along one dimension. */
float m_cellWidth;
+ /** 1.0 / cell width */
+ float m_invCellWidth;
+
/** Conservative bounds; the actual data may be smaller. */
AABox m_bounds;
@@ -74,6 +78,7 @@ private:
<code>position * m_cellWidth</code>*/
CellTable m_data;
+ MemoryManager::Ref m_memoryManager;
/** Intentionally unimplemented: prevent copy construction. */
PointHashGrid(const ThisType&);
@@ -85,8 +90,7 @@ private:
/** Locate the cell and index within that cell containing v. Called by
remove() and contains(). */
- bool find(
- const Value& v,
+ bool find(const Value& v,
Vector3int32& foundCellCoord,
Cell*& foundCell,
int& index) {
@@ -118,9 +122,9 @@ private:
/** Given a real-space position, returns the cell coord
containing it.*/
- void getCellCoord(const Vector3& pos, Vector3int32& cellCoord) const {
+ inline void getCellCoord(const Vector3& pos, Vector3int32& cellCoord) const {
for (int a = 0; a < 3; ++a) {
- cellCoord[a] = iFloor(pos[a] / m_cellWidth);
+ cellCoord[a] = iFloor(pos[a] * m_invCellWidth);
}
}
@@ -153,11 +157,13 @@ public:
beginSphereIntersection and beginBoxIntersection. If two <i>Value</i>s are equal,
their positions must be within this radius as well.
*/
- PointHashGrid(float radiusHint) : m_size(0) {
+ PointHashGrid(float radiusHint, const MemoryManager::Ref& m = MemoryManager::create()) : m_size(0), m_memoryManager(m) {
initOffsetArray();
+ m_data.clearAndSetMemoryManager(m_memoryManager);
debugAssertM(radiusHint > 0, "Cell radius must be positive");
m_cellWidth = radiusHint;
+ m_invCellWidth = 1.0f / m_cellWidth;
}
/**
@@ -165,8 +171,9 @@ public:
about 5 values in each grid cell (which means about 27 * 5
values for each beginIntersection call).
*/
- PointHashGrid(const Array<Value>& init, float radiusHint = -1.0f) : m_size(0) {
+ PointHashGrid(const Array<Value>& init, float radiusHint = -1.0f, const MemoryManager::Ref& m = MemoryManager::create()) : m_size(0), m_memoryManager(m) {
initOffsetArray();
+ m_data.clearAndSetMemoryManager(m_memoryManager);
Vector3 lo(Vector3::inf());
Vector3 hi(-lo);
@@ -228,16 +235,14 @@ public:
getCellCoord(pos, cellCoord);
// See if the cell already exists
- Cell* cell = m_data.getPointer(cellCoord);
+ Cell& cell = m_data.getCreate(cellCoord);
- if (cell == NULL) {
- // The cell did not exist; create it
- m_data.set(cellCoord, Cell());
- cell = m_data.getPointer(cellCoord);
+ if (cell.size() == 0) {
+ // Use the same memory manager as for the whole class
+ cell.clearAndSetMemoryManager(m_memoryManager);
}
- debugAssert(cell != NULL);
- Entry& entry = cell->next();
+ Entry& entry = cell.next();
entry.value = v;
entry.position = pos;
@@ -264,7 +269,7 @@ public:
/** If there are multiple copies of an element, you must
delete them multiple times.
- @param shrinkAsNeeded If <b>true</b>, deallocate underlying data
+ @param shrinkIfNecessary If <b>true</b>, deallocate underlying data
structures as they are emptied. False increases performace at
the cost of memory overhead for dynamic structures.
@@ -538,6 +543,9 @@ public:
return (*m_cell)[m_arrayIndex].position;
}
+ // Intentionally unimplemented
+ BoxIterator& operator=(const BoxIterator&);
+
public:
inline bool operator!=(const BoxIterator& other) const {
@@ -653,6 +661,8 @@ public:
// cell's box to see if the cell itself is actually inside the sphere
// before iterating through it, since there may be many boxes outside the sphere.
+ // Intentionally unimplemented
+ SphereIterator& operator=(const SphereIterator&);
public:
inline bool operator!=(const SphereIterator& other) const {
@@ -723,6 +733,7 @@ public:
for(PointHashGrid<Vector3>::CellIterator iter = grid.beginCells(); iter != grid.endCells(); ++iter) {
entriesFound += iter->size();
}
+ </pre>
*/
class CellIterator {
private:
@@ -785,6 +796,9 @@ public:
m_isEnd = ! m_tableIterator.hasMore();
}
+ // Intentionally unimplemented
+ CellIterator& operator=(const CellIterator&);
+
public:
const CellObject& operator*() const { return m_indirection; }
@@ -839,7 +853,7 @@ public:
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
- /** Returns true if there is a value that is exactly equal to @a. This will
+ /** Returns true if there is a value that is exactly equal to @a v. This will
check all neighboring cells to avoid roundoff error at cell boundaries.
*/
bool contains(const Value& v) const {
@@ -863,6 +877,15 @@ public:
clear();
}
+ void clearAndSetMemoryManager(const MemoryManager::Ref& m) {
+ ++m_epoch;
+ m_size = 0;
+ m_bounds = AABox();
+
+ m_data.clearAndSetMemoryManager(m);
+ m_memoryManager = m;
+ }
+
/** Removes all data.
@param shrink If true, underlying structures are deallocated as
they are freed.*/
diff --git a/externals/g3dlite/G3D.lib/include/G3D/PointAABSPTree.h b/externals/g3dlite/G3D/PointKDTree.h
index c8d527a45c2..151cbd5f2f3 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/PointAABSPTree.h
+++ b/externals/g3dlite/G3D/PointKDTree.h
@@ -1,12 +1,12 @@
/**
- @file PointAABSPTree.h
+ @file PointKDTree.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2004-01-11
@edited 2008-11-02
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -30,26 +30,6 @@
#include "G3D/PositionTrait.h"
#include <algorithm>
-
-///////////////////////////////////////////////////////
-
-/** @deprecated */
-inline void getPosition(const G3D::Vector3& v, G3D::Vector3& p) {
- p = v;
-}
-
-/** @deprecated */
-inline void getPosition(const G3D::Vector4& v, G3D::Vector3& p) {
- p = v.xyz();
-}
-
-/** @deprecated */
-inline void getPosition(const G3D::Vector2& v, G3D::Vector3& p) {
- p.x = v.x;
- p.y = v.y;
- p.z = 0;
-}
-
namespace G3D {
/**
@@ -872,7 +852,7 @@ public:
/**
Typically used to find all visible
objects inside the view frustum (see also GCamera::getClipPlanes)... i.e. all objects
- <B>not<B> culled by frustum.
+ <B>not</B> culled by frustum.
Example:
<PRE>
@@ -1200,8 +1180,6 @@ public:
#undef TreeType
};
-#define PointAABSPTree PointKDTree
-
}
#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Pointer.h b/externals/g3dlite/G3D/Pointer.h
index 2b80187bae5..6e35062a746 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Pointer.h
+++ b/externals/g3dlite/G3D/Pointer.h
@@ -1,16 +1,16 @@
/**
@file Pointer.h
- @maintainer Morgan McGuire, graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-05-16
- @edited 2007-06-22
+ @edited 2009-03-26
- Copyright 2000-2007, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_POINTER_H
-#define G3D_POINTER_H
+#ifndef G3D_Pointer_h
+#define G3D_Pointer_h
#include "G3D/debugAssert.h"
#include "G3D/ReferenceCount.h"
@@ -68,6 +68,7 @@ private:
virtual void set(ValueType b) = 0;
virtual ValueType get() const = 0;
virtual Interface* clone() const = 0;
+ virtual bool isNull() const = 0;
};
class Memory : public Interface {
@@ -78,7 +79,7 @@ private:
public:
Memory(ValueType* value) : value(value) {
- debugAssert(value != NULL);
+ //debugAssert(value != NULL);
}
virtual void set(ValueType v) {
@@ -92,6 +93,10 @@ private:
virtual Interface* clone() const {
return new Memory(value);
}
+
+ virtual bool isNull() const {
+ return value == NULL;
+ }
};
template<class T, typename GetMethod, typename SetMethod>
@@ -121,6 +126,10 @@ private:
virtual Interface* clone() const {
return new Accessor(object, getMethod, setMethod);
}
+
+ virtual bool isNull() const {
+ return object == NULL;
+ }
};
@@ -153,30 +162,38 @@ private:
virtual Interface* clone() const {
return new RefAccessor(object, getMethod, setMethod);
}
+
+ virtual bool isNull() const {
+ return object.isNull();
+ }
};
- Interface* interface;
+ Interface* m_interface;
public:
- Pointer() : interface(NULL) {};
+ Pointer() : m_interface(NULL) {};
/** Allows implicit cast from real pointer */
- Pointer(ValueType* v) : interface(new Memory(v)) {}
+ Pointer(ValueType* v) : m_interface(new Memory(v)) {}
+
+ inline bool isNull() const {
+ return (m_interface == NULL) || m_interface->isNull();
+ }
// Assignment
inline Pointer& operator=(const Pointer& r) {
- delete interface;
- if (r.interface != NULL) {
- interface = r.interface->clone();
+ delete m_interface;
+ if (r.m_interface != NULL) {
+ m_interface = r.m_interface->clone();
} else {
- interface = NULL;
+ m_interface = NULL;
}
return this[0];
}
- Pointer(const Pointer& p) : interface(NULL) {
+ Pointer(const Pointer& p) : m_interface(NULL) {
this[0] = p;
}
@@ -184,62 +201,62 @@ public:
Pointer(const ReferenceCountedPointer<Class>& object,
ValueType (Class::*getMethod)() const,
void (Class::*setMethod)(ValueType)) :
- interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
+ m_interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
template<class Class>
Pointer(const ReferenceCountedPointer<Class>& object,
const ValueType& (Class::*getMethod)() const,
void (Class::*setMethod)(ValueType)) :
- interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
+ m_interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
template<class Class>
Pointer(const ReferenceCountedPointer<Class>& object,
ValueType (Class::*getMethod)() const,
void (Class::*setMethod)(const ValueType&)) :
- interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
+ m_interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
template<class Class>
Pointer(const ReferenceCountedPointer<Class>& object,
const ValueType& (Class::*getMethod)() const,
void (Class::*setMethod)(const ValueType&)) :
- interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
+ m_interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
template<class Class>
Pointer(Class* object,
const ValueType& (Class::*getMethod)() const,
void (Class::*setMethod)(const ValueType&)) :
- interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
+ m_interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
template<class Class>
Pointer(Class* object,
ValueType (Class::*getMethod)() const,
void (Class::*setMethod)(const ValueType&)) :
- interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
+ m_interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
template<class Class>
Pointer(Class* object,
const ValueType& (Class::*getMethod)() const,
void (Class::*setMethod)(ValueType)) :
- interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
+ m_interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
template<class Class>
Pointer(Class* object,
ValueType (Class::*getMethod)() const,
void (Class::*setMethod)(ValueType)) :
- interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
+ m_interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
~Pointer() {
- delete interface;
+ delete m_interface;
}
inline const ValueType getValue() const {
- debugAssert(interface != NULL);
- return interface->get();
+ debugAssert(m_interface != NULL);
+ return m_interface->get();
}
inline void setValue(const ValueType& v) {
- debugAssert(interface != NULL);
- interface->set(v);
+ debugAssert(m_interface != NULL);
+ m_interface->set(v);
}
class IndirectValue {
diff --git a/externals/g3dlite/G3D.lib/include/G3D/PositionTrait.h b/externals/g3dlite/G3D/PositionTrait.h
index 67a4f64138a..67a4f64138a 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/PositionTrait.h
+++ b/externals/g3dlite/G3D/PositionTrait.h
diff --git a/externals/g3dlite/G3D/PrecomputedRandom.h b/externals/g3dlite/G3D/PrecomputedRandom.h
new file mode 100644
index 00000000000..411d128c582
--- /dev/null
+++ b/externals/g3dlite/G3D/PrecomputedRandom.h
@@ -0,0 +1,110 @@
+/**
+ @file PrecomputedRandom.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-03-31
+ @edited 2009-03-31
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_PrecomputedRandom_h
+#define G3D_PrecomputedRandom_h
+
+#include "G3D/platform.h"
+#include "G3D/Random.h"
+
+namespace G3D {
+
+/** Fast random numbers using a precomputed data table.
+
+ e.g., generates cosHemi about 13x faster than Random.
+ This is useful for quickly generating seeded random
+ numbers for reproducibility. G3D::Random takes a long
+ time to seed; this is instantaneous (providing the
+ precomputed data is already available.)
+
+ Not threadsafe.*/
+class PrecomputedRandom : public Random {
+public:
+ /** Put the cosHemi and the uniform together so that when
+ alternating between them we stay in cache. This is also packed
+ into a good size for SIMD and GPU operations.*/
+ class HemiUniformData {
+ public:
+ float cosHemiX;
+ float cosHemiY;
+ float cosHemiZ;
+ float uniform;
+ };
+
+ class SphereBitsData {
+ public:
+ float sphereX;
+ float sphereY;
+ float sphereZ;
+ uint32 bits;
+ };
+
+protected:
+
+ /** Array of 2^n elements. */
+ const HemiUniformData* m_hemiUniform;
+ const SphereBitsData* m_sphereBits;
+
+ /** 2^n - 1; the AND mask for computing a fast modulo */
+ int m_modMask;
+
+ int m_index;
+
+ /** If true, free m_hemiUniform and m_sphereBits in destructor */
+ bool m_freeData;
+
+public:
+
+ /*
+ \param dataSize Must be a power of 2
+ \param data Will NOT be deleted by the destructor.
+ */
+ PrecomputedRandom(const HemiUniformData* data1, const SphereBitsData* data2, int dataSize, uint32 seed = 0xF018A4D2);
+
+ /**
+ \param dataSize Number of random numbers that can be requested before periodicity. Must be a power of 2.
+ */
+ PrecomputedRandom(int dataSize, uint32 seed = 0xF018A4D2);
+
+ ~PrecomputedRandom();
+
+ /** Each bit is random. Subclasses can choose to override just
+ this method and the other methods will all work automatically. */
+ virtual uint32 bits();
+
+ // integer is inherited
+
+ /** Uniform random float on the range [min, max] */
+ virtual float uniform(float low, float high);
+
+ /** Uniform random float on the range [0, 1] */
+ virtual float uniform();
+
+ // gaussian is inherited
+
+ /** Returns 3D unit vectors distributed according to
+ a cosine distribution about the z axis. */
+ virtual void cosHemi(float& x, float& y, float& z);
+
+ /** Returns 3D unit vectors distributed according to a cosine
+ power distribution (\f$ \mbox{cos}^k \theta \f$) about
+ the z-axis. */
+ virtual void cosPowHemi(const float k, float& x, float& y, float& z);
+
+ // hemi is inherited
+
+ /** Returns 3D unit vectors uniformly distributed on the sphere */
+ virtual void sphere(float& x, float& y, float& z);
+};
+
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Quat.h b/externals/g3dlite/G3D/Quat.h
index d4b892623d8..9ef3d57b301 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Quat.h
+++ b/externals/g3dlite/G3D/Quat.h
@@ -3,14 +3,14 @@
Quaternion
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-01-23
- @edited 2006-05-10
+ @edited 2009-05-10
*/
-#ifndef G3D_QUAT_H
-#define G3D_QUAT_H
+#ifndef G3D_Quat_h
+#define G3D_Quat_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
diff --git a/externals/g3dlite/G3D/Quat.inl b/externals/g3dlite/G3D/Quat.inl
new file mode 100644
index 00000000000..9e4c861d93b
--- /dev/null
+++ b/externals/g3dlite/G3D/Quat.inl
@@ -0,0 +1,36 @@
+/**
+ Quat.inl
+
+ @cite Quaternion implementation based on Watt & Watt page 363.
+ Thanks to Max McGuire for slerp optimizations.
+
+ @maintainer Morgan McGuire, matrix@graphics3d.com
+
+ @created 2002-01-23
+ @edited 2004-03-04
+ */
+
+namespace G3D {
+
+inline float& Quat::operator[] (int i) {
+ debugAssert(i >= 0);
+ debugAssert(i < 4);
+ return ((float*)this)[i];
+}
+
+inline const float& Quat::operator[] (int i) const {
+ debugAssert(i >= 0);
+ debugAssert(i < 4);
+ return ((float*)this)[i];
+}
+
+inline Quat Quat::operator-(const Quat& other) const {
+ return Quat(x - other.x, y - other.y, z - other.z, w - other.w);
+}
+
+inline Quat Quat::operator+(const Quat& other) const {
+ return Quat(x + other.x, y + other.y, z + other.z, w + other.w);
+}
+
+}
+
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Queue.h b/externals/g3dlite/G3D/Queue.h
index b64eced820a..36573265d1a 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Queue.h
+++ b/externals/g3dlite/G3D/Queue.h
@@ -1,10 +1,10 @@
/**
@file Queue.h
- @maintainer Morgan McGuire, graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-07-09
- @edited 2005-08-20
+ @edited 2008-12-20
*/
#ifndef G3D_QUEUE_H
@@ -316,6 +316,15 @@ public:
}
+ /** Returns the back element */
+ inline const T& last() const {
+ return (*this)[size() - 1];
+ }
+
+ inline T& last() {
+ return (*this)[size() - 1];
+ }
+
/**
Returns true if the given element is in the queue.
*/
diff --git a/externals/g3dlite/G3D/Random.h b/externals/g3dlite/G3D/Random.h
new file mode 100644
index 00000000000..54491d06f1b
--- /dev/null
+++ b/externals/g3dlite/G3D/Random.h
@@ -0,0 +1,139 @@
+/**
+ @file Random.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-01-02
+ @edited 2009-03-20
+
+ Copyright 2000-2009, Morgan McGuire.
+ All rights reserved.
+ */
+#ifndef G3D_Random_h
+#define G3D_Random_h
+
+#include "G3D/platform.h"
+#include "G3D/g3dmath.h"
+#include "G3D/GMutex.h"
+
+namespace G3D {
+
+/** Random number generator.
+
+ Threadsafe.
+
+ Useful for generating consistent random numbers across platforms
+ and when multiple threads are involved.
+
+ Uses the Fast Mersenne Twister (FMT-19937) algorithm.
+
+ On average, uniform() runs about 2x-3x faster than rand().
+
+ @cite http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html
+
+ On OS X, Random is about 10x faster than drand48() (which is
+ threadsafe) and 4x faster than rand() (which is not threadsafe).
+ */
+class Random {
+protected:
+
+ /** Constants (important for the algorithm; do not modify) */
+ enum {
+ N = 624,
+ M = 397,
+ R = 31,
+ U = 11,
+ S = 7,
+ T = 15,
+ L = 18,
+ A = 0x9908B0DF,
+ B = 0x9D2C5680,
+ C = 0xEFC60000};
+
+ /**
+ Prevents multiple overlapping calls to generate().
+ */
+ Spinlock lock;
+
+ /** State vector (these are the next N values that will be returned) */
+ uint32* state;
+
+ /** Index into state */
+ int index;
+
+ bool m_threadsafe;
+
+ /** Generate the next N ints, and store them for readback later.
+ Called from bits() */
+ virtual void generate();
+
+ /** For subclasses. The void* parameter is just to distinguish this from the
+ public constructor.*/
+ Random(void*);
+
+public:
+
+ /** \param threadsafe Set to false if you know that this random
+ will only be used on a single thread. This eliminates the
+ lock and improves performance on some platforms.
+ */
+ Random(uint32 seed = 0xF018A4D2, bool threadsafe = true);
+
+ virtual ~Random();
+
+ /** Each bit is random. Subclasses can choose to override just
+ this method and the other methods will all work automatically. */
+ virtual uint32 bits();
+
+ /** Uniform random integer on the range [min, max] */
+ virtual int integer(int min, int max);
+
+ /** Uniform random float on the range [min, max] */
+ virtual inline float uniform(float low, float high) {
+ // We could compute the ratio in double precision here for
+ // about 1.5x slower performance and slightly better
+ // precision.
+ return low + (high - low) * ((float)bits() / (float)0xFFFFFFFFUL);
+ }
+
+ /** Uniform random float on the range [0, 1] */
+ virtual inline float uniform() {
+ // We could compute the ratio in double precision here for
+ // about 1.5x slower performance and slightly better
+ // precision.
+ const float norm = 1.0f / (float)0xFFFFFFFFUL;
+ return (float)bits() * norm;
+ }
+
+ /** Normally distributed reals. */
+ virtual float gaussian(float mean, float stdev);
+
+ /** Returns 3D unit vectors distributed according to
+ a cosine distribution about the z-axis. */
+ virtual void cosHemi(float& x, float& y, float& z);
+
+ /** Returns 3D unit vectors distributed according to a cosine
+ power distribution (\f$ \cos^k \theta \f$) about
+ the z-axis. */
+ virtual void cosPowHemi(const float k, float& x, float& y, float& z);
+
+ /** Returns 3D unit vectors uniformly distributed on the
+ hemisphere about the z-axis. */
+ virtual void hemi(float& x, float& y, float& z);
+
+ /** Returns 3D unit vectors uniformly distributed on the sphere */
+ virtual void sphere(float& x, float& y, float& z);
+
+ /**
+ A shared instance for when the performance and features but not
+ consistency of the class are desired. It is slightly (10%)
+ faster to use a distinct instance than to use the common one.
+
+ Threadsafe.
+ */
+ static Random& common();
+};
+
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Ray.h b/externals/g3dlite/G3D/Ray.h
index ab43c82933a..80df5828aff 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Ray.h
+++ b/externals/g3dlite/G3D/Ray.h
@@ -3,14 +3,14 @@
Ray class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-07-12
- @edited 2006-02-21
+ @edited 2009-06-29
*/
-#ifndef G3D_RAY_H
-#define G3D_RAY_H
+#ifndef G3D_Ray_h
+#define G3D_Ray_h
#include "G3D/platform.h"
#include "G3D/Vector3.h"
@@ -23,45 +23,85 @@ namespace G3D {
*/
class Ray {
private:
- Ray(const Vector3& origin, const Vector3& direction) {
- this->origin = origin;
- this->direction = direction;
- }
+ friend class Intersect;
+
+ Vector3 m_origin;
+
+ /** Unit length */
+ Vector3 m_direction;
+
+ /** 1.0 / direction */
+ Vector3 m_invDirection;
+
+
+ // The following are for the "ray slope" optimization from
+ // "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
+ // by Martin Eisemann, Thorsten Grosch, Stefan Müller and Marcus Magnor
+ // Computer Graphics Lab, TU Braunschweig, Germany and
+ // University of Koblenz-Landau, Germany*/
+ enum Classification {MMM, MMP, MPM, MPP, PMM, PMP, PPM, PPP, POO, MOO, OPO, OMO, OOP, OOM, OMM, OMP, OPM, OPP, MOM, MOP, POM, POP, MMO, MPO, PMO, PPO}; Classification classification;
+ // ray slope
+ float ibyj, jbyi, kbyj, jbyk, ibyk, kbyi;
+ // Precomputed components
+ float c_xy, c_xz, c_yx, c_yz, c_zx, c_zy;
public:
- Vector3 origin;
- /**
- Not unit length
- */
- Vector3 direction;
+ void set(const Vector3& origin, const Vector3& direction);
- Ray() : origin(Vector3::zero()), direction(Vector3::zero()) {}
+ inline const Vector3& origin() const {
+ return m_origin;
+ }
+
+ /** Unit direction vector. */
+ inline const Vector3& direction() const {
+ return m_direction;
+ }
+
+ /** Component-wise inverse of direction vector. May have inf() components */
+ inline const Vector3& invDirection() const {
+ return m_invDirection;
+ }
+
+ inline Ray() {
+ set(Vector3::zero(), Vector3::unitX());
+ }
+
+ inline Ray(const Vector3& origin, const Vector3& direction) {
+ set(origin, direction);
+ }
Ray(class BinaryInput& b);
+
void serialize(class BinaryOutput& b) const;
void deserialize(class BinaryInput& b);
/**
- Creates a Ray from a origin and a (nonzero) direction.
+ Creates a Ray from a origin and a (nonzero) unit direction.
*/
static Ray fromOriginAndDirection(const Vector3& point, const Vector3& direction) {
return Ray(point, direction);
}
- Ray unit() const {
- return Ray(origin, direction.unit());
- }
+ /** Advances the origin along the direction by @a distance */
+ inline Ray bump(float distance) const {
+ return Ray(m_origin + m_direction * distance, m_direction);
+ }
+
+ /** Advances the origin along the @a bumpDirection by @a distance and returns the new ray*/
+ inline Ray bump(float distance, const Vector3& bumpDirection) const {
+ return Ray(m_origin + bumpDirection * distance, m_direction);
+ }
/**
Returns the closest point on the Ray to point.
*/
Vector3 closestPoint(const Vector3& point) const {
- float t = direction.dot(point - this->origin);
+ float t = m_direction.dot(point - m_origin);
if (t < 0) {
- return this->origin;
+ return m_origin;
} else {
- return this->origin + direction * t;
+ return m_origin + m_direction * t;
}
}
@@ -82,7 +122,7 @@ public:
Vector3 intersection(const class Plane& plane) const;
/**
- Returns the distance until intersection with the (solid) sphere.
+ Returns the distance until intersection with the sphere or the (solid) ball bounded by the sphere.
Will be 0 if inside the sphere, inf if there is no intersection.
The ray direction is <B>not</B> normalized. If the ray direction
@@ -92,8 +132,10 @@ public:
See also the G3D::CollisionDetection "movingPoint" methods,
which give more information about the intersection.
+
+ \param solid If true, rays inside the sphere immediately intersect (good for collision detection). If false, they hit the opposite side of the sphere (good for ray tracing).
*/
- float intersectionTime(const class Sphere& sphere) const;
+ float intersectionTime(const class Sphere& sphere, bool solid = false) const;
float intersectionTime(const class Plane& plane) const;
@@ -209,33 +251,33 @@ inline float Ray::intersectionTime(
float tvec[3], pvec[3], qvec[3];
// begin calculating determinant - also used to calculate U parameter
- CROSS(pvec, direction, edge2);
+ CROSS(pvec, m_direction, edge2);
// if determinant is near zero, ray lies in plane of triangle
const float det = DOT(edge1, pvec);
if (det < EPSILON) {
- return (float)inf();
+ return finf();
}
// calculate distance from vert0 to ray origin
- SUB(tvec, origin, vert0);
+ SUB(tvec, m_origin, vert0);
// calculate U parameter and test bounds
u = DOT(tvec, pvec);
if ((u < 0.0f) || (u > det)) {
// Hit the plane outside the triangle
- return (float)inf();
+ return finf();
}
// prepare to test V parameter
CROSS(qvec, tvec, edge1);
// calculate V parameter and test bounds
- v = DOT(direction, qvec);
+ v = DOT(m_direction, qvec);
if ((v < 0.0f) || (u + v > det)) {
// Hit the plane outside the triangle
- return (float)inf();
+ return finf();
}
@@ -247,7 +289,7 @@ inline float Ray::intersectionTime(
return t / det;
} else {
// We had to travel backwards in time to intersect
- return (float)inf();
+ return finf();
}
}
@@ -271,33 +313,33 @@ inline float Ray::intersectionTime(
float tvec[3], pvec[3], qvec[3];
// begin calculating determinant - also used to calculate U parameter
- CROSS(pvec, direction, edge2);
+ CROSS(pvec, m_direction, edge2);
// if determinant is near zero, ray lies in plane of triangle
const float det = DOT(edge1, pvec);
if (det < EPSILON) {
- return (float)inf();
+ return finf();
}
// calculate distance from vert0 to ray origin
- SUB(tvec, origin, vert0);
+ SUB(tvec, m_origin, vert0);
// calculate U parameter and test bounds
u = DOT(tvec, pvec);
if ((u < 0.0f) || (u > det)) {
// Hit the plane outside the triangle
- return (float)inf();
+ return finf();
}
// prepare to test V parameter
CROSS(qvec, tvec, edge1);
// calculate V parameter and test bounds
- v = DOT(direction, qvec);
+ v = DOT(m_direction, qvec);
if ((v < 0.0f) || (u + v > det)) {
// Hit the plane outside the triangle
- return (float)inf();
+ return finf();
}
float t = DOT(edge2, qvec);
@@ -315,7 +357,7 @@ inline float Ray::intersectionTime(
return t;
} else {
// We had to travel backwards in time to intersect
- return (float)inf();
+ return finf();
}
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Rect2D.h b/externals/g3dlite/G3D/Rect2D.h
index a6c0b7cd0cb..2fb58c50465 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Rect2D.h
+++ b/externals/g3dlite/G3D/Rect2D.h
@@ -1,17 +1,17 @@
/**
@file Rect2D.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-11-13
- @created 2008-11-16
+ @created 2009-11-16
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_RECT2D_H
-#define G3D_RECT2D_H
+#ifndef G3D_Rect2D_h
+#define G3D_Rect2D_h
// Linux defines this as a macro
#ifdef border
@@ -22,8 +22,17 @@
#include "G3D/Array.h"
#include "G3D/Vector2.h"
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
+#endif
+
+
namespace G3D {
+class Any;
+
/**
If you are using this class for pixel rectangles, keep in mind that the last
pixel you can draw to is at x0() + width() - 1.
@@ -110,84 +119,87 @@ private:
public:
- inline Rect2D() : min(0, 0), max(0, 0) {}
+ /** \param any Must either Rect2D::xywh(#, #, #, #) or Rect2D::xyxy(#, #, #, #)*/
+ Rect2D(const Any& any);
+
+ /** Converts the Rect2D to an Any. */
+ operator Any() const;
+
+ Rect2D() : min(0, 0), max(0, 0) {}
/** Creates a rectangle at 0,0 with the given width and height*/
- inline Rect2D(const Vector2& wh) : min(0, 0), max(wh.x, wh.y) {}
+ Rect2D(const Vector2& wh) : min(0, 0), max(wh.x, wh.y) {}
/** Computes a rectangle that contains both @a a and @a b.
Note that even if @a or @b has zero area, its origin will be included.*/
- inline Rect2D(const Rect2D& a, const Rect2D& b) {
+ Rect2D(const Rect2D& a, const Rect2D& b) {
min = a.min.min(b.min);
max = a.max.max(b.max);
}
/** @brief Uniformly random point on the interior */
- inline Vector2 randomPoint() const {
+ Vector2 randomPoint() const {
return Vector2(uniformRandom(0, max.x - min.x) + min.x,
uniformRandom(0, max.y - min.y) + min.y);
}
- inline float width() const {
+ float width() const {
return max.x - min.x;
}
- inline float height() const {
+ float height() const {
return max.y - min.y;
}
- inline float x0() const {
+ float x0() const {
return min.x;
}
- inline float x1() const {
+ float x1() const {
return max.x;
}
- inline float y0() const {
+ float y0() const {
return min.y;
}
- inline float y1() const {
+ float y1() const {
return max.y;
}
/** Min, min corner */
- inline Vector2 x0y0() const {
+ Vector2 x0y0() const {
return min;
}
- inline Vector2 x1y0() const {
+ Vector2 x1y0() const {
return Vector2(max.x, min.y);
}
- inline Vector2 x0y1() const {
+ Vector2 x0y1() const {
return Vector2(min.x, max.y);
}
/** Max,max corner */
- inline Vector2 x1y1() const {
+ Vector2 x1y1() const {
return max;
}
/** Width and height */
- inline Vector2 wh() const {
+ Vector2 wh() const {
return max - min;
}
- inline Vector2 center() const {
+ Vector2 center() const {
return (max + min) * 0.5;
}
- inline static Rect2D xyxy(float x0, float y0, float x1, float y1) {
- Rect2D r;
-
- r.min.x = G3D::min(x0, x1);
- r.min.y = G3D::min(y0, y1);
- r.max.x = G3D::max(x0, x1);
- r.max.y = G3D::max(y0, y1);
+ float area() const {
+ return width() * height();
+ }
- return r;
+ bool isFinite() const {
+ return (min.isFinite() && max.isFinite());
}
Rect2D lerp(const Rect2D& other, float alpha) const {
@@ -199,7 +211,18 @@ public:
return out;
}
- inline static Rect2D xyxy(const Vector2& v0, const Vector2& v1) {
+ static Rect2D xyxy(float x0, float y0, float x1, float y1) {
+ Rect2D r;
+
+ r.min.x = G3D::min(x0, x1);
+ r.min.y = G3D::min(y0, y1);
+ r.max.x = G3D::max(x0, x1);
+ r.max.y = G3D::max(y0, y1);
+
+ return r;
+ }
+
+ static Rect2D xyxy(const Vector2& v0, const Vector2& v1) {
Rect2D r;
r.min = v0.min(v1);
@@ -208,19 +231,26 @@ public:
return r;
}
- inline static Rect2D xywh(float x, float y, float w, float h) {
+ static Rect2D xywh(float x, float y, float w, float h) {
return xyxy(x, y, x + w, y + h);
}
- inline static Rect2D xywh(const Vector2& v, const Vector2& w) {
+ static Rect2D xywh(const Vector2& v, const Vector2& w) {
return xyxy(v.x, v.y, v.x + w.x, v.y + w.y);
}
- inline bool contains(const Vector2& v) const {
+ /** Constructs a Rect2D with infinite boundaries.
+ Use isFinite() to test either min or max.
+ */
+ static Rect2D inf() {
+ return xyxy(Vector2::inf(), Vector2::inf());
+ }
+
+ bool contains(const Vector2& v) const {
return (v.x >= min.x) && (v.y >= min.y) && (v.x <= max.x) && (v.y <= max.y);
}
- inline bool contains(const Rect2D& r) const {
+ bool contains(const Rect2D& r) const {
return (min.x <= r.min.x) && (min.y <= r.min.y) &&
(max.x >= r.max.x) && (max.y >= r.max.y);
}
@@ -228,47 +258,47 @@ public:
/** True if there is non-zero area to the intersection between @a this and @a r.
Note that two rectangles that are adjacent do not intersect because there is
zero area to the overlap, even though one of them "contains" the corners of the other.*/
- inline bool intersects(const Rect2D& r) const {
+ bool intersects(const Rect2D& r) const {
return (min.x < r.max.x) && (min.y < r.max.y) &&
(max.x > r.min.x) && (max.y > r.min.y);
}
/** Like intersection, but counts the adjacent case as touching. */
- inline bool intersectsOrTouches(const Rect2D& r) const {
+ bool intersectsOrTouches(const Rect2D& r) const {
return (min.x <= r.max.x) && (min.y <= r.max.y) &&
(max.x >= r.min.x) && (max.y >= r.min.y);
}
- inline Rect2D operator*(float s) const {
+ Rect2D operator*(float s) const {
return xyxy(min.x * s, min.y * s, max.x * s, max.y * s);
}
- inline Rect2D operator/(float s) const {
+ Rect2D operator/(float s) const {
return xyxy(min / s, max / s);
}
- inline Rect2D operator/(const Vector2& s) const {
+ Rect2D operator/(const Vector2& s) const {
return xyxy(min / s, max / s);
}
- inline Rect2D operator+(const Vector2& v) const {
+ Rect2D operator+(const Vector2& v) const {
return xyxy(min + v, max + v);
}
- inline Rect2D operator-(const Vector2& v) const {
+ Rect2D operator-(const Vector2& v) const {
return xyxy(min - v, max - v);
}
- inline bool operator==(const Rect2D& other) const {
+ bool operator==(const Rect2D& other) const {
return (min == other.min) && (max == other.max);
}
- inline bool operator!=(const Rect2D& other) const {
+ bool operator!=(const Rect2D& other) const {
return (min != other.min) || (max != other.max);
}
/** Returns the corners in the order: (min,min), (max,min), (max,max), (min,max). */
- inline Vector2 corner(int i) const {
+ Vector2 corner(int i) const {
debugAssert(i >= 0 && i < 4);
switch (i & 3) {
case 0:
@@ -288,7 +318,7 @@ public:
/** @deprecated
@sa expand() */
- inline Rect2D border(float delta) const {
+ Rect2D border(float delta) const {
return Rect2D::xywh(x0() + delta,
y0() + delta,
width() - 2.0f * delta,
@@ -297,7 +327,7 @@ public:
/** Returns a new Rect2D that is bigger/smaller by the specified amount
(negative is shrink.) */
- inline Rect2D expand(float delta) const {
+ Rect2D expand(float delta) const {
float newX = x0() - delta;
float newY = y0() - delta;
float newW = width() + 2.0f * delta;
@@ -379,10 +409,6 @@ public:
return Rect2D::xywh(0, 0, 0, 0);
}
}
-
- float area() const {
- return width() * height();
- }
};
typedef Rect2D AABox2D;
diff --git a/externals/g3dlite/G3D.lib/include/G3D/ReferenceCount.h b/externals/g3dlite/G3D/ReferenceCount.h
index f55a22be0e1..84591c6d8e5 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/ReferenceCount.h
+++ b/externals/g3dlite/G3D/ReferenceCount.h
@@ -3,16 +3,15 @@
Reference Counting Garbage Collector for C++
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Adapted and extended from Justin Miller's "RGC" class that appeared in BYTE magazine.
@cite See also http://www.jelovic.com/articles/cpp_without_memory_errors_slides.htm
@created 2001-10-23
- @edited 2008-09-25
+ @edited 2009-04-25
*/
-
-#ifndef G3D_RGC_H
-#define G3D_RGC_H
+#ifndef G3D_ReferenceCount_h
+#define G3D_ReferenceCount_h
#include "G3D/platform.h"
#include "G3D/debug.h"
@@ -20,6 +19,12 @@
namespace G3D {
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+# pragma warning (disable : 4127)
+#endif
+
/** Base class for WeakReferenceCountedPointer */
class _WeakPtr {
public:
@@ -111,8 +116,6 @@ int main(int argc, char *argv[]) {
return 0;
}
</PRE>
-
-@deprecated To be replaced by boost::shared_ptr in 7.0
*/
class ReferenceCountedObject {
public:
@@ -133,13 +136,7 @@ public:
protected:
- ReferenceCountedObject() :
- ReferenceCountedObject_refCount(0),
- ReferenceCountedObject_weakPointer(0) {
-
- debugAssertM(isValidHeapPointer(this),
- "Reference counted objects must be allocated on the heap.");
- }
+ ReferenceCountedObject();
public:
@@ -147,45 +144,18 @@ public:
This is not called from the destructor because it needs to be invoked
before the subclass destructor.
*/
- void ReferenceCountedObject_zeroWeakPointers() {
- // Tell all of my weak pointers that I'm gone.
-
- _WeakPtrLinkedList* node = ReferenceCountedObject_weakPointer;
-
- while (node != 0) {
-
- // Notify the weak pointer that it is going away
- node->weakPtr->objectCollected();
-
- // Free the node and advance
- _WeakPtrLinkedList* tmp = node;
- node = node->next;
- delete tmp;
- }
- }
+ void ReferenceCountedObject_zeroWeakPointers();
- virtual ~ReferenceCountedObject() {}
+ virtual ~ReferenceCountedObject();
/**
Note: copies will initially start out with 0
references and 0 weak references like any other object.
*/
- ReferenceCountedObject(const ReferenceCountedObject& notUsed) :
- ReferenceCountedObject_refCount(0),
- ReferenceCountedObject_weakPointer(0) {
- (void)notUsed;
- debugAssertM(G3D::isValidHeapPointer(this),
- "Reference counted objects must be allocated on the heap.");
- }
-
- ReferenceCountedObject& operator=(const ReferenceCountedObject& other) {
- (void)other;
- // Nothing changes when I am assigned; the reference count on
- // both objects is the same (although my super-class probably
- // changes).
- return *this;
- }
+ ReferenceCountedObject(const ReferenceCountedObject& notUsed);
+
+ ReferenceCountedObject& operator=(const ReferenceCountedObject& other);
};
@@ -215,15 +185,16 @@ private:
void zeroPointer() {
if (m_pointer != NULL) {
+ ReferenceCountedObject* pointer = ((ReferenceCountedObject*)m_pointer);
debugAssert(G3D::isValidHeapPointer(m_pointer));
- debugAssertM(m_pointer->ReferenceCountedObject_refCount.value() > 0,
+ debugAssertM(pointer->ReferenceCountedObject_refCount.value() > 0,
"Dangling reference detected.");
// Only delete if this instance caused the count to hit
// exactly zero. If there is a race condition, the value
// may be zero after decrement returns, but only one of
// the instances will get a zero return value.
- if (m_pointer->ReferenceCountedObject_refCount.decrement() == 0) {
+ if (pointer->ReferenceCountedObject_refCount.decrement() == 0) {
// We held the last reference, so delete the object.
// This test is threadsafe because there is no way for
// the reference count to increase after the last
@@ -235,8 +206,8 @@ private:
// are cycles of weak references.
// Note that since there are no strong references at this point,
// it is perfectly fair to zero the weak pointers anyway.
- m_pointer->ReferenceCountedObject_zeroWeakPointers();
- delete m_pointer;
+ pointer->ReferenceCountedObject_zeroWeakPointers();
+ delete pointer;
}
m_pointer = NULL;
@@ -258,9 +229,10 @@ private:
// Note that the ref count can be zero if this is the
// first pointer to it
- debugAssertM(m_pointer->ReferenceCountedObject_refCount.value() >= 0,
+ ReferenceCountedObject* pointer = (ReferenceCountedObject*)m_pointer;
+ debugAssertM(pointer->ReferenceCountedObject_refCount.value() >= 0,
"Negative reference count detected.");
- m_pointer->ReferenceCountedObject_refCount.increment();
+ pointer->ReferenceCountedObject_refCount.increment();
}
}
}
@@ -314,10 +286,14 @@ public:
}
/** Allows construction from a raw pointer. That object will thereafter be
- reference counted -- do not call delete on it. */
- inline ReferenceCountedPointer(T* p) : m_pointer(NULL) {
- setPointer(p);
+ reference counted -- do not call delete on it.
+
+ Use of const allows downcast on const references */
+ inline ReferenceCountedPointer(const T* p) : m_pointer(NULL) {
+ // only const constructor is defined to remove ambiguity using NULL
+ setPointer(const_cast<T*>(p));
}
+
inline ~ReferenceCountedPointer() {
zeroPointer();
@@ -433,14 +409,11 @@ public:
return ReferenceCountedPointer<T>(pointer);
}
-
private:
- /**
- Thread issues: safe because this is only called when another
+ /** Thread issues: safe because this is only called when another
object is guaranteed to keep p alive for the duration of this
- call.
- */
+ call. */
void setPointer(T* p) {
// TODO: must prevent the object from being collected while in
// this method
@@ -448,7 +421,7 @@ private:
zeroPointer();
pointer = p;
- if (pointer != 0) {
+ if (pointer != NULL) {
// TODO: threadsafe: must update the list atomically
// Add myself to the head of my target's list of weak pointers
@@ -478,11 +451,11 @@ private:
// If the following test fails then the object was collected before we
// reached it.
if (strong.notNull()) {
- debugAssertM(pointer->ReferenceCountedObject_weakPointer != NULL,
+ debugAssertM(((ReferenceCountedObject*)pointer)->ReferenceCountedObject_weakPointer != NULL,
"Weak pointer exists without a backpointer from the object.");
// Remove myself from my target's list of weak pointers
- _WeakPtrLinkedList** node = &pointer->ReferenceCountedObject_weakPointer;
+ _WeakPtrLinkedList** node = &((ReferenceCountedObject*)pointer)->ReferenceCountedObject_weakPointer;
while ((*node)->weakPtr != this) {
node = &((*node)->next);
debugAssertM(*node != NULL,
@@ -583,7 +556,7 @@ public:
protected:
/** Invoked by the destructor on ReferenceCountedPointer. */
- virtual void objectCollected() {
+ void objectCollected() {
debugAssertM(pointer != NULL,
"Removed a weak pointer twice.");
pointer = NULL;
diff --git a/externals/g3dlite/G3D.lib/include/G3D/RegistryUtil.h b/externals/g3dlite/G3D/RegistryUtil.h
index 4b47be5f4bd..4b47be5f4bd 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/RegistryUtil.h
+++ b/externals/g3dlite/G3D/RegistryUtil.h
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Set.h b/externals/g3dlite/G3D/Set.h
index 629d802cdd4..9a8e1b619bb 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Set.h
+++ b/externals/g3dlite/G3D/Set.h
@@ -3,17 +3,18 @@
Hash set
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-12-09
- @edited 2006-02-20
+ @edited 2009-06-10
*/
-#ifndef G3D_SET_H
-#define G3D_SET_H
+#ifndef G3D_Set_h
+#define G3D_Set_h
#include "G3D/platform.h"
#include "G3D/Table.h"
+#include "G3D/MemoryManager.h"
#include <assert.h>
#include <string>
@@ -29,17 +30,21 @@ namespace G3D {
*/
// There is not copy constructor or assignment operator defined because
// the default ones are correct for Set.
-template<class T>
+template<class T, class HashFunc = HashTrait<T>, class EqualsFunc = EqualsTrait<T> >
class Set {
/**
If an object is a member, it is contained in
this table.
*/
- Table<T, bool> memberTable;
+ Table<T, bool, HashFunc, EqualsFunc> memberTable;
public:
+ void clearAndSetMemoryManager(const MemoryManager::Ref& m) {
+ memberTable.clearAndSetMemoryManager(m);
+ }
+
virtual ~Set() {}
int size() const {
@@ -58,11 +63,28 @@ public:
}
/**
- It is an error to remove members that are not already
- present.
+ Returns true if the element was present and removed. Returns false
+ if the element was not present.
+ */
+ bool remove(const T& member) {
+ return memberTable.remove(member);
+ }
+
+ /** If @a member is present, sets @a removed to the element
+ being removed and returns true. Otherwise returns false
+ and does not write to @a removed. This is useful when building
+ efficient hashed data structures that wrap Set.
+ */
+ bool getRemove(const T& member, T& removed) {
+ bool ignore;
+ return memberTable.getRemove(member, removed, ignore);
+ }
+
+ /** If a value that is EqualsFunc to @a member is present, returns a pointer to the
+ version stored in the data structure, otherwise returns NULL.
*/
- void remove(const T& member) {
- memberTable.remove(member);
+ const T* getPointer(const T& member) const {
+ return memberTable.getKeyPointer(member);
}
Array<T> getMembers() const {
@@ -100,6 +122,10 @@ public:
return !(*this == other);
}
+ bool hasMore() const {
+ return it.hasMore();
+ }
+
bool operator==(const Iterator& other) const {
return it == other.it;
}
diff --git a/externals/g3dlite/G3D/SmallArray.h b/externals/g3dlite/G3D/SmallArray.h
new file mode 100644
index 00000000000..41f9959e264
--- /dev/null
+++ b/externals/g3dlite/G3D/SmallArray.h
@@ -0,0 +1,155 @@
+/**
+ @file SmallArray.h
+
+ @created 2009-04-26
+ @edited 2009-04-26
+
+ Copyright 2000-2009, Morgan McGuire, http://graphics.cs.williams.edu
+ All rights reserved.
+ */
+#ifndef G3D_SmallArray_h
+#define G3D_SmallArray_h
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+
+namespace G3D {
+
+/** Embeds \a N elements to reduce allocation time and increase
+ memory coherence when working with arrays of arrays.
+ Offers a limited subset of the functionality of G3D::Array.*/
+template<class T, int N>
+class SmallArray {
+private:
+ int m_size;
+
+ /** First N elements */
+ T m_embedded[N];
+
+ /** Remaining elements */
+ Array<T> m_rest;
+
+public:
+
+ SmallArray() : m_size(0) {}
+
+ inline int size() const {
+ return m_size;
+ }
+
+ void resize(int n, bool shrinkIfNecessary = true) {
+ m_rest.resize(std::max(0, n - N), shrinkIfNecessary);
+ m_size = n;
+ }
+
+ void clear(bool shrinkIfNecessary = true) {
+ resize(0, shrinkIfNecessary);
+ }
+
+ inline T& operator[](int i) {
+ debugAssert(i < m_size && i >= 0);
+ if (i < N) {
+ return m_embedded[i];
+ } else {
+ return m_rest[i - N];
+ }
+ }
+
+ inline const T& operator[](int i) const {
+ debugAssert(i < m_size && i >= 0);
+ if (i < N) {
+ return m_embedded[i];
+ } else {
+ return m_rest[i - N];
+ }
+ }
+
+ inline void push(const T& v) {
+ ++m_size;
+ if (m_size <= N) {
+ m_embedded[m_size - 1] = v;
+ } else {
+ m_rest.append(v);
+ }
+ }
+
+ inline void append(const T& v) {
+ push(v);
+ }
+
+ void fastRemove(int i) {
+ debugAssert(i < m_size && i >= 0);
+ if (i < N) {
+ if (m_size <= N) {
+ // Exclusively embedded
+ m_embedded[i] = m_embedded[m_size - 1];
+ } else {
+ // Move one down from the rest array
+ m_embedded[i] = m_rest.pop();
+ }
+ } else {
+ // Removing from the rest array
+ m_rest.fastRemove(i - N);
+ }
+ --m_size;
+ }
+
+ T pop() {
+ debugAssert(m_size > 0);
+ if (m_size <= N) {
+ // Popping from embedded, don't need a temporary
+ --m_size;
+ return m_embedded[m_size];
+ } else {
+ // Popping from rest
+ --m_size;
+ return m_rest.pop();
+ }
+ }
+
+ inline void popDiscard() {
+ debugAssert(m_size > 0);
+ if (m_size > N) {
+ m_rest.popDiscard();
+ }
+ --m_size;
+ }
+
+ inline T& next() {
+ ++m_size;
+ if (m_size <= N) {
+ return m_embedded[m_size - 1];
+ } else {
+ return m_rest.next();
+ }
+ }
+
+ bool contains(const T& value) const {
+ for (int i = std::min(m_size, N) - 1; i >= 0; --i) {
+ if (m_embedded[i] == value) {
+ return true;
+ }
+ }
+ return m_rest.contains(value);
+ }
+
+ template<int MIN_ELEMENTS, int MIN_BYTES>
+ SmallArray<T, N>& operator=(const Array<T, MIN_ELEMENTS, MIN_BYTES>& src) {
+ resize(src.size());
+ for (int i = 0; i < src.size(); ++i) {
+ (*this)[i] = src[i];
+ }
+ return *this;
+ }
+
+ inline const T& last() const {
+ return (*this)[size() - 1];
+ }
+
+ inline T& last() {
+ return (*this)[size() - 1];
+ }
+};
+
+}
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Sphere.h b/externals/g3dlite/G3D/Sphere.h
index 7d4c412185d..595b61c4bf1 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Sphere.h
+++ b/externals/g3dlite/G3D/Sphere.h
@@ -3,7 +3,7 @@
Sphere class
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
@edited 2008-10-07
@@ -64,13 +64,15 @@ public:
*/
bool contains(const Vector3& point) const;
+ bool contains(const Sphere& other) const;
+
/**
@deprecated Use culledBy(Array<Plane>&)
*/
bool culledBy(
const class Plane* plane,
int numPlanes,
- int32& cullingPlaneIndex,
+ int32& cullingPlaneIndex,
const uint32 testMask,
uint32& childMask) const;
@@ -129,6 +131,9 @@ public:
Sphere operator-(const Vector3& v) const {
return Sphere(center - v, radius);
}
+
+ /** Sets this to the smallest sphere that encapsulates both */
+ void merge(const Sphere& s);
};
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Spline.h b/externals/g3dlite/G3D/Spline.h
index af9b08230b8..fdd29e69ce9 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Spline.h
+++ b/externals/g3dlite/G3D/Spline.h
@@ -1,7 +1,7 @@
/**
@file Spline.h
- @author Morgan McGuire, morgan@cs.williams.edu
+ @author Morgan McGuire, http://graphics.cs.williams.edu
*/
#ifndef G3D_SPLINE_H
@@ -62,8 +62,8 @@ public:
/**
Given a time @a s, finds @a i and 0 <= @a u < 1 such that
- @s = time[@a i] * @a u + time[@a i + 1] * (1 - @a u). Note that
- @i may be outside the bounds of the time and control arrays;
+ @a s = time[@a i] * @a u + time[@a i + 1] * (1 - @a u). Note that
+ @a i may be outside the bounds of the time and control arrays;
use getControl to handle wraparound and extrapolation issues.
This function takes expected O(1) time for control points with
@@ -274,10 +274,10 @@ protected:
method by one that wraps the values if they are angles or quaternions
for which "shortest path" interpolation is significant.
*/
- virtual void ensureShortestPath(Control* A, int N) const {}
+ virtual void ensureShortestPath(Control* A, int N) const { (void)A; (void) N;}
/** Normalize or otherwise adjust this interpolated Control. */
- virtual void correct(Control& A) const {}
+ virtual void correct(Control& A) const { (void)A; }
public:
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Stopwatch.h b/externals/g3dlite/G3D/Stopwatch.h
index aee3b0f69c9..3f2aa9c8d86 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Stopwatch.h
+++ b/externals/g3dlite/G3D/Stopwatch.h
@@ -1,17 +1,17 @@
/**
@file Stopwatch.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2005-10-05
- @edited 2005-10-05
+ @edited 2009-05-10
- Copyright 2000-2003, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_STOPWATCH_H
-#define G3D_STOPWATCH_H
+#ifndef G3D_Stopwatch_h
+#define G3D_Stopwatch_h
#include "G3D/platform.h"
#include "G3D/Queue.h"
@@ -21,10 +21,35 @@
namespace G3D {
/**
- Utility class for profiling duration and frame rates.
+ \brief Accurately measure durations and framerates.
+
+ Example 1: For profiling code in the context of a rendering loop:
+ <pre>
+ sw.tick();
+ ...timed code...
+ sw.tock();
+
+ screenPrintf("%f\n", sw.smoothFPS());
+ </pre>
+
+
+ Example 2: For profiling pieces of a sequence:
+ <pre>
+ Stopwatch sw;
+ slowOperation();
+ sw.after("slowOperation");
+ kdTree.balance();
+ sw.after("Balance tree");
+ </pre>
*/
class Stopwatch {
private:
+
+ std::string myName;
+ double startTime;
+ std::string prevMark;
+ double prevTime;
+
/** True between tick and tock */
bool inBetween;
@@ -58,7 +83,7 @@ private:
public:
- Stopwatch();
+ Stopwatch(const std::string& name = "Stopwatch");
/** Returns the number of times that tick was called per wall-clock second;
e.g. frames-per-second. */
@@ -99,8 +124,19 @@ public:
/** Call at the end of the period that you want timed. */
void tock();
+
+
+ /** Reset the start time used by after() and the emwa value.*/
+ void reset();
+
+ /** Call after an operation has completed, with the name of the operation, to
+ print a debug message listing the time since the previous after() call. */
+ void after(const std::string& s = "");
+
};
+/** Because it is hard to remember the proper capitalization. */
+typedef Stopwatch StopWatch;
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/System.h b/externals/g3dlite/G3D/System.h
index 3755dc5e36f..56ef9c8e3dc 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/System.h
+++ b/externals/g3dlite/G3D/System.h
@@ -1,8 +1,8 @@
-/**
+/**
@file System.h
-
- @maintainer Morgan McGuire, matrix@graphics3d.com
-
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
@cite Rob Wyatt http://www.gamasutra.com/features/wyatts_world/19990709/processor_detection_01.htm
@cite Benjamin Jurke http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-ProcessorDetectionClass&forum=cotd&id=-1
@cite Michael Herf http://www.stereopsis.com/memcpy.html
@@ -11,8 +11,8 @@
@edited 2008-10-14
*/
-#ifndef G3D_SYSTEM_H
-#define G3D_SYSTEM_H
+#ifndef G3D_System_h
+#define G3D_System_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
@@ -21,7 +21,7 @@
#include <string>
#ifdef G3D_OSX
-# include <CoreServices/CoreServices.h>
+# include <CoreServices/CoreServices.h>
#endif
namespace G3D {
@@ -29,29 +29,41 @@ namespace G3D {
/**
Routine used by the demos to find the data. Searches in
../data, ../../data, etc. up to 5 levels back. Checks
- common locations like c:\libraries\g3d-<version>\data
+ common locations like \verbatim c:\libraries\g3d-<version>\data \endverbatim
and some hard-coded paths on the Brown University file
system.
+
+ @deprecated
*/
std::string demoFindData(bool errorIfNotFound = true);
/** G3D, SDL, and IJG libraries require license documentation
to be distributed with your program. This generates the
- string that must appear in your documentation.
+ string that must appear in your documentation.
<B>Your program can be commercial, closed-source</B> under
- any license you want.*/
+ any license you want.
+ @deprecated Use System::license
+*/
std::string license();
/**
-The order in which the bytes of an integer are stored on a machine. Intel/AMD chips tend to be G3D_LITTLE_ENDIAN, Mac PPC's and Suns are G3D_BIG_ENDIAN. However, this is primarily used to specify the byte order of file formats, which are fixed.
+@brief The order in which the bytes of an integer are stored on a
+machine.
+
+Intel/AMD chips tend to be G3D_LITTLE_ENDIAN, Mac PPC's and Suns are
+G3D_BIG_ENDIAN. However, this is primarily used to specify the byte
+order of file formats, which are fixed.
*/
enum G3DEndian {
- G3D_BIG_ENDIAN, G3D_LITTLE_ENDIAN
+ G3D_BIG_ENDIAN,
+ G3D_LITTLE_ENDIAN
};
/**
- OS and processor abstraction. The first time any method is called the processor
- will be analyzed. Future calls are then fast.
+ @brief OS and processor abstraction.
+
+ The first time any method is called the processor will be analyzed.
+ Future calls are then fast.
Timing function overview:
System::getCycleCount
@@ -64,108 +76,203 @@ enum G3DEndian {
- High-resolution time in seconds since Jan 1, 1970
(because it is stored in a double, this may be less
accurate than getTick)
-
*/
class System {
public:
+ /**
+ @param size Size of memory that the system was trying to allocate
+
+ @param recoverable If true, the system will attempt to allocate again
+ if the callback returns true. If false, malloc is going to return
+ NULL and this invocation is just to notify the application.
+
+ @return Return true to force malloc to attempt allocation again if the
+ error was recoverable.
+ */
+ typedef bool (*OutOfMemoryCallback)(size_t size, bool recoverable);
+
+private:
- /** Called automatically by the other System routines.*/
- static void init();
-
- /** */
- static bool hasMMX();
-
- /** */
- static bool hasCPUID();
-
- /** */
- static bool hasSSE();
-
- /** */
- static bool hasSSE2();
-
- /** */
- static bool hasSSE3();
-
- /** */
- static bool has3DNow();
-
-
- /** */
- static bool hasRDTSC();
-
- static const std::string& cpuVendor();
-
- /** e.g. "Windows", "GNU/Linux" */
- static const std::string& operatingSystem();
-
- /** */
- static const std::string& cpuArchitecture();
+ bool m_initialized;
+ int m_cpuSpeed;
+ bool m_hasCPUID;
+ bool m_hasRDTSC;
+ bool m_hasMMX;
+ bool m_hasSSE;
+ bool m_hasSSE2;
+ bool m_hasSSE3;
+ bool m_has3DNOW;
+ bool m_has3DNOW2;
+ bool m_hasAMDMMX;
+ std::string m_cpuVendor;
+ int m_numCores;
+
+ /** this holds the data directory set by the application (currently
+ GApp) for use by findDataFile */
+ std::string m_appDataDir;
+
+ G3DEndian m_machineEndian;
+ std::string m_cpuArch;
+ std::string m_operatingSystem;
+
+# ifdef G3D_WIN32
+ /** Used by getTick() for timing */
+ LARGE_INTEGER m_start;
+ LARGE_INTEGER m_counterFrequency;
+#else
+ struct timeval m_start;
+#endif
+
+ std::string m_version;
+ OutOfMemoryCallback m_outOfMemoryCallback;
+
+#ifdef G3D_OSX
+ /** In Cycles/Second */
+ SInt32 m_OSXCPUSpeed;
+ double m_secondsPerNS;
+#endif
+
+ /** The Real-World time of System::getTick() time 0. Set by initTime */
+ RealTime m_realWorldGetTickTime0;
+
+ uint32 m_highestCPUIDFunction;
+
+ /** @brief Used for the singleton instance only. */
+ System();
+
+ /** @brief The singleton instance.
+
+ Used instead of a global variable to ensure that the order of
+ intialization is correct, which is critical because other
+ globals may allocate memory using System::malloc.
+ */
+ static System& instance();
+
+ enum CPUIDFunction {
+ CPUID_VENDOR_ID = 0x00000000,
+ CPUID_PROCESSOR_FEATURES = 0x00000001,
+ CPUID_NUM_CORES = 0x00000004,
+ CPUID_GET_HIGHEST_FUNCTION = 0x80000000,
+ CPUID_EXTENDED_FEATURES = 0x80000001};
+
+ /** Helper macro to call cpuid functions and return all values
+
+ See http://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/
+ or http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf
+
+ for description of the arguments.
+ */
+ static void cpuid(CPUIDFunction func, uint32& areg, uint32& breg, uint32& creg, uint32& dreg);
+
+ void init();
+
+ /** Called from init() */
+ void getStandardProcessorExtensions();
+
+ /** Called from init() */
+ void initTime();
+
+public:
+
+ /** Returns the speed of processor 0 in MHz.
+ Always returns 0 on linux.*/
+ inline static int cpuSpeedMHz() {
+ return instance().m_cpuSpeed;
+ }
+
+ /** Returns the number of logical processor cores (i.e., the
+ number of execution units for threads) */
+ inline static int numCores() {
+ return instance().m_numCores;
+ }
+
+ inline static bool hasCPUID() {
+ return instance().m_hasCPUID;
+ }
+
+ inline static bool hasRDTSC() {
+ return instance().m_hasRDTSC;
+ }
+
+ inline static bool hasSSE() {
+ return instance().m_hasSSE;
+ }
+
+ inline static bool hasSSE2() {
+ return instance().m_hasSSE2;
+ }
+
+ inline static bool hasSSE3() {
+ return instance().m_hasSSE3;
+ }
+
+ inline static bool hasMMX() {
+ return instance().m_hasMMX;
+ }
+
+ inline static bool has3DNow() {
+ return instance().m_has3DNOW;
+ }
+
+ inline static const std::string& cpuVendor() {
+ return instance().m_cpuVendor;
+ }
/**
Returns the endianness of this machine.
- */
- static G3DEndian machineEndian();
+ */
+ inline static G3DEndian machineEndian() {
+ return instance().m_machineEndian;
+ }
+
+ /** e.g., "Windows", "GNU/Linux" */
+ inline static const std::string& operatingSystem() {
+ return instance().m_operatingSystem;
+ }
+
+ /** e.g., 80686 */
+ inline static const std::string& cpuArchitecture() {
+ return instance().m_cpuArch;
+ }
/**
- Returns the current date as a string in the form YYYY-MM-DD
+ Returns the current date as a string in the form YYYY-MM-DD
*/
static std::string currentDateString();
/**
- Guarantees that the start of the array is aligned to the
- specified number of bytes.
- */
+ Guarantees that the start of the array is aligned to the
+ specified number of bytes.
+ */
static void* alignedMalloc(size_t bytes, size_t alignment);
/**
- Uses pooled storage to optimize small allocations (1 byte to 5 kilobytes).
- Can be 10x to 100x faster than calling ::malloc or new.
+ Uses pooled storage to optimize small allocations (1 byte to 5
+ kilobytes). Can be 10x to 100x faster than calling ::malloc or
+ new.
- The result must be freed with free.
+ The result must be freed with free.
- Threadsafe on Win32.
+ Threadsafe on Win32.
- @sa calloc realloc OutOfMemoryCallback free
- */
+ @sa calloc realloc OutOfMemoryCallback free
+ */
static void* malloc(size_t bytes);
static void* calloc(size_t n, size_t x);
/**
- @param size Size of memory that the system was trying to allocate
- @param recoverable If true, the system will attempt to allocate again
- if the callback returns true. If false, malloc is going to return
- NULL and this invocation is just to notify the application.
- @return Return true to force malloc to attempt allocation again if the
- error was recoverable.
- */
- typedef bool (*OutOfMemoryCallback)(size_t size, bool recoverable);
-
- /**
- When System::malloc fails to allocate memory because the system is
- out of memory, it invokes this handler (if it is not NULL).
- The argument to the callback is the amount of memory that malloc
- was trying to allocate when it ran out. If the callback returns
- true, System::malloc will attempt to allocate the memory again.
- If the callback returns false, then System::malloc will return NULL.
-
- You can use outOfMemoryCallback to free data structures or to
- register the failure.
- */
- static OutOfMemoryCallback outOfMemoryCallback;
-
- /**
Version of realloc that works with System::malloc.
*/
static void* realloc(void* block, size_t bytes);
- /** Returns a string describing how well System::malloc is using its internal pooled storage.
- "heap" memory was slow to allocate; the other data sizes are comparatively fast.*/
+ /** Returns a string describing how well System::malloc is using
+ its internal pooled storage. "heap" memory was slow to
+ allocate; the other data sizes are comparatively fast.*/
static std::string mallocPerformance();
static void resetMallocPerformanceCounters();
- /**
+ /**
Returns a string describing the current usage of the buffer pools used for
optimizing System::malloc.
*/
@@ -183,15 +290,15 @@ public:
*/
static void alignedFree(void* ptr);
- /** An implementation of memcpy that may be up to 2x as fast as the C library
- one on some processors. Guaranteed to have the same behavior as memcpy
- in all cases. */
- static void memcpy(void* dst, const void* src, size_t numBytes);
+ /** An implementation of memcpy that may be up to 2x as fast as the C library
+ one on some processors. Guaranteed to have the same behavior as memcpy
+ in all cases. */
+ static void memcpy(void* dst, const void* src, size_t numBytes);
- /** An implementation of memset that may be up to 2x as fast as the C library
- one on some processors. Guaranteed to have the same behavior as memset
- in all cases. */
- static void memset(void* dst, uint8 value, size_t numBytes);
+ /** An implementation of memset that may be up to 2x as fast as the C library
+ one on some processors. Guaranteed to have the same behavior as memset
+ in all cases. */
+ static void memset(void* dst, uint8 value, size_t numBytes);
/**
Returns the fully qualified filename for the currently running executable.
@@ -204,21 +311,27 @@ public:
*/
static std::string currentProgramFilename();
- /** Name of this program. Note that you can mutate this string to set your app name explicitly.*/
+ /** Name of this program. Note that you can mutate this string to
+ set your app name explicitly.*/
static std::string& appName();
/** G3D Version string */
- static const std::string& version();
+ inline static const std::string& version() {
+ return instance().m_version;
+ }
+
+ /**
+ @brief The optimization status of the G3D library (not the program compiled against it)
- /**
- Either Debug or Release, depending on whether _DEBUG was defined at compile-time for the library.
+ Either "Debug" or "Release", depending on whether _DEBUG was
+ defined at compile-time for the library.
*/
static const std::string& build();
/**
Causes the current thread to yield for the specified duration
and consume almost no CPU.
- The sleep will be extremely precise; it uses System::time()
+ The sleep will be extremely precise; it uses System::time()
to calibrate the exact yeild time.
*/
static void sleep(RealTime t);
@@ -234,7 +347,7 @@ public:
Console programs only.
*/
static bool consoleKeyPressed();
-
+
/**
Blocks until a key is read (use consoleKeyPressed to determine if
a key is waiting to be read) then returns the character code for
@@ -245,7 +358,7 @@ public:
/**
The actual time (measured in seconds since
Jan 1 1970 midnight).
-
+
Adjusted for local timezone and daylight savings
time. This is as accurate and fast as getCycleCount().
*/
@@ -260,16 +373,35 @@ public:
...
System::endCycleCount(count);
// count now contains the cycle count for the intervening operation.
-
+ </PRE>
*/
- static void beginCycleCount(uint64& cycleCount);
+ /* static void beginCycleCount(uint64& cycleCount);
static void endCycleCount(uint64& cycleCount);
- static uint64 getCycleCount();
+ static uint64 getCycleCount(); */
+
+ inline static void setOutOfMemoryCallback(OutOfMemoryCallback c) {
+ instance().m_outOfMemoryCallback = c;
+ }
+
+ /**
+ When System::malloc fails to allocate memory because the system is
+ out of memory, it invokes this handler (if it is not NULL).
+ The argument to the callback is the amount of memory that malloc
+ was trying to allocate when it ran out. If the callback returns
+ true, System::malloc will attempt to allocate the memory again.
+ If the callback returns false, then System::malloc will return NULL.
+
+ You can use outOfMemoryCallback to free data structures or to
+ register the failure.
+ */
+ inline static OutOfMemoryCallback outOfMemoryCallback() {
+ return instance().m_outOfMemoryCallback;
+ }
/** Set an environment variable for the current process */
static void setEnv(const std::string& name, const std::string& value);
-
+
/** Get an environment variable for the current process. Returns NULL if the variable doesn't exist. */
static const char* getEnv(const std::string& name);
@@ -283,11 +415,6 @@ public:
static void describeSystem(
std::string& s);
- /** Returns the speed of processor 0 in MHz.
- Always returns 0 on linux.*/
- static int cpuSpeedMHz();
-
-
/** On Win32, returns the clipboard text contents. Does nothing on other
platforms (yet) */
static std::string getClipboardText();
@@ -299,7 +426,7 @@ public:
Tries to locate the resource by looking in related directories.
If found, returns the full path to the resource, otherwise
returns the empty string.
- */
+ */
static std::string findDataFile(const std::string& full, bool errorIfNotFound = true);
/**
@@ -309,18 +436,9 @@ public:
*/
static void setAppDataDir(const std::string& path);
-private:
- /**
- (CKO) Note: Not sure why these are specifically needed
- for OS X. I made them private though.
- */
-# ifdef G3D_OSX
- static long m_OSXCPUSpeed; //In Cycles/Second
- static double m_secondsPerNS;
-# endif
};
-
+/* don't need that for MaNGOS, not portable to Win64...
#ifdef _MSC_VER
inline uint64 System::getCycleCount() {
uint32 timehi, timelo;
@@ -354,11 +472,11 @@ private:
#elif defined(G3D_OSX)
inline uint64 System::getCycleCount() {
- //Note: To put off extra processing until the end, this does not
+ //Note: To put off extra processing until the end, this does not
//return the actual clock cycle count. It is a bus cycle count.
//When endCycleCount() is called, it converts the two into a difference
//of clock cycles
-
+
return (uint64) UnsignedWideToUInt64(UpTime());
//return (uint64) mach_absolute_time();
}
@@ -371,19 +489,18 @@ inline void System::beginCycleCount(uint64& cycleCount) {
inline void System::endCycleCount(uint64& cycleCount) {
- #ifndef G3D_OSX
- cycleCount = getCycleCount() - cycleCount;
- #else
- AbsoluteTime end = UpTime();
- init();
- Nanoseconds diffNS =
- AbsoluteDeltaToNanoseconds(end, UInt64ToUnsignedWide(cycleCount));
- cycleCount =
- (uint64) ((double) (System::m_OSXCPUSpeed) *
- (double) UnsignedWideToUInt64(diffNS) * m_secondsPerNS);
- #endif
+#ifndef G3D_OSX
+ cycleCount = getCycleCount() - cycleCount;
+#else
+ AbsoluteTime end = UpTime();
+ Nanoseconds diffNS =
+ AbsoluteDeltaToNanoseconds(end, UInt64ToUnsignedWide(cycleCount));
+ cycleCount =
+ (uint64) ((double) (instance().m_OSXCPUSpeed) *
+ (double) UnsignedWideToUInt64(diffNS) * instance().m_secondsPerNS);
+#endif
}
-
+ */
} // namespace
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Table.h b/externals/g3dlite/G3D/Table.h
index 9ccd4f5c101..287efa94d97 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Table.h
+++ b/externals/g3dlite/G3D/Table.h
@@ -3,15 +3,15 @@
Templated hash table class.
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-04-22
- @edited 2008-07-01
- Copyright 2000-2008, Morgan McGuire.
+ @edited 2010-01-28
+ Copyright 2000-2010, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_TABLE_H
-#define G3D_TABLE_H
+#ifndef G3D_Table_h
+#define G3D_Table_h
#include <cstddef>
#include <string>
@@ -23,6 +23,7 @@
#include "G3D/g3dmath.h"
#include "G3D/EqualsTrait.h"
#include "G3D/HashTrait.h"
+#include "G3D/MemoryManager.h"
#ifdef _MSC_VER
# pragma warning (push)
@@ -35,6 +36,31 @@ namespace G3D {
/**
An unordered data structure mapping keys to values.
+ There are two ways of definining custom hash functions (G3D provides built-in ones for most classes):
+
+ <pre>
+ class Foo {
+ public:
+ std::string name;
+ int index;
+ static size_t hashCode(const Foo& key) {
+ return HashTrait<std::string>::hashCode(key.name) + key.index;
+ }
+ };
+
+ template<> struct HashTrait<class Foo> {
+ static size_t hashCode(const Foo& key) { return HashTrait<std::string>::hashCode(key.name) + key.index; }
+ };
+
+
+ // Use Foo::hashCode
+ Table<Foo, std::string, Foo> fooTable1;
+
+ // Use HashTrait<Foo>
+ Table<Foo, std::string> fooTable2;
+ </pre>
+
+
Key must be a pointer, an int, a std::string or provide overloads for:
<PRE>
@@ -83,7 +109,10 @@ public:
Key key;
Value value;
Entry() {}
+ Entry(const Key& k) : key(k) {}
Entry(const Key& k, const Value& v) : key(k), value(v) {}
+ bool operator==(const Entry &peer) const { return (key == peer.key && value == peer.value); }
+ bool operator!=(const Entry &peer) const { return !operator==(peer); }
};
private:
@@ -98,33 +127,48 @@ private:
Entry entry;
size_t hashCode;
Node* next;
-
- /** Provide pooled allocation for speed. */
- inline void* operator new (size_t size) {
- return System::malloc(size);
- }
-
- inline void operator delete (void* p) {
- System::free(p);
- }
+ private:
+
+ // Private to require use of the allocator
Node(const Key& k, const Value& v, size_t h, Node* n)
: entry(k, v), hashCode(h), next(n) {
}
+ Node(const Key& k, size_t h, Node* n)
+ : entry(k), hashCode(h), next(n) {
+ }
+
+ public:
+
+ static Node* create(const Key& k, const Value& v, size_t h, Node* n, MemoryManager::Ref& mm) {
+ Node* node = (Node*)mm->alloc(sizeof(Node));
+ return new (node) Node(k, v, h, n);
+ }
+
+ static Node* create(const Key& k, size_t hashCode, Node* n, MemoryManager::Ref& mm) {
+ Node* node = (Node*)mm->alloc(sizeof(Node));
+ return new (node) Node(k, hashCode, n);
+ }
+
+ static void destroy(Node* n, MemoryManager::Ref& mm) {
+ n->~Node();
+ mm->free(n);
+ }
+
/**
Clones a whole chain;
*/
- Node* clone() {
- return new Node(this->entry.key, this->entry.value, hashCode, (next == NULL) ? NULL : next->clone());
+ Node* clone(MemoryManager::Ref& mm) {
+ return create(this->entry.key, this->entry.value, hashCode, (next == NULL) ? NULL : next->clone(mm), mm);
}
};
void checkIntegrity() const {
# ifdef G3D_DEBUG
- debugAssert(bucket == NULL || isValidHeapPointer(bucket));
- for (size_t b = 0; b < numBuckets; ++b) {
- Node* node = bucket[b];
+ debugAssert(m_bucket == NULL || isValidHeapPointer(m_bucket));
+ for (size_t b = 0; b < m_numBuckets; ++b) {
+ Node* node = m_bucket[b];
debugAssert(node == NULL || isValidHeapPointer(node));
while (node != NULL) {
debugAssert(node == NULL || isValidHeapPointer(node));
@@ -134,47 +178,58 @@ private:
# endif
}
- /**
- Number of elements in the table.
- */
- size_t _size;
+ /** Number of elements in the table.*/
+ size_t m_size;
/**
Array of Node*.
- We don't use Array<Node*> because Table is lower level.
+
+ We don't use Array<Node*> because Table is lower-level than Array.
Some elements may be NULL.
*/
- Node** bucket;
+ Node** m_bucket;
/**
- Length of the bucket array.
+ Length of the m_bucket array.
*/
- size_t numBuckets;
+ size_t m_numBuckets;
+
+ MemoryManager::Ref m_memoryManager;
+
+ void* alloc(size_t s) const {
+ return m_memoryManager->alloc(s);
+ }
+
+ void free(void* p) const {
+ return m_memoryManager->free(p);
+ }
/**
- Re-hashes for a larger bucket size.
+ Re-hashes for a larger m_bucket size.
*/
void resize(size_t newSize) {
- // Hang onto the old bucket array
- Node** oldBucket = bucket;
+ // Hang onto the old m_bucket array
+ Node** oldBucket = m_bucket;
- // Allocate a new bucket array with the new size
- bucket = (Node**)System::calloc(sizeof(Node*), newSize);
- debugAssertM(bucket != NULL, "System::calloc returned NULL. Out of memory.");
+ // Allocate a new m_bucket array with the new size
+ m_bucket = (Node**)alloc(sizeof(Node*) * newSize);
+ // Set all pointers to NULL
+ System::memset(m_bucket, 0, newSize * sizeof(Node*));
+ debugAssertM(m_bucket != NULL, "MemoryManager::alloc returned NULL. Out of memory.");
// Move each node to its new hash location
- for (size_t b = 0; b < numBuckets; ++b) {
+ for (size_t b = 0; b < m_numBuckets; ++b) {
Node* node = oldBucket[b];
- // There is a linked list of nodes at this bucket
+ // There is a linked list of nodes at this m_bucket
while (node != NULL) {
// Hang onto the old next pointer
Node* nextNode = node->next;
- // Insert at the head of the list for bucket[i]
+ // Insert at the head of the list for m_bucket[i]
size_t i = node->hashCode % newSize;
- node->next = bucket[i];
- bucket[i] = node;
+ node->next = m_bucket[i];
+ m_bucket[i] = node;
// Move on to the next node
node = nextNode;
@@ -185,8 +240,8 @@ private:
}
// Delete the old storage
- System::free(oldBucket);
- this->numBuckets = newSize;
+ free(oldBucket);
+ this->m_numBuckets = newSize;
checkIntegrity();
}
@@ -197,14 +252,17 @@ private:
return;
}
- debugAssert(bucket == NULL);
- _size = h._size;
- numBuckets = h.numBuckets;
- bucket = (Node**)System::calloc(sizeof(Node*), numBuckets);
+ debugAssert(m_bucket == NULL);
+ m_size = h.m_size;
+ m_numBuckets = h.m_numBuckets;
+ m_bucket = (Node**)alloc(sizeof(Node*) * m_numBuckets);
+ // No need to NULL elements since we're about to overwrite them
- for (size_t b = 0; b < numBuckets; b++) {
- if (h.bucket[b] != NULL) {
- bucket[b] = h.bucket[b]->clone();
+ for (size_t b = 0; b < m_numBuckets; ++b) {
+ if (h.m_bucket[b] != NULL) {
+ m_bucket[b] = h.m_bucket[b]->clone(m_memoryManager);
+ } else {
+ m_bucket[b] = NULL;
}
}
@@ -217,40 +275,47 @@ private:
void freeMemory() {
checkIntegrity();
- for (size_t b = 0; b < numBuckets; b++) {
- Node* node = bucket[b];
+ for (size_t b = 0; b < m_numBuckets; b++) {
+ Node* node = m_bucket[b];
while (node != NULL) {
Node* next = node->next;
- delete node;
+ Node::destroy(node, m_memoryManager);
node = next;
}
- bucket[b] = NULL;
+ m_bucket[b] = NULL;
}
- System::free(bucket);
- bucket = NULL;
- numBuckets = 0;
- _size = 0;
+ free(m_bucket);
+ m_bucket = NULL;
+ m_numBuckets = 0;
+ m_size = 0;
}
-
public:
/**
- Creates an empty hash table. This causes some heap allocation to occur.
+ Creates an empty hash table using the default MemoryManager.
*/
- Table() : bucket(NULL) {
- numBuckets = 10;
- _size = 0;
- bucket = (Node**)System::calloc(sizeof(Node*), numBuckets);
+ Table() : m_bucket(NULL) {
+ m_memoryManager = MemoryManager::create();
+ m_numBuckets = 0;
+ m_size = 0;
+ m_bucket = NULL;
checkIntegrity();
}
+ /** Changes the internal memory manager to m */
+ void clearAndSetMemoryManager(const MemoryManager::Ref& m) {
+ clear();
+ debugAssert(m_bucket == NULL);
+ m_memoryManager = m;
+ }
+
/**
Recommends that the table resize to anticipate at least this number of elements.
*/
void setSizeHint(size_t n) {
size_t s = n * 3;
- if (s > numBuckets) {
+ if (s > m_numBuckets) {
resize(s);
}
}
@@ -265,10 +330,12 @@ public:
freeMemory();
}
+ /** Uses the default memory manager */
Table(const ThisType& h) {
- numBuckets = 0;
- _size = 0;
- bucket = NULL;
+ m_memoryManager = MemoryManager::create();
+ m_numBuckets = 0;
+ m_size = 0;
+ m_bucket = NULL;
this->copyFrom(h);
checkIntegrity();
}
@@ -286,14 +353,14 @@ public:
}
/**
- Returns the length of the deepest bucket.
+ Returns the length of the deepest m_bucket.
*/
size_t debugGetDeepestBucketSize() const {
size_t deepest = 0;
- for (size_t b = 0; b < numBuckets; b++) {
+ for (size_t b = 0; b < m_numBuckets; b++) {
size_t count = 0;
- Node* node = bucket[b];
+ Node* node = m_bucket[b];
while (node != NULL) {
node = node->next;
++count;
@@ -314,8 +381,8 @@ public:
size_t num = 0;
size_t count = 0;
- for (size_t b = 0; b < numBuckets; b++) {
- Node* node = bucket[b];
+ for (size_t b = 0; b < m_numBuckets; b++) {
+ Node* node = m_bucket[b];
if (node != NULL) {
++num;
while (node != NULL) {
@@ -343,7 +410,7 @@ public:
Returns the number of buckets.
*/
size_t debugGetNumBuckets() const {
- return numBuckets;
+ return m_numBuckets;
}
/**
@@ -363,8 +430,8 @@ public:
*/
Node* node;
ThisType* table;
- size_t numBuckets;
- Node** bucket;
+ size_t m_numBuckets;
+ Node** m_bucket;
bool isDone;
/**
@@ -374,19 +441,19 @@ public:
isDone = true;
}
- Iterator(const ThisType* table, size_t numBuckets, Node** bucket) :
+ Iterator(const ThisType* table, size_t m_numBuckets, Node** m_bucket) :
table(const_cast<ThisType*>(table)),
- numBuckets(numBuckets),
- bucket(bucket) {
+ m_numBuckets(m_numBuckets),
+ m_bucket(m_bucket) {
- if (numBuckets == 0) {
+ if (m_numBuckets == 0) {
// Empty table
isDone = true;
return;
}
index = 0;
- node = bucket[index];
+ node = m_bucket[index];
isDone = false;
findNext();
}
@@ -398,11 +465,11 @@ public:
void findNext() {
while (node == NULL) {
index++;
- if (index >= numBuckets) {
+ if (index >= m_numBuckets) {
isDone = true;
break;
} else {
- node = bucket[index];
+ node = m_bucket[index];
}
}
}
@@ -466,7 +533,7 @@ public:
the next element. Do not modify the table while iterating.
*/
Iterator begin() const {
- return Iterator(this, numBuckets, bucket);
+ return Iterator(this, m_numBuckets, m_bucket);
}
/**
@@ -482,9 +549,9 @@ public:
*/
void clear() {
freeMemory();
- numBuckets = 10;
- _size = 0;
- bucket = (Node**)System::calloc(sizeof(Node*), numBuckets);
+ m_numBuckets = 0;
+ m_size = 0;
+ m_bucket = NULL;
}
@@ -492,7 +559,7 @@ public:
Returns the number of keys.
*/
size_t size() const {
- return _size;
+ return m_size;
}
@@ -502,80 +569,21 @@ public:
key into a table is O(1), but may cause a potentially slow rehashing.
*/
void set(const Key& key, const Value& value) {
- size_t code = HashFunc::hashCode(key);
- size_t b = code % numBuckets;
-
- // Go to the bucket
- Node* n = bucket[b];
-
- // No bucket, so this must be the first
- if (n == NULL) {
- bucket[b] = new Node(key, value, code, NULL);
- ++_size;
- return;
- }
-
- size_t bucketLength = 1;
-
- // Sometimes a bad hash code will cause all elements
- // to collide. Detect this case and don't rehash when
- // it occurs; nothing good will come from the rehashing.
- bool allSameCode = true;
-
- // Try to find the node
- do {
- allSameCode = allSameCode && (code == n->hashCode);
-
- if ((code == n->hashCode) && EqualsFunc::equals(n->entry.key, key)) {
- // Replace the existing node.
- n->entry.value = value;
- return;
- }
-
- n = n->next;
- ++bucketLength;
- } while (n != NULL);
-
- const size_t maxBucketLength = 3;
- // (Don't bother changing the size of the table if all entries
- // have the same hashcode--they'll still collide)
- if ((bucketLength > maxBucketLength) &&
- ! allSameCode &&
- (numBuckets < _size * 15)) {
+ getCreateEntry(key).value = value;
+ }
- // This bucket was really large; rehash if all elements
- // don't have the same hashcode the number of buckets is
- // reasonable.
+private:
- // Back off the scale factor as the number of buckets gets
- // large
- float f = 3.0f;
- if (numBuckets > 1000000) {
- f = 1.5f;
- } else if (numBuckets > 100000) {
- f = 2.0f;
- }
- int newSize = iMax((int)(numBuckets * f) + 1, (int)(_size * f));
- resize(newSize);
+ /** Helper for remove() and getRemove() */
+ bool remove(const Key& key, Key& removedKey, Value& removedValue, bool updateRemoved) {
+ if (m_numBuckets == 0) {
+ return false;
}
-
- // Not found; insert at the head.
- b = code % numBuckets;
- bucket[b] = new Node(key, value, code, bucket[b]);
- ++_size;
- }
-
- /**
- Removes an element from the table if it is present.
- @return true if the element was found and removed, otherwise false
- */
- bool remove(const Key& key) {
-
size_t code = HashFunc::hashCode(key);
- size_t b = code % numBuckets;
+ size_t b = code % m_numBuckets;
- // Go to the bucket
- Node* n = bucket[b];
+ // Go to the m_bucket
+ Node* n = m_bucket[b];
if (n == NULL) {
return false;
@@ -590,14 +598,18 @@ public:
// Replace the previous's next pointer
if (previous == NULL) {
- bucket[b] = n->next;
+ m_bucket[b] = n->next;
} else {
previous->next = n->next;
}
+ if (updateRemoved) {
+ removedKey = n->entry.key;
+ removedValue = n->entry.value;
+ }
// Delete the node
- delete n;
- --_size;
+ Node::destroy(n, m_memoryManager);
+ --m_size;
return true;
}
@@ -605,33 +617,73 @@ public:
n = n->next;
} while (n != NULL);
-
return false;
//alwaysAssertM(false, "Tried to remove a key that was not in the table.");
}
- /**
- Returns the value associated with key.
- @deprecated Use get(key, val) or getPointer(key)
+public:
+
+ /** If @a member is present, sets @a removed to the element
+ being removed and returns true. Otherwise returns false
+ and does not write to @a removed. */
+ bool getRemove(const Key& key, Key& removedKey, Value& removedValue) {
+ return remove(key, removedKey, removedValue, true);
+ }
+
+ /**
+ Removes an element from the table if it is present.
+ @return true if the element was found and removed, otherwise false
*/
- Value& get(const Key& key) const {
+ bool remove(const Key& key) {
+ Key x;
+ Value v;
+ return remove(key, x, v, false);
+ }
+
+private:
+
+ Entry* getEntryPointer(const Key& key) const {
+ if (m_numBuckets == 0) {
+ return NULL;
+ }
size_t code = HashFunc::hashCode(key);
- size_t b = code % numBuckets;
+ size_t b = code % m_numBuckets;
- Node* node = bucket[b];
+ Node* node = m_bucket[b];
- while (node != NULL) {
- if ((node->hashCode == code) && EqualsFunc::equals(node->entry.key, key)) {
- return node->entry.value;
- }
- node = node->next;
- }
+ while (node != NULL) {
+ if ((node->hashCode == code) && EqualsFunc::equals(node->entry.key, key)) {
+ return &(node->entry);
+ }
+ node = node->next;
+ }
+
+ return NULL;
+ }
+
+public:
+
+ /** If a value that is EqualsFunc to @a member is present, returns a pointer to the
+ version stored in the data structure, otherwise returns NULL.
+ */
+ const Key* getKeyPointer(const Key& key) const {
+ const Entry* e = getEntryPointer(key);
+ if (e == NULL) {
+ return NULL;
+ } else {
+ return &(e->key);
+ }
+ }
- debugAssertM(false, "Key not found");
- // The next line is here just to make
- // a compiler warning go away.
- return node->entry.value;
+ /**
+ Returns the value associated with key.
+ @deprecated Use get(key, val) or getPointer(key)
+ */
+ Value& get(const Key& key) const {
+ Entry* e = getEntryPointer(key);
+ debugAssertM(e != NULL, "Key not found");
+ return e->value;
}
@@ -646,12 +698,16 @@ public:
pointer errors.
*/
Value* getPointer(const Key& key) const {
+ if (m_numBuckets == 0) {
+ return NULL;
+ }
+
size_t code = HashFunc::hashCode(key);
- size_t b = code % numBuckets;
+ size_t b = code % m_numBuckets;
- Node* node = bucket[b];
+ Node* node = m_bucket[b];
- while (node != NULL) {
+ while (node != NULL) {
if ((node->hashCode == code) && EqualsFunc::equals(node->entry.key, key)) {
// found key
return &(node->entry.value);
@@ -677,14 +733,113 @@ public:
}
}
+
+
+ /** Called by getCreate() and set()
+
+ \param created Set to true if the entry was created by this method.
+ */
+ Entry& getCreateEntry(const Key& key, bool& created) {
+ created = false;
+
+ if (m_numBuckets == 0) {
+ resize(10);
+ }
+
+ size_t code = HashFunc::hashCode(key);
+ size_t b = code % m_numBuckets;
+
+ // Go to the m_bucket
+ Node* n = m_bucket[b];
+
+ // No m_bucket, so this must be the first
+ if (n == NULL) {
+ m_bucket[b] = Node::create(key, code, NULL, m_memoryManager);
+ ++m_size;
+ created = true;
+ return m_bucket[b]->entry;
+ }
+
+ size_t bucketLength = 1;
+
+ // Sometimes a bad hash code will cause all elements
+ // to collide. Detect this case and don't rehash when
+ // it occurs; nothing good will come from the rehashing.
+ bool allSameCode = true;
+
+ // Try to find the node
+ do {
+ allSameCode = allSameCode && (code == n->hashCode);
+
+ if ((code == n->hashCode) && EqualsFunc::equals(n->entry.key, key)) {
+ // This is the a pre-existing node
+ return n->entry;
+ }
+
+ n = n->next;
+ ++bucketLength;
+ } while (n != NULL);
+
+ const size_t maxBucketLength = 3;
+ // (Don't bother changing the size of the table if all entries
+ // have the same hashcode--they'll still collide)
+ if ((bucketLength > maxBucketLength) &&
+ ! allSameCode &&
+ (m_numBuckets < m_size * 15)) {
+
+ // This m_bucket was really large; rehash if all elements
+ // don't have the same hashcode the number of buckets is
+ // reasonable.
+
+ // Back off the scale factor as the number of buckets gets
+ // large
+ float f = 3.0f;
+ if (m_numBuckets > 1000000) {
+ f = 1.5f;
+ } else if (m_numBuckets > 100000) {
+ f = 2.0f;
+ }
+ int newSize = iMax((int)(m_numBuckets * f) + 1, (int)(m_size * f));
+ resize(newSize);
+ }
+
+ // Not found; insert at the head.
+ b = code % m_numBuckets;
+ m_bucket[b] = Node::create(key, code, m_bucket[b], m_memoryManager);
+ ++m_size;
+ created = true;
+ return m_bucket[b]->entry;
+ }
+
+ Entry& getCreateEntry(const Key& key) {
+ bool ignore;
+ return getCreateEntry(key, ignore);
+ }
+
+
+ /** Returns the current value that key maps to, creating it if necessary.*/
+ Value& getCreate(const Key& key) {
+ return getCreateEntry(key).value;
+ }
+
+ /** \param created True if the element was created. */
+ Value& getCreate(const Key& key, bool& created) {
+ return getCreateEntry(key, created).value;
+ }
+
+
/**
Returns true if key is in the table.
*/
bool containsKey(const Key& key) const {
+ if (m_numBuckets == 0) {
+ return false;
+ }
+
size_t code = HashFunc::hashCode(key);
- size_t b = code % numBuckets;
+ size_t b = code % m_numBuckets;
- Node* node = bucket[b];
+ Node* node = m_bucket[b];
while (node != NULL) {
if ((node->hashCode == code) && EqualsFunc::equals(node->entry.key, key)) {
@@ -704,7 +859,6 @@ public:
return get(key);
}
-
/**
Returns an array of all of the keys in the table.
You can iterate over the keys to get the values.
@@ -718,8 +872,8 @@ public:
void getKeys(Array<Key>& keyArray) const {
keyArray.resize(0, DONT_SHRINK_UNDERLYING_ARRAY);
- for (size_t i = 0; i < numBuckets; i++) {
- Node* node = bucket[i];
+ for (size_t i = 0; i < m_numBuckets; i++) {
+ Node* node = m_bucket[i];
while (node != NULL) {
keyArray.append(node->entry.key);
node = node->next;
@@ -731,8 +885,8 @@ public:
Calls delete on all of the keys and then clears the table.
*/
void deleteKeys() {
- for (size_t i = 0; i < numBuckets; i++) {
- Node* node = bucket[i];
+ for (size_t i = 0; i < m_numBuckets; i++) {
+ Node* node = m_bucket[i];
while (node != NULL) {
delete node->entry.key;
node = node->next;
@@ -750,8 +904,8 @@ public:
of NULL pointers.
*/
void deleteValues() {
- for (size_t i = 0; i < numBuckets; ++i) {
- Node* node = bucket[i];
+ for (size_t i = 0; i < m_numBuckets; ++i) {
+ Node* node = m_bucket[i];
while (node != NULL) {
delete node->entry.value;
node->entry.value = NULL;
diff --git a/externals/g3dlite/G3D.lib/include/G3D/TextInput.h b/externals/g3dlite/G3D/TextInput.h
index b6dcad39b8b..33eb8c48e53 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/TextInput.h
+++ b/externals/g3dlite/G3D/TextInput.h
@@ -3,23 +3,24 @@
Simple text lexer/tokenizer.
- @maintainer Morgan McGuire, morgan@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Based on a lexer written by Aaron Orenstein.
@created 2002-11-27
- @edited 2006-10-24
+ @edited 2009-11-24
- Copyright 2000-2007, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_TEXTINPUT_H
-#define G3D_TEXTINPUT_H
+#ifndef G3D_TextInput_h
+#define G3D_TextInput_h
#include "G3D/platform.h"
#include "G3D/Array.h"
#include "G3D/Set.h"
+#include "G3D/ParseError.h"
#include <string>
#include <queue>
#include <ctype.h>
@@ -43,6 +44,9 @@ public:
FLOATING_POINT_TYPE,
INTEGER_TYPE,
BOOLEAN_TYPE,
+ LINE_COMMENT_TYPE,
+ BLOCK_COMMENT_TYPE,
+ NEWLINE_TYPE,
END_TYPE
};
@@ -53,7 +57,9 @@ public:
STRING = DOUBLE_QUOTED_TYPE,
SYMBOL = SYMBOL_TYPE,
NUMBER = FLOATING_POINT_TYPE,
- BOOLEAN = BOOLEAN_TYPE,
+ BOOLEAN = BOOLEAN_TYPE,
+ COMMENT = LINE_COMMENT_TYPE,
+ NEWLINE = NEWLINE_TYPE,
END = END_TYPE
};
@@ -142,12 +148,15 @@ public:
recognized operator:
<ul>
- <li><CODE>Token::SINGLE_QUOTED_TYPE</CODE> string of characters surrounded by single quotes, e.g., 'x', '\0', 'foo'.
+ <li><CODE>Token::SINGLE_QUOTED_TYPE</CODE> string of characters surrounded by single quotes, e.g., 'x', '\\0', 'foo'.
<li><CODE>Token::DOUBLE_QUOTED_TYPE</CODE> string of characters surrounded by double quotes, e.g., "x", "abc\txyz", "b o b".
<li><CODE>Token::SYMBOL_TYPE</CODE> legal C++ operators, keywords, and identifiers. e.g., >=, Foo, _X, class, {
<li><CODE>Token::INTEGER_TYPE</CODE> numbers without decimal places or exponential notation. e.g., 10, 0x17F, 32, 0, -155
<li><CODE>Token::FLOATING_POINT_TYPE</CODE> numbers with decimal places or exponential notation. e.g., 1e3, -1.2, .4, 0.5
<li><CODE>Token::BOOLEAN_TYPE</CODE> special symbols like "true" and "false"; the exact details can be configured in TextInput::Settings
+ <li><CODE>Token::LINE_COMMENT_TYPE</CODE> (disabled by default); generated for line comments as specified by TextInput::Settings
+ <li><CODE>Token::BLOCK_COMMENT_TYPE</CODE> (disabled by default); generated for c-style block comments as specified by TextInput::Settings
+ <li><CODE>Token::NEWLINE_TYPE</CODE> (disabled by default); generated for any of "\\r", "\\n" or "\\r\\n"
</ul>
<P>The special ".." and "..." tokens are always recognized in
@@ -163,9 +172,9 @@ public:
Color3.
Inside quoted strings escape sequences are converted. Thus the
- string token for ["a\nb"] is 'a', followed by a newline, followed by
+ string token for ["a\\nb"] is 'a', followed by a newline, followed by
'b'. Outside of quoted strings, escape sequences are not converted,
- so the token sequence for [a\nb] is symbol 'a', symbol '\', symbol
+ so the token sequence for [a\\nb] is symbol 'a', symbol '\\', symbol
'nb' (this matches what a C++ parser would do). The exception is
that a specified TextInput::Settings::otherCommentCharacter preceeded
by a backslash is assumed to be an escaped comment character and is
@@ -207,38 +216,74 @@ public:
/** Tokenizer configuration options. */
class Settings {
public:
- /** If true, slash-star marks a multi-line comment. Default
- is true. */
- bool cComments;
+ /** If true, C-style slash-star marks a multi-line comment.
- /** If true, // begins a single line comment. Default is true. */
- bool cppComments;
+ See generateCommentTokens for rules on how this is applied.
- /** If true, \r, \n, \t, \0, \\ and other escape sequences inside
+ Default is true.
+ */
+ bool cppBlockComments;
+
+ /** If true, // begins a single line comment.
+
+ See generateCommentTokens for rules on how this is applied.
+
+ Default is true.
+ */
+ bool cppLineComments;
+
+ /** If true, otherCommentCharacter and otherCommentCharacter2
+ are used to begin single line comments in the same way
+ cppLineComments is.
+
+ See generateCommentTokens for rules on how this is applied.
+
+ Default is true.
+ */
+ bool otherLineComments;
+
+ /** If true, \\r, \\n, \\t, \\0, \\\\ and other escape sequences inside
strings are converted to the equivalent C++ escaped character.
If false, backslashes are treated literally. It is convenient to
set to false if reading Windows paths, for example, like
- c:\foo\bar.
+ c:\\foo\\bar.
Default is true.
*/
bool escapeSequencesInStrings;
- /** If non-NUL, specifies a character that begins single line
+ /** If not '\\0', specifies a character that begins single line
comments ('#' and '%' are popular choices). This is independent
- of the cppComments flag. If the character appears in text with a
- backslash in front of it, it is considered escaped and is not
+ of the cppLineComments flag. If the character appears in text with
+ a backslash in front of it, it is considered escaped and is not
treated as a comment character.
- Default is '\0'.
+ Default is '\\0'.
*/
char otherCommentCharacter;
/** Another (optional) 1-comment character. Useful for files that
- support multiple comment syntaxes. Default is '\0'.
+ support multiple comment syntaxes. Default is '\\0'.
*/
char otherCommentCharacter2;
+ /** If true, comments enabled by cppBlockComments, cppLineComments
+ and otherLineComments will generate their respective tokens.
+ If false, the same settings will enable parsing and ignoring
+ comments
+
+ Default is false.
+ */
+ bool generateCommentTokens;
+
+ /** If true, newlines will generate tokens.
+ If false, newlines will be discarded as whitespace when parsed
+ outside of other tokens.
+
+ Default is false.
+ */
+ bool generateNewlineTokens;
+
/** If true, "-1" parses as the number -1 instead of the
symbol "-" followed by the number 1. Default is true.*/
bool signedNumbers;
@@ -248,6 +293,11 @@ public:
symbol. Default is true. Backquote (`) is always parsed
as a symbol. */
bool singleQuotedStrings;
+
+ /** The character to use as a single quote. Defaults to "'" (backquote),
+ occasionally useful to set to "`" (forward quote) or to "," (comma) for
+ reading CSV files. */
+ char singleQuoteCharacter;
/** If set to a non-empty string, that string will be used in
place of the real file name (or in place of a pseudonym
@@ -327,7 +377,7 @@ public:
/** See trueSymbols. Default is {false}*/
Set<std::string> falseSymbols;
- Settings ();
+ Settings();
};
private:
@@ -343,7 +393,7 @@ private:
Offset of current character (the next character to consumed) in
input buffer.
*/
- unsigned int currentCharOffset;
+ int currentCharOffset;
/**
Line number of next character to be consumed from the input buffer. (1
@@ -353,7 +403,7 @@ private:
consumed from the input, not the line number of the @e last character
consumed!
*/
- unsigned int lineNumber;
+ int lineNumber;
/**
Character number (within the line) of the next character to be consumed
@@ -363,7 +413,7 @@ private:
consumed from the input, not the character number of the @e last
character consumed!
*/
- unsigned int charNumber;
+ int charNumber;
/** Configuration options. This includes the file name that will be
reported in tokens and exceptions. */
@@ -393,7 +443,7 @@ private:
relative to the next character. Default is 0, for the next character in
the input buffer.
*/
- int peekInputChar(unsigned int distance = 0);
+ int peekInputChar(int distance = 0);
/**
Helper function to consume the next character in the input buffer and
@@ -410,36 +460,23 @@ private:
*/
Token nextToken();
- /**
- Helper for nextToken. Appends characters to t._string until the end
- delimiter is reached.
-
- When called, the next character in the input buffer should be first the
- first character after the opening delimiter character.
- */
- void parseQuotedString(unsigned char delimiter, Token& t);
+ /**
+ Helper for nextToken. Appends characters to t._string until the end
+ delimiter is reached.
+
+ When called, the next character in the input buffer should be first the
+ first character after the opening delimiter character.
+ */
+ void parseQuotedString(unsigned char delimiter, Token& t);
public:
- class TokenException {
+ class TokenException : public ParseError {
public:
- /** Name of file being parsed when exception occurred. */
- std::string sourceFile;
-
- /** Line number of start of token which caused the exception. 1 is
- the first line of the file. Note that you can use
- TextInput::Settings::startingLineNumberOffset to shift the effective line
- number that is reported.
- */
- int line;
-
- /** Character number in the line of start of token which caused the
- exception. 1 is the character in the line.
+ /** Name of file being parsed when exception occurred.
+ \deprecated Use filename
*/
- int character;
-
- /** Pre-formatted error message */
- std::string message;
+ std::string sourceFile;
virtual ~TokenException() {}
@@ -452,7 +489,7 @@ public:
};
- /** While parsing a number of the form 1.#IN?00, ? was
+ /** While parsing a number of the form 1.\#IN?00, ? was
not 'D' or 'F'. */
class BadMSVCSpecial : public TokenException {
public:
@@ -533,6 +570,8 @@ public:
*/
Token read();
+ /** Calls read() until the result is not a newline or comment */
+ Token readSignificant();
/** Read one token (or possibly two) as a number or throws
WrongTokenType, and returns the number.
@@ -587,6 +626,75 @@ public:
*/
void readString(const std::string& s);
+ /** Reads a comment token or throws WrongTokenType, and returns the token.
+
+ Use this method (rather than readComment) if you want the token's
+ location as well as its value.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a comment. When an exception is thrown, no tokens are
+ consumed.
+ */
+ Token readCommentToken();
+
+ /** Like readCommentToken, but returns the token's string.
+
+ Use this method (rather than readCommentToken) if you want the token's
+ value but don't really care about its location in the input. Use of
+ readCommentToken is encouraged for better error reporting.
+ */
+ std::string readComment();
+
+ /** Reads a specific comment token or throws either WrongTokenType or
+ WrongString. If the next token in the input is a comment matching @p
+ s, it will be consumed.
+
+ Use this method if you want to match a specific comment from the
+ input. In that case, typically error reporting related to the token
+ is only going to occur because of a mismatch, so no location
+ information is needed by the caller.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a comment. WrongString will be thrown if the next token in the
+ input stream is a comment but does not match the @p s parameter. When
+ an exception is thrown, no tokens are consumed.
+ */
+ void readComment(const std::string& s);
+
+ /** Reads a newline token or throws WrongTokenType, and returns the token.
+
+ Use this method (rather than readNewline) if you want the token's
+ location as well as its value.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a newline. When an exception is thrown, no tokens are
+ consumed.
+ */
+ Token readNewlineToken();
+
+ /** Like readNewlineToken, but returns the token's string.
+
+ Use this method (rather than readNewlineToken) if you want the token's
+ value but don't really care about its location in the input. Use of
+ readNewlineToken is encouraged for better error reporting.
+ */
+ std::string readNewline();
+
+ /** Reads a specific newline token or throws either WrongTokenType or
+ WrongString. If the next token in the input is a newline matching @p
+ s, it will be consumed.
+
+ Use this method if you want to match a specific newline from the
+ input. In that case, typically error reporting related to the token
+ is only going to occur because of a mismatch, so no location
+ information is needed by the caller.
+
+ WrongTokenType will be thrown if the next token in the input stream
+ is not a newline. WrongString will be thrown if the next token in the
+ input stream is a newlin but does not match the @p s parameter. When
+ an exception is thrown, no tokens are consumed.
+ */
+ void readNewline(const std::string& s);
/** Reads a symbol token or throws WrongTokenType, and returns the token.
@@ -675,7 +783,7 @@ public:
/** Returns the filename from which this input is drawn, or the first few
characters of the string if created from a string.
- If options::filename is non-empty that will replace the
+ If settings::filename is non-empty that will replace the
true filename.*/
const std::string& filename() const;
};
diff --git a/externals/g3dlite/G3D.lib/include/G3D/TextOutput.h b/externals/g3dlite/G3D/TextOutput.h
index 6ae7d14fe00..4c22b7d5653 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/TextOutput.h
+++ b/externals/g3dlite/G3D/TextOutput.h
@@ -1,7 +1,7 @@
/**
@file TextOutput.h
- @maintainer Morgan McGuire, morgan@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2004-06-21
@edited 2006-10-24
@@ -69,7 +69,7 @@ public:
WRAP_ALWAYS Wrap even if it means breaking a continuous line or
a quoted string.
- Word wrapping is only allowed at whitespaces ('\n', '\r', '\t', ' '); it
+ Word wrapping is only allowed at whitespaces ('\\n', '\\r', '\\t', ' '); it
will not occur after commas, punctuation, minus signs, or any other characters
*/
enum WordWrapMode {WRAP_NONE, WRAP_WITHOUT_BREAKING, WRAP_ALWAYS};
@@ -193,7 +193,7 @@ public:
/** Produces a new string that contains the output */
std::string commitString();
- /** Writes a quoted string. Special characters in the string (e.g., \, \t, \n) are escaped so that
+ /** Writes a quoted string. Special characters in the string (e.g., \\, \\t, \\n) are escaped so that
TextInput will produce the identical string on reading.*/
void writeString(const std::string& string);
diff --git a/externals/g3dlite/G3D.lib/include/G3D/ThreadSet.h b/externals/g3dlite/G3D/ThreadSet.h
index 59c57b062ae..121f1415a1d 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/ThreadSet.h
+++ b/externals/g3dlite/G3D/ThreadSet.h
@@ -5,6 +5,7 @@
#include "G3D/Array.h"
#include "G3D/ReferenceCount.h"
#include "G3D/GThread.h"
+#include "G3D/GMutex.h"
namespace G3D {
@@ -38,8 +39,15 @@ public:
/** Number of threads that have been started */
int numStarted() const;
- /** Start all threads that are not currently started */
- void start() const;
+ /** Start all threads that are not currently started.
+
+ @param lastThreadBehavior If USE_CURRENT_THREAD, takes the last unstarted thread and executes it manually on
+ the current thread. This helps to take full advantage of the machine when
+ running a large number of jobs and avoids the overhead of a thread start for single-thread groups.
+ Note that this forces start() to block until
+ that thread is complete.
+ */
+ void start(GThread::SpawnBehavior lastThreadBehavior = GThread::USE_NEW_THREAD) const;
/** Terminate all threads that are currently started */
void terminate() const;
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Triangle.h b/externals/g3dlite/G3D/Triangle.h
index 8b67acf4624..590dbaad946 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Triangle.h
+++ b/externals/g3dlite/G3D/Triangle.h
@@ -1,14 +1,14 @@
/**
@file Triangle.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-04-05
@edited 2008-10-06
@cite Random point method by Greg Turk, Generating random points in triangles. In A. S. Glassner, ed., Graphics Gems, pp. 24-28. Academic Press, 1990
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -98,11 +98,13 @@ public:
/** Returns a random point in the triangle. */
Vector3 randomPoint() const;
- inline void getRandomSurfacePoint(Vector3& P,
- Vector3& N = Vector3::dummy) const {
+ inline void getRandomSurfacePoint
+ (Vector3& P,
+ Vector3& N = Vector3::ignore()) const {
P = randomPoint();
N = normal();
}
+
/**
For two triangles to be equal they must have
the same vertices <I>in the same order</I>.
@@ -127,6 +129,21 @@ public:
void getBounds(class AABox&) const;
+ /**
+ @brief Intersect the ray at distance less than @a distance.
+
+ @param distance Set to the maximum distance (can be G3D::inf())
+ to search for an intersection. On return, this is the smaller
+ of the distance to the intersection, if one exists, and the original
+ value.
+
+ @param baryCoord If a triangle is hit before @a distance, a
+ the barycentric coordinates of the hit location on the triangle.
+ Otherwise, unmodified.
+
+ @return True if there was an intersection before the original distance.
+ */
+ bool intersect(const class Ray& ray, float& distance, float baryCoord[3]) const;
};
} // namespace G3D
diff --git a/externals/g3dlite/G3D.lib/include/G3D/UprightFrame.h b/externals/g3dlite/G3D/UprightFrame.h
index 52db3080b80..ad5157cb14b 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/UprightFrame.h
+++ b/externals/g3dlite/G3D/UprightFrame.h
@@ -1,7 +1,7 @@
/**
@file UprightFrame.h
- @author Morgan McGuire, morgan@cs.williams.edu
+ @author Morgan McGuire, http://graphics.cs.williams.edu
*/
#ifndef G3D_UPRIGHTFRAME_H
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Vector2.h b/externals/g3dlite/G3D/Vector2.h
index b610a1a3500..dba7353785e 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Vector2.h
+++ b/externals/g3dlite/G3D/Vector2.h
@@ -3,12 +3,12 @@
2D vector class
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
@edited 2008-11-30
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -22,12 +22,14 @@
#include "G3D/Table.h"
#include "G3D/HashTrait.h"
#include "G3D/Vector2int16.h"
+#include "G3D/Random.h"
namespace G3D {
class Vector2;
class Vector3;
class Vector4;
+class Any;
/**
Do not subclass-- this implementation makes assumptions about the
@@ -45,6 +47,12 @@ public:
float x;
float y;
+ /** \param any Must either Vector2(#, #) or Vector2 {x = #, y = #}*/
+ Vector2(const Any& any);
+
+ /** Converts the Vector2 to an Any. */
+ operator Any() const;
+
/** Creates the zero vector */
Vector2();
Vector2(class TextInput& t);
@@ -53,7 +61,7 @@ public:
Vector2(float coordinate[2]);
Vector2(double coordinate[2]);
Vector2(const Vector2& other);
- Vector2(const class Vector2int16& other);
+ Vector2(const Vector2int16& other);
void serialize(class BinaryOutput& b) const;
void deserialize(class BinaryInput& b);
@@ -63,8 +71,6 @@ public:
float& operator[](int i);
const float& operator[](int i) const;
- operator float*();
- operator const float*() const;
// assignment and comparison
Vector2& operator=(const Vector2& other);
@@ -159,12 +165,12 @@ public:
Vector2 max(const Vector2& v) const;
/** Uniformly distributed random vector on the unit sphere */
- static Vector2 random();
+ static Vector2 random(Random& r = Random::common());
// Special values.
// Intentionally not inlined: see Matrix3::identity() for details.
static const Vector2& zero();
- inline static const Vector2& one() { static const Vector2 v(1, 1); return v; }
+ static const Vector2& one();
static const Vector2& unitX();
static const Vector2& unitY();
static const Vector2& inf();
@@ -269,15 +275,6 @@ inline const float& Vector2::operator[] (int i) const {
}
-inline Vector2::operator float* () {
- return (float*)this;
-}
-
-inline Vector2::operator const float* () const {
- return (float*)this;
-}
-
-
inline Vector2& Vector2::operator= (const Vector2& rkVector) {
x = rkVector.x;
y = rkVector.y;
diff --git a/externals/g3dlite/G3D/Vector2.inl b/externals/g3dlite/G3D/Vector2.inl
new file mode 100644
index 00000000000..4f7c55a39cf
--- /dev/null
+++ b/externals/g3dlite/G3D/Vector2.inl
@@ -0,0 +1,18 @@
+/**
+ @file Vector2.inl
+
+ @maintainer Morgan McGuire, matrix@graphics3d.com
+ @cite Portions by Laura Wollstadt, graphics3d.com
+
+ @cite Portions based on Dave Eberly'x Magic Software Library
+ at http://www.magic-software.com
+
+ @created 2001-06-02
+ @edited 2006-01-14
+
+ Copyright 2000-2006, Morgan McGuire.
+ All rights reserved.
+ */
+
+}
+
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Vector2int16.h b/externals/g3dlite/G3D/Vector2int16.h
index b7149ad6c90..ba72266d75a 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Vector2int16.h
+++ b/externals/g3dlite/G3D/Vector2int16.h
@@ -20,13 +20,10 @@
namespace G3D {
/**
+ \class Vector2int16
A Vector2 that packs its fields into uint16s.
*/
-#ifdef G3D_WIN32
- // Switch to tight alignment
- #pragma pack(push, 2)
-#endif
-
+G3D_BEGIN_PACKED_CLASS(2)
class Vector2int16 {
private:
// Hidden operators
@@ -119,14 +116,7 @@ public:
void serialize(class BinaryOutput& bo) const;
void deserialize(class BinaryInput& bi);
}
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- __attribute((aligned(1)))
-#endif
-;
-
-#ifdef G3D_WIN32
- #pragma pack(pop)
-#endif
+G3D_END_PACKED_CLASS(2)
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Vector3.h b/externals/g3dlite/G3D/Vector3.h
index d37638a229d..4825efb9985 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Vector3.h
+++ b/externals/g3dlite/G3D/Vector3.h
@@ -3,19 +3,20 @@
3D vector class
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
- @edited 2008-11-01
- Copyright 2000-2008, Morgan McGuire.
+ @edited 2009-11-01
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_VECTOR3_H
-#define G3D_VECTOR3_H
+#ifndef G3D_Vector3_h
+#define G3D_Vector3_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
+#include "G3D/Random.h"
#include "G3D/Vector2.h"
#include "G3D/Table.h"
#include "G3D/HashTrait.h"
@@ -24,25 +25,13 @@
#include <iostream>
#include <string>
-//----------------------------------------------------------------------------
-#ifdef SSE
- // If you receive an error on this line, it is because you do not have the file
- // xmmintrin.h needed for MMX & SSE extensions. Download and install
- //
- // http://download.microsoft.com/download/vstudio60ent/SP5/Wideband-Full/WIN98Me/EN-US/vs6sp5.exe
- // and
- // http://download.microsoft.com/download/vb60ent/Update/6/W9X2KXP/EN-US/vcpp5.exe
- //
- // to get this file.
-# include <xmmintrin.h>
-#endif
-
namespace G3D {
-class Vector2;
-class Vector3;
+class Vector2;
class Vector4;
class Vector4int8;
+class Vector3int32;
+class Any;
/**
<B>Swizzles</B>
@@ -66,24 +55,12 @@ j = b.xx();
memory layout.
*/
class Vector3 {
-private:
- /**
- Reflect this vector about the (not necessarily unit) normal.
- Note that if used for a collision or ray reflection you
- must negate the resulting vector to get a direction pointing
- <I>away</I> from the collision.
+public:
- <PRE>
- V' N V
-
- r ^ -,
- \ | /
- \|/
- </PRE>
+ // coordinates
+ float x, y, z;
- See also Vector3::reflectionDirection
- */
- Vector3 reflectAbout(const Vector3& normal) const;
+private:
// Hidden operators
bool operator<(const Vector3&) const;
@@ -92,19 +69,26 @@ private:
bool operator>=(const Vector3&) const;
public:
- // construction
+ /** Initializes to zero */
Vector3();
+ /** \param any Must either Vector3(#, #, #) or Vector3 {x = #, y = #, z = #}*/
+ Vector3(const Any& any);
+
+ /** Converts the Vector3 to an Any. */
+ operator Any() const;
+
/** Divides by 127 */
Vector3(const Vector4int8&);
+ Vector3(const class Vector3int32& v);
explicit Vector3(class BinaryInput& b);
Vector3(float _x, float _y, float _z);
explicit Vector3(const class Vector2& v, float _z);
explicit Vector3(float coordinate[3]);
explicit Vector3(double coordinate[3]);
- Vector3(const Vector3& rkVector);
Vector3(const class Vector3int16& v);
explicit Vector3(class TextInput& t);
+ explicit Vector3(const class Color3& c);
/** Format is three float32's */
void serialize(class BinaryOutput& b) const;
@@ -113,26 +97,15 @@ public:
/** Format is "(%f, %f, %f)" */
void serialize(class TextOutput& t) const;
void deserialize(class TextInput& t);
-
- // coordinates
- float x, y, z;
// access vector V as V[0] = V.x, V[1] = V.y, V[2] = V.z
//
// WARNING. These member functions rely on
// (1) Vector3 not having virtual functions
// (2) the data packed in a 3*sizeof(float) memory block
- const float& operator[] (int i) const;
+ const float& __fastcall operator[] (int i) const;
float& operator[] (int i);
- inline operator float* () {
- return (float*)this;
- }
-
- operator const float* () const {
- return (float*)this;
- }
-
enum Axis {X_AXIS=0, Y_AXIS=1, Z_AXIS=2, DETECT_AXIS=-1};
/**
@@ -142,7 +115,7 @@ public:
Axis primaryAxis() const;
// assignment and comparison
- Vector3& operator= (const Vector3& rkVector);
+ Vector3& __fastcall operator= (const Vector3& rkVector);
bool operator== (const Vector3& rkVector) const;
bool operator!= (const Vector3& rkVector) const;
size_t hashCode() const;
@@ -159,21 +132,25 @@ public:
bool isUnit() const;
// arithmetic operations
- Vector3 operator+ (const Vector3& v) const;
- Vector3 operator- (const Vector3& v) const;
- Vector3 operator* (float s) const;
- Vector3 operator/ (float s) const;
- Vector3 operator* (const Vector3& v) const;
- Vector3 operator/ (const Vector3& v) const;
- Vector3 operator- () const;
+ Vector3 __fastcall operator+ (const Vector3& v) const;
+ Vector3 __fastcall operator- (const Vector3& v) const;
+ Vector3 __fastcall operator* (float s) const;
+ inline Vector3 __fastcall operator/ (float s) const {
+ return *this * (1.0f / s);
+ }
+ Vector3 __fastcall operator* (const Vector3& v) const;
+ Vector3 __fastcall operator/ (const Vector3& v) const;
+ Vector3 __fastcall operator- () const;
// arithmetic updates
- Vector3& operator+= (const Vector3& v);
- Vector3& operator-= (const Vector3& v);
- Vector3& operator*= (float s);
- Vector3& operator/= (float s);
- Vector3& operator*= (const Vector3& v);
- Vector3& operator/= (const Vector3& v);
+ Vector3& __fastcall operator+= (const Vector3& v);
+ Vector3& __fastcall operator-= (const Vector3& v);
+ Vector3& __fastcall operator*= (float s);
+ inline Vector3& __fastcall operator/= (float s) {
+ return (*this *= (1.0f / s));
+ }
+ Vector3& __fastcall operator*= (const Vector3& v);
+ Vector3& __fastcall operator/= (const Vector3& v);
/** Same as magnitude */
float length() const;
@@ -191,6 +168,26 @@ public:
*/
Vector3 fastDirection() const;
+ /**
+ Reflect this vector about the (not necessarily unit) normal.
+ Assumes that both the before and after vectors point away from
+ the base of the normal.
+
+ Note that if used for a collision or ray reflection you
+ must negate the resulting vector to get a direction pointing
+ <I>away</I> from the collision.
+
+ <PRE>
+ V' N V
+
+ r ^ -,
+ \ | /
+ \|/
+ </PRE>
+
+ See also Vector3::reflectionDirection
+ */
+ Vector3 reflectAbout(const Vector3& normal) const;
/**
See also G3D::Ray::reflect.
@@ -269,15 +266,15 @@ public:
float squaredMagnitude () const;
- float dot(const Vector3& rkVector) const;
+ float __fastcall dot(const Vector3& rkVector) const;
float unitize(float tolerance = 1e-06);
/** Cross product. Note that two cross products in a row
can be computed more cheaply: v1 x (v2 x v3) = (v1 dot v3) v2 - (v1 dot v2) v3.
*/
- Vector3 cross(const Vector3& rkVector) const;
- Vector3 unitCross (const Vector3& rkVector) const;
+ Vector3 __fastcall cross(const Vector3& rkVector) const;
+ Vector3 unitCross(const Vector3& rkVector) const;
/**
Returns a matrix such that v.cross() * w = v.cross(w).
@@ -289,8 +286,8 @@ public:
*/
class Matrix3 cross() const;
- Vector3 min(const Vector3 &v) const;
- Vector3 max(const Vector3 &v) const;
+ Vector3 __fastcall min(const Vector3 &v) const;
+ Vector3 __fastcall max(const Vector3 &v) const;
/** Smallest element */
inline float min() const {
@@ -328,26 +325,56 @@ public:
/** Gram-Schmidt orthonormalization. */
static void orthonormalize (Vector3 akVector[3]);
- /** Random unit vector, uniformly distributed */
- static Vector3 random();
+ /** \brief Random unit vector, uniformly distributed on the sphere.
+
+ Distribution rendered by G3D::DirectionHistogram:
+ \image html vector3-random.png
+ */
+ static Vector3 random(Random& r = Random::common());
+
+ /** \brief Random unit vector, distributed according to \f$\max(\cos \theta,0)\f$.
+
+ That is, so that the probability of \f$\vec{V}\f$ is proportional
+ to \f$\max(\vec{v} \cdot \vec{n}, 0)\f$. Useful in photon mapping for
+ Lambertian scattering.
+
+ Distribution rendered by G3D::DirectionHistogram:
+ \image html vector3-coshemirandom.png
- /** Random unit vector, distributed
- so that the probability of V is proportional
- to max(V dot Normal, 0).
+ \param n Unit vector at the center of the distribution.
@cite Henrik Wann Jensen, Realistic Image Synthesis using Photon Mapping eqn 2.24
*/
- static Vector3 cosRandom(const Vector3& normal);
+ static Vector3 cosHemiRandom(const Vector3& n, Random& r = Random::common());
+ /** \brief Random unit vector, distributed according to \f$\max(\cos^k \theta,0)\f$.
+
+ That is, so that the probability of \f$\vec{V}\f$ is
+ proportional to \f$\max((\vec{v} \cdot \vec{n})^k, 0)\f$.
+ Useful in photon mapping for glossy scattering.
+
+ Distribution rendered by G3D::DirectionHistogram:
+ \image html vector3-cospowhemirandom.png
+
+ \param n Unit vector at the center of the distribution.
+
+ @cite Ashikhmin and Shirley, An anisotropic Phong BRDF model, Journal of Graphics Tools, 2002
+ */
+ static Vector3 cosPowHemiRandom(const Vector3& n, const float k, Random& r = Random::common());
/**
- Random vector distributed over the hemisphere about normal.
+ \brief Random vector distributed over the hemisphere about normal.
+
+ Distribution rendered by G3D::DirectionHistogram:
+ \image html vector3-hemirandom.png
*/
- static Vector3 hemiRandom(const Vector3& normal);
+ static Vector3 hemiRandom(const Vector3& normal, Random& r = Random::common());
- // Input W must be initialize to a nonzero vector, output is {U,V,W}
- // an orthonormal basis. A hint is provided about whether or not W
- // is already unit length.
+ /** Input W must be initialize to a nonzero vector, output is {U,V,W}
+ an orthonormal basis. A hint is provided about whether or not W
+ is already unit length.
+ @deprecated Use getTangents
+ */
static void generateOrthonormalBasis (Vector3& rkU, Vector3& rkV,
Vector3& rkW, bool bUnitLengthW = true);
@@ -360,17 +387,37 @@ public:
}
// Special values.
- inline static const Vector3& zero() { static Vector3 v(0, 0, 0); return v; }
- inline static const Vector3& one() { static Vector3 v(1, 1, 1); return v; }
- inline static const Vector3& unitX() { static Vector3 v(1, 0, 0); return v; }
- inline static const Vector3& unitY() { static Vector3 v(0, 1, 0); return v; }
- inline static const Vector3& unitZ() { static Vector3 v(0, 0, 1); return v; }
- inline static const Vector3& inf() { static Vector3 v((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); return v; }
- inline static const Vector3& nan() { static Vector3 v((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); return v; }
+ static const Vector3& zero();
+ static const Vector3& one();
+ static const Vector3& unitX();
+ static const Vector3& unitY();
+ static const Vector3& unitZ();
+ static const Vector3& inf();
+ static const Vector3& nan();
+
/** Smallest (most negative) representable vector */
- inline static const Vector3& minFinite(){ static Vector3 v(-FLT_MAX, -FLT_MAX, -FLT_MAX); return v; }
+ static const Vector3& minFinite();
+
/** Largest representable vector */
- inline static const Vector3& maxFinite(){ static Vector3 v(FLT_MAX, FLT_MAX, FLT_MAX); return v; }
+ static const Vector3& maxFinite();
+
+
+ /** Creates two orthonormal tangent vectors X and Y such that
+ if Z = this, X x Y = Z.*/
+ inline void getTangents(Vector3& X, Vector3& Y) const {
+ debugAssertM(G3D::fuzzyEq(length(), 1.0f),
+ "makeAxes requires Z to have unit length");
+
+ // Choose another vector not perpendicular
+ X = (abs(x) < 0.9f) ? Vector3::unitX() : Vector3::unitY();
+
+ // Remove the part that is parallel to Z
+ X -= *this * this->dot(X);
+ X /= X.length();
+
+ Y = this->cross(X);
+ }
+
// 2-char swizzles
@@ -498,8 +545,8 @@ public:
Vector4 yzzz() const;
Vector4 zzzz() const;
- /** A value that can be passed to ignore a parameter. Never look at the result of dummy. */
- static Vector3 dummy;
+ /** Can be passed to ignore a vector3 parameter */
+ static Vector3& ignore();
};
inline G3D::Vector3 operator*(float s, const G3D::Vector3& v) {
@@ -533,22 +580,12 @@ inline Vector3::Vector3 (float fX, float fY, float fZ) : x(fX), y(fY), z(fZ) {
//----------------------------------------------------------------------------
inline Vector3::Vector3 (float V[3]) : x(V[0]), y(V[1]), z(V[2]){
}
-//----------------------------------------------------------------------------
-inline Vector3::Vector3 (double V[3]) : x((float)V[0]), y((float)V[1]), z((float)V[2]){
-}
//----------------------------------------------------------------------------
-inline Vector3::Vector3 (const Vector3& V) : x(V.x), y(V.y), z(V.z) {
+inline Vector3::Vector3 (double V[3]) : x((float)V[0]), y((float)V[1]), z((float)V[2]){
}
//----------------------------------------------------------------------------
-
-//inline Vector3::Vector3 (const __m128& m) {
- // Cast from SSE packed floats
-// *this = *(Vector3*)&m;
-//}
-
-//----------------------------------------------------------------------------
inline const float& Vector3::operator[] (int i) const {
return ((float*)this)[i];
}
@@ -675,7 +712,7 @@ inline float Vector3::squaredLength () const {
//----------------------------------------------------------------------------
inline float Vector3::magnitude() const {
- return sqrtf(x*x + y*y + z*z);
+ return ::sqrtf(x*x + y*y + z*z);
}
//----------------------------------------------------------------------------
@@ -685,8 +722,8 @@ inline float Vector3::length() const {
//----------------------------------------------------------------------------
inline Vector3 Vector3::direction () const {
- float lenSquared = squaredMagnitude();
- float invSqrt = 1.0f / sqrtf(lenSquared);
+ const float lenSquared = squaredMagnitude();
+ const float invSqrt = 1.0f / sqrtf(lenSquared);
return Vector3(x * invSqrt, y * invSqrt, z * invSqrt);
}
diff --git a/externals/g3dlite/G3D/Vector3.inl b/externals/g3dlite/G3D/Vector3.inl
new file mode 100644
index 00000000000..9211c2a70fd
--- /dev/null
+++ b/externals/g3dlite/G3D/Vector3.inl
@@ -0,0 +1,249 @@
+/**
+ @file Vector3.inl
+
+ @maintainer Morgan McGuire, matrix@graphics3d.com
+
+ @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
+
+ @created 2001-06-02
+ @edited 2004-05-21
+ Copyright 2000-2004, Morgan McGuire.
+ All rights reserved.
+ */
+
+//----------------------------------------------------------------------------
+#ifdef SSE
+ // If you receive an error on this line, it is because you do not have the file
+ // xmmintrin.h needed for MMX & SSE extensions. Download and install
+ //
+ // http://download.microsoft.com/download/vstudio60ent/SP5/Wideband-Full/WIN98Me/EN-US/vs6sp5.exe
+ // and
+ // http://download.microsoft.com/download/vb60ent/Update/6/W9X2KXP/EN-US/vcpp5.exe
+ //
+ // to get this file.
+# include <xmmintrin.h>
+#endif
+
+inline unsigned int hashCode(const G3D::Vector3& v) {
+ return v.hashCode();
+}
+
+namespace G3D {
+
+//----------------------------------------------------------------------------
+inline Vector3::Vector3() : x(0.0f), y(0.0f), z(0.0f) {
+}
+
+//----------------------------------------------------------------------------
+
+inline Vector3::Vector3 (float fX, float fY, float fZ) : x(fX), y(fY), z(fZ) {
+}
+
+//----------------------------------------------------------------------------
+inline Vector3::Vector3 (float V[3]) : x(V[0]), y(V[1]), z(V[2]){
+}
+//----------------------------------------------------------------------------
+inline Vector3::Vector3 (double V[3]) : x((float)V[0]), y((float)V[1]), z((float)V[2]){
+}
+
+//----------------------------------------------------------------------------
+inline Vector3::Vector3 (const Vector3& V) : x(V.x), y(V.y), z(V.z) {
+}
+
+//----------------------------------------------------------------------------
+
+//inline Vector3::Vector3 (const __m128& m) {
+ // Cast from SSE packed floats
+// *this = *(Vector3*)&m;
+//}
+
+//----------------------------------------------------------------------------
+inline const float& Vector3::operator[] (int i) const {
+ return ((float*)this)[i];
+}
+
+inline float& Vector3::operator[] (int i) {
+ return ((float*)this)[i];
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator= (const Vector3& rkVector) {
+ x = rkVector.x;
+ y = rkVector.y;
+ z = rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector3::fuzzyEq(const Vector3& other) const {
+ return G3D::fuzzyEq((*this - other).squaredMagnitude(), 0);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector3::fuzzyNe(const Vector3& other) const {
+ return G3D::fuzzyNe((*this - other).squaredMagnitude(), 0);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector3::isFinite() const {
+ return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z);
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector3::operator== (const Vector3& rkVector) const {
+ return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector3::operator!= (const Vector3& rkVector) const {
+ return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator+ (const Vector3& rkVector) const {
+ return Vector3(x + rkVector.x, y + rkVector.y, z + rkVector.z);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator- (const Vector3& rkVector) const {
+ return Vector3(x - rkVector.x, y - rkVector.y, z - rkVector.z);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator* (const Vector3& rkVector) const {
+ return Vector3(x * rkVector.x, y * rkVector.y, z * rkVector.z);
+}
+
+inline Vector3 Vector3::operator*(float f) const {
+ return Vector3(x * f, y * f, z * f);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator/ (const Vector3& rkVector) const {
+ return Vector3(x / rkVector.x, y / rkVector.y, z / rkVector.z);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::operator- () const {
+ return Vector3(-x, -y, -z);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator+= (const Vector3& rkVector) {
+ x += rkVector.x;
+ y += rkVector.y;
+ z += rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator-= (const Vector3& rkVector) {
+ x -= rkVector.x;
+ y -= rkVector.y;
+ z -= rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator*= (float fScalar) {
+ x *= fScalar;
+ y *= fScalar;
+ z *= fScalar;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator*= (const Vector3& rkVector) {
+ x *= rkVector.x;
+ y *= rkVector.y;
+ z *= rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3& Vector3::operator/= (const Vector3& rkVector) {
+ x /= rkVector.x;
+ y /= rkVector.y;
+ z /= rkVector.z;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::squaredMagnitude () const {
+ return x*x + y*y + z*z;
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::squaredLength () const {
+ return squaredMagnitude();
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::magnitude() const {
+ return sqrtf(x*x + y*y + z*z);
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::length() const {
+ return magnitude();
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::direction () const {
+ float lenSquared = squaredMagnitude();
+ float invSqrt = 1.0f / sqrtf(lenSquared);
+ return Vector3(x * invSqrt, y * invSqrt, z * invSqrt);
+}
+
+//----------------------------------------------------------------------------
+
+inline Vector3 Vector3::fastDirection () const {
+ float lenSquared = x * x + y * y + z * z;
+ float invSqrt = rsq(lenSquared);
+ return Vector3(x * invSqrt, y * invSqrt, z * invSqrt);
+}
+
+//----------------------------------------------------------------------------
+inline float Vector3::dot (const Vector3& rkVector) const {
+ return x*rkVector.x + y*rkVector.y + z*rkVector.z;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::cross (const Vector3& rkVector) const {
+ return Vector3(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z,
+ x*rkVector.y - y*rkVector.x);
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::unitCross (const Vector3& rkVector) const {
+ Vector3 kCross(y*rkVector.z - z*rkVector.y, z*rkVector.x - x*rkVector.z,
+ x*rkVector.y - y*rkVector.x);
+ kCross.unitize();
+ return kCross;
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::min(const Vector3 &v) const {
+ return Vector3(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z));
+}
+
+//----------------------------------------------------------------------------
+inline Vector3 Vector3::max(const Vector3 &v) const {
+ return Vector3(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z));
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector3::isZero() const {
+ return G3D::fuzzyEq(squaredMagnitude(), 0.0f);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector3::isUnit() const {
+ return G3D::fuzzyEq(squaredMagnitude(), 1.0f);
+}
+
+} // namespace
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Vector3int16.h b/externals/g3dlite/G3D/Vector3int16.h
index f3f30a5bab4..3197ea49d1a 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Vector3int16.h
+++ b/externals/g3dlite/G3D/Vector3int16.h
@@ -16,16 +16,20 @@
#include "G3D/g3dmath.h"
#include "G3D/HashTrait.h"
+#ifdef _MSC_VER
+// Turn off "conditional expression is constant" warning; MSVC generates this
+// for debug assertions in inlined methods.
+#pragma warning (disable : 4127)
+#endif
+
+
namespace G3D {
/**
+ \class Vector3int16
A Vector3 that packs its fields into uint16s.
*/
-#ifdef G3D_WIN32
- // Switch to tight alignment
- #pragma pack(push, 2)
-#endif
-
+G3D_BEGIN_PACKED_CLASS(2)
class Vector3int16 {
private:
// Hidden operators
@@ -70,7 +74,7 @@ public:
}
inline Vector3int16 operator*(const int s) const {
- return Vector3int16(x * s, y * s, z * s);
+ return Vector3int16(int16(x * s), int16(y * s), int16(z * s));
}
inline Vector3int16& operator+=(const Vector3int16& other) {
@@ -103,23 +107,16 @@ public:
}
Vector3int16 max(const Vector3int16& v) const {
- return Vector3int16(iMax(x, v.x), iMax(y, v.y), iMax(z, v.z));
+ return Vector3int16(std::max(x, v.x), std::max(y, v.y), std::max(z, v.z));
}
Vector3int16 min(const Vector3int16& v) const {
- return Vector3int16(iMin(x, v.x), iMin(y, v.y), iMin(z, v.z));
+ return Vector3int16(std::min(x, v.x), std::min(y, v.y), std::min(z, v.z));
}
std::string toString() const;
}
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- __attribute((aligned(1)))
-#endif
-;
-
-#ifdef G3D_WIN32
- #pragma pack(pop)
-#endif
+G3D_END_PACKED_CLASS(2)
}
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Vector3int32.h b/externals/g3dlite/G3D/Vector3int32.h
index 01c8581b47a..2f256ea0300 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Vector3int32.h
+++ b/externals/g3dlite/G3D/Vector3int32.h
@@ -5,7 +5,7 @@
@created 2008-07-01
@edited 2008-07-01
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
@@ -19,13 +19,10 @@
namespace G3D {
/**
+ \ Vector3int32
A Vector3 that packs its fields into uint32s.
*/
-#ifdef G3D_WIN32
- // Switch to tight alignment
- #pragma pack(push, 4)
-#endif
-
+G3D_BEGIN_PACKED_CLASS(4)
class Vector3int32 {
private:
// Hidden operators
@@ -113,21 +110,14 @@ public:
std::string toString() const;
}
-#if defined(G3D_LINUX) || defined(G3D_OSX)
- __attribute((aligned(1)))
-#endif
-;
-
-#ifdef G3D_WIN32
- #pragma pack(pop)
-#endif
+G3D_END_PACKED_CLASS(4)
}
template <> struct HashTrait<G3D::Vector3int32> {
static size_t hashCode(const G3D::Vector3int32& key) {
// Mask for the top bit of a uint32
- const G3D::uint32 top = (1 << 31);
+ const G3D::uint32 top = (1UL << 31);
// Mask for the bottom 10 bits of a uint32
const G3D::uint32 bot = 0x000003FF;
return static_cast<size_t>(((key.x & top) | ((key.y & top) >> 1) | ((key.z & top) >> 2)) |
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Vector4.h b/externals/g3dlite/G3D/Vector4.h
index d60ff76ea8b..5e511451f86 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Vector4.h
+++ b/externals/g3dlite/G3D/Vector4.h
@@ -3,17 +3,17 @@
Homogeneous vector class.
- @maintainer Morgan McGuire, morgan@cs.williams.edu
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2002-07-09
@edited 2008-11-01
- Copyright 2000-2008, Morgan McGuire.
+ Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_VECTOR4_H
-#define G3D_VECTOR4_H
+#ifndef G3D_Vector4_h
+#define G3D_Vector4_h
#include "G3D/platform.h"
#include "G3D/g3dmath.h"
@@ -30,6 +30,7 @@ class Vector2;
class Vector3;
class Vector4;
class Vector4int8;
+class Any;
/**
Do not subclass-- this implementation makes assumptions about the
@@ -44,6 +45,13 @@ private:
bool operator>=(const Vector4&) const;
public:
+
+ /** \param any Must either Vector4(#, #, #, #) or Vector3 {x = #, y = #, z = #, w =#}*/
+ Vector4(const Any& any);
+
+ /** Converts the Vector4 to an Any. */
+ operator Any() const;
+
// construction
Vector4();
Vector4(float fX, float fY, float fZ, float fW);
@@ -71,14 +79,14 @@ public:
// (2) the data packed in a 4*sizeof(float) memory block
float& operator[] (int i);
const float& operator[] (int i) const;
- operator float* ();
- operator const float* () const;
// assignment and comparison
Vector4& operator= (const Vector4& rkVector);
bool operator== (const Vector4& rkVector) const;
bool operator!= (const Vector4& rkVector) const;
+ static const Vector4& zero();
+
inline void set(float _x, float _y, float _z, float _w) {
x = _x;
y = _y;
@@ -104,8 +112,8 @@ public:
bool fuzzyEq(const Vector4& other) const;
bool fuzzyNe(const Vector4& other) const;
- inline static const Vector4& inf() { static Vector4 v((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf()); return v; }
- inline static const Vector4& nan() { static Vector4 v((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan()); return v; }
+ static const Vector4& inf();
+ static const Vector4& nan();
/** sqrt(this->dot(*this)) */
float length() const;
@@ -573,15 +581,6 @@ inline const float& Vector4::operator[] (int i) const {
}
//----------------------------------------------------------------------------
-inline Vector4::operator float* () {
- return (float*)this;
-}
-
-inline Vector4::operator const float* () const {
- return (float*)this;
-}
-
-//----------------------------------------------------------------------------
inline Vector4& Vector4::operator= (const Vector4& rkVector) {
x = rkVector.x;
y = rkVector.y;
diff --git a/externals/g3dlite/G3D/Vector4.inl b/externals/g3dlite/G3D/Vector4.inl
new file mode 100644
index 00000000000..576cca83b56
--- /dev/null
+++ b/externals/g3dlite/G3D/Vector4.inl
@@ -0,0 +1,191 @@
+/**
+ @file Vector4.inl
+
+ @maintainer Morgan McGuire, matrix@graphics3d.com
+
+ @created 2002-07-09
+ @edited 2003-02-10
+ */
+
+//----------------------------------------------------------------------------
+
+inline unsigned int hashCode(const G3D::Vector4& v) {
+ return v.hashCode();
+}
+
+namespace G3D {
+
+//----------------------------------------------------------------------------
+inline Vector4::Vector4() {
+ x = y = z = w = 0;
+}
+
+//----------------------------------------------------------------------------
+
+inline Vector4::Vector4 (float fX, float fY, float fZ, float fW) {
+ x = fX;
+ y = fY;
+ z = fZ;
+ w = fW;
+}
+
+//----------------------------------------------------------------------------
+inline Vector4::Vector4 (float afCoordinate[4]) {
+ x = afCoordinate[0];
+ y = afCoordinate[1];
+ z = afCoordinate[2];
+ w = afCoordinate[3];
+}
+
+//----------------------------------------------------------------------------
+inline Vector4::Vector4(const Vector4& rkVector) {
+ x = rkVector.x;
+ y = rkVector.y;
+ z = rkVector.z;
+ w = rkVector.w;
+}
+//----------------------------------------------------------------------------
+inline Vector4::Vector4(const Vector3& rkVector, float fW) {
+ x = rkVector.x;
+ y = rkVector.y;
+ z = rkVector.z;
+ w = fW;
+}
+
+//----------------------------------------------------------------------------
+inline float& Vector4::operator[] (int i) {
+ return ((float*)this)[i];
+}
+
+//----------------------------------------------------------------------------
+inline const float& Vector4::operator[] (int i) const {
+ return ((float*)this)[i];
+}
+
+//----------------------------------------------------------------------------
+inline Vector4::operator float* () {
+ return (float*)this;
+}
+
+inline Vector4::operator const float* () const {
+ return (float*)this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector4& Vector4::operator= (const Vector4& rkVector) {
+ x = rkVector.x;
+ y = rkVector.y;
+ z = rkVector.z;
+ w = rkVector.w;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector4::operator== (const Vector4& rkVector) const {
+ return ( (x == rkVector.x) && (y == rkVector.y) && (z == rkVector.z) && (w == rkVector.w));
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector4::operator!= (const Vector4& rkVector) const {
+ return ( x != rkVector.x || y != rkVector.y || z != rkVector.z || w != rkVector.w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::operator+ (const Vector4& rkVector) const {
+ return Vector4(x + rkVector.x, y + rkVector.y, z + rkVector.z, w + rkVector.w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::operator- (const Vector4& rkVector) const {
+ return Vector4(x - rkVector.x, y - rkVector.y, z - rkVector.z, w - rkVector.w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::operator* (float fScalar) const {
+ return Vector4(fScalar*x, fScalar*y, fScalar*z, fScalar*w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::operator- () const {
+ return Vector4( -x, -y, -z, -w);
+}
+
+//----------------------------------------------------------------------------
+inline Vector4& Vector4::operator+= (const Vector4& rkVector) {
+ x += rkVector.x;
+ y += rkVector.y;
+ z += rkVector.z;
+ w += rkVector.w;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline Vector4& Vector4::operator-= (const Vector4& rkVector) {
+ x -= rkVector.x;
+ y -= rkVector.y;
+ z -= rkVector.z;
+ w -= rkVector.w;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+
+inline Vector4 Vector4::lerp(const Vector4& v, float alpha) const {
+ return (*this) + (v - *this) * alpha;
+}
+
+//----------------------------------------------------------------------------
+inline Vector4& Vector4::operator*= (float fScalar) {
+ x *= fScalar;
+ y *= fScalar;
+ z *= fScalar;
+ w *= fScalar;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+inline float Vector4::dot(const Vector4& rkVector) const {
+ return x*rkVector.x + y*rkVector.y + z*rkVector.z + w*rkVector.w;
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::min(const Vector4 &v) const {
+ return Vector4(G3D::min(v.x, x), G3D::min(v.y, y), G3D::min(v.z, z), G3D::min(v.w, w));
+}
+
+//----------------------------------------------------------------------------
+inline Vector4 Vector4::max(const Vector4 &v) const {
+ return Vector4(G3D::max(v.x, x), G3D::max(v.y, y), G3D::max(v.z, z), G3D::max(v.w, w));
+}
+
+//----------------------------------------------------------------------------
+inline bool Vector4::isZero() const {
+ return (x == 0.0f) && (y == 0.0f) && (z == 0.0f) && (w == 0.0f);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector4::isFinite() const {
+ return G3D::isFinite(x) && G3D::isFinite(y) && G3D::isFinite(z) && G3D::isFinite(w);
+}
+
+//----------------------------------------------------------------------------
+
+inline bool Vector4::isUnit() const {
+ return squaredLength() == 1.0;
+}
+
+//----------------------------------------------------------------------------
+
+inline float Vector4::length() const {
+ return sqrtf(squaredLength());
+}
+
+//----------------------------------------------------------------------------
+
+inline float Vector4::squaredLength() const {
+ return x * x + y * y + z * z + w * w;
+}
+
+}
+
diff --git a/externals/g3dlite/G3D.lib/include/G3D/Vector4int8.h b/externals/g3dlite/G3D/Vector4int8.h
index 8476a2d008b..544b693e8b3 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/Vector4int8.h
+++ b/externals/g3dlite/G3D/Vector4int8.h
@@ -3,7 +3,7 @@
Homogeneous vector class.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-02-09
@edited 2007-02-09
diff --git a/externals/g3dlite/G3D.lib/include/G3D/WeakCache.h b/externals/g3dlite/G3D/WeakCache.h
index 87988aaf5cb..f9fdc4bbd5b 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/WeakCache.h
+++ b/externals/g3dlite/G3D/WeakCache.h
@@ -85,6 +85,38 @@ public:
}
};
+#if 0 // To turn off all WeakCaching
+template<class Key, class ValueRef>
+class WeakCache {
+private:
+
+ Table<Key, ValueRef> table;
+
+public:
+ /**
+ Returns NULL if the object is not in the cache
+ */
+ ValueRef operator[](const Key& k) {
+ if (table.containsKey(k)) {
+ return table[k];
+ } else {
+ return NULL;
+ }
+ }
+
+ void set(const Key& k, ValueRef v) {
+ table.set(k, v);
+ }
+
+ /** Removes k from the cache or does nothing if it is not currently in the cache.*/
+ void remove(const Key& k) {
+ if (table.containsKey(k)) {
+ table.remove(k);
+ }
+ }
+};
+#endif
+
}
#endif
diff --git a/externals/g3dlite/G3D/Welder.h b/externals/g3dlite/G3D/Welder.h
new file mode 100644
index 00000000000..2c2554da7b6
--- /dev/null
+++ b/externals/g3dlite/G3D/Welder.h
@@ -0,0 +1,82 @@
+#ifndef G3D_Welder_h
+#define G3D_Welder_h
+
+#include "G3D/platform.h"
+#include "G3D/Array.h"
+#include "G3D/Vector3.h"
+#include "G3D/Vector2.h"
+
+namespace G3D {
+
+class Any;
+
+class Welder {
+private:
+
+ Welder() {}
+
+public:
+
+ class Settings {
+ public:
+ /** Surfaces with normals that are within this angle of each
+ other are considered to be curved. Default value is toRadians(70.0f).*/
+ float normalSmoothingAngle;
+ float vertexWeldRadius;
+ float textureWeldRadius;
+ float normalWeldRadius;
+
+ inline Settings(float normalSmoothAngle = toRadians(70.0f)) :
+ normalSmoothingAngle(normalSmoothAngle),
+ vertexWeldRadius(0.0001f),
+ textureWeldRadius(0.0001f),
+ normalWeldRadius(0.01f) {}
+
+
+ Settings(const Any& any);
+ operator Any() const;
+ };
+
+/**
+ Mutates geometry, texCoord, and indexArray so that the output has collocated vertices collapsed (welded).
+
+ @param vertices Input and output
+ @param textureCoords Input and output
+ @param normals Output only
+ @param indices Input and output. This is an array of trilist indices.
+ @param oldToNewIndex Output argument
+ @param normalSmoothingAngle Varies from 0 (flat shading) to toRadians(180) for extremely smooth shading. Default is toRadians(70)
+ */
+ static void weld(
+ Array<Vector3>& vertices,
+ Array<Vector2>& textureCoords,
+ Array<Vector3>& normals,
+ Array<Array<int>*>& indices,
+ const Settings& settings);
+
+ /**
+ Mutates geometry, texCoord, and indexArray so that the output has collocated vertices collapsed (welded).
+
+ @param vertices Input and output
+ @param textureCoords Input and output
+ @param normals Output only
+ @param indices Input and output. This is an array of trilist indices.
+ @param oldToNewIndex Output argument
+ @param normalSmoothingAngle Varies from 0 (flat shading) to toRadians(180) for extremely smooth shading. Default is toRadians(70)
+ */
+ inline static void weld(
+ Array<Vector3>& vertices,
+ Array<Vector2>& textureCoords,
+ Array<Vector3>& normals,
+ Array<int>& indices,
+ const Settings& settings) {
+
+ Array<Array<int>*> meta;
+ meta.append(&indices);
+ weld(vertices, textureCoords, normals, meta, settings);
+ }
+};
+
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/WrapMode.h b/externals/g3dlite/G3D/WrapMode.h
index f97e68d6910..8ef38a77c23 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/WrapMode.h
+++ b/externals/g3dlite/G3D/WrapMode.h
@@ -1,17 +1,17 @@
/**
@file WrapMode.h
- @maintainer Morgan McGuire, graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-04-17
@edited 2007-04-17
- Copyright 2000-2007, Morgan McGuire.
+ Copyright 2000-2010, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_WRAPMODE_H
-#define G3D_WRAPMODE_H
+#ifndef G3D_WrapMode_h
+#define G3D_WrapMode_h
#include "G3D/platform.h"
#include "G3D/enumclass.h"
@@ -29,8 +29,9 @@
namespace G3D {
/**
- Describes the behavior of G3D::Texture, G3D::Map2D, G3D::Image3, etc. when accessing an out-of-bounds
- pixel. Not all classes support all modes.
+ Describes the behavior of G3D::Texture, G3D::Map2D, G3D::Image3,
+ etc. when accessing an out-of-bounds pixel. Not all classes support
+ all modes.
Refer to these as scoped enums, e.g., <code>WrapMode m = WrapMode::CLAMP;</code>.
@@ -70,6 +71,19 @@ public:
G3D_DECLARE_ENUM_CLASS_METHODS(WrapMode);
+ inline const char* toString() const {
+ static const char* s[] = {"CLAMP", "TILE", "ZERO", "IGNORE", "ERROR"};
+ return s[value];
+ }
+
+ inline explicit WrapMode(const std::string& x) : value(ERROR) {
+ static const char* s[] = {"CLAMP", "TILE", "ZERO", "IGNORE", "ERROR"};
+ for (int i = 0; i < 5; ++i) {
+ if (x == s[i]) {
+ value = (Value)i;
+ }
+ }
+ }
};
} // namespace G3D
diff --git a/externals/g3dlite/G3D/constants.h b/externals/g3dlite/G3D/constants.h
new file mode 100644
index 00000000000..dd5cb3649e5
--- /dev/null
+++ b/externals/g3dlite/G3D/constants.h
@@ -0,0 +1,129 @@
+/**
+ @file G3D/constants.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ @created 2009-05-20
+ @edited 2009-05-20
+*/
+#ifndef G3D_constants_h
+#define G3D_constants_h
+
+#include "G3D/platform.h"
+#include "G3D/enumclass.h"
+
+namespace G3D {
+
+/** These are defined to have the same value as the equivalent OpenGL
+ constant. */
+class PrimitiveType {
+public:
+ enum Value {
+ POINTS = 0x0000,
+ LINES = 0x0001,
+ LINE_STRIP = 0x0003,
+ TRIANGLES = 0x0004,
+ TRIANGLE_STRIP = 0x0005,
+ TRIANGLE_FAN = 0x0006,
+ QUADS = 0x0007,
+ QUAD_STRIP = 0x0008
+ };
+
+private:
+
+ Value value;
+
+public:
+
+ G3D_DECLARE_ENUM_CLASS_METHODS(PrimitiveType);
+};
+
+
+/** Values for SuperSurface::GPUGeom::refractionHint. */
+class RefractionQuality {
+public:
+ enum Value {
+ /** No refraction; a translucent object will appear as if it had the same index of refraction
+ as the surrounding medium and objects will be undistorted in the background. */
+ NONE = 0,
+
+ /** Use a static environment map (cube or paraboloid) for computing transmissivity.*/
+ STATIC_ENV = 25,
+
+ /** Use a dynamically rendered 2D environment map; distort the background. This looks good for many scenes
+ but avoids the cost of rendering a cube map for DYNAMIC_ENV. */
+ DYNAMIC_FLAT = 50,
+
+ /** Use a dynamically rendered 2D environment map that is re-captured per transparent object. This works well
+ for transparent objects that are separated by a significant camera space z distance but overlap in screen space.*/
+ DYNAMIC_FLAT_MULTILAYER = 55,
+
+ /** Render a dynamic environment map */
+ DYNAMIC_ENV = 75,
+
+ /** Use the best method available, ideally true ray tracing. */
+ BEST = 100
+ };
+
+private:
+
+ /** Used for to/from string conversion. Last is the emtpy string as a sentinel */
+ static const std::string str[7];
+ static const Value enm[6];
+ Value value;
+
+public:
+ G3D_DECLARE_ENUM_CLASS_METHODS(RefractionQuality);
+
+ RefractionQuality(const class Any&);
+ RefractionQuality& operator=(const Any&);
+ operator Any() const;
+ const std::string& toString() const;
+};
+
+
+/** Values for SuperSurface::GPUGeom::mirrorHint. */
+class MirrorQuality {
+public:
+
+ enum Value {
+ /** Reflections are black */
+ NONE = 0,
+
+ /** Use a static environment map. This is what most games use */
+ STATIC_ENV = 25,
+
+ /** Planar reflection, typically for water or glass windows. This assumes that the mirror is flat;
+ it is distinct from RefractionQuality::DYNAMIC_FLAT, which assumes the <i>background</i> is flat.*/
+ DYNAMIC_PLANAR = 50,
+
+ /** Render a dynamic environment map. */
+ DYNAMIC_ENV = 75,
+
+ /** Use the best method available, ideally true ray tracing. */
+ BEST = 100
+ };
+
+private:
+
+ /** Used for to/from string conversion. Last is the emtpy string as a sentinel */
+ static const std::string str[6];
+ static const Value enm[5];
+
+ Value value;
+
+public:
+ G3D_DECLARE_ENUM_CLASS_METHODS(MirrorQuality);
+ MirrorQuality(const class Any&);
+ MirrorQuality& operator=(const Any&);
+ operator Any() const;
+ const std::string& toString() const;
+};
+
+} // namespace G3D
+
+G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::PrimitiveType)
+G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::RefractionQuality)
+G3D_DECLARE_ENUM_CLASS_HASHCODE(G3D::MirrorQuality)
+
+#endif
+
diff --git a/externals/g3dlite/G3D.lib/include/G3D/debug.h b/externals/g3dlite/G3D/debug.h
index a96babc6fa0..a7697fe9c01 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/debug.h
+++ b/externals/g3dlite/G3D/debug.h
@@ -1,7 +1,7 @@
/**
@file debug.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-08-26
@edited 2006-02-16
diff --git a/externals/g3dlite/G3D.lib/include/G3D/debugAssert.h b/externals/g3dlite/G3D/debugAssert.h
index f9b5bea4e9f..432e97e679d 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/debugAssert.h
+++ b/externals/g3dlite/G3D/debugAssert.h
@@ -14,7 +14,7 @@
<A HREF="http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-AssertReplace&forum=cotd&id=-1">
http://www.flipcode.com/cgi-bin/msg.cgi?showThread=COTD-AssertReplace&forum=cotd&id=-1</A>
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-08-26
@edited 2006-01-12
@@ -39,14 +39,11 @@
#ifdef G3D_LINUX
// Needed so we can define a global display
// pointer for debugAssert.
+#if SOMEONE_MADE_THIS_USEFUL
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#endif
-
-#ifdef G3D_OSX
- // Need this for DebugStr()
- #import <CoreServices/CoreServices.h>
#endif
@@ -61,7 +58,7 @@
@def debugAssert(exp)
Breaks if the expression is false. If G3D_DEBUG_NOGUI is defined, prompts at
the console, otherwise pops up a dialog. The user may then break (debug),
- ignore, ignore always, or halt the program.
+ ignore, or halt the program.
The assertion is also posted to the clipboard under Win32.
*/
@@ -70,18 +67,22 @@
@def debugAssertM(exp, msg)
Breaks if the expression is false and displays a message. If G3D_DEBUG_NOGUI
is defined, prompts at the console, otherwise pops up a dialog. The user may
- then break (debug), ignore, ignore always, or halt the program.
+ then break (debug), ignore, or halt the program.
The assertion is also posted to the clipboard under Win32.
*/
+/**
+ @def alwaysAssertM(exp, msg)
+ Same as debugAssertM except that it asserts in release builds as well.
+ */
+
namespace G3D {
typedef bool (*AssertionHook)(
const char* _expression,
const std::string& message,
const char* filename,
int lineNumber,
- bool& ignoreAlways,
bool useGuiPrompt);
/**
@@ -123,8 +124,6 @@ namespace _internal {
// some other gcc
# define rawBreak() ::abort()
# endif
-// old mac code:
-//# define rawBreak() DebugStr((const unsigned char*)("\nG3D: Invoking breakpoint in debugger.")); /* XCode must be set to break on Debugger()/DebugStr() */
# define debugBreak() G3D::_internal::_releaseInputGrab_(); rawBreak(); G3D::_internal::_restoreInputGrab_();
@@ -137,11 +136,10 @@ namespace _internal {
#endif
#define debugAssertM(exp, message) do { \
- static bool __debugAssertIgnoreAlways__ = false; \
- if (!__debugAssertIgnoreAlways__ && !(exp)) { \
+ if (!(exp)) { \
G3D::_internal::_releaseInputGrab_(); \
if ((G3D::_internal::_debugHook != NULL) && \
- G3D::_internal::_debugHook((const char*)(#exp), message, __FILE__, __LINE__, __debugAssertIgnoreAlways__, __debugPromptShowDialog__)) { \
+ G3D::_internal::_debugHook((const char*)(#exp), message, __FILE__, __LINE__, __debugPromptShowDialog__)) { \
rawBreak(); \
} \
G3D::_internal::_restoreInputGrab_(); \
@@ -165,11 +163,10 @@ namespace _internal {
// But keep the 'always' assertions
#define alwaysAssertM(exp, message) { \
- static bool __alwaysAssertIgnoreAlways__ = false; \
- if (!__alwaysAssertIgnoreAlways__ && !(exp)) { \
+ if (!(exp)) { \
G3D::_internal::_releaseInputGrab_(); \
if ((G3D::_internal::_failureHook != NULL) && \
- G3D::_internal::_failureHook(#exp, message, __FILE__, __LINE__, __alwaysAssertIgnoreAlways__, __debugPromptShowDialog__)) { \
+ G3D::_internal::_failureHook(#exp, message, __FILE__, __LINE__, __debugPromptShowDialog__)) { \
::exit(-1); \
} \
G3D::_internal::_restoreInputGrab_(); \
@@ -183,6 +180,7 @@ namespace _internal {
namespace G3D { namespace _internal {
#ifdef G3D_LINUX
+#if SOMEONE_MADE_THIS_USEFUL
/**
A pointer to the X11 display. Initially NULL. If set to a
non-null value (e.g. by SDLWindow), debugAssert attempts to use
@@ -199,6 +197,7 @@ namespace G3D { namespace _internal {
*/
extern Window x11Window;
#endif
+#endif
/**
Pops up an assertion dialog or prints an assertion
@@ -211,7 +210,6 @@ bool _handleDebugAssert_(
const std::string& message,
const char* filename,
int lineNumber,
- bool& ignoreAlways,
bool useGuiPrompt);
bool _handleErrorCheck_(
@@ -219,7 +217,6 @@ bool _handleErrorCheck_(
const std::string& message,
const char* filename,
int lineNumber,
- bool& ignoreAlways,
bool useGuiPrompt);
/** Attempts to give the user back their mouse and keyboard if they
diff --git a/externals/g3dlite/G3D.lib/include/G3D/debugPrintf.h b/externals/g3dlite/G3D/debugPrintf.h
index bc3315c8a6d..b42151cae9e 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/debugPrintf.h
+++ b/externals/g3dlite/G3D/debugPrintf.h
@@ -1,7 +1,7 @@
/**
@file debugPrintf.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-08-26
@edited 2007-07-20
diff --git a/externals/g3dlite/G3D.lib/include/G3D/enumclass.h b/externals/g3dlite/G3D/enumclass.h
index 7e7bc3f6ac3..c7dfe45f14f 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/enumclass.h
+++ b/externals/g3dlite/G3D/enumclass.h
@@ -1,25 +1,29 @@
/**
@file G3D/enumclass.h
- @maintainer Morgan McGuire, morgan@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-01-27
@edited 2007-07-20
*/
-#ifndef G3D_ENUMCLASS_H
-#define G3D_ENUMCLASS_H
+#ifndef G3D_enumclass_h
+#define G3D_enumclass_h
-#include "G3D/Table.h"
+#include "G3D/HashTrait.h"
#include "G3D/BinaryInput.h"
#include "G3D/BinaryOutput.h"
/**
- Creates a series of methods that turn a class into a scoped enumeration.
+\def G3D_DECLARE_ENUM_CLASS_METHODS
+
+ \brief Creates a series of methods that turn a class into a scoped enumeration.
+
Uses the "Intelligent Enum" design pattern
http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4001/
Enum classes are initialized to their zero value by default.
See GLG3D/GKey.h for an example.
+ \sa G3D_DECLARE_ENUM_CLASS_HASHCODE
*/
#define G3D_DECLARE_ENUM_CLASS_METHODS(Classname)\
inline Classname(char v) : value((Value)v) {}\
@@ -119,14 +123,16 @@
return (unsigned int)value;\
}\
\
- void serialize(BinaryOutput& b) const {\
+ inline void serialize(BinaryOutput& b) const {\
b.writeInt32(value);\
}\
\
- void deserialize(BinaryInput& b) {\
+ inline void deserialize(BinaryInput& b) {\
value = (Value)b.readInt32();\
}
+/** \def G3D_DECLARE_ENUM_CLASS_HASHCODE
+*/
#define G3D_DECLARE_ENUM_CLASS_HASHCODE(Classname)\
template <> struct HashTrait<Classname::Value> \
{ \
diff --git a/externals/g3dlite/G3D.lib/include/G3D/fileutils.h b/externals/g3dlite/G3D/fileutils.h
index ead20720870..9e49777d93a 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/fileutils.h
+++ b/externals/g3dlite/G3D/fileutils.h
@@ -1,17 +1,17 @@
/**
@file fileutils.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@author 2002-06-06
- @edited 2007-01-18
+ @edited 2010-02-06
- Copyright 2000-2007, Morgan McGuire.
+ Copyright 2000-2010, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3D_FILEUTILS_H
-#define G3D_FILEUTILS_H
+#ifndef G3D_fileUtils_h
+#define G3D_fileUtils_h
#include "G3D/platform.h"
#include <string>
@@ -42,7 +42,7 @@ std::string readWholeFile(
into memory. Does not support recursive zip calls (i.e. a .zip
stored within another .zip)
- @param file the path, of the format C:\...\something.zip\...\desiredfile.ext
+ @param file the path, of the format C:\\...\\something.zip\\...\\desiredfile.ext
@param data a pointer to the memory where the file will be stored
@param length the size of the file decompressed to memory */
void zipRead(const std::string& file,
@@ -88,7 +88,7 @@ std::string resolveFilename(const std::string& filename);
(can be done with resolveFilename).
Wildcards can only appear to the right of the last slash in filespec.
Works with .zip files used as paths, if filespec is passed in the form
- C:\...\something.zip\* Does not work recursively with zipfiles (a
+ C:\\...\\something.zip\\* Does not work recursively with zipfiles (a
.zip within a .zip will not work)
*/
void getFiles(
@@ -103,7 +103,7 @@ void getFiles(
(can be done with resolveFilename).
Does not append special directories "." or "..".
Works with .zip files used as paths, if filespec is passed in the form
- C:\...\something.zip\* Does not work recursively with zipfiles (a
+ C:\\...\\something.zip\\* Does not work recursively with zipfiles (a
.zip within a .zip will not work)
*/
void getDirs(
@@ -144,12 +144,21 @@ FILE* createTempFile();
/**
Returns true if the given file (or directory) exists.
- @param filename the path to test. must not end in a trailing slash.
- @param lookInZipfiles if the path does not exist, calls zipfileExists()
+ \param filename the path to test. must not end in a trailing slash.
+ \param lookInZipfiles if the path does not exist, calls zipfileExists()
+ \param trustCache If true and \a lookInZipfiles is true, cache directory and zipfile contents
+ so that subsequent calls to the same directory are fast.
+
+ \sa G3D::clearFileSystemCache, G3D::zipfileExists
*/
-bool fileExists(
- const std::string& filename,
- const bool lookInZipfiles = true);
+bool fileExists
+(const std::string& filename,
+ bool lookInZipfiles = true,
+ bool trustCache = true);
+
+
+/** Clears the cache used by fileExists */
+void clearFileSystemCache();
/**
Returns true if the given file (or directory) exists
@@ -163,11 +172,10 @@ bool fileExists(
@param outInternalFile the path (within the .zip) where the desired file is located, if valid
*/
-bool zipfileExists(
- const std::string& filename,
- std::string& outZipfile,
- std::string& outInternalFile
- );
+bool zipfileExists
+(const std::string& filename,
+ std::string& outZipfile,
+ std::string& outInternalFile);
bool zipfileExists(const std::string& filename);
@@ -176,8 +184,8 @@ bool zipfileExists(const std::string& filename);
Examples:
- c:\a\b\d.e
- root = "c:\"
+ c:\\a\\b\\d.e
+ root = "c:\\"
path = "a" "b"
base = "d"
ext = "e"
@@ -221,8 +229,8 @@ std::string filenameExt(const std::string& filename);
std::string filenameBase(const std::string& filename);
/** Creates a unique filename base in the current directory using the
- specified prefix.*/
-std::string generateFilenameBase(const std::string& prefix = "");
+ specified prefix and suffix.*/
+std::string generateFilenameBase(const std::string& prefix = "", const std::string& suffix = "");
/**
Returns the drive (if Win32) and path from a filename, including
diff --git a/externals/g3dlite/G3D.lib/include/G3D/filter.h b/externals/g3dlite/G3D/filter.h
index 74a32ad01ea..609477b79c9 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/filter.h
+++ b/externals/g3dlite/G3D/filter.h
@@ -1,7 +1,7 @@
/**
@file G3D/filter.h
- @author Morgan McGuire, matrix@graphics3d.com
+ @author Morgan McGuire, http://graphics.cs.williams.edu
@created 2007-03-01
@edited 2007-03-01
diff --git a/externals/g3dlite/G3D.lib/include/G3D/format.h b/externals/g3dlite/G3D/format.h
index f993a74038f..3c7f0678876 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/format.h
+++ b/externals/g3dlite/G3D/format.h
@@ -1,7 +1,7 @@
/**
@file format.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@author 2000-09-09
@edited 2005-11-03
diff --git a/externals/g3dlite/G3D/g3dfnmatch.h b/externals/g3dlite/G3D/g3dfnmatch.h
new file mode 100644
index 00000000000..464b3927eee
--- /dev/null
+++ b/externals/g3dlite/G3D/g3dfnmatch.h
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 1992, 1993
+ *The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *This product includes software developed by the University of
+ *California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *@(#)fnmatch.h8.1 (Berkeley) 6/2/93
+ *
+ * From FreeBSD fnmatch.h 1.7
+ * $Id: g3dfnmatch.h,v 1.1 2010/02/06 06:51:28 morgan3d Exp $
+ */
+#ifndef G3D_g3dfnmatch_h
+#define G3D_g3dfnmatch_h
+
+#include "G3D/platform.h"
+
+namespace G3D {
+
+#if defined(G3D_WIN32)
+
+# if ! defined(FNM_NOMATCH)
+# define FNM_NOMATCH 1 /* Match failed. */
+# define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
+# define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
+# define FNM_PERIOD 0x04 /* Period must be matched by period. */
+# define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
+# define FNM_CASEFOLD 0x10 /* Case insensitive search. */
+# define FNM_PREFIX_DIRS 0x20 /* Directory prefixes of pattern match too. */
+# endif
+
+#else
+
+ // On non-windows systems, include fnmatch directly
+# include <fnmatch.h>
+#endif
+
+
+/**
+ Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ Compares a filename or pathname to a pattern.
+
+The fnmatch() function checks whether the string argument matches the pattern argument, which is a shell wildcard pattern.
+The flags argument modifies the behaviour; it is the bitwise OR of zero or more of the following flags:
+
+- FNM_NOESCAPE If this flag is set, treat backslash as an ordinary character, instead of an escape character.
+- FNM_PATHNAME If this flag is set, match a slash in string only with a slash in pattern and not by an asterisk (*) or a question mark (?) metacharacter, nor by a bracket expression ([]) containing a slash.
+- FNM_PERIOD If this flag is set, a leading period in string has to be matched exactly by a period in pattern. A period is considered to be leading if it is the first character in string, or if both FNM_PATHNAME is set and the period immediately follows a slash.
+- FNM_FILE_NAME This is a GNU synonym for FNM_PATHNAME.
+- FNM_LEADING_DIR If this flag (a GNU extension) is set, the pattern is considered to be matched if it matches an initial segment of string which is followed by a slash. This flag is mainly for the internal use of glibc and is only implemented in certain cases.
+- FNM_CASEFOLD If this flag (a GNU extension) is set, the pattern is matched case-insensitively.
+
+\return Zero if \a string matches \a pattern, FNM_NOMATCH if there is no match or another non-zero value if there is an error
+
+ */
+int g3dfnmatch(const char *pattern, const char *string, int flags);
+}
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/g3dmath.h b/externals/g3dlite/G3D/g3dmath.h
index 0a4f01f11c6..d16214ebb37 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/g3dmath.h
+++ b/externals/g3dlite/G3D/g3dmath.h
@@ -3,18 +3,18 @@
Math util class.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite highestBit by Jukka Liimatta
@created 2001-06-02
- @edited 2006-01-16
+ @edited 2009-04-07
Copyright 2000-2006, Morgan McGuire.
All rights reserved.
*/
-#ifndef G3DMATH_H
-#define G3DMATH_H
+#ifndef G3D_g3dmath_h
+#define G3D_g3dmath_h
#ifdef _MSC_VER
// Disable conditional expression is constant, which occurs incorrectly on inlined functions
@@ -61,6 +61,11 @@
namespace G3D {
#ifdef _MSC_VER
+inline double __fastcall drand48() {
+ return ::rand() / double(RAND_MAX);
+}
+
+#if !defined(_WIN64)
/**
Win32 implementation of the C99 fast rounding routines.
@@ -96,48 +101,46 @@ __inline long int lrintf(float flt) {
return intgr;
}
-#endif
+#else
+ __inline long int lrint (double flt) {
+ return (long int)floor(flt+0.5f);
+ }
-const double fuzzyEpsilon = 0.00001;
+ __inline long int lrintf(float flt) {
+ return (long int)floorf(flt+0.5f);
+ }
-/** Returns a reference to a static double.
- This value should not be tested against directly, instead
- G3D::isNan() and G3D::isFinite() will return reliable results. */
-inline const double& inf() {
+#endif
- // double is a standard type and should have infinity
- static const double i = std::numeric_limits<double>::infinity();
- return i;
-}
+#endif
-/** Returns a reference to a static double.
+
+#define fuzzyEpsilon (0.00001f)
+/**
This value should not be tested against directly, instead
G3D::isNan() and G3D::isFinite() will return reliable results. */
-inline const double& nan() {
+double inf();
- // double is a standard type and should have quiet NaN
- static const double n = std::numeric_limits<double>::quiet_NaN();
- return n;
-}
+/** This value should not be tested against directly, instead
+ G3D::isNan() and G3D::isFinite() will return reliable results. */
+double nan();
+
+float finf();
+
+float fnan();
-/** Returns a reference to a static double. Use instead of G3D_PI. */
-inline const double& pi() {
- static const double p = 3.1415926535898;
- return p;
+inline double pi() {
+ return 3.1415926535898;
}
-/** Returns a reference to a static double. */
-inline const double& halfPi() {
- static const double p = pi() / 2.0;
- return p;
+inline double halfPi() {
+ return 1.57079633;
}
-/** Returns a reference to a static double. */
-inline const double& twoPi() {
- static const double p = pi() * 2.0;;
- return p;
+inline double twoPi() {
+ return 6.28318531;
}
typedef signed char int8;
@@ -220,6 +223,7 @@ inline int iRound(float f) {
/**
Returns a random number uniformly at random between low and hi
(inclusive).
+ @deprecated Use Random::integer
*/
int iRandom(int low, int hi);
@@ -242,6 +246,11 @@ bool isFinite(double x);
comparisons against nan return false.
*/
bool isNaN(double x);
+bool isNaN(float x);
+inline bool isNaN(int x) {
+ (void)x;
+ return false;
+}
/**
Computes x % 3.
@@ -250,14 +259,28 @@ int iMod3(int x);
/**
Uniform random number between low and hi, inclusive. [low, hi]
+ @deprecated
+ @sa Random::uniform
*/
float uniformRandom(float low = 0.0f, float hi = 1.0f);
/**
Normally distributed random number.
+
+ @deprecated
+ @sa Random::gaussian
*/
float gaussRandom(float mean = 0.0f, float stdev = 1.0f);
+
+/** Returns x<sup>5</sup> */
+template <class T>
+inline T pow5(T x) {
+ const T y = x * x;
+ return y * y * x;
+}
+
+
template <class T>
inline T min(const T& x, const T& y) {
return std::min<T>(x, y);
@@ -338,24 +361,6 @@ inline float rsq(float x) {
}
/**
- Uses SSE to implement rsq.
- @cite Nick nicolas@capens.net
- */
-inline float SSErsq(float x) {
-
- #if defined(SSE) && defined(G3D_WIN32)
- __asm {
- movss xmm0, x
- rsqrtss xmm0, xmm0
- movss x, xmm0
- }
- return x;
- #else
- return 1.0f / sqrt(x);
- #endif
-}
-
-/**
Return the next power of 2 higher than the input
If the input is already a power of 2, the output will be the same
as the input.
@@ -367,18 +372,14 @@ inline int pow2(unsigned int x) {
return 1 << x;
}
-
-/** Log base 2 */
-inline float log2(float x) {
- return ::logf(x) / ::logf(2.0f);
+inline double log2(double x) {
+ return ::log(x) * 1.442695;
}
-/** Log base 2 */
-inline double log2(double x) {
- return ::log(x) / ::log(2.0);
+inline float log2(float x) {
+ return ::logf(x) * 1.442695f;
}
-/** Log base 2 */
inline double log2(int x) {
return log2((double)x);
}
@@ -438,10 +439,20 @@ inline double exp2(double x) {
return pow(2.0, x);
}
+inline float exp2(float x) {
+ return powf(2.0f, x);
+}
+
+/** @deprecated Use rsq */
inline double rsqrt(double x) {
return 1.0 / sqrt(x);
}
+/** @deprecated Use rsq */
+inline float rsqrt(float x) {
+ // TODO: default this to using the SSE2 instruction
+ return 1.0 / sqrtf(x);
+}
/**
sin(x)/x
@@ -489,17 +500,14 @@ inline double wrap(double t, double hi) {
}
-inline bool isNaN(double x) {
- bool b1 = (x < 0.0);
- bool b2 = (x >= 0.0);
- bool b3 = !(b1 || b2);
- return b3;
-}
-
inline bool isFinite(double x) {
return ! isNaN(x) && (x < G3D::inf()) && (x > -G3D::inf());
}
+inline bool isFinite(float x) {
+ return ! isNaN(x) && (x < G3D::finf()) && (x > -G3D::finf());
+}
+
//----------------------------------------------------------------------------
inline int iAbs (int iValue) {
return ( iValue >= 0 ? iValue : -iValue );
@@ -653,32 +661,59 @@ inline float uniformRandom(float low, float hi) {
return (hi - low) * float(::rand()) / float(RAND_MAX) + low;
}
-//----------------------------------------------------------------------------
inline double square(double x) {
return x * x;
}
+inline float square(float x) {
+ return x * x;
+}
+
+inline int square(int x) {
+ return x * x;
+}
+
//----------------------------------------------------------------------------
inline double sumSquares(double x, double y) {
return x*x + y*y;
}
//----------------------------------------------------------------------------
+inline float sumSquares(float x, float y) {
+ return x*x + y*y;
+}
+
+//----------------------------------------------------------------------------
inline double sumSquares(double x, double y, double z) {
return x*x + y*y + z*z;
}
//----------------------------------------------------------------------------
+inline float sumSquares(float x, float y, float z) {
+ return x*x + y*y + z*z;
+}
+
+//----------------------------------------------------------------------------
inline double distance(double x, double y) {
return sqrt(sumSquares(x, y));
}
//----------------------------------------------------------------------------
+inline float distance(float x, float y) {
+ return sqrt(sumSquares(x, y));
+}
+
+//----------------------------------------------------------------------------
inline double distance(double x, double y, double z) {
return sqrt(sumSquares(x, y, z));
}
//----------------------------------------------------------------------------
+inline float distance(float x, float y, float z) {
+ return sqrt(sumSquares(x, y, z));
+}
+
+//----------------------------------------------------------------------------
/** @deprecated use G3D::min */
inline int iMin(int x, int y) {
@@ -748,7 +783,7 @@ inline double eps(double a, double b) {
// since it either has the same magnitude or the comparison
// will fail anyway.
(void)b;
- const double aa = abs(a) + 1;
+ const double aa = abs(a) + 1.0;
if (aa == inf()) {
return fuzzyEpsilon;
} else {
diff --git a/externals/g3dlite/G3D/g3dmath.inl b/externals/g3dlite/G3D/g3dmath.inl
new file mode 100644
index 00000000000..9bf661a7ebc
--- /dev/null
+++ b/externals/g3dlite/G3D/g3dmath.inl
@@ -0,0 +1,288 @@
+/**
+ @file g3dmath.inl
+
+ @maintainer Morgan McGuire, matrix@graphics3d.com
+
+ @created 2001-06-02
+ @edited 2006-01-14
+ */
+
+#include <stdlib.h>
+
+#ifdef _MSC_VER
+// Disable conditional expression is constant, which occurs incorrectly on inlined functions
+# pragma warning (push)
+# pragma warning( disable : 4127 )
+#endif
+
+namespace G3D {
+
+inline bool isNaN(double x) {
+ bool b1 = (x < 0.0);
+ bool b2 = (x >= 0.0);
+ bool b3 = !(b1 || b2);
+ return b3;
+}
+
+inline bool isFinite(double x) {
+ return ! isNaN(x) && (x < G3D::inf()) && (x > -G3D::inf());
+}
+
+//----------------------------------------------------------------------------
+inline int iAbs (int iValue) {
+ return ( iValue >= 0 ? iValue : -iValue );
+}
+
+//----------------------------------------------------------------------------
+inline int iCeil (double fValue) {
+ return int(::ceil(fValue));
+}
+
+//----------------------------------------------------------------------------
+
+inline int iClamp(int val, int low, int hi) {
+ debugAssert(low <= hi);
+ if (val <= low) {
+ return low;
+ } else if (val >= hi) {
+ return hi;
+ } else {
+ return val;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+inline double clamp(double val, double low, double hi) {
+ debugAssert(low <= hi);
+ if (val <= low) {
+ return low;
+ } else if (val >= hi) {
+ return hi;
+ } else {
+ return val;
+ }
+}
+
+inline float clamp(float val, float low, float hi) {
+ debugAssert(low <= hi);
+ if (val <= low) {
+ return low;
+ } else if (val >= hi) {
+ return hi;
+ } else {
+ return val;
+ }
+}
+//----------------------------------------------------------------------------
+
+inline int iWrap(int val, int hi) {
+ if (val < 0) {
+ return ((val % hi) + hi) % hi;
+ } else {
+ return val % hi;
+ }
+}
+
+//----------------------------------------------------------------------------
+inline int iFloor (double fValue) {
+ return int(::floor(fValue));
+}
+
+//----------------------------------------------------------------------------
+inline int iSign (int iValue) {
+ return ( iValue > 0 ? + 1 : ( iValue < 0 ? -1 : 0 ) );
+}
+
+inline int iSign (double fValue) {
+ return ( fValue > 0.0 ? + 1 : ( fValue < 0.0 ? -1 : 0 ) );
+}
+
+//----------------------------------------------------------------------------
+inline double abs (double fValue) {
+ return double(::fabs(fValue));
+}
+
+//----------------------------------------------------------------------------
+inline double aCos (double fValue) {
+ if ( -1.0 < fValue ) {
+ if ( fValue < 1.0 )
+ return double(::acos(fValue));
+ else
+ return 0.0;
+ } else {
+ return G3D_PI;
+ }
+}
+
+//----------------------------------------------------------------------------
+inline double aSin (double fValue) {
+ if ( -1.0 < fValue ) {
+ if ( fValue < 1.0 ) {
+ return double(::asin(fValue));
+ } else {
+ return -G3D_HALF_PI;
+ }
+ } else {
+ return G3D_HALF_PI;
+ }
+}
+
+//----------------------------------------------------------------------------
+inline double aTan (double fValue) {
+ return double(::atan(fValue));
+}
+
+//----------------------------------------------------------------------------
+inline double aTan2 (double fY, double fX) {
+ return double(::atan2(fY, fX));
+}
+
+//----------------------------------------------------------------------------
+inline double sign (double fValue) {
+ if (fValue > 0.0) {
+ return 1.0;
+ }
+
+ if (fValue < 0.0) {
+ return -1.0;
+ }
+
+ return 0.0;
+}
+
+inline double G3D_DEPRECATED unitRandom () {
+ return double(::rand()) / double(RAND_MAX);
+}
+
+inline float uniformRandom(float low, float hi) {
+ return (hi - low) * float(::rand()) / float(RAND_MAX) + low;
+}
+
+//----------------------------------------------------------------------------
+inline double G3D_DEPRECATED symmetricRandom () {
+ return 2.0 * double(::rand()) / double(RAND_MAX) - 1.0;
+}
+
+//----------------------------------------------------------------------------
+inline double square(double x) {
+ return x * x;
+}
+
+//----------------------------------------------------------------------------
+inline double sumSquares(double x, double y) {
+ return x*x + y*y;
+}
+
+//----------------------------------------------------------------------------
+inline double sumSquares(double x, double y, double z) {
+ return x*x + y*y + z*z;
+}
+
+//----------------------------------------------------------------------------
+inline double distance(double x, double y) {
+ return sqrt(sumSquares(x, y));
+}
+
+//----------------------------------------------------------------------------
+inline double distance(double x, double y, double z) {
+ return sqrt(sumSquares(x, y, z));
+}
+
+//----------------------------------------------------------------------------
+
+/** @deprecated use G3D::min */
+inline int iMin(int x, int y) {
+ return (x >= y) ? y : x;
+}
+
+//----------------------------------------------------------------------------
+/** @deprecated use G3D::min */
+inline int iMax(int x, int y) {
+ return (x >= y) ? x : y;
+}
+
+//----------------------------------------------------------------------------
+inline int ceilPow2(unsigned int in) {
+ in -= 1;
+
+ in |= in >> 16;
+ in |= in >> 8;
+ in |= in >> 4;
+ in |= in >> 2;
+ in |= in >> 1;
+
+ return in + 1;
+}
+
+inline bool isPow2(int num) {
+ return ((num & -num) == num);
+}
+
+inline bool isOdd(int num) {
+ return (num & 1) == 1;
+}
+
+inline bool isEven(int num) {
+ return (num & 1) == 0;
+}
+
+inline double toRadians(double deg) {
+ return deg * G3D_PI / 180.0;
+}
+
+inline double toDegrees(double rad) {
+ return rad * 180.0 / G3D_PI;
+}
+
+/**
+ Computes an appropriate epsilon for comparing a and b.
+ */
+inline double eps(double a, double b) {
+ // For a and b to be nearly equal, they must have nearly
+ // the same magnitude. This means that we can ignore b
+ // since it either has the same magnitude or the comparison
+ // will fail anyway.
+ (void)b;
+ const double aa = abs(a) + 1;
+ if (aa == inf()) {
+ return fuzzyEpsilon;
+ } else {
+ return fuzzyEpsilon * aa;
+ }
+}
+
+inline bool fuzzyEq(double a, double b) {
+ return (a == b) || (abs(a - b) <= eps(a, b));
+}
+
+inline bool fuzzyNe(double a, double b) {
+ return ! fuzzyEq(a, b);
+}
+
+inline bool fuzzyGt(double a, double b) {
+ return a > b + eps(a, b);
+}
+
+inline bool fuzzyGe(double a, double b) {
+ return a > b - eps(a, b);
+}
+
+inline bool fuzzyLt(double a, double b) {
+ return a < b - eps(a, b);
+}
+
+inline bool fuzzyLe(double a, double b) {
+ return a < b + eps(a, b);
+}
+
+inline int iMod3(int x) {
+ return x % 3;
+}
+
+} // namespace G3D
+
+#ifdef _MSC_VER
+// Disable conditional expression is constant, which occurs incorrectly on inlined functions
+# pragma warning (pop)
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/platform.h b/externals/g3dlite/G3D/platform.h
index be9ec4d5123..11ba0127a16 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/platform.h
+++ b/externals/g3dlite/G3D/platform.h
@@ -1,22 +1,27 @@
/**
@file platform.h
- #defines for platform specific issues.
+ \#defines for platform specific issues.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-06-09
- @edited 2007-07-30
+ @edited 2010-01-11
*/
-#ifndef G3D_PLATFORM_H
-#define G3D_PLATFORM_H
+#ifndef G3D_platform_h
+#define G3D_platform_h
/**
- The version number of G3D in the form: MmmBB ->
+ The version number of G3D in the form: MmmBB ->
version M.mm [beta BB]
*/
-#define G3D_VER 70100
+#define G3D_VER 80004
+
+// fatal error for unsupported architectures
+#if defined(__powerpc__)
+# error PowerPC is not supported by G3D!
+#endif
#if defined(G3D_RELEASEDEBUG)
# define G3D_DEBUGRELEASE
@@ -26,11 +31,19 @@
# undef _DEBUG
#endif
+/** @def G3D_DEBUG()
+ Defined if G3D is built in debug mode. */
#if !defined(G3D_DEBUG) && (defined(_DEBUG) || defined(G3D_DEBUGRELEASE))
# define G3D_DEBUG
#endif
-#ifdef _MSC_VER
+#ifndef _MSC_VER
+/// Fast call is a register-based optimized calling convention supported only by Visual C++
+#define __fastcall
+
+#endif
+
+#ifdef _MSC_VER
#define G3D_WIN32
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
#define G3D_FREEBSD
@@ -44,20 +57,22 @@
// pi as a constant, which creates a conflict with G3D
#define __FP__
#else
- #error Unknown platform
+ #error Unknown platform
#endif
-
-// Default to compiling with SSE, but if you want to compile
-// without installing SP5.0 and the Processor Pack on Windows, compile with NO_SSE
-// defined (can be passed to the compiler command line with /D "NO_SSE")
-#if !defined(NO_SSE)
- #define SSE
+// Detect 64-bit under various compilers
+#if (defined(_M_X64) || defined(_WIN64) || defined(__LP64__) || defined(_LP64))
+# define G3D_64BIT
+ #if defined(WIN32)
+ #include <intrin.h>
+ #endif
+#else
+# define G3D_32BIT
#endif
-// On g++, recognize cases where the -msse2 flag was not specified
-#if defined(SSE) && defined(__GNUC__) && ! defined (__SSE__)
-# undef SSE
+// Strongly encourage inlining on gcc
+#ifdef __GNUC__
+#define inline __inline__
#endif
@@ -74,7 +89,7 @@
# ifndef __GNUC__
# error G3D only supports the gcc compiler on OS X.
# endif
-
+
# if defined(__i386__)
# define G3D_OSX_INTEL
# elif defined(__PPC__)
@@ -93,13 +108,15 @@
// Microsoft Visual C++ 6.0 _MSC_VER = 1200
// Microsoft Visual C++ 5.0 _MSC_VER = 1100
-// Turn off warnings about deprecated C routines (TODO: revisit)
+// Turn off warnings about deprecated C routines
# pragma warning (disable : 4996)
// Turn off "conditional expression is constant" warning; MSVC generates this
// for debug assertions in inlined methods.
# pragma warning (disable : 4127)
+/** @def G3D_DEPRECATED()
+ Creates deprecated warning. */
# define G3D_DEPRECATED __declspec(deprecated)
// Prevent Winsock conflicts by hiding the winsock API
@@ -113,19 +130,28 @@
// TODO: remove
# pragma warning (disable : 4244)
-# define ZLIB_WINAPI
-
# define restrict
-# define G3D_CHECK_PRINTF_ARGS
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
+# define G3D_CHECK_PRINTF_ARGS
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_VPRINTF_ARGS
-# define G3D_CHECK_PRINTF_METHOD_ARGS
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
+# define G3D_CHECK_PRINTF_METHOD_ARGS
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_VPRINTF_METHOD_ARGS
// On MSVC, we need to link against the multithreaded DLL version of
// the C++ runtime because that is what SDL and ZLIB are compiled
// against. This is not the default for MSVC, so we set the following
- // defines to force correct linking.
+ // defines to force correct linking.
//
// For documentation on compiler options, see:
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/_core_.2f.md.2c_2f.ml.2c_2f.mt.2c_2f.ld.asp
@@ -191,6 +217,8 @@
# endif
+/** @def G3D_START_AT_MAIN()
+ Defines necessary wrapper around WinMain on Windows to allow transfer of execution to main(). */
# define G3D_START_AT_MAIN()\
int WINAPI G3D_WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw);\
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
@@ -199,6 +227,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
#else
+/** @def G3D_START_AT_MAIN()
+ Defines necessary wrapper around WinMain on Windows to allow transfer of execution to main(). */
# define G3D_START_AT_MAIN()
#endif // win32
@@ -211,6 +241,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
# define restrict __restrict__
# endif
+/** @def G3D_DEPRECATED()
+ Creates deprecated warning. */
# define G3D_DEPRECATED __attribute__((__deprecated__))
// setup function calling conventions
@@ -224,7 +256,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
# define __stdcall __attribute__((stdcall))
# endif
-# elif defined(__x86_64__) || defined(__powerpc__)
+# elif defined(__x86_64__)
# ifndef __cdecl
# define __cdecl
@@ -235,22 +267,65 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) {\
# endif
# endif // calling conventions
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_PRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 3)))
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_VPRINTF_METHOD_ARGS __attribute__((__format__(__printf__, 2, 0)))
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_PRINTF_ARGS __attribute__((__format__(__printf__, 1, 2)))
+
+/** @def G3D_CHECK_PRINTF_METHOD_ARGS()
+ Enables printf parameter validation on gcc. */
# define G3D_CHECK_VPRINTF_ARGS __attribute__((__format__(__printf__, 1, 0)))
#endif
-/**
+/**
@def STR(expression)
Creates a string from the expression. Frequently used with G3D::Shader
- to express shading programs inline.
+ to express shading programs inline.
- <CODE>STR(this becomes a string)<PRE> evaluates the same as <CODE>"this becomes a string"</CODE>
+ <CODE>STR(this becomes a string)\verbatim<PRE>\endverbatim evaluates the same as \verbatim<CODE>\endverbatim"this becomes a string"</CODE>
*/
#define STR(x) #x
+/** @def PRAGMA(expression)
+ \#pragma may not appear inside a macro, so this uses the pragma operator
+ to create an equivalent statement.*/
+#ifdef _MSC_VER
+// Microsoft's version http://msdn.microsoft.com/en-us/library/d9x1s805.aspx
+# define PRAGMA(x) __pragma(x)
+#else
+// C99 standard http://www.delorie.com/gnu/docs/gcc/cpp_45.html
+# define PRAGMA(x) _Pragma(#x)
+#endif
+
+/** @def G3D_BEGIN_PACKED_CLASS(byteAlign)
+ Switch to tight alignment
+ See G3D::Color3uint8 for an example.*/
+#ifdef _MSC_VER
+# define G3D_BEGIN_PACKED_CLASS(byteAlign) PRAGMA( pack(push, byteAlign) )
+#else
+# define G3D_BEGIN_PACKED_CLASS(byteAlign)
+#endif
+
+/** @def G3D_END_PACKED_CLASS(byteAlign)
+ End switch to tight alignment
+ See G3D::Color3uint8 for an example.*/
+#ifdef _MSC_VER
+# define G3D_END_PACKED_CLASS(byteAlign) ; PRAGMA( pack(pop) )
+#elif defined(__GNUC__)
+# define G3D_END_PACKED_CLASS(byteAlign) __attribute((aligned(byteAlign))) ;
+#else
+# define G3D_END_PACKED_CLASS(byteAlign) ;
+#endif
+
+
// Header guard
#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/prompt.h b/externals/g3dlite/G3D/prompt.h
index e25b955ab28..c6df628099e 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/prompt.h
+++ b/externals/g3dlite/G3D/prompt.h
@@ -1,7 +1,7 @@
/**
@file prompt.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Windows GUI code by Max McGuire
@created 2001-08-26
diff --git a/externals/g3dlite/G3D.lib/include/G3D/serialize.h b/externals/g3dlite/G3D/serialize.h
index 2382c0ee0fd..2382c0ee0fd 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/serialize.h
+++ b/externals/g3dlite/G3D/serialize.h
diff --git a/externals/g3dlite/G3D.lib/include/G3D/splinefunc.h b/externals/g3dlite/G3D/splinefunc.h
index a9daad9b578..3f3a018c292 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/splinefunc.h
+++ b/externals/g3dlite/G3D/splinefunc.h
@@ -1,7 +1,7 @@
/**
@file spline.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2004-07-25
@edited 2007-05-05
@@ -10,13 +10,13 @@
#ifndef G3D_SPLINEFUNC_H
#define G3D_SPLINEFUNC_H
-namespace G3D {
-
#include "G3D/platform.h"
#include "G3D/debug.h"
#include "G3D/Array.h"
#include "G3D/g3dmath.h"
+namespace G3D {
+
/**
Interpolates a property according to a piecewise linear spline. This provides
C0 continuity but the derivatives are not smooth.
diff --git a/externals/g3dlite/G3D.lib/include/G3D/stringutils.h b/externals/g3dlite/G3D/stringutils.h
index 20a2ff6e795..e15a757a7a6 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/stringutils.h
+++ b/externals/g3dlite/G3D/stringutils.h
@@ -1,7 +1,7 @@
/**
@file stringutils.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@author 2000-09-09
@edited 2008-08-05
@@ -18,6 +18,16 @@ namespace G3D {
extern const char* NEWLINE;
+/** Separates a comma-separated line, properly escaping commas within
+ double quotes (") and super quotes ("""). This matches Microsoft Excel's
+ CSV output.
+
+ \param stripQuotes If true, strips leading and trailing " and """
+
+ \sa G3D::stringSplit, G3D::TextInput, G3D::readWholeFile
+*/
+void parseCommaSeparated(const std::string s, Array<std::string>& array, bool stripQuotes = true);
+
/**
Returns true if the test string begins with the pattern string.
*/
diff --git a/externals/g3dlite/G3D.lib/include/G3D/uint128.h b/externals/g3dlite/G3D/uint128.h
index 3e970cb2a7e..da1af3ec272 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/uint128.h
+++ b/externals/g3dlite/G3D/uint128.h
@@ -1,7 +1,7 @@
/**
@file uint128.h
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@author Kyle Whitson
@created 2008-07-17
diff --git a/externals/g3dlite/G3D/units.h b/externals/g3dlite/G3D/units.h
new file mode 100644
index 00000000000..2e30304dc62
--- /dev/null
+++ b/externals/g3dlite/G3D/units.h
@@ -0,0 +1,126 @@
+/**
+ @file units.h
+
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+
+ @created 2009-08-21
+ @edited 2009-08-21
+ */
+#ifndef G3D_units_h
+#define G3D_units_h
+
+#include "G3D/platform.h"
+
+namespace G3D {
+/** Use <code>using namespace G3D::units;</code> to include all units
+ into your program. The units system is specifically designed not to
+ be general but to support commonly used units efficiently and
+ clearly. See http://en.wikipedia.org/wiki/SI_prefix for interesting facts
+ about SI/metric units and full definitions.*/
+namespace units {
+
+/** 1e-9 m */
+inline float nanometers() {
+ return 1e-9f;
+}
+
+/** 1e-6 m */
+inline float micrometers() {
+ return 1e-6f;
+}
+
+/** 0.001 m */
+inline float millimeters() {
+ return 0.001f;
+}
+
+/** 0.01 m */
+inline float centimeters() {
+ return 0.01f;
+}
+
+/** SI base unit of distance measure. */
+inline float meters() {
+ return 1.0f;
+}
+
+/** 1000 m */
+inline float kilometers() {
+ return 100.0f;
+}
+
+/** 0.0254 m */
+inline float inches() {
+ return 0.0254f;
+}
+
+/** 0.3048 m */
+inline float feet() {
+ return 0.3048f;
+}
+
+/** 0.9144 m */
+inline float yards() {
+ return 0.9144f;
+}
+
+/** 1609.344 m */
+inline float miles() {
+ return 1609.344f;
+}
+
+/////////////////////////////////////////////////////////////
+
+/** SI base unit of angular measure. */
+inline float radians() {
+ return 1.0f;
+}
+
+/** pi/180 */
+inline float degrees() {
+ return 0.0174532925f;
+}
+
+//////////////////////////////////////////////////////////////
+
+/** 1e-9 s */
+inline float nanoseconds() {
+ return 1e-9f;
+}
+
+/** 1e-3 s */
+inline float milliseconds() {
+ return 1e-3f;
+}
+
+/** Base unit of time */
+inline float seconds() {
+ return 1.0;
+}
+
+/** 60 s */
+inline float minutes() {
+ return 60.0f;
+}
+
+/** 3600 s */
+inline float hours() {
+ return 3600.0f;
+}
+
+/** 86400 s */
+inline float days() {
+ return 86400.0f;
+}
+
+/** 31556926 s */
+inline float years() {
+ return 31556926.0f;
+}
+
+///////////////////////////////////////////
+
+}
+}
+
+#endif
diff --git a/externals/g3dlite/G3D.lib/include/G3D/vectorMath.h b/externals/g3dlite/G3D/vectorMath.h
index aedc731e7f8..ac6d2b32e9d 100644
--- a/externals/g3dlite/G3D.lib/include/G3D/vectorMath.h
+++ b/externals/g3dlite/G3D/vectorMath.h
@@ -3,7 +3,7 @@
Function aliases for popular vector methods.
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created: 2001-06-02
@edited: 2004-02-02
diff --git a/externals/g3dlite/doc-files/changelog.dox b/externals/g3dlite/doc-files/changelog.dox
deleted file mode 100644
index fd52b99f271..00000000000
--- a/externals/g3dlite/doc-files/changelog.dox
+++ /dev/null
@@ -1,1872 +0,0 @@
-/**
- @page changelog Change Log
-
-<P>
-
- Major version numbers introduce API changes that are not backwards
- compatible. Minor versions are backwards compatible to the
- previous major release, except for critical bug fixes. Deprecated functionality
- will be supported until (at least) the next major release.
-
-
-<hr>
-
- <P>
- Changes in 7.01:
- <ul>
- <li> Video file reading and writing via FFmpeg added
- <li> Added computeBounds method to ArticulatedModel::Part that calls computeBounds on each TriList. Changed updateAll to automatically call computeBounds [Kyle]
- <li> Added constructor to Matrix4 to construct a matrix from an upper-left 3x3 submatrix and an upper-right 3x1 submatrix [Kyle]
- <li> <b>Incompatible change</b>: RegistryUtil functions now require an explicit value parameter instead of extracting the value from the key string.
- <li> <b>Incompatible change</b>:GApp now calls the onLogic handler before the simulation handlers but after the user input and network handlers
- <li> <b>Incompatible change</b>: Changed GHashCode and other functors to traits. See \link guidenewuser \endlink. Added typedefs and adapters to make this mostly backwards compatible.
- <li> Added parallax occlusion mapping to G3D::SuperShader (specify Material::parallaxSteps > 1)
- <li> Added normal mapping to G3D::SuperShader (specify Material::parallaxSteps == 0)
- <li> G3D::Texture resizes textures that exceed the device maximum size
- <li> G3D::Array now allows control over MIN_ELEMENTS and MIN_BYTES using template parameters
- <li> Clarified G3D::Any file format in documentation
- <li> G3D::Texture::PreProcess::gammaAdjust
- <li> G3D::ShadowMap::lightProjection(), G3D::ShadowMap::lightFrame()
- <li> Added Barycentric coordinates to CollisionDetection::isPointInTriangle
- <li> G3D::RenderDevice::beginOpenGL, G3D::RenderDevice::endOpenGL
- <li> PointAABSPTree::clearData
- <li> AABSPTree -> KDTree
- <li> GApp now allows the MidgetManager to process events in onEvent before the GApp::onEvent executes
- <li> Added spotlight support to SuperShader
- <li> Switched SuperShader to use ph
- <li> Adjusted standard deviation used in G3D::GaussianBlur to provide smoother filtering
- <li> Put HashTrait and EqualsTrait in their own headers separate from Table.h
- <li> ArticulatedModel::facet
- <li> Renamed GWindow to G3D::OSWindow
- <li> ReferenceCountedPointer now asserts that the pointer is not NULL on method invocation
- <li> G3D::ShadowMap now computes appropriate matrices for spot lights
- <li> Added ImageFormat::convert [Danny and Kyle]
- <li> 3- and 4- argument min and max
- <li> G3D::GaussianBlur now correctly sets the output viewport
- <li> G3D::Framebuffer::clear
- <li> IFSModel and ArticulatedModel now load Princeton Shape Benchmark OFF files.
- <li> G3D::Any CoordinateFrame now serialized using angles
- <li> CameraControlWindow now prints angles in degrees
- <li> ImageXXX classes now have a format() method
- <li> OSWindow::create
- <li> MeshAlg::toIndexedTriList now supports TRIANGLE_FAN input.
- <li> Tuned Table and hash functions for performance [Kyle & Morgan]
- <li> GEvent::toString
- <li> G3D::TextInput now treats characters with ASCII code greater than 127 as symbols
- <li> G3D::ThreadSet
- <li> G3D::Texture::white
- <li> G3D::Matrix4::upper3x3
- <li> G3D::Matrix4::homoMul
- <li> ArticulateModel::fromFile now takes a Matrix4 instead of a CoordinateFrame to allow arbitrary linear transformations.
- <li> ArticulatedModel::createCornellBox
- <li> Material::createDiffuse
- <li> ImageFormat::convert
- <li> G3D::filenameBase
- <li> Removed SDL_SysWMEvent, which was never supported by GEvent anyway
- <li> Removed TextureFormat::SAME_AS_SCREEN to break dependence on OpenGL
- <li> TextureFormat has been renamed to G3D::ImageFormat and moved into G3D.lib
- <li> Added variable time control points to G3D::Spline
- <li> Gui controls now have configureable GuiControl::setCaptionSize
- <li> Gui controls now default to no indent if the caption is "" (use " " for indent with no caption)
- <li> G3D::GuiContainer
- <li> G3D::GThread::started
- <li> buildg3d installation arguments changed--see
- <li> G3D::Vector3int32
- <li> GuiButton now accepts an optional callback function/method
- <li> FileDialog now accepts an extra "note" argument
- <li> FileDialog::getFilename non-static to support subclassing
- <li> System::currentDateString
- <li> Expanded G3D::ArticulatedModel documentation
- <li> Build system now executes on multiple processors (about 1.8x speedup for dual-core)
- <li> Build system now caches dependencies (about 5x speedup for small incremental builds)
- <li> Patched LOAD_EXTENSION to work around gcc pointer-to-function cast issues
- <li> Tool buttons added to a G3D::GuiPane automatically align to the previous one.
- <li> Added invisible GuiPane style
- <li> G3D::uint128 [Kyle]
- <li> Increased BSPMap rendering by 10% by reducing state changes
- <li> Added prompt argument to FileDialog::getFilename
- <li> G3D::PosedModel::getBoxBounds on an array
- <li> G3D::PosedModel::getSphereBounds on an array
- <li> Changed RenderDevice::screenshot to save .png instead of .jpg files
- <li> G3D::SuperShader now supports a customMap and customConstant for experimenting with shaders.
- <li> G3D::SuperShader now does not ever light the "back" of a bump-mapped poly, even if the bumps should create a light-facing surface
- <li> G3D::Material promoted to its own class (was G3D::SuperShader::Material)
- <li> G3D::Matrix2
- <li> G3D::VertexAndPixelShader::ArgList::size
- <li> G3D::pathConcat
- <li> G3D::WidgetManager::moveWidgetToBack
- <li> SuperShader / NonShadowed.pix now uses arrays of lights instead of separate variables
- <li> Reduced cost of release-mode Shader argument validation
- <li> G3D::PosedModel::sortAndRender now performs view-frustum culling of objects
- <li> G3D::Draw::lighting for visualizing light sources
- <li> G3D::SuperShader::Pass::purgeCache
- <li> G3D::GuiSlider::setRange
- <li> G3D::GuiPane::addPane no longer takes a
- <li> G3D::VertexAndPixelShader::ArgList::remove
- <li> Optimized G3D::Matrix::pseudoInverse; now about 2x faster
- <li> G3D::GLight::effectSphere
- <li> G3D::GuiWindow::moveTo
- <li> G3D::GuiWindow::setEnabled, enabled
- <li> G3D::GuiButton now sizes to its caption
- <li> G3D::GuiSlider now fires events on change and drag
- <li> G3D::Shader arguments (in G3D::VertexAndPixelShader::ArgList) may now be "optional"
- <li> G3D::GLight::point now has quadratic attenuation by default.
- <li> G3D::ImageFormat::name
- <li> g3dmath.h now includes inttypes.h on gcc and simulates it on visual studio
- <li> G3D::RenderDevice::cullFace
- <li> G3D::LineSegment2D::intersection
- <li> G3D::BinaryInput::setEndian
- <li> G3D::GEvent::MOUSE_BUTTON_CLICK
- <li> Generalized ShadowMap to work with spotlights as well as directional lights
- <li> G3D::GLCaps::supportsTexture, G3D::GLCaps::supportsRenderBuffer
- <li> Opaque G3D::ArticulatedModels now support more than 2 non-shadow casting light sources
- <li> Added proof symbol parsing to TextInput [Corey Taylor]
- <li> Added G3D::AABox::corner() to match G3D::Box::corner() [Corey Taylor]
- <li> OS X: G3D::CarbonWindow [Casey]
- <li> OS X: iCompile now generates OS X application bundles and dmg files
- <li> OS X build no longer depends on X11
- <li> G3D::FileDialog
- <li> G3D::Table now allows overriding the default equality operator for keys
- <li> <b>Incompatible change</b>: GApp::onBeforeSimulation now allows mutation of the timesteps
- <li> <b>Incompatible change</b>: Merged GApp::simTime and idealSimTime (the sim time is now idealized)
- <li> cmake now generates project files for Xcode, MinGW, and all Visual Studio versions [Corey Taylor]
- <li> OS X: icompile and buildg3d now generate universal binaries on Intel machines
- <li> G3D::PosedModel::objectSpaceTangents
- <li> G3D::IFSModel::fromData
- <li> G3D::MeshAlg::generateGrid
- <li> G3D::BinaryOutput::ok()
- <li> G3D::generateFilenameBase
- <li> G3D::IFSModel::fromFile now defaults to not welding for improved performance
- <li> G3D::IFSModel members are now protected to allow subclassing
- <li> Removed G3D::uint in favor of G3D::uint32 [Corey Taylor]
- <li> Added G3D::GMaterial(TextureRef) constructor
- <li> Made G3D::GMaterial fields floats
- <li> G3D::GuiControl::setCaption, G3D::GuiWindow::setCaption
- <li> G3D::GuiControl can now be subclassed for custom user-defined controls
- <li> G3D::GuiTheme::renderCanvas
- <li> G3D::GuiTheme::pauseRendering, G3D::GuiTheme::resumeRendering
- <li> G3D::PosedModel::sortAndRender
- <li> G3D::Framebuffer can now attach cube map faces
- <li> System::describeSystem now prints current working directory and application name
- <li> Added /usr/local/-G3D dir- to system data file path [Kai Schroeder]
- <li> Various patches for detecting new CPUs in System.cpp [Corey Taylor]
- <li> g3d_Index macro now available in G3D::Shader GLSL code
- <li> G3D::BackgroundWidget
- <li> G3D::TriangleShape
- <li> Fix: <B>incompatible change</b> OSWindow::Settings::asynchronous is now spelled correclty, with two "n"s
- <li> Fix: Fixes for point-in-triangle and moving-sphere-fixed-tri; previous code projected onto the wrong axes, so barycentric coords were wrong for nearly vertical triangles.
- <li> Fix: Changed some doubles to floats in G3D::Triangle
- <li> Fix: Changed all of the isXXX(char) methods to take unsigned char arguments so that they can parse extended symbols
- <li> Fix: AABSPTree::deserializeStructure was missing a return statement [Derex]
- <li> Fix: Draw::plane was drawing the plane reflected through the origin [Macklin Chaffee]
- <li> Fix: Added template parameters to friends in AABSPTree and PointAABSPTree [expiring_frog]
- <li> Fix: System::findDataFile uses data directory set by GApp
- <li> Fix: AtomicInt32 decrement returns int32 instead of uint32
- <li> Fix: OS X function keys now work correctly under CarbonWindow
- <li> Fix: OS X modifier keys now work correctly under CarbonWindow
- <li> Fix: OS X arrow keys now work correctly under CarbonWindow
- <li> Fix: Rewrote buildg3d to fix many longstanding bugs, including mismatched 'bin' directories and confusion about the 'install' target
- <li> Fix: gfxmeter reports now format correctly regardless of monitor width
- <li> Fix: patch to initialize correctly on the Mesa library, which crashes when requesting DEPTH24_STENCIL8
- <li> Fix: stringSplit now works correctly for adjacent split characters [Akita Noek]
- <li> Fix: Draw::axes labels now obey current viewport
- <li> Fix: GuiWindow now loses focus when hidden
- <li> Fix: GFont::draw2D now computes correct horizontal bounds on text
- <li> Fix: GuiPane no longer renders when invisible
- <li> Fix: Clicking off of all GuiWindows makes none of them have focus
- <li> Fix: Win32Window now allows windows programmatically positioned anywhere on a multiple monitor screen
- <li> Fix: Win32Window now does not fail when dragging a GL context between multiple monitors
- <li> Fix: SuperShader now correctly lights bump-mapped surfaces in tangent space [Kyle Whitson]
- <li> Fix: GuiPane now renders its caption
- <li> Fix: Rect2D::border now grows the correct way (positive = grow)
- <li> Fix: Added % operator to TextInput
- <li> Fix: Added multi-line printing to GConsole
- <li> Fix: G3D::Texture can now create empty cube maps
- <li> Fix: G3D::Table iterator now correctly parameterized on hashfunction and equality function as well as key and value
- <li> Fix: G3D::Table now passes Values by reference when setting them, avoiding one copy
- <li> Fix: various Framebuffer/empty texture initialization bugs on ATI cards
- <li> Fix: uniform arrays for GLSL
- <li> Fix: All aliasing warnings have been fixed no longer needs -fno-strict-aliasing [Corey Taylor]
- <li> Fix: [ 1829704 ] debugAssert in Array::operator[](unsigned int n) wrong
- <li> Fix: GuiWindow::pack now recursively packs all child panes
- <li> Fix: patch to continue build when javac isn't found on both windows and linux [Corey Taylor]
- <li> Fix: [ 1599139 ] Fixes to make buildg3d work on non C:\ windows systems [Patrick Burke]
- <li> Fix: Added faster overloads of GImage::stripAlpha() and GImage::insertRedAsAlpha() [Corey Taylor]
- <li> Fix: GImage::save() with odd-widths bmp files [Corey Taylor]
- <li> Fix: Draw::capule renders properly (capule was not visible) [Corey Taylor]
- <li> Fix: Patched ShadowMap to work around ATI and OS X driver shadow map bugs.
- <b>Incompatible change:</b>Required changing several interfaces to take ShadowMapRef arguments.
- <li> Fix: GCamera::Frustum was facing backwards
- <li> Fix: [ 1774479 ] texture glformats wrong (caused incorrect font rendering on Intel)
- <li> Fix: ArticulatedModel static methods do not force loading of shaders unless an ArticulatedModel has actually been loaded.
- <li> Fix: RenderDevice::setAlphaWrite/setColorWrite implemented correctly
- <li> Fix: Implemented ImageFormat::fromCode
- <li> Fix: [ 1766509 ] Texture doesn't handle 3D textures correctly
- <li> Fix: Separate bool, float, and int back ends for GLSL shaders
- </ul>
-
-<hr>
- <P>
- Changes in 7.00:
- <ul>
- <li> Upgraded to iCompile 0.5.3. Requires users to delete their old ice.txt and ~/.icompile files
- <li> Key to toggle the user camera is now F2 (was Tab)
- <li> Support for g++ 4.1 [Corey]
- <li> Patches for 64-bit compilation [Corey]
- <li> WinMain is now compiled as C++ code (fixed some "manifest" errors on certain VC8 installations)
- <li> G3D::ShadowMap
- <li> Cleaned up and documented G3D::GCamera project/unproject API [Jeff Marsceill]
- <li> Made G3D::MD2Model::Pose easier to use
- <li> G3D::Matrix
- <li> Added G3D::Texture methods for reading back color and depth textures
- <li> G3D::RenderDevice::getFixedFunctionLighting
- <li> G3D::debugPrintf -> G3D::consolePrintf
- <li> G3D::GApp::debugPrintf -> G3D::screenPrintf
- <li> Reduced ArticulatedModel and MD2Model push/popState calls
- <li> G3D::Shader now defines platform and graphics vendor macros
- <li> User camera control requires right mouse click to move
- <li> G3D::AnyVal::fromFile, G3D::AnyVal::load, G3D::AnyVal::save
- <li> G3D::AnyVal now uses copy-on-mutate for fast Array/Table copies
- <li> G3D::AnyVal no longer separates table entries with ";"
- <li> G3D::AnyVal now provides casts to basic data types
- <li> G3D::AnyVal G3D::Rect2D and G3D::AABox types
- <li> G3D::NetListener, G3D::ReliableConduit, and G3D::LightweightConduit can now be created without an explicit NetworkDevice pointer
- <li> GApp::onGraphics now takes posed model arguments
- <li> G3D::RenderDevice::beginFrame no longer executes a pushState-- state will carry over between frames
- <li> G3D::GUniqueID
- <li> GApp::onPose
- <li> All classes that read from files can now read data inside zipfiles.
- <li> Changed G3D::hashCode(T) to ::GHashCode<T>(T) [Corey]
- <li> Removed "G3D::" from the printed portion of the documentation index to make it easier to read.
- <li> OSWindow::fireEvent for inserting user events into the queue
- <li> G3D::logPrintf
- <li> System::findDataFile
- <li> On OS X, G3D::FirstPersonManipulator now treats ctrl-click as right click
- <li> Increased mouse sensitivity of G3D::FirstPersonManipulator on OS X
- <li> System::getClipboardText, System::setClipboardText
- <li> Widget::window() accessor
- <li> Replaced SDLEvent with G3D::GEvent
- <li> Increased GFont rendering performance, added GFont::send2DQuads for fast rendering of large amounts of text
- <li> G3D::GFont now supports fonts with 256 characters (.fnt file format version 2)
- <li> Upgraded to the OpenGL 2.0 glext/glxext/wglext headers
- <li> G3D::GuiTheme, G3D::GuiText
- <li> G3D::UprightFrame, G3D::UprightSpline
- <li> G3D::Spline
- <li> G3D::RenderDevice::clip2D
- <li> G3D::Win32Window now returns events for up to 5 mouse buttons
- <li> Significantly changed GEvent delivery and Widget mechanisms to incorporate notions of focus--see upgrade.html
- <li> Motion events (joystick/mouse) can no longer be cancelled by Widget::onEvent
- <li> Mouse motion events for all platforms
- <li> G3D::PosedModel::Ref::sendGeometry
- <li> G3D::RenderDevice::pushState(FramebufferRef)
- <li> G3D::Texture::PreProcess::computeNormalMap
- <li> direct.h is now included by fileutils.h on Win32 to ensure that chdir, mkdir, etc. are available
- <li> Changed distribution directories to place include, lib, and bin under a directory named after the platform
- and all other files one directory up.
- <li> G3D::GCamera::unproject
- <li> Made G3D::Ray non-virtual for efficiency
- <li> RenderDevice::alphaWrite now defaults to true
- <li> Changed G3D install directory from g3d-7_00 to g3d-7.00
- <li> On a GL 2.0 or greater driver, G3D::GLCaps now assumes the presence of all GL2 extensions even if they are not explicitly listed by the card [Corey Taylor]
- <li> debugPrintf now flushes stderr on Unix systems
- <li> G3D::Lighting::fromSky
- <li> G3D::Texture::newGLTexture2D [Corey Taylor]
- <li> Added 10-bit cinema texture formats [Corey Taylor]
- <li> Added G3D::ArticulatedModel to the core (includes 3DS loading)
- <li> Added G3D::SuperShader to the core
- <li> Merged GApp and GApplet into GApp to make the common case easier to implement
- <li> Removed GApp::debugMode options, removed "debug" prefix from most fields.
- <li> G3D::zipfileExists for testing if a filename path contains a .zip to be opened [Eric]
- <li> G3D::isZipfile tests the header of a file to see if it is a .zip [Eric]
- <li> G3D::zipRead and G3D::zipClose to open and close .zip files [Eric]
- <li> G3D::fileExists supports filename paths that contain .zip [Eric]
- <li> G3D::fileLength supports filename paths that contain .zip [Eric]
- <li> G3D::getFiles and G3D::getDirs support filename paths that contain .zip [Eric]
- <li> Texture::isSupportedImage - static method, returns true if a filename exists and is compatible with Texture [Eric]
- <li> Viewer (tool) - Allows drag and drop viewing of many supported file formats [Eric]
- <li> GFXMeter (tool) - Updated for 7.00 compatibility: GApplet structure removed [Eric]
- <li> OSWindow::Settings has an allowMaximize field. Win32Window will have an activated 'Maximize' button if true [Eric]
- <li> GApp2::debugCamera -> GApp2::defaultCamera
- <li> GApp2::debugController -> GApp2::defaultController
- <li> Made GApp2::debugText private
- <li> Added g3d_WorldLight0 to the G3D shader extensions
- <li> Added Shader support for GL_FLOAT_MAT3_ARB uniforms
- <li> Tab (command completion) no longer auto-repeats in GConsole
- <li> GConsole now limits the key repeat rate to the framerate
- <li> Removed GApp::Settings::useNetwork because it was no longer needed--Win32 does not trigger firewall checks anymore
- <li> Optimized AABSPTree balance and queries; now about 20% faster than 6.10, but requires 30 bytes more memory per member
- <li> G3D::Array::pop now shrinks the underlying array by default (Array::popRemove does not shrink the array and is faster)
- <li> Fast O(<i>n</i>), non-destructive G3D::Array::partition and G3D::Array::medianPartition
- <li> Increased ReliableConduit read attempts before timeout from 10 to 100
- <li> G3D::GImage::pixel1 now returns G3D::Color1uint8*
- <li> G3D::Color1, G3D::Color1uint8
- <li> G3D::Image1, G3D::Image1uint8
- <li> G3D::Image3, G3D::Image3uint8
- <li> G3D::Image4, G3D::Image4uint8
- <li> BinaryInput::flipEndian32, BinaryInput::flipEndian16
- <li> Texture::createEmpty now intializes invertY = true, which is usually desirable for Framebuffer rendering.
- <li> G3D::Map2D
- <li> G3D::Vector4int8
- <li> G3D::PointShape
- <li> G3D::GImage::RGBAtoRGB
- <li> Added GLEW compatibility [nico]
- <li> Added data-files directory to the locations searched for G3D demo data
- <li> On Win32, assertions now print ot the Output window as well as the dialog box.
- <li> On Win32, $TEMP is now used for the logfile location instead of c:\tmp
- <li> G3D::GKey replaces old SDL key enumeration
- <li> Decreased memory requirements and increased balance speed of G3D::AABSPTree by adding a level of indirection
- between tree nodes and the data stored in them.
- <li> Added OSWindow::Settings::caption
- <li> <b>Win32 programs must call the macro <b><code>G3D_START_AT_MAIN();</code></b> at top-level if they do not define WinMain themselves.</b>
- <li> Win32 switched from MBCS to UNICODE for the binaries (G3D sources compile under either, but UNICODE is the VC8 default)
- <li> Replaced SDL event types with G3D event types
- <li> Added support for GL_ARB_point_sprite
- <li> Win32 programs must call the macro <b><code>G3D_START_AT_MAIN();</code></b> at top-level if they do not define WinMain themselves.
- <li> Win32 switched from MBCS to UNICODE for the binaries (G3D sources compile under either)
- <li> Changed G3D::GApp::main to return an int
- <li> Added header support for GL_EXT_geometry_shader4 ("Geometry shaders")
- <li> Changed IFSModel::create to IFSModel::fromFile
- <li> G3D::BSPMap for loading Quake3 .bsp files
- <li> G3D::TextInput::Settings::caseSensitive
- <li> G3D::TextInput::readBoolean, G3D::TextInput::Settings::trueSymbols, G3D::TextInput::Settings::falseSymbols, G3D::TextOutput::Settings::trueSymbol, G3D::TextOutput::Settings::falseSymbol, G3D::TextOutput::writeBoolean, G3D::Token::BOOLEAN_TYPE
- <li> G3D::TextInput::Settings::msvcSpecials now defaults to true
- <li> Made the input to G3D::tessellateComplexPolygon a constant array reference
- <li> Removed SDL from Win32 build
- <li> Increased maximum ReliableConduit message size to 60 MB
- <li> Removed error macro
- <li> G3D::GConsole
- <li> Rect2D::lerp
- <li> Added GL_EXT_packed_depth_stencil
- <li> Added G3D::ImageFormat::DEPTH24_STENCIL8 packed stencil mode
- <li> getOpenGLState now includes GL_LIGHT_MODEL_TWO_SIDE value
- <li> Made ThirdPersonManipulator constructor protected (use ThirdPersonManipulator::create now)
- <li> G3D::ToneMap
- <li> Changed Renderbuffer::createEmpty argument order to match Texture::createEmpty
- <li> G3D::IFSModel can now remove degenerate faces on load
- <li> G3D::MD2Model::textureFromFile
- <li> Replaced AABSPTree::beginRayIntersection with simpler AABSPTree::intersectRay interface.
- <li> G3D::MD2Model now uses floating point texture coordinates, which makes it easier to
- write pixel shaders for MD2Models
- <li> G3D::GImage::computeNormalMap now accepts a scale factor indicating how steep the input bump map is
- <li> Added G3D::Shader support for the GLSL #version directive
- <li> Optimized G3D::GImage::computeNormalMap to use primarily integer math
- <li> G3D::AABox::contains(AABox)
- <li> Added large file (>2GB) support to BinaryInput [Peter]
- <li> Renamed graphics3d.h to G3D/G3D.h
- <li> Renamed GLG3D.h to GLG3D/GLG3D.h
- <li> Renamed G3DAll.h to G3D/G3DAll.h
- <li> G3D::Quat::unitize now normalizes in place
- <li> Added G3D::Quat::operator*=
- <li> Removed G3D::FirstPersonManipulator's constructor--use the static G3D::FirstPersonManipulator::create method now.
- <li> Changed BSPMap leaf bounds from Box to AABox--50% improvement in frustum culling speed
- <li> Optimized BSPMap rendering performance
- <li> Removed all deprecated APIs
- <li> All accessors of the form "getXXX" that take no arguments are now named just "xxx"
- <li> G3D::Sky::create is now named G3D::Sky::fromFile and no longer accepts a G3D::RenderDevice. G3D::Sky::render now requires a RenderDevice.
- <li> G3D::GFont::fromFile no longer accepts a G3D::RenderDevice and G3D::GFont::draw2D now requires a RenderDevice.
- <li> Removed an assertion in BinaryInput requiring that compressed buffers be copied on construction [Nick Bray]
- <li> Removed CoordinateFrame::zLookDirection (use -1)
- <li> Removed Capsule::endPoint (use point)
- <li> Removed CoordinateFrame::getStrafeVector (use rightVector)
- <li> Removed static constants (use equivalent lower-case methods)
- <li> Removed Cylinder::getPoint1 (use point)
- <li> Fix: BSPMap::getStartingPosition now works correctly on all maps [Jeff]
- <li> Fix: Workaround for ATI drivers that do not support zero-area scissor region
- <li> Fix: GL_EXT_texture_3D -> GL_EXT_texture3D
- <li> Fix: ARB_texture_cube_map and EXT_texture_cube_map are now aliases on all cards
- <li> Fix: EXT_texture_edge_clamp and SGIS_texture_edge_clamp are now aliases on all cards
- <li> Fix: G3D::Sky now turns off lighting
- <li> Fix: Win32Window now returns mousebutton and motion events according to the GEvent spec
- <li> Fix: Win32Window now operates correctly in fullscreen mode
- <li> Fix: Fixed TGA decode to load from the middle of a binaryinput
- <li> Fix: Added texture coordinates to posed MD2Models
- <li> Fix: prompt/debugAssert now correctly responds to button presses on OS X
- <li> Fix: GConsole now filename completes after the first word
- <li> Fix: RenderDevice::getDepthBufferValue now checks for the presence of a depth buffer.
- <li> Fix: G3D::AABSPTree now correctly handles members with infinite bounds on ray intersection tests
- <li> Fix: Removed use of tmpfile on Unix
- <li> Fix: Java ReliableConduit now properly waits if the buffer is full when sending
- <li> Fix: [ 1607693 ] Triangles/Second display is now correct (rates were too low in 6.10)
- <li> Fix: NetworkDevice now does not perform a test broadcast during initialization
- <li> Fix: G3D::LightweightConduit::ok is now false if any error occurs during initialization
- <li> Fix: BSPMAP for cards without glMultiDrawElementsEXT
- <li> Fix: [ 1584335 ] ReliableConduit incorrectly assumes it's ok
- <li> Fix: RenderDevide::push2D no longer resets the frameBuffer.
- <li> Fix: Framebuffer logic for counting number of attachments was broken
- <li> Fix: [ 1581986 ] Matrix3::fromAxisAngle now normalizes the input vector
- <li> Fix: [1490643] Linux/FreeBSD/OS X binaries are now compiled with -fno-strict-aliasing, which fixes some
- memory corruption problems that occurred with full optimizations.
- <li> Fix: Fixed all warnings on gcc-4.1 and VC8.
- <li> Fix: Matrix and CoordinateFrame serializers inside G3D::AnyVal dropped data
- <li> Fix: [ 1535759 ] valgrind finds initialization/deletion errors in TextOutput, Matrix [Chris Demetriou]
- <li> Fix: Patched MD2Model to automatically reduce animation times to less than 100000; large time were overflowing double->int conversion and causing animations to appear scrambled.
- <li> Fix: [ 1535292 ] global Table hashCode overloads broken [Chris Demetriou]
- <li> Fix: [ 1535736 ] Fixed System.cpp memory allocator to compile on 64-bit machines correctly [Chris Demetriou]
- </ul>
-
- <hr>
- <P>
- Changes in 6.10:
- <UL>
- <LI> Optimized G3D::CoordinateFrame::pointToObjectSpace to be fully inlined via left-multiplication
- <LI> G3D::Matrix4::orthogonalProjection from a G3D::Rect2D
- <LI> G3D::RenderDevice::swapBuffers
- <LI> G3D::AnyVal
- <LI> G3D::ThirdPersonManipulator
- <LI> Added support for GL_SGIS_texture_lod in Texture.
- <LI> Fix: [ 1490655 ] MeshAlg::Edge::containVertex goes off the end of the array
- <LI> Fix: [ 1511729 ] NVIDIA rectangle generates errors in mipmap code
- <LI> Fix: [ 1507296 ] RenderDevice must swapBuffer on resize
- </UL>
-<hr>
- <P>
- Changes in 6.09:
- <UL>
- <LI> glDepthBoundsEXT
- <LI> G3D::Quat::sameRotation
- <LI> Full loading of the GL_ATI_separate_stencil extension, support within RenderDevice
- <LI> platform.h undefines WIN32_LEAN_AND_MEAN, NOMINMAX after it has defined them
- <LI> G3D::Texture::Settings::maxMipMap
- <LI> Renamed Texture::Parameters to Texture::Settings (backwards compatible typedef added)
- <LI> Optimized IFSModel rendering by increasing internal VAR cache size and reducing the number of state changes.
- Can now render more than 1000 IFSModels at 30 fps on GeForce 7800.
- <LI> G3D::System::mallocStatus
- <LI> Range checking on Vector2int16::operator[]
- <li> GImage::BAYER_G8R8_B8G8_to_R8G8B8_MHC, GImage::BAYER_B8G8_G8R8_to_R8G8B8_MHC
- <LI> IFSModel and MD2Model now allocated their posed models using System::malloc
- <LI> Increased the memory maintained by G3D::System for buffer pools up to a total of 13 MB:
- 8 MB tiny (preallocated), 1 MB small (on demand), 4 MB medium (on demand). This was observed to
- dramatically increase performance (15x) in real programs that were
- performance limited by memory allocation time.
- <LI> NetworkDevice now uses Winsock2.0 on Windows (controlled by the G3D_WINSOCK_MAJOR_VERSION/G3D_WINSOCK_MINOR_VERSION settings in NetAddress.h)
- <LI> G3D::Manipulator
- <LI> G3D::GApplet now runs installed G3D::GModules (except for graphics, which is left to the progrmamer)
- <LI> G3D::GApp::addWidget, G3D::GApplet::addWidget, G3D::GApp::removeWidget, G3D::GApplet::removeWidget
- <LI> G3D::Widget, G3D::WidgetManager
- <LI> G3D::System::getEnv()
- <LI> G3D::PosedModel2D
- <LI> G3D::DXCaps
- <LI> Increased precision of several Quat operations
- <LI> G3D::Quat::fuzzyEq
- <LI> G3D::Quat::operator-
- <LI> G3D::LineSegment::length, G3D::LineSegment::point
- <LI> Increased fuzzyEpsilon by a factor of 10 to take into account the new float32 focus of the APIs
- <LI> G3D::RegistryUtil
- <LI> G3D::LineSegment2D
- <LI> G3D::ConvexPolygon2D
- <LI> G3D::AxesShape
- <LI> contrib/shaders/showDepth
- <LI> G3D::Crypto with MD5 and CRC32 hashes
- <LI> TextureManager::findTexture, TextureManager::cacheTexture [Erik]
- <LI> Win32Window::_directInput created on-demand [Erik]
- <LI> WeakReferenceCountedPointer has more comparison operators [Erik]
- <LI> GImage::resolveFormat utility function [Erik]
- <LI> GLCaps supports MESA
- <LI> G3D::Win32Window and G3D::SDLWindow now release input capture and make the mouse visible on destruction
- <LI> G3D::OSWindow::setInputCaptureCount, G3D::OSWindow::inputCaptureCount, G3D::OSWindow::incInputCaptureCount, G3D::OSWindow::decInputCaptureCount
- <LI> GImage::makeCheckerboard
- <LI> G3D::Vector3::one()
- <LI> G3D::Shader now supports g3d_size(sampler2D) and g3d_invSize(sampler2D) extensions in GLSL shaders.
- <LI> Renamed GAppSettings to G3D::GApp::Settings (old name is supported but deprecated)
- <LI> Renamed GWindowSettings to G3D::OSWindow::Settings (old name is supported but deprecated)
- <LI> Renamed TextInput::Options to G3D::TextInput::Options (old name is supported but deprecated)
- <LI> G3D::FPManualController::setAutoActive for World of Warcraft style controller
- <LI> G3D::isSlash, G3D::isQuote
- <LI> G3D::GApplet::onEvent can now consume (i.e., prevent G3D::GApp from seeing) the event
- <LI> G3D::CoordinateFrame::fuzzyIsIdentity, G3D::CoordinateFrame::isIdentity, G3D::CoordinateFrame::fuzzyEq
- <LI> Matrix3::isOrthonormal
- <LI> [1421201] Removed excess gl (NVIDIA) headers
- <LI> Win32Window destructor now releases the mouse if it was captured and the current GL context is that window and the window was not created from an existing HDC/HWND
- <LI> Fix: com.graphics3d.g3d.ReliableConduit now correctly selects on the waiting socket
- <LI> Fix: [ 1166057 ] AABSPTree::beginBoxIntersection
- <LI> Fix: GLCaps::supports(ImageFormat) now returns correct results on all cards
- <LI> Fix: Shadow map rendering of default PosedModels now enables lighting
- <LI> Fix: G3D::UserInput now restores the mouse position after pureDeltaMouse is turned off
- <LI> Fix: G3D::Win32Window now clips precisely to the client area during an input grab.
- <LI> Fix: [ 1383042 ] free static variables on shutdown
- <LI> Fix: [1449115 ] Texture loading for odd-byte rows
- <LI> Fix: G3D::Win32Window now produces correct character and scan codes for key events
- <LI> Fix: G3D::GApplet::onEvent calls GApplet::processEvent by default
- <LI> Fix: [ 1444320 ] TextInput parsed ".1" as "1" instead of "0.1"
- <LI> Fix: G3D::Shape::type is now const
- <LI> Fix: 0 --> 0.0f FrameBuffer.h [Erik]
- <LI> Fix: Fixed Texture read-back dimensions for cube-map
- <LI> Fix: Missing #include in SkyParameters.h [Erik]
- <LI> Fix: Quad triangle counts are now accurate (were off by factor of 4 in 6.08)
- <LI> Fix: contrib/ArticulatedModel now correctly masks all components using the diffuse alpha in fixed function mode
- <LI> Fix: G3D::CoordinateFrame::getHeading was flipped front-to-back
- <LI> Fix: [ 1404487 ] Missing Alt key up/down events on Win32
- <LI> Fix: [ 1484924 ] collisionTimeForMovingPointFixedBox normals
- </UL>
- <P>
-<hr>
- Changes in 6.08:
- <UL>
- <LI> Moved Win32 linker statements out of platform.h for IncrediBuild compatibility.
- <LI> G3D::Texture and G3D::Sky now accept a rescaling factor
- <LI> Added GFont::fromMemory() [Corey]
- <LI> Added optional argument to Quat::slerp() for slerp/lerp angle threshold. [Corey]
- <LI> Across-the-board performance optimizations. Most apps should render 10% faster.
- Includes removal of Milestones when using VBO VAR [Nick Bray], GFont::draw2D and
- Draw::rect2D stripped down to raw OpenGL, consistent internal use of float,
- increased RenderDevice state change optimization.
- <LI> Minimized header interdependencies (GLG3D headers no longer include all of G3D)
- <LI> Added GThread and GMutex classes. [Corey]
- <LI> Added ImageFormat::fromCode(). [Corey]
- <LI> Added Plane::distance() and Plane::closestPoint() helper methods. [Corey]
- <LI> G3D::ImageFormat::code, G3D::ImageFormat::colorSpace
- <LI> <B>incompatible change</B> G3D::MeshAlg::computeTangentSpace basis now computes a right-handed coordinate frame,
- where the binormal direction is the negative of the direction it faced in G3D 6.07.
- <LI> Exposed G3D::RenderDevice::beforePrimitive and G3D::RenderDevice::afterPrimitive to end-user code for
- integrating raw OpenGL calls.
- <LI> G3D::Framebuffer and G3D::Renderbuffer to implement the Framebuffer_object extension [Dan Hilferty]
- <LI> G3D::Shader::hasArgument
- <LI> G3D::Texture::getImage
- <LI> Changed SECOND, MINUTE, DAY, HOUR, SUNRISE, SUNSET, MIDNIGHT, METER, KILOMETER to enum values instead of #defines
- <LI> G3D::Texture::Parameters; deprecated most Texture constructors in favor of ones that use this class
- <LI> Moved most image manipulation routines into GImage.
- <LI> G3D::GImage now allocates the underlying buffer in multiples of bytes to allow slight overflor for MMX algorithms
- <LI> G3D::GImage::BAYER_R8G8_G8R8_to_R8G8B8_MHC
- <LI> G3D::GImage::R8G8B8_to_Y8U8V8
- <LI> G3D::GImage::Y8U8V8_to_R8G8B8
- <LI> G3D::GImage now supports PPM binary
- <LI> Various Rect2D helpers [Nick Bray]
- <LI> ConvexPolyhedron improved clipping [Nick Bray]
- <LI> G3D::System::build
- <LI> G3D::System::calloc
- <LI> G3D::GImage::convertToRGBA
- <LI> contrib/AVI can read most AVI files on Windows.
- <LI> contrib/wxGWindow now uses wxWidgets 2.6.2
- <LI> G3D_DEBUG now controls whether debug code is enabled; it defaults to the value of _DEBUG
- <LI> zlib upgraded to 1.2.3 [Corey]
- <LI> zlib now statically linked on Win32 (no longer requires zlib1.dll at runtime) [Corey]
- <LI> G3D::MeshShape
- <LI> Changed std::string hashCode to use CRC32 to reduce collisions
- <LI> G3D::crc32
- <LI> Added occlusion query #defines [Nick Bray]
- <LI> G3D::Win32Window now shares textures and vertex buffers across all GL contexts
- <LI> G3D::Win32Window now enforces single-threading among GL contexts
- <LI> G3D::GLCaps::slowVBO
- <LI> G3D::VARArea now uses main memory vertex buffers on cards with slow VBO implementations.
- <LI> G3D::Matrix3::toString [Peter]
- <LI> G3D::Matrix4::toString [Peter]
- <LI> G3D::Color3::fromHSV [Peter]
- <LI> G3D::Color3::toHSV [Peter]
- <LI> G3D::Color3::jetColorMap [Peter]
- <LI> Optimized G3D::iRound (now faster than casting!)
- <LI> G3D::MD2Model::create now accepts a scale factor
- <LI> #G3D_DEPRECATED macro
- <LI> #G3D_CHECK_PRINTF_ARGS, #G3D_CHECK_VPRINTF_ARGS macros to allow
- checking of printf argument strings under gcc at compile time with
- -Wformat.
- <LI> G3D::TextInput::filename
- <LI> G3D::TextInput::Options::msvcSpecials
- <LI> G3D::TextInput::Options::startingLineNumberOffset
- <LI> G3D::TextInput::readSymbolToken [cgd]
- <LI> G3D::TextInput::readStringToken [cgd]
- <LI> G3D_DEPRECATED macro
- <LI> Threadsafe G3D::ReferenceCountedPointer
- <LI> G3D::AtomicInt32
- <LI> G3D::GThread [Corey]
- <LI> G3D::Array::popDiscard
- <LI> Optimized multi-argument Array::append
- <LI> G3D::GFont 2x faster than in G3D 6.07
- <LI> G3D::RenderDevice::pushState 2x faster than in G3D 6.07
- <LI> G3D::RenderDevice::pushState no longer stores GL texgen and fog information
- <LI> G3D::Draw::fastRect2D
- <LI> G3D::System::outOfMemoryCallback
- <LI> G3D::Queue::fastClear [Chris Demetriou]
- <LI> G3D::Rect2D::x0y1 and x1y0
- <LI> G3D::GLCaps bug tests now run in a separate GL context [Erik Cassel]
- <LI> G3D::GApplet tracks real and simulation time.
- <LI> contrib/Q3Map updated to correctly render instanced objects [Alex Rice]
- <LI> G3D::OSWindow subclasses now required to invoke OSWindow::loadExtensions
- <LI> G3D::Quat::log for non-unit quats and for real-only quats.
- <LI> G3D::GApplet::doUserInput
- <LI> G3D::GApp prints time for each component
- <LI> G3D::Stopwatch
- <LI> G3D::OSWindow::renderDevice()
- <LI> G3D::OSWindow::current()
- <LI> G3D::GLCaps::hasBug_redBlueMipmapSwap and workaround for G3D::Texture on Radeon 7500
- <LI> Fix: CollisionDetection::penetrationDepthForFixedSphereFixedPlane() contact point and normal values. [Corey]
- <LI> Fix: Quat::slerp has invalid shortest path [Corey]
- <LI> Fix: G3D::drawFeatureEdges now uses correctly normalized face edges (and offers a crease angle)
- <LI> Fix: G3D::SDLWindow now releases the mouse on Linux during an assertion.
- <LI> Fix: All keys are reset to up when Win32Window loses focus. [Corey]
- <LI> Fix: gaussRandom is unit gaussian [Corey]
- <LI> Fix: [ 1418276 ] 6.08: Unsupported format for depth texture
- <LI> Fix: Ignoring extra/unused set Shader arguments. [Corey]
- <LI> Fix: [ 1229205 ] uniform texture array (Could not set indexed array uniforms). [Corey]
- <LI> Fix: <B>incompatible change</B> BinaryInput/BinaryOutput copy constructors and assignments were accessible. [Corey]
- <LI> Fix: RenderDevice::screenshotPic would corrupt GImage's heap. [Corey]
- <LI> Fix: Alt-Tab window switching caused an invalid Alt key state. [Corey]
- <LI> Fix: Incorrect window size event in Win32Window sent to OpenGL. [Corey]
- <LI> Fix: [ 1227915 ] Textures don't bind on ATI under GLSL.
- <LI> Fix: [ 1358477 ] ray-plane intersection bug [Dan Keefe]
- <LI> Fix: [ 1370665 ] hash_map moved to stdext in VC8 (2005)
- <LI> Fix: ToneMap extended to use DIM_2D_NPOT instead of DIM_2D_RECT
- <LI> Fix: Texture::copyFromScreen now works with DIM_2D_NPOT textures
- <LI> Fix: Wrapped debugAssertM in do {} while (0) to ensure correct compilation in single-line statements [ERik Cassel]
- <LI> Fix: G3D::Draw::cylinder now renders the bottom correctly
- <LI> Fix: Array::front now compiles under gcc
- <LI> Fix: G3D::Ray::distance used to measure against the origin [David]
- <LI> Fix: [ 1293151 ] ArticulatedModel clipping on Radeon -- disabled auto-mipmap generation on mobile radeon 9xxx
- <LI> Fix: G3D::TextInput now parses ^=, character 255 correctly [cgd]
- <LI> Fix: G3D::TextInput now reports line numbers correctly with raw newlines [cgd]
- <LI> Fix: .ICO files with transparency loaded incorrectly [Corey]
- <LI> Fix: G3D::Draw::rect2DBorder inner border was 1 pixel too thick.
- <LI> Fix: [ 1326173 ] Win32Window::init should call makeCurrent.[Erik Cassel]
- <LI> Fix: [ 1326423 ] G3D::Queue::_copy broken [Chris Demetriou]
- <LI> Fix: [ 1313293 ] 6.08: TextInput gets symbol extendedType() wrong [Chris Demetriou]
- <LI> Fix: IFSModel::save, for PLY2 forgot newlines [Peter]
- <LI> Fix: Quat(Matrix3) now computes trace correctly (gave negative quats in some cases)
- <LI> Fix: Setting RenderDevice::polygonOffset now always produces a depth shift,
- even for faces perpendicular to the view axis.
- <LI> Fix: GImage now auto-resolves formats for files with 1 character base names
- <LI> Fix: WeakReferenceCountedPointer cycle bug
- <LI> Fix: Corrected lag encountered when using some ReliableConduit constructors [Dan Keefe]
- </UL>
-
- <P>
-<hr>
- Changes in 6.07:
- <UL>
- <LI> G3D::OSWindow::makeCurrent
- <LI> Win32 release binaries now built with no debug information (used to have line numbers)
- <LI> AABox::AABox enforces the constraint low <= high
- <LI> Optimized G3D::Array, Table, Queue, and Set for performance. Now significantly (up to 10x) faster
- than their std::counterparts.
- <LI> G3D::Vector3(Vector2, float) constructor
- <LI> G3D::Vector2::fastDirection
- <LI> G3D::TextInput::Options::cComments
- <LI> G3D::TextInput::Options::escapeSequencesInStrings
- <LI> G3D::TextInput::Options::otherCommentCharacter2
- <LI> G3D::TextInput::WrongString
- <LI> GLCaps::supports_GL_ATI_separate_stencil
- <LI> GLCaps can now test a card/driver and detect specific bugs:
- <ul><li>G3D::GLCaps::hasBug_glMultiTexCoord3fvARB
- <LI> G3D::GLCaps::hasBug_normalMapTexGen
- </ul>
- <LI> G3D::ReferenceCountedPointer::downcast for non VC6 compilers
- <LI> Improved G3D::ReferenceCountedPointer documentation to make subclassing features clearer
- <LI> Moved typedef for uint into G3D namespace and into g3d (was in glg3d)
- <LI> G3D::Shape
- <LI> G3D::Cylinder
- <LI> G3D::System::malloc, G3D::System::realloc, G3D::System::free for fast allocation of small objects
- <LI> G3D::Draw::plane
- <LI> G3D::Draw::cylinder
- <LI> G3D::gaussRandom
- <LI> GCamera deserialize(BinaryInput) & serialize(BinaryOutput) functions [Peter]
- <LI> G3D::GApp now writes a description of the whole system to the log to aid debugging.
- <LI> [ 1217928 ] OpenGL occlusion query entry points are loaded on initialization
- <LI> New texture interpolation modes: BILINEAR_MIPMAP, NEAREST_MIPMAP, NEAREST_NO_MIPMAP
- <LI> New texture formats:
- <UL>
- <LI> G3D::ImageFormat::L16;
- <LI> G3D::ImageFormat::L16F;
- <LI> G3D::ImageFormat::L32F;
- <LI> G3D::ImageFormat::A16;
- <LI> G3D::ImageFormat::A16F;
- <LI> G3D::ImageFormat::A32F;
- <LI> G3D::ImageFormat::LA4;
- <LI> G3D::ImageFormat::LA16;
- <LI> G3D::ImageFormat::LA16F;
- <LI> G3D::ImageFormat::LA32F;
- <LI> G3D::ImageFormat::RGB16;
- <LI> G3D::ImageFormat::RGB16F;
- <LI> G3D::ImageFormat::RGB32F;
- <LI> G3D::ImageFormat::RGBA16;
- <LI> G3D::ImageFormat::RGBA16F;
- <LI> G3D::ImageFormat::RGBA32F;
- </UL>
- <LI> isValidPointer and isValidHeapPointer no longer check the Win32 debug heap in order to support offset and padded memory blocks.
- <LI> Restructured unit tests
- <LI> G3D::CoordinateFrame::lookRay [David Baszucki]
- <LI> G3D::System::describeSystem, G3D::NetworkDevice::describeSystem, G3D::RenderDevice::describeSystem
- <LI> G3D::Array performance tuning for short arrays and arrays of small objects
- <LI> Added glext.h entries for GL_ARB_draw_buffers, GL_ARB_texture_rectangle,
- GL_ARB_color_buffer_float, GL_ARB_half_float_pixel, GL_ARB_texture_float,
- and GL_ARB_pixel_buffer_object extensions
- <LI> IFSModel::create added weld option, defaults to true (to keep compatibility). [Peter]
- <LI> G3D::RenderDevice::alphaTestReference, RenderDevice::alphaTest
- <LI> G3D::VAR::set
- <LI> G3D::Log::vprintf
- <LI> G3D::WeakReferenceCountedPointer
- <LI> GCC 4.0 build support added [Corey]
- <LI> G3D::CoordinateFrame::lookAt now gives a valid output even when look == up
- <LI> contrib/GChunk
- <LI> GLCaps now loads GL_EXT_framebuffer_object functions
- <LI> Added MSVC 6 support for C99 restrict keyword
- <LI> G3D::Win32Window properly resizes viewport on window resize [Corey]
- <LI> G3D::BinaryFormat, G3D::byteSize, G3D::binaryFormatOf
- <LI> Removed dead ManualCameraControllerHelper code
- <li> Added consistent area and volume methods to geometric primitives, deprecated old methods.
- <LI> Fast G3D::BinaryInput::read / G3D::BinaryOutput::write methods for arrays
- <LI> Enabled cube mapping on Radeon mobility cards and added a workaround to the known problems with texcoords on those cards.
- <LI> Can now create G3D::Win32Window with existing HWND and HDC [Corey]
- <LI> G3D::VertexAndPixelShader::ArgList::set(std::string, Array<T>)-- [ 1192401 ] Shader support arrays
- <LI> Fix: SDLWindow used std::string's instead of C strings in printf and format inside some exception handling code. [Peter]
- <LI> G3D::X11Window (same as SDLWindow in this release)
- <LI> Fix: [ 1277854 ] Win32Window fails on 24-bit modes
- <LI> RFE: [ 1242466 ] Inline Matrix3 methods
- <LI> Fix: [ 1226272 ] end caps of capsules in wrong position
- <LI> Fix: G3D::ImageFormat::LA8 now has 8-bits per channel
- <LI> Fix: [ 1124491 ] Remove GL_SAMPLER_2DRECT_ARB
- <LI> Fix: [ 1257113 ] G3D::Queue problems comining pushFront and pushBack
- <LI> Fix: MeshAlg::Weld now linear time (was O(n^2) due to a bug)
- <LI> Fix: [ 1298873 ] fast & correct CoordinateFrame::lerp
- </UL>
-
- <P>
-<hr>
- Changes in 6.06:
- <UL>
- <LI> G3D::Lighting::emissiveScale
- <LI> G3D::RenderDevice::drawBuffer
- <LI> G3D::RenderDevice::debugNumMinorStateChanges, debugNumMinorOpenGLStateChanges, debugNumMajorStateChanges, debugNumMajorOpenGLStateChanges.
- <LI> In stereo mode, Texture::copyFromScreen automatically chooses the left/right buffer to read based on the current glDrawBuffer
- <LI> contrib/ArticulatedModel/ToneMap
- <LI> Lazy state changes for shaders
- <LI> 50% performance improvement for G3D::BinaryInput, G3D::BinaryOutput when machine endian matches file endian
- <LI> Textures load with default of maxAnisotroy = 2.0
- <LI> maxAnisotropy argument to G3D::Texture constructors.
- <LI> GLCaps now loads GL_ATI_fragment_shader extension
- <LI> contrib/ArticulatedModel now supports rigid body hierarchies
- <LI> Added TEX_SUBTRACT, TEX_ADD_SIGNED, TEX_DOT3, TEX_DOT3_RGBA modes for G3D::RenderDevice::setTextureCombineMode
- <LI> G3D::RenderDevice now cleans up all static G3D::VARArea s when it shuts down
- <LI> FIX: [ 1208157 ] GLSL slow on ATI
- <LI> FIX: Off-by-one on viewport scale for 2D rendering
- <LI> FIX: MeshAlg::computeTangentSpaceBasis now works correctly
- <LI> FIX: 6.05 enabled all fixed function lights by default. This caused major performance problems on some cards.
- <LI> FIX: Extended cube map workaround to all Radeon Mobility cards
- <LI> FIX: Added check for glBlendEq before calling in RenderDevice
- <LI> FIX: Added a test for GL_EXT_texture_env_add in RenderDevice
- <LI> FIX: [ 1191817 ] unsigned warnings in BinaryInput
- </UL>
-
-<hr>
- <P>
- Changes in 6.05:
- <UL>
- <LI> G3D::BAYER_G8B8_R8G8_to_R8G8B8_MHC
- <LI> G3D::Quarter_R8G8B8_to_BAYER_G8B8_R8G8
- <LI> G3D::BAYER_G8B8_R8G8_to_Quarter_R8G8B8
- <LI> contrib/Matrix
- <LI> contrib/Java
- <LI> Texture::alphaOnlyVersion
- <LI> Draw::sphere speed improved over 25% with single quad strip (improves Draw::capsule) [Corey]
- <LI> Allow 1-channel GImage saving - BMP (expanded to RGB), PNG [Corey]
- <LI> Allow 1-channel GImage loading - PNG [Corey]
- <LI> Added shader and framebuffer extensions to glext.h
- <LI> All files used during current execution are available via G3D::getFiles() [Corey]
- <LI> Implemented OSX version of glGetCurrentContext with CGL. [Corey + Derek]
- <LI> ReferenceCountedObject is-in-heap checks were removed to allow better multiple and virtual inheritance for reference counted objects. ReferenceCountedPointer still appropriately checks does an is-in-heap check on assignment. [Corey]
- <LI> Added Dev C++ compatability
- <LI> glGetAttribLocationARB
- <LI> Changed GLight == operator to not use memcpy (was causing issues due to byte padding on some compilers)
- <LI> Made CoordinateFrame destructor non-virtual (eliminates vtable)
- <LI> Added new FAQ documentation
- <LI> Added support to G3D::BinaryInput and G3D::BinaryOutput
- reading and writing huge (larger than available memory) files.
- Files are still restricted to about 2 GB total, and compressed
- files must fit entirely in memory.
- <LI> Tweaked allocation strategy for small G3D::Array
- <LI> G3D::Texture::rect2DBounds, G3D::Texture::vector2Bounds
- <LI> G3D::Vector4 * G3D::Vector4, Vector4 / Vector4
- <LI> G3D::Array::operator=(std::vector)
- <LI> G3D::Sky::getEnvironmentMap now returns the top texture on machines
- that don't support cube maps.
- <LI> glDisableAllTextures()
- <LI> G3D::setFailureHook
- <LI> G3D::Shader::fromStrings now accepts optional names for the vertex and pixel shader
- <LI> G3D::Shader no longer requires values for declared but unused uniform variables
- <LI> G3D::RenderDevice now stores texture matrix at 32-bit precision (for faster push/popState)
- <LI> G3D::RenderDevice::setTextureLODBias
- <LI> G3D::Shader now supports shadow map arguments
- <LI> G3D::Shader::ArgList checks to see if Texture arguments are null
- <LI> G3D::RenderDevice::setAlphaWrite now defaults to true if the OSWindow has an alpha channel.
- <LI> G3D::RenderDevice::screenshotPic now supports alpha
- <LI> contrib/VideoSerializer
- <LI> G3D::BinaryOutput::writeBits, G3d::BinaryInput::readBits
- <LI> G3D::Sky can now be initialized with a NULL renderDevice, provided a non-null one
- is used with the G3D::Sky::render method.
- <LI> G3D::pi(), G3D::halfPi(), G3D::twoPi() added to replace defines [Corey]
- <LI> contrib/Q3Map
- <LI> Increased G3D::Draw::sphere performance using vertex arrays.
- <LI> G3D::Array::fastClear
- <LI> G3D::AABSPTree::insert(Array<T>)
- <LI> G3D::Texture::sizeOfAllTexturesInMemory
- <LI> G3D::VARArea::sizeOfAllVARAreasInMemory
- <LI> G3D::RenderDevice stores cameraToWorldMatrixInverse for faster coordinate system changes.
- <LI> inlined G3D::Matrix3::operator= for performance
- <LI> Created installer for Windows install [Corey]
- <LI> Reorganized the documentation topic index based on abstraction level, added hyperlinks to demo/contrib code
- <LI> G3D::ReliableConduit and G3D::LightweightConduit now send and receive
- objects directly; no need to make a G3D::NetMessage. G3D::NetMessage
- and associated methods are now deprecated.
- <LI> Win32 GUI G3D::prompt now auto-expands \\n to \\r\\n in prompt string [Corey]
- <LI> G3D::Draw::frustum
- <LI> Increased timeout and attempts for G3D::ReliableConduit to handle huge (1 MB) packets
- <LI> G3D::BinaryOutput::reset (memory writing only; not supported for disk)
- <LI> Reduced overhead for G3D::ReliableConduit and
- G3D::LightWeightConduit send routines
- <LI> Added PPM/PGM/PBM ASCII encode/decode support to G3D::GImage [Corey]
- <LI> New G3D::PosedModel rendering methods appropriate for shadow casting
- (with efficient default implementations).
- <LI> G3D::Lighting
- <LI> Changed RenderDevice::TEX_INTERPOLATE to mean GL_DECAL and added TEX_BLEND for GL_BLEND
- <LI> G3D::CoordinateFrame::upVector
- <LI> G3D::GLight::diffuse
- <LI> G3D::Rect2D::contains is now const
- <LI> Rewrote G3D::BinaryOutput to not use G3D::Array
- <LI> G3D::MD2Model::textureMatrix
- <LI> G3D::MeshAlg::computeBounds(vertex, index, ...)
- <LI> G3D::RenderDevice::colorWriteEnabled(), depthWriteEnabled, alphaWriteEnabled
- <LI> G3D::RenderDevice::setSpecularCoefficient(Color3)
- <LI> G3D::VAR::maxSize
- <LI> G3D::RenderDevice::enableTwoSidedLighting
- <LI> G3D::PosedModel::hasTransparency
- <LI> G3D::PosedModel::sort
- <LI> G3D::RenderDevice::renderMode
- <LI> G3D::MeshAlg::computeNormals(geometry, indexArray);
- <LI> contrib/ArticulatedModel (beta 3DS support)
- <LI> G3D::RenderDevice::swapBuffersAutomatically allows caller to suppress page flip.
- <LI> Added coordinate system documentation.
- <LI> RenderDevice::enableClip2D, RenderDevice::disableClip2D (scissor region)
- <LI> contrib/wxGWindow is stable and full featured-- use wxWidgets 2.5.3 with G3D!
- <LI> G3D::fileIsNewer
- <LI> G3D::isDirectory
- <LI> G3D::filenameContainsWildcards
- <LI> G3D::filenamePath
- <LI> G3D::Draw::lineSegment now accepts a scale (allowing arrows and axes to thicken appropriately)
- <LI> G3D::Rect2D::largestCenteredSubRect
- <LI> G3D::Matrix4::serialize, G3D::Matrix4::deserialize
- <LI> glTexImage3DEXT
- <LI> Removed glut.lib and glut.dll from the win32-lib directory.
- <LI> G3D::writeStringToFile, G3D::TextOutput, and G3D::BinaryOutput now flush by default (safe, not fast).
- <LI> Shifted push2D by 0.375 pixels as recommended in the OpenGL guide to bias integer coords towards pixel centers
- <LI> G3D::Draw::rect2DBorder
- <LI> G3D::Rect2D::border
- <LI> G3D::RenderDevice now creates a G3D::Win32Window on Windows instead of a G3D::SDLWindow. SDLWindow is now
- deprecated on Windows.
- <LI> G3D::VARArea now updates allocation sizes instead of G3D::VAR internally. Added
- more accessor methods to VARArea to futher remove VAR from VARArea internals. [Corey]
- <LI> VARSystem.cpp moved to VARArea.cpp - filename change only! [Corey]
- <LI> Linux build system updated:
- Builds only static libraries, Does not require libtool/libtoolize anymore,
- Does not check for or require libraries that normally linked with the .so files,
- Automatically builds Test project with iCompile during install. [Corey]
- <LI> G3D::Quat::deserialize, G3D::Quat::serialize
- <LI> G3D::PhysicsFrame::deserialize, G3D::PhysicsFrame::serialize
- <LI> G3D::TextInput::Options::singleQuotedStrings (defaults to true, changing the behavior
- from previous versions).
- <LI> G3D::Token::extendedType returns information disambiguating characters and strings
- and floats and ints.
- <LI> Added data/ah64-body and ah64-rotor
- <LI> demos/Network_Demo now uses a helicopter model instead of a plane
- <LI> G3D::VARArea::gl_vertexBufferObject and G3D::VARArea::gl_basePointer for breaking
- the VARArea abstraction.
- <LI> GLG3D.h no longer links against SDLMain.lib on Windows if _CONSOLE is defined
- (since console programs have no WinMain).
- <LI> SDL's redefinition of main is cleared when not linking sdlmain.lib [Corey]
- <LI> Moved contrib/Win32Window to G3D::Win32Window
- <LI> G3D::TextInput::readSymbols
- <LI> contrib/Image [Morgan]
- <LI> contrib/wxGWindow [Morgan]
- <LI> Added support for full-screen antialiasing to contrib/Win32Window
- <LI> Added joystick support to contrib/Win32Window [Corey]
- <LI> Win32Window fully-implements OSWindow [Corey]
- <LI> Texture now supports DDS(2D/CubeMap) and PNG files [Corey]
- <LI> Added Win32 pbuffer routines (no G3D wrapper, though-- we're waiting for the new ARB API).
- <LI> G3D::PosedModel::texCoords
- <LI> G3D::IFSModel now loads IFS 1.1 [Peter]
- <LI> G3D::IFSModel now loads and saves PLY2 files (plain text IFS format) [Peter]
- <LI> Automatically switch to glCompressedTexImage2D in G3D::Texture::fromMemory [Corey]
- <LI> Added G3D::Sky::fromCubeMap for preloaded CubeMap Texture::Ref's [Corey]
- <LI> Added G3D::Sky::fromFile and deprecated Sky::create [Corey]
- <LI> Demo and Test projects now build with iCompile, which is included [Corey]
- <LI> Fix: TextOutput::writeString now escapes special characters
- <LI> Fix: AABSPTree::serializeStructure
- <LI> Fix: Properly handle gl_ uniforms on Radeon for Shader
- <LI> Fix: [ 875467 ] OS X debugBreak (requires default XCode debug menu item 'Break on DebugStr()') [Corey + Derek]
- <LI> Fix: Can make a G3D::Texture::fromGImage with one channel (defaults to L8 format)
- <LI> Fix: [ 1149972 ] 6.05: Make Sky render correctly on low-end cards (no Cube mapping) [Corey]
- <LI> Fix: [ 1032742 ] OS X _DEBUG not defined [Derek]
- <LI> Fix: 16-bit integer reads in BinaryInput that always reversed endianness. (OSX file reading) [Corey + Derek]
- <LI> Fix: Matrix4 operator[] was returning a matrix value cast to a pointer [Corey]
- <LI> Fix: Matrix3 and Matrix4 had missing float* / const float* operators [Corey]
- <LI> Fix: Rect2D::clip broken for types other than Vector2
- <LI> Fix: RenderDevice::configureShadowMap result depends on objectToWorldMatrix
- <LI> Fix: [ 1150650 ] DebugBreak() undefined
- <LI> Fix: [ 1111534 ] Network Demo crashes starting 2nd server on same machine
- <LI> Fix: [ 1102091 ] ReliableConduit::receive times out
- <LI> Fix: Implemented MD2Model::objectSpaceBoundingX methods.
- <LI> Fix: G3D::Triangle::area is now zero for zero-area triangles (was inf)
- <LI> Fix: AABSPTree with extent on MSVC 6 no longer enters infinite loop in std::sort
- <LI> Fix: [ 1105641 ] Does not build with g++ 3.4.x [Corey]
- <LI> Fix: [ 1103619 ] RenderDevice::countPrimitive is wrong (changed to RenderDevice::countTriangles) [Corey]
- <LI> Fix: AABSPTree::BoxIntersectionIterator doesn't compile
- <LI> Fix: [ 1101680 ] copyfile won't overwrite (on Windows now overwrites) [Corey]
- <LI> Fix: [ 1101646 ] GCamera::frustum incorrect for non-square viewport
- <LI> Fix: Ultra bright lens flare at sunset [Nicholas Bray]
- <LI> Fix: IP address strings were reversed by NetAddress(std::string)
- <LI> Fix: TextInput now returns end of file token for files without trailing whitespace
- <LI> Fix: [ 1094166 ] 6.05: Release mouse stuck on x-axis [Corey + Morgan]
- <LI> Fix: Recognize buggy ATI Radeon Mobility cube maps and work around
- <LI> Fix: Textures now initialize without setting error bit on cards without GL_ARB_shadow
- <LI> Fix: filenameBaseExt now operates correctly on strings with both \ and / slashes.
- <LI> Fix: [ 1062659 ] BinaryInput::BinaryInput() memory leak
- <LI> Fix: Removed RenderDevice::polygonCount, which was never used.
- <LI> Fix: TextInput::readNumber no longer accepts double preceeding +/- on numbers when Options::signedNumbers is true
- <LI> Fix: [ 1038733 ] OSWindow cannot set icon properly [Corey]
- <LI> Fix: [ 939400 ] Linux mouse set position (Wild camera swinging on startup) [Corey]
- <LI> Fix: [ 1042591 ] Software GL Causes Assertion [Corey]
- <LI> Fix: [ 1036634 ] debugAssert doesn't work on MSVC 7 [Corey]
- <LI> Fix: [ 1049024 ] Fix compile warnings from gcc/Linux build [Corey]
- <LI> Fix: [ 1051272 ] Win32Window doesn't use GWindowSettings properly. [Corey]
- <LI> Fix: Win32Window clips the proper cursor region during input capture. [Corey]
- <LI> Fix: GWindows now center and maximize on the primary monitor for Windows.
- <LI> Fix: [ 1052945 ] TextOutput wordWrap starts on newlines
- <LI> Fix: [ 1050957 ] TextInput readNumber support for capital 'E' numbers.
- <LI> Fix: [ 1049674 ] TextInput failes on X. numbers.
- <LI> Fix: [ 1044028 ] Linux TextOutput Warning
- <LI> Fix: [ 1032750 ] Grayscale JPG errors [Corey]
- <LI> Fix: [ 1036225 ] Encode TGA support strips alpha channel [Corey]
- <LI> Fix: [ 1038631 ] CoordinateFrame::slerp (Quat::slerp has fix) [Corey]
- <LI> Fix: [ 1033686 ] GImage::GImage(filename) dies on certain (BMP) images [Corey]
- <LI> Fix: Texture mapping modes for pre-OpenGL 1.3 cards [Dan & Morgan]
- </UL>
-
-<hr>
- <P>
- Changes in 6.04:
- <UL>
- <LI> G3D Manual! [ Morgan and Sascha ]
- <LI> Initial MSVC7 build script. MSVC7 is not an officially supported platform
- however the release contains MSVC7 precompiled binaries and the build script
- will automatically build on both 6 and 7.
- <LI> Improved performance of G3D::writeStringToFile
- <LI> G3D::ReferenceCountedPointer assignment now allows compile time subtyping
- <LI> G3D::ReferenceCountedPointer != operator
- <LI> G3D::ReferenceCountedPointer::notNull
- <LI> G3D::GLight::directional now normalizes the light vector
- <LI> G3D::setAssertionHook
- <LI> [ 1029256 ] G3D::Shader / G3D::VertexAndPixelShader define g3d_ uniforms inside shaders
- <LI> static G3D::IFSModel::save/load for writing/reading IFS files
- <LI> G3D::TextInput allows ' inside quoted strings
- <LI> G3D::TextInput allows \ as a symbol token
- <LI> G3D::TextInput supports an arbitrary comment character (e.g. '#')
- <LI> Precompiled binaries for VisualC++ 7 (.NET 2002/2003)
- <LI> VisualC++ 7 (.NET 2002/2003) supported by build script
- <LI> Build now MOVEs binaries instead of COPYing them on Windows (allows
- two compilers to output to the same location)
- <LI> G3D Guide overview documentation
- <LI> Changelog and Error FAQ moved under Doxygen
- <LI> Build scripts and documentation now under the 'doc' .dsp on Windows
- <LI> Textures now support a DepthReadMode that can be used to perform hardware
- shadow map comparisions. <B>RenderDevice::configureShadowMap now requires
- an appropriately configured texture-- in previous releases it would
- reconfigure the texture for you.</B>
- <LI> G3D::UserInput::keyReleased, G3D::UserInput::ReleasedKeys
- <LI> G3D::Array::randomElement
- <LI> G3D::Array::insert
- <LI> G3D::RenderDevice::getObjectToWorldMatrix and getCameraToWorldMatrix now return
- const CoordinateFrame&
- <LI> Optimized G3D::Array::randomize
- <LI> G3D::cyclicCatmullRomSpline
- <LI> G3D::wrap
- <LI> contrib/AudioDevice
- <LI> G3D::System::time();
- <LI> More precise System::sleep
- <LI> G3D::IFSModel::pose with no arguments
- <LI> G3D::AABSPTree::serializeStructure, deserializeStructure,
- <LI> serialize(Vector3::Axis, BinaryOutput), deserialize(Vector3::Axis, BinaryInput),
- <LI> "glslc" GLSL compiler in the tools directory for getting compile-time errors from shaders
- <LI> GLCaps::init now takes optional debug log
- <LI> G3D::VertexAndPixelShader static constructors take optional 'debug' argument
- <LI> GWindowSettings::visible; Win32Window can now start invisible
- <LI> [ 991147 ] glBlendEquationEXT, RenderDevice::BlendEq, min, max, subtract, reverse subtract alpha blending
- <LI> [ 989785 ] Draw::rect2D
- <LI> GLCaps::numTextureCoords, GLCaps::numTextureUnits, GLCaps::numTextures
- <LI> GLCaps::G3D_MAX_TEXTURE_UNITS
- <LI> Rect2D::corner
- <LI> GCamera::getFrustum, GCamera::frustum, GCamera::Frustum, GCamera::Frustum::Face
- <LI> Plane constructor that accepts Vector4s (possibly at infinity)
- <LI> AABox::inf, AABox::zero, AABox::maxFinite
- <LI> AABox::intersects(Sphere)
- <LI> Vector3::minFinite, Vector3::maxFinite
- <LI> Plane::halfSpaceContainsFinite
- <LI> Plane::halfSpaceContains(Vector4)
- <LI> AABSPTree::getIntersectingMembers(Array<Plane>)
- <LI> AABSPTree::getIntersectingMembers(GCamera::Frustum) for view-frustum culling
- <LI> AABSPTree::getIntersectingMembers(Sphere)
- <LI> AABox::split
- <LI> Extended AABox::culledBy, Box::culledBy, and Sphere::culledBy with extra
- information for bounding volume hierarchies
- <LI> G3D::computeNormalMap
- <LI> Matrix3::fuzzyEq(Matrix3)
- <LI> Removed System::sleep(0.02) from GLG3D demo to give more accurate performance measure
- <LI> [ 965824 ] changed link library defaults
- <LI> serialize/deserialize for int, bool, double, float, std::string
- <LI> G3D::TextOutput
- <LI> [ 976924 ] Texture::texelWidth
- <LI> [ 973413 ] VertexAndPixelShader::ArgList::set can be called more than once per variable
- <LI> OSWindow::setIcon(std::string filename)
- <LI> Texture::fromMemory that takes a single image (instead of an array of images)
- <LI> [972604] RenderDevice::setTextureMatrix(uint, Matrix4)
- <LI> [972747] Rect2D::center
- <LI> GImage and Texture now load ICO files
- <LI> GL_SAMPLER_1D_ARB, 2D, 3D, CUBE
- <LI> Win32Window mouse events
- <LI> Added normals to AABox collision results
- <LI> Fix: [ 1026534 ]various cast bugs using Ref types.
- Removed G3D::ReferenceCountedPointer implicit cast to underlying pointer type
- This is technically an <B>incompatible change</B>, however we found no occurance
- in the library or demos using this that was not a bug!
- <LI> Fix: VAR constructor takes VARAreaRef instead of VARArea* <B>Incompatible change</B>
- <LI> Fix: ManualCameraController is prevented from looking precisely along the Y-axis, which would cause
- a singularity.
- <LI> Fix: Added '?' as a valid symbol Token
- <LI> Fix: [ 946235 ] GFont::align right w/ fixed_spacing
- <LI> Fix: [ 1001033 ] RenderDevice with 0 texture units
- <LI> Fix: GLCaps:: ARB stencil two side -> EXT stencil two side (stencilled shadows were broken)
- <LI> Fix: [ 993449 ] vsnprintf crashes MSVC 7
- <LI> Fix: [ 991320 ] Pointer truncation Warnings
- <LI> Fix: [ 981440 ] AUTO with Texture::fromMemory
- <LI> Fix: Plane::halfSpaceContains now works for infinite and semi-infinite points
- <LI> Fix: [ 979032 ] Quat <-> Matrix3 roundtrip inverts
- <LI> Fix: [ 976743 ] document GLCaps functions
- <LI> Fix: [ 976746 ] #include GLCaps in g3dall
- <LI> Fix: [ 973550 ] sampler2DRect now supported in GLSL shaders (NVIDIA only; ATI drivers are broken)
- <LI> Fix: [ 973490 ] Win32Window width/height off by non-client amount
- <LI> Fix: [ 961827 ] In debug mode, RenderDevice tries to access
- GL_MAX_TEXTURE_IMAGE_UNITS_ARB and an assertion fails on cards that
- don't support it.
- <LI> Fix: Texture binding for VertexAndPixelShader
- </UL>
-<hr>
- <P>
- Changes in 6.03:
- <UL>
- <LI> Matrix4::approxCoordinateFrame
- <LI> Vector2(const Vector2int16&) [Giulio]
- <LI> RenderDevice::setObjectShader
- <LI> RenderDevice::setVertexAndPixelShader
- <LI> G3D::RenderDevice supports "..._CURRENT" as an option for most settings
- <LI> inf -> inf(), nan -> nan(), NAN -> NAN()
- <B>This is an incompatible change-- it was needed to fix a bug with the order
- of initialization of globals</B>
- <LI> GImage::sizeInMemory
- <LI> Defined std::ostream << NetAddress, std::ostream << Vector3
- <LI> 'build doc' copies the contrib directory to the install directory
- <LI> LightweightConduit::PacketSizeException
- <LI> Quat::unitRandom() [Giulio]
- <LI> Color3::wheelRandom
- <LI> GImage::save and encode now const [Thanks Arni Mar Jonsson]
- <LI> LightweightConduit::send that accepts multiple destinations
- <LI> ReliableConduit::multisend
- <LI> Moved IFSBuilder from demos to contrib
- <LI> LightweightConduit and ReliableConduit send/receive can now take references as well as pointers
- <LI> RenderDevice::clear() that takes no arguments
- <LI> RenderDevice::setShader
- <LI> G3D::GApp now catches ShaderGroup::ArgumentError exceptions
- <LI> System::operatingSystem() now includes a version number on Linux
- <LI> SDLWindow no longer initializes the audio system; use SDL_InitSubsytem if you need audio.
- <LI> Extended GLenumToString with GL_SHADER_OBJECTS_ARB types.
- <LI> NVIDIA p-buffer: GLX_SAMPLE_BUFFERS_ARB, GLX_SAMPLES_ARB, GLX_FLOAT_COMPONENTS_NV,
- glXDestroyGLXPbufferSGIX, glXChooseFBConfigSGIX, glXCreateGLXPbufferSGIX,
- glXCreateContextWithConfigSGIX, glXQueryGLXPbufferSGIX
- <LI> NVIDIA swap lock: glXJoinSwapGroupNV, glXBindSwapBarrierNV, glXQuerySwapGroupNV,
- glXQueryMaxSwapGroupsNV, glXQueryFrameCountNV, glXResetFrameCountNV
- <LI> OSWindow::requiresMainLoop, OSWindow::runMainLoop (Beta)
- <LI> OSWindow::pollEvent, SDLWindow::pollEvent
- <LI> G3D::GApp accepts an optional OSWindow on construction
- <LI> G3D::VertexAndPixelShader, G3D::ObjectShader (Beta)
- <LI> Deprecated GPUProgram, VertexProgram, and PixelProgram (the OpenGL 1.5 shaders
- follow a different paradigm than the OpenGL 1.3 ones, so the G3D API must change
- to match it).
- <LI> Support for GL_ARB_vertex_shader, GL_ARB_fragment_shader, and GL_ARB_shader_objects
- <LI> G3D::drawFeatureEdges
- <LI> const Array<Vector3>& G3D::MD2Model::PosedModel::objectSpaceFaceNormals();
- <LI> G3D::RenderDevice::sendSequentialIndices
- <LI> Network_Demo
- <LI> contrib/Win32Window
- <LI> contrib/pingtest
- <LI> contrib/GlutWindow [Morgan and Dan Keefe]
- <LI> contrib/ObjModel [Corey Taylor]
- <LI> G3D::GLCaps
- <LI> GAppSettings::logFilename
- <LI> Deprecated RenderDevice::suportsOpenGLExtension, RenderDevice::supportsImageFormat,
- other supports shortcuts (use GLCaps instead).
- <LI> DiscoveryClient::cleanup
- <LI> Optimized BinaryInput::readUInt32, readUInt16
- <LI> Extended network documentation
- <LI> 'fastlib' build target for G3D library developers
- <LI> glGetVector2, glGetVector3, glGetVector4
- <LI> float * Quat (double * Quat already existed)
- <LI> GApp automatically generates g3d-license.txt at runtime ([RFE#856338] CREDIT.TXT)
- <LI> G3D::license
- <LI> Removed several large files (tag, ppt, exe) from the source zipfile, bringing it down to 3 MB
- <LI> Improved CoordinateFrame:pointToObjectSpace() (RFE#715996) [Giulio]
- <LI> [RFE#945935] Make static constants into functions [Giulio]
- <LI> Fix: LightweightConduit::send verifies that the packet size is smaller than the UDP limit
- <LI> Fix: Multitexture on ATI and Wildcat cards
- <LI> Fix: Incorrect occlusion in GLG3D_Demo (was caused by global constant problem)
- <LI> Fix: [BUG#949377] Checks for stencil extensions [Giulio]
- <LI> Fix: [BUG#922725] Non-multitexture implementation for getTextureState() [Giulio]
- <LI> Fix: Restore ambient light color after RenderDevice::popState
- <LI> Fix: RenderDevice now initializes OpenGL extensions before testing for multitexture [Erik Cassel, Dan Keefe]
- <LI> Fix: Bottom clipping plane of GCamera frustum now correct (was slanted incorrectly, making frustum too big)
- <LI> Fix: GFont::draw2D now returns correct y value (used to be too small)
- <LI> Fix: NetworkDevice now returns useful hostname on Linux (used to be "localhost")
- <LI> Fix: The conduit returned from NetworkDevice::createReliableConduit now has ok() == false when connect fails
- <LI> Fix: Tangent space computation of constant u, v now correct (was missing a factor of 2, leading to slight errors) [Max McGuire]
- <LI> Fix: [ 925456 ] select broken on Linux (Networking was broken on Linux)
- <LI> Fix: getDepthBufferValue off by 1 [Andi Fein]
- </UL>
-
-<hr>
- <P>
- Changes in 6.02:
- <UL>
- <LI> Default constructor for Line.
- <LI> Various patches to make G3D work with the CAVE [Dan Keefe]
- <LI> AABox::set
- <LI> Made OSWindow::setPosition non-const
- <LI> VARArea now tests for the presence of all VBO extensions, on the freak chance that
- a driver has only partial support (due to a bug)
- <LI> Linux build statically links OpenGL 1.2.1 and loads extensions through OpenGL 1.5
- to work around Wildcat Linux driver bug (Windows and Mac statically link OpenGL 1.1
- and load extensions through OpenGL 1.5)
- <LI> Triangle stores precomputed edge lengths
- <LI> Ray-triangle with vertex weights
- <LI> Highly optimized ray-triangle intersection test [Tomas Moller & Ben Trumbore]
- <LI> Create a texture from 6 different cube-map filenames
- <LI> Added contrib directory built as part of the 'doc' target
- <LI> contrib/CoreyGWindow: OSWindow implementations for various platforms
- <LI> AABSPSet::beginRayIntersection [Pete Hopkins]
- <LI> AABSPTree::beginBoxIntersection
- <LI> CollisionDetection::intersectionTimeForMovingPointFixedAABox, Ray::intersectionTime(AABox)
- [Pierre Terdiman and Andrew Woo]
- <LI> Triangle::center
- <LI> Renamed KDTreeSet to AABSPTree, old name is #defined
- <LI> RenderDevice now works on cards without multitexture
- <LI> void glTexCoord(const G3D::Vector4& t); [Dan Keefe]
- <LI> Overloaded float, double, and int * Matrix3
- <LI> Fix: [ 923944 ] Matrix/Quat ambiguity
- <LI> Fix: fuzzyEq(inf, inf) is true
- <LI> Fix: Triangle::randomPoint returns values outside the triangle
- <LI> Fix: [ 913763 ] tokenTypeToString(Token::END)
- <LI> Fix: Compute number of texture coordinates before RenderDevice::setVideoMode [Dan Keefe]
- <LI> Changed the default depth bits to '0' for wider compatibility
- (Fix: Unable to create OpenGL screen: Couldn't find matching GLX visual)
- <LI> Fix: [912305] Table, Queue, and Set assignment operators do not free old values
- <LI> Fix: Separate specular and Multisample on Tablet PC w/ Trident [Dan Keefe]
- <LI> Fix: Linux debug build now has line numbers
- <LI> Upgraded to SDL 1.2.7
- Fix: [ 838030 ] SDL 1.2.6 blocks prompt
- Fix: FSAA does not work under SDL
- Fix: Default Win32 refresh rate
- <LI> Draw::vertexVectors
- <LI> New meshes from Brown University: hemisphere.ifs, curvy.ifs, head.ifs,
- closed-low-poly-teapot.ifs, bump.ifs
- <LI> GLight::specular
- <LI> SDLWindow::setWindowDimensions and setWindowPosition now work on Win32
- <LI> GWindowSettings::x, GWindowSettings::y, GWindowSettings::center
- <LI> System::setEnv
- <LI> [ 909999 ] OSWindow Joystick interface
- <LI> double * Quat ([ 909305 ] scalar * {quat, vector, matrix})
- <LI> Increased the precision of several Vector2 and Vector3 methods
- <LI> MeshAlg::computeNormals now returns 0 instead of NaN for degenerate normals
- <LI> Updated main-no-GApp.cpp for 6.02
- <LI> RenderDevice::screenshotPic can copy from the back buffer
- <LI> Improved VAR documentation.
- <LI> If NO_SDL_MAIN is defined, G3D does not attempt to link against sdlmain.lib
- <LI> UserInput::setPureDeltaMouse
- <LI> UserInput::mouseXY, mouseX, mouseY
- <LI> UserInput::mouseDXY
- <LI> Deprecated UserInput keyMapping constructor argument
- <LI> RenderDevice::setDrawBuffer [Dan Keefe]
- <LI> GFont::draw3D [Dan Keefe]
- <LI> GImage::pixel3(x, y) and GImage::pixel4(x, y)
- <LI> debugAssert, debugBreak, debugAssertM, etc. all release input grab
- when an assertion fails (Win32 and Linux) and restore it when the
- program continues (Win32). This also fixes the DirectInput laggy
- cursor that occurs after a break.
- </UL>
-
-<hr>
- <P>
- Changes in 6.01:
- <UL>
- <LI> Default constructor for G3D::LineSegment
- <LI> Rect2D::clipPoly (Pete & Morgan)
- <LI> Draw::poly2D, Draw::poly2DOutline (Pete & Morgan)
- <LI> Added instructions for rotated text to G3D::GFont::draw2D
- <LI> Fix: iRandom now compiles correctly under gcc.
- <LI> Fix: [ 852076 ] Compute better/faster vertex normals in MeshAlg
- MeshAlg::computeNormals now weighs adjacent faces by their area
- <LI> Fix: [ 896028 ] Textures broken on Trident TabletPC (Dan Keefe)
- <LI> Fix: [ 860800 ] ManualCameraController cursor jumps
- <LI> Fix: G3D::UserInput no longer offsets the mouse position by 1/2 pixel
- <LI> Fix: Alt-Tab no longer toggles the GApp camera before switching windows
- <LI> Fix: [ 901248 ] Font bounds y-value incorrect
- <LI> Fix: G3D::PhysicsFrame::toCoordinateFrame() was rotated by 90 degrees
- <LI> Fix: [ 895493 ] Radeon 7500 Cube Map
- <LI> Fix: G3D::MeshAlg::computeWeld produces linker errors on Linux
- <LI> G3D::TextInput::peekLineNumber(), G3D::TextInput::peekCharacterNumber()
- <LI> G3D::GAppSettings::dataDir
- <LI> html/gettingstarted.html
- <LI> G3D::MeshAlg::debugCheckConsistency
- <LI> G3D::MD2Model and G3D::IFSModel now weld their adjacency information
- <LI> Renamed/retyped G3D::PosedModel::adjacentFaces to G3D::PosedModel::vertices
- (most programs can be fixed by changing the type from Array< Array<int> > to
- Array<MeshAlg::Vertex> and adjacentVertexArray[v] to vertexArray[v].faceIndex)
- <LI> Shadow volumes now use the welded adjacency information
- <LI> G3D::PosedModel now offers both welded and non-welded adjacency information
- <LI> G3D::contains for C-Arrays
- <LI> Generate .tag files in the build
- <LI> G3D::MeshAlg::computeAdjacency does not merge colocated vertices
- <LI> G3D::MeshAlg::computeAdjacency does not remove degenerate faces and edges
- <LI> G3D::MeshAlg::Vertex
- <LI> G3D::Vector3::directionOrZero
- <LI> G3D::GMaterial
- <LI> ManualCameraController renamed to G3D::FPCameraController
- <LI> glGetCurrentContext (beta)
- <LI> G3D::RenderDevice::supportsImageFormat
- <LI> G3D::Vector3::magnitude
- <LI> G3D::Vector3::cross() [returns Matrix3]
- <LI> G3D::Quat changes (API is still in beta)
- <LI> G3D::Quat::norm now returns the 2-norm, not the function Dave Eberly uses.
- <LI> Matrix3 default constructor
- <LI> Switched UserInput to use SDLWindow internally
- <LI> Switched RenderDevice to use SDLWindow internally
- <LI> G3D::Window
- <LI> G3D::SDLWindow
- <LI> Renamed G3D::RenderDeviceSettings to G3D::WindowSettings (with a typedef for the old name)
- <LI> IFSModel now loads models with up to 10 million polygons (like the buddha).
- <LI> Internal G3D::KDTreeSet state now private.
- </UL>
-
-<hr>
- <P>
- Changes in 6.00:
- <UL>
- <LI> FIX: warning: passing `double' for argument 1 of `void G3D::Queue<T>::repackAndRealloc(int)'
- <LI> Optimized static Matrix3::transpose (36 cycle) and
- Matrix3::mul (52 cycle) variations.
- <LI> Changed some lerp arguments from float to double
- <LI> MeshAlg::computeTangentSpaceBasis
- <LI> Draw::axes now uses scale to compute axis length
- <LI> New ParallaxBump demo
- <LI> Changed several Vector3 return values from float to double
- <LI> Real-world stars, sun, and moon path (Nick Musurca)
- <LI> Now compiles under MSVC++ 7.0 (David Baszucki)
- <LI> Now compiles under g++ OS/X (Ben Landon)
- <LI> Changed the default RenderDeviceSettings::alphaBits to 0 in the hope that it
- will work with more graphics cards.
- <LI> Matrix3::fromX methods became factory methods
- <LI> G3D::sinc
- <LI> Multi-platform lib directories
- <LI> Vector3::average(), Color3::average(), Vector3::sum(), Color3::sum()
- <LI> Ray::reflect, Ray::refract
- <LI> Physically correct sky model
- <LI> FIX: Older graphics cards can now initialize properly
- <LI> Increased fuzzyEpsilon to 0.000001
- <LI> Color3::max, Color3::min, Color4::max, Color4::min
- <LI> Array::sortSubArray
- <LI> GCamera::getClipPlanes now takes a G3D::Array
- <LI> G3D::AABox
- <LI> Box::randomInteriorPoint, Box::randomSurfacePoint
- <LI> Vector3::cosRandom, Vector3::hemiRandom, Vector3::reflectAbout, Vector3::reflectionDirection, Vector3::refractionDirection
- <LI> log(Color3)
- <LI> Upgraded to zlib 1.2.1
- <LI> VAR::valid (Peter)
- <LI> System::getLocalTime, System::getTicks
- <LI> High-performance cycle count and time queries on Linux
- <LI> UserInput::anyKeyPressed
- <LI> G3D::Box now provides axes, center, and extent information
- (serialization is backwards compatible to 5.xx)
- <LI> TextInput's exceptions now provide file, line, and character numbers
- as well as preformatted error messages in the style of MSVC++.
- <LI> G3D::Texture::fromGImage
- <LI> G3D::TextInput now parses hex numbers of the form 0x#####
- <LI> G3D::CollisionDetection::penetrationDepthForFixedSphereFixedPlane
- <LI> G3D::CollisionDetection::penetrationDepthForFixedSphereFixedBox
- <LI> G3D::beginMarkShadows, G3D::endMarkShadows, G3D::markShadows
- <LI> GFont::draw2D now returns the string bounds
- <LI> Sphere::surfaceArea, Sphere::volume, Box::surfaceArea, Box::volume
- <LI> Two-sided stencil operations
- <LI> Removed G3D::Real
- <LI> FIX: [ 855947 ] Fonts are broken on Radeon
- <LI> Switched vertex arrays to use the new ARB_vertex_buffer_object extension.
- Compared to 5.xx rendering speed: NVIDIA/Win32 is the same (fast),
- ATI and Linux rendering are about 10x faster. The API has changed
- slightly-- most significant, the vertex, normal, color, etc. arrays
- must all come from the same VARArea now.
- <LI> Disabled the "conditional is constant" level 4 warning on Windows
- that is triggered by the for-loop scoping fix.
- <LI> G3D::SkyParameters::directionalLight
- <LI> G3D::TextureManager (Peter S. & Morgan)
- <LI> Flipped skybox X-axis to match OpenGL cube map coordinates
- <LI> Texture now uses hardware MIP-map generation
- <LI> Texture::copyFromScreen for cube map faces
- <LI> RenderDevice::configureReflectionMap
- <LI> RenderDevice::configureShadowMap
- <LI> Renamed CFont to GFont
- <LI> Renamed CImage to GImage
- <LI> G3D::Matrix3::getRow
- <LI> Added optional argument drawCelestialBodies to Sky::create.
- <LI> RenderDevice::getTextureMatrix
- <LI> Depth Textures
- <LI> Texture::createEmpty
- <LI> RenderDevice::setViewport has flipped the y-axis since version 5.00
- <LI> ReferenceCountedPointer::isLastReference
- <LI> Support for textures beyond the number of texture units (which occurs on NVIDIA cards)
- <LI> G3D::PosedModel
- <LI> G3D::IFSModel
- <LI> G3D::CoordinateFrame::normalToObjectSpace, G3D::CoordinateFrame::normalToWorldSpace
- <LI> Simplified arguments on Texture::copyFromScreen
- <LI> Moved Camera in GLG3D to GCamera in G3D
- <LI> Moved setProjectionAndCameraMatrix from Camera to RenderDevice
- <LI> Moved G3D::Rect2D to G3D from GLG3D, changed interface
- <LI> G3D::setRenderMode
- <LI> G3D::RenderDevice::setSpecularCoefficient, G3D::RenderDevice::setShininess
- <LI> G3D::GLight
- <LI> Renamed G3D::RenderDevice::configureDirectionalLight, configurePointLight to G3D::RenderDevice::setLight
- <LI> Changed G3D::Rect2D to use doubles
- <LI> G3D::Camera::setPosition()
- <LI> G3D::Camera::lookAt()
- <LI> G3D::ManualCameraController::setPosition()
- <LI> G3D::System::getTick, G3D::System::getLocalTime
- <LI> Fixed [ 839618 ] peak var only updated on reset()
- <LI> G3D::Array::findIndex (thanks to David Baszucki for the suggestion)
- <LI> Removed RenderDevice::setProjectionMatrix3D and RenderDevice::setProjectionMatrix2D
- <LI> RenderDevice::project
- <LI> RenderDevice::push2D() now uses the current viewport instead of full screen by default
- <LI> RenderDevice::getViewport
- <LI> G3D::SimTime
- <LI> Sky::render no longer needs a camera matrix (it gets it from the render device)
- <LI> SkyRef, Sky::create()
- <LI> Removed Sky::getName
- <LI> Removed RenderDevice::setAmbientLightLevel (duplicated RenderDevice::setAmbientLightColor)
- <LI> G3D::GApp, G3D::GApplet, G3D::GAppSettings
- <LI> RenderDevice::getCardDescription
- <LI> GPUProgram interface for setting program constants [Peter, Morgan & Dan]
- <LI> RenderDevice::getModelViewMatrix
- <LI> RenderDevice::getModelViewProjectionMatrix
- <LI> RenderDevice::getProjectionMatrix
- <LI> Documented some more common compiler errors.
- <LI> Moved RenderDevice::debugDraw methods to the Draw class, changed rendering from
- cylinders to lines for wireframe (for performance)
- <LI> Ray::direction no longer has unit length
- <LI> Line::point, Line::direction
- <LI> LineSegment::endPoint
- <LI> IFSBuilder loads Brown University Sketch Model (sm) format
- <LI> New IFS models: angel, distributor-cap, dragon2, duck, elephant, hippo, hub, mech-part, rotor, sandal, trumpet, venus-torso, woman
- <LI> RenderDevices are now optionally resizable
- <LI> MeshAlg::computeWeld
- <LI> Array::randomize
- <LI> Table now refuses to push the load factor above 19/20 and stops rehashing
- <LI> Table always keeps an odd number of buckets
- <LI> Sphere::randomInteriorPoint, Sphere::randomSurfacePoint
- <LI> LineSegment::randomPoint
- <LI> Hardcoded some common paths into demoFindData
- <LI> Deprecated old RenderDevice::init method.
- <LI> Full screen anti-aliasing (FSAA)
- <LI> G3D::RenderDeviceSettings
- <LI> All 2, 3, and 4 character swizzles for Vector2, Vector3, Vector4 are defined.
- <LI> G3D::rsqrt
- <LI> Most vector methods are also defined as functions now
- <LI> sign(Vector2), sign(Vector3), sign(Vector4)
- <LI> G3D::Matrix4
- <LI> Changed G3D_VER from double to integer
- <LI> G3D::lerp
- <LI> Changed G3D::PI, G3D::HALF_PI, and G3D::TWO_PI to #defines
- <LI> Vector2::clamp, Vector3::clamp, Vector4::clamp
- <LI> Changed order of arguments to all lerp methods to match DirectX/Cg
- <LI> Changed order of arguments to G3D::clamp and G3D::iClamp to match DirectX/Cg
- <LI> G3D::ManualCameraController::ManualCameraController now requires a G3D::UserInput
- <LI> G3D::UserInput::appHasFocus
- <LI> G3D::ManualCameraController now stops tracking the mouse when the app loses focus
- <LI> G3D::ManualCameraController::setActive
- <LI> G3D::ManualCameraController now manages the mouse cursor instead of G3D::RenderDevice
- <LI> G3D::UserInput::getMouseXY, G3D::UserInput::getXY
- <LI> RenderDevice::debugDrawVertexNormals
- <LI> GPUProgram, VertexProgram, and PixelProgram now recognize the output of the
- Cg compiler and automatically bind constants.
- <LI> RenderDevice now loads glActiveStencilFaceEXT
- <LI> RenderDevice::numTextureCoords
- <LI> Moved changelog to a separate page
- <LI> Reformatted overview to be smaller
- <LI> Added model debugging info to the IFSBuilder display
- <LI> Welded some broken vertices in the teapot.ifs file
- <LI> Renamed Font.* to CFont.*
- <LI> CFont::draw2DString renamed to CFont::draw2D (use a #define to port old code)
- <LI> MeshAlg
- <LI> RenderDevice now enables GL_COLOR_MATERIAL by default
- <LI> msgBox
- <LI> MD2 model gallery in documentation (Kevin)
- <LI> MD2Documentor (Kevin)
- <LI> debugAssertGLOk macro
- <LI> VertexProgram now supports NVIDIA Vertex Program 2.0
- <LI> RenderDevice now loads glGenProgramsNV, glDeleteProgramsNV, glBindProgramNV, glLoadProgramNV, glTrackMatrixNV, glProgramParameter4fvNV, glGetProgramParameterfvNV, glGetProgramParameterdvNV extensions
- <LI> VertexProgram and PixelProgram static factory methods now return reference counted values.
- <LI> Split the reference value from RenderDevice::setStencilTest into setStencilConstant
- <LI> RenderDevice::STENCIL_INVERT, RenderDevice::STENCIL_REPLACE, RenderDevice::STENCIL_ZERO
- <LI> Added brighten argument to Texture::fromFile
- <LI> Increased CImage JPEG save quality
- <LI> RenderDevice::screenshot now returns the name of the file that was written
- <LI> nextPowerOf2 renamed to ceilPow2
- <LI> System::alignedMalloc, System::alignedFree
- <LI> Carbon, Crackman, Edenmill, Futurist, Interplanetary,
- Iomanoid, Starlight, Lesser, and Wild fonts by Ray Larabie.
- Like all of our fonts, they are free, but please consider a
- donation to him if you like them. http://www.larabiefonts.com/
- <LI> MD2Model_Demo
- <LI> G3D::MD2Model
- <LI> FIX: Fixed a bug in Array shrinking that could cause memory corruption
- <LI> FIX: RenderDevice windows with an aspect ratio of less than 1 now allowed.
- <LI> FIX: TextInput now parses '#', '~', '~=', '&', '&&', '|', '||' correctly
- <LI> VARArea::reset() now waits for rendering calls using its vertex
- arrays to complete before wiping the memory.
- <LI> G3D::filenameBaseExt, G3D::filenameExt
- <LI> VARArea::finish()
- <LI> Milestone
- <LI> TextInput::Options::signedNumbers
- <LI> RenderDevice now loads glFlushVertexArrayRangeNV
- <LI> Vector2int16
- <LI> RenderDevice::freeVARSize()
- <LI> Array now allocates 16-byte aligned pointers.
- <LI> Decreased the default camera movement rate by 50% for better resolution.
- <LI> RenderDevice enables GL_NORMALIZE by default
- <LI> Improved the performance of Array::append/Array::push/Array::next
- <LI> Fix: [ 875219 ] Array::sort must use std::sort
- <LI> Array::next
- <LI> Array::reverse
- <LI> PCX file loading
- <LI> Test images
- <LI> Color3uint8 as uint8[] addressing
- <LI> Color4uint8 as uint8[] addressing
- <LI> Removed const from VAR::pointer
- <LI> ReferenceCountedPointer::isNull
- <LI> alwaysAssertM
- <LI> Log::common, Log::getCommonLogFilename
- <LI> Switched from static to dynamic linking of zlib
- <LI> Upgraded to zlib 1.1.3
- <LI> On Win32 the lib list is automatically updated through pragmas
- (5.xx programs should revert to linking against default libraries)
- <LI> Increased default sky quality to 1.00
- <LI> G3D::CFontRef
- <LI> RenderDevice now loads all register combiner extensions (NVIDIA only)
- <LI> Sky::getEnvironmentMap
- <LI> Sky implementation now uses a cube map (when one is available)
- <LI> G3D::Sky constructor now takes a render device
- <LI> Rotated Sky box 90 degrees to match environment maps
- <LI> G3D::Sky now takes the environment filenames as "sky_*.jpg" instead of "sky_ft.jpg"
- <LI> Added default filename for Sky constructor
- <LI> Added caustics textures created with Kjell Andersson's generator http://www.lysator.liu.se/~kand/caustics/
- <LI> #defined "for" under MSVC so that it obeys C99 scoping rules
- <LI> System::consoleKeyPressed
- <LI> System::consoleClearScreen
- <LI> System::consoleReadKey
- <LI> NetMessage::type()
- <LI> Changed the Conduit message protocol to include a message type.
- The API is backwards compatible to 5.01 even though the protocol is not.
- <LI> Removed optional argument maxSize from LightweightConduit::receive.
- <LI> NetAddress::serialize
- <LI> NetAddress::deserialize
- <LI> NetAddress == NetAddress
- <LI> hashCode(NetAddress)
- <LI> RenderDevice::init now prints ATI or NVIDIA driver version to the log under Windows
- <LI> readme.html library build instructions now have downloads for required libraries
- <LI> Library list has changed for Win32 (added version.lib)
- <LI> System::cpuArchitecture
- <LI> System::operatingSystem
- <LI> double-precision Plane::getEquation
- <LI> Vector2::lerp
- <LI> Platform specific #defines G3D_WIN32, G3D_LINUX, G3D_OSX
- <LI> G3D::Array::contains
- <LI> G3D::Queue::contains
- <LI> G3D::ImageFormat
- <LI> G3D::Texture::DIM_CUBE_MAP
- <LI> G3D::Texture resizes non-power of two textures
- <LI> G3D::Texture constructors are completely changed from 5.01 (and hopefully easier to use)
- <LI> G3D::CImage now supports images with alpha
- <LI> Removed most of the width/height arguments from G3D::Camera methods
- <LI> BinaryInput::readBytes and BinaryOutput::writeBytes now take void* as an argument to avoid casting
- <LI> Plane::fromEquation
- <LI> Removed Plane::getNormal (use Plane::normal instead)
- <LI> Removed CDTriangle (use G3D::Triangle instead)
- <LI> Removed Font (use G3D::CFont instead)
- <LI> FIX: Camera::getClipPlanes now transforms infinite planes correctly.
- <LI> FIX: The last reference of an RGC pointer assigned to itself no
- longer tries to collect before re-assigning
- </UL>
-
-<hr>
- <P>
- Changes in 5.01
- <UL>
- <LI> G3D::tesselateComplexPolygon
- <LI> G3D::ConvexPolygon
- <LI> G3D::ConvexPolyhedron
- <LI> G3D::iClamp, G3D::clamp
- <LI> G3D::iWrap
- <LI> G3D::iRandom, G3D::random
- <LI> G3D::getFiles
- <LI> G3D::getDirs
- <LI> G3D::VAR::pointer
- <LI> G3D::realWorldLocalTime
- <LI> G3D::Texture::TRANSPARENT_BORDER
- <LI> DECLARE_GLFORMATOF
- <LI> G3D::System::machineEndian
- <LI> G3D::VertexProgram, G3D::VertexProgramRef, G3D::RenderDevice::setVertexProgram
- <LI> G3D::PixelProgram, G3D::PixelProgramRef, G3D::RenderDevice::setPixelProgram
- <LI> G3D::GPUProgram, G3D::GPUProgramRef
- <LI> G3D::sizeOfGLFormat
- <LI> G3D::RenderDevice::setVertexAttrib
- <LI> G3D::Vector2*=Vector2, /= Vector2, * Vector2, / Vector2
- <LI> glFormatOf
- <LI> G3D::Color4uint8
- <LI> G3D::Color3uint8
- <LI> G3D::Vector3int16
- <LI> G3D::System::currentProgramFilename
- <LI> CImage::insertRedAsAlpha
- <LI> CImage::stripAlpha
- <LI> Texture::hasAlpha
- <LI> Added support for TGA with alpha channel
- <LI> Re-implemented Texture to support a broader range of formats and cleaner implementation.
- <LI> Fix: Improved Texture::LUMINANCE support
- <LI> Added == and != overloads for Texture::Ref so that "a != NULL" is now legal and does not require a cast to Texture::Ref.
- <LI> G3D::CFont is a typedef for G3D::Font to avoid name conflicts with X11 Font under Linux. In future releases, the name Font will be deprecated.
- <LI> RenderDevice::setPointSize
- <LI> Added a new teapot (teapot.ifs) that is closed, with a properly fitting top. The classic teapot is now called "utah-teapot.ifs" (Sebastian Schuberth and Simon Winkelbach)
- <LI> RenderDevice::init now loads glPointParameterfvARB, glPointParameterfARB,
- glMultiDrawArraysEXT, and glMultiDrawElementsEXT functions.
- <LI> GLenumToString(4) now returns "GL_TRIANGLES" instead of "GL_LINE_BIT" (both are correct)
- <LI> Added TextInput::Options to optionally allow C++ comments to
- be treated as two slashes instead of a comment
- <LI> Added data/image/meter.jpg, a meter stick texture convenient for testing
- <LI> Added sansserif, news, and terminal fonts based on Bitstream's <A HREF="http://www.gnome.org/fonts/">free fonts</A>
- <LI> RenderDevice::numTextureUnits
- <LI> Added stars to night Sky
- <LI> Added classic GL dinosaur model as data/ifs/dinosaur.ifs
- <LI> Documented G3D::glGetProcAddress
- <LI> Fix: Texture now restored GL_ENABLE bits properly after creation
- <LI> Fix: Texture::sizeInMemory now accounts for MIP-map levels
- <LI> Fix: Fonts and skies now adjust their brightness for the screen gamma level
- <LI> Fix: Strange compilation bug was causing Sky to be black for some programs
- <LI> resolveFilename
- <LI> GLProgram_Demo to show how to use vertex programs in G3D
- <LI> Support for GL_ARB_vertex_program
- <LI> Modified ManualCameraController so that diagonal movement does not exceed
- maximum rate.
- <LI> Added support for non-GL_FLOAT vertex arrays to RenderDevice
- <LI> Added support for Wavefront OBJ files to IFSBuilder
- <LI> Removed duplicate copies of SDL.dll from the source tree
- <LI> Renamed G3D::CDTriangle to G3D::Triangle
- <LI> Added several G3D::Triangle methods
- <LI> Moved CollisionDetection::primaryAxis to Vector3::primaryAxis
- <LI> Fix: Texture::sizeInMemory now returns correct results for RGB8 textures.
- <LI> Changed texture constructors in ways that slightly break backwards compatibility
- <LI> Deprecated several arguments to the texture constructors.
- </UL>
-
-<hr>
- Changes in 5.00
- <UL>
- <LI> Color3::operator*=(const Color3&)
- <LI> Color3::operator*(const Color3&)
- <LI> Eliminated duplicate GL headers [James O'Sullivan]
- <LI> Linux Makefiles [James O'Sullivan, Jordan Parker]
- <LI> RenderDevice::getProjectionMatrixParams
- <LI> RenderDevice::debugDrawCylinder
- <LI> Added an option to not copy input memory for BinaryInput
- <LI> Added data/ifs/sphere.ifs
- <LI> Added data/ifs/spikeball.ifs
- <LI> Added a new (imperfect) demo/tool that converts 3DS and MD2 to IFS.
- <LI> Added RenderDevice to the Font constructor
- <LI> Removed RenderDevice from Font::drawString
- <LI> Included glut32.lib, .dll, and .h (Version 3.7.6) in the distribution.
- The windows glut port is by Nate Robbins and is from
- http://www.xmission.com/~nate/glut.html.
- glut was originally written by Mark Kilgard.
- <LI> Modified OpenGL headers to work cross platform, with the latest NVIDIA extensions
- <LI> Changed library name from graphics3D.lib to G3D.lib, same for
- debug version.
- <LI> Changed directory structure and added readme.html to explain
- the new setup.
- <LI> Changed BinaryInput::readBytes to allow reading onto the stack
- <LI> Added Vector4::isFinite
- <LI> G3D::CDTriangle (for 35% faster collision detection)
- <LI> CollisionDetection::closestPointToRectangle
- <LI> CollisionDetection::movingSpherePassesThroughFixedBox
- <LI> CollisionDetection::movingSpherePassesThroughFixedSphere
- <LI> Changed CollisionDetection::movingXFixedTriangle arguments
- <LI> CollisionDetection::collisionTimeForMovingSphereFixedSphere
- <LI> Changed CollisionDetection::distanceToX methods to closestPointToX
- <LI> Vector3::NAN3
- <LI> Made Vector3::isUnit fuzzy
- <LI> Made Vector3::isZero fuzzy
- <LI> Fix: Texture(std::string, std::string) constructor now works for alpha-only textures.
- <LI> FIX: Array now calls copy constructor when resizing
- <LI> FIX: Triangle-sphere and rectangle-sphere collision detection
- returned an incorrect collision location; now fixed.
- <LI> FIX: changed VectorX::isFinite to call isFinite (used to give bad result for NaNs)
- <LI> FIX: Used the normalized edge to compute intersection in
- CollisionDetection::distanceToTrianglePerimeter
- <LI> FIX: Changed the order of corners returned from Box::getFaceCorners so the
- face is ccw, facing out
- <LI> FIX: ManualCameraController::lookAt now faces along the -z axis.
- <LI> FIX: data/ifs/icosa.ifs model is now an icosahedron
- <LI> Made Set::begin() and Set::end() const
- <LI> Added ifdef _WIN32 all over for typedefing types from Windows to Linux and vice versa.
- <LI> G3D::isNaN, G3D::isFinite
- <LI> Added a single triangle triangle.ifs file
- <LI> G3D::LineSegment
- <LI> RenderDevice::debugDrawRay
- <LI> CoordinateFrame::toObjectSpace(Ray&)
- <LI> CoordinateFrame::toObjectSpace(Box&)
- <LI> CoordinateFrame::toObjectSpace(Sphere&)
- <LI> Changed CollisionDetection routines to return the surface normal of the
- surface at the collision location.
- <LI> CollisionDetection::collisionTimeForMovingPointFixedCapsule
- <LI> CollisionDetection::collisionTimeForMovingSphereFixedCapsule
- <LI> G3D::Capsule class
- <LI> Removed e-mail addresses from contributor list to protect them from spammers
- <LI> Linux port [Hari Khalsa & Chris Kern]
- <LI> Added serialize and deserialize methods, deserializing constructor to
- Vector2, Vector3, Vector4, Color3, Color4, Matrix3, CoordinateFrame, Box,
- Sphere, Plane, Ray, Line, Capsule, LineSegment
- <LI> Moved parts of Plane.h into Plane.cpp
- <LI> BinaryInput::readBool8 and BinaryOutput::writeBool8
- <LI> G3D::System [based on Michael Herf, Rob Wyatt, and Benjamin
- Jurke's work]
- <LI> Networking infrastructure: G3D::NetworkDevice, G3D::NetAddress,
- G3D::ReliableConduit, G3D::LightweightConduit, G3D::NetListener
- <LI> G3D::Camera
- <LI> Vector2::toString
- <LI> G3D::createTempFile
- <LI> G3D::fileLength
- <LI> UserInput::setKeyMapping
- <LI> UserInput::keyCodeToString, UserInput::stringToKeyCode
- <LI> JPEG library uses createTempFile
- <LI> JPEG library will allocate up to 6MB before resorting to temp
- files-- faster and more reliable
- <LI> Moved SDL initialization to RenderDevice constructor from the init
- method so extension can be used earlier
- <LI> Support for up to 8 texture units, no longer crashes on machines
- that have more than 4 units
- <LI> Made Arrays allocate at least 32 bytes when resized to improve
- performance of small char stacks
- <LI> Added UserInput key codes for mouse wheel buttons
- <LI> UserInput::keyPressed, UserInput::pressedKeys()
- <LI> UserInput::GKey
- <LI> Renamed UserInput::poll() to UserInput::endEvents(), added
- UserInput::beginEvents()
- <LI> Moved custom UserInput key codes into an enum so they are
- compile-time constants
- <LI> Changed all <io.h> to <stdio.h> for cross-platform [Rob & Chris]
- <LI> Moved LITTLE_ENDIAN and BIG_ENDIAN constants to an enum and renamed
- them to G3D_LITTLE_ENDIAN and G3D_BIG_ENDIAN for cross-platform
- [Rob & Chris]
- <LI> Permanently fixed the precision of Real to be 32-bit float.
- <LI> RenderDevice now loads the NVIDIA VAR fence extensions.
- <LI> Renamed RenderDevice::begin to RenderDevice::beginPrimitive, same
- for end.
- <LI> Redesigned the vertex array system; see VAR and VARArea.
- <LI> Changed GLG3D demo to demonstrate the use of the new VAR and
- VARArea classes
- <LI> CoordinateFrame(Vector3) constructor.
- <LI> Improved the performance of zero-radius sphere [aka point]
- collision detection
- </UL>
-
-<hr>
- <P>
- Changes in 4.01
- <UL>
- <LI> trimWhitespace()
- <LI> Pointwise multiplication and division for Vector3
- <LI> Array::sort now uses > operator by default; two alternative sort methods allow qsort style sorting
- <LI> Texture::copyFromScreen
- <LI> Texture::invertY
- <LI> BinaryInput/BinaryOutput compression (via zlib)
- <LI> Alpha-only G3D::Texture mode
- <LI> G3D::Font and fonts in data/font
- <LI> Array::fastRemove
- <LI> TextInput [Morgan & Aaron]
- <LI> Color4::CLEAR
- <LI> Table [] operator now returns a non-const reference
- <LI> RenderDevice::getFrameRate, RenderDevice::getTriangleRate, RenderDevice::getTriangleCount
- <LI> ManualCameraController::setMoveRate, ManualCameraController::setTurnRate
- <LI> SkyParameters default constructor
- <LI> Vector2, Vector3, Vector4 isZero(), isUnit(), isFinite()
- <LI> Vector4::length(), Vector4::squaredLength()
- <LI> isValidPointer now returns false for 0xFEEEFEEE
- <LI> RenderDevice checks for texture compression extensions
- <LI> Restructured the directories for the CPP sources (only affects people who build G3D)
- <LI> Included NVIDIA and SGI OpenGL headers in the distribution, changed install notes
- <LI> Fixed a bug that previously prevented textures from being garbage collected
- <LI> Fixed Line::distance returning values too small
- <LI> Fixed Plane(normal, point) constructor to compute point from normalized direction [Kevin]
- <LI> LED font by Matthew Welch daffy-duck@worldnet.att.net
- <LI> VenusRising font by Ray Larabie <A HREF="mailto:drowsy@cheerful.com">drowsy@cheerful.com</A>
- <LI> VideoFreak font by Jakob Fischer pizzadude@pizzadude.dk
- </UL>
-
-<hr>
- <P>
- Changes in 4.00
- <UL>
- <LI> Moved texture combine modes from Textures onto RenderDevice texture units
- <LI> Documented RenderDevice::getHDC() (Windows only)
- <LI> Renamed RenderDevice::swapBuffers() to RenderDevice::endFrame(), added corresponding RenderDevice::beginFrame()
- <LI> Moved getNumJoySticks from RenderDevice to UserInput
- <LI> Added TEX_ADD combine mode
- <LI> Table::getKeys and Set::getMembers now have overloads that take an Array as input.
- <LI> BinaryOutput::getCArray
- <LI> RenderDevice::getObjectToWorldMatrix(), RenderDevice::getCameraToWorldMatrix()
- <LI> RenderDevice::debugDrawAxes(), RenderDevice::debugDrawBox(), RenderDevice::debugDrawSphere()
- <LI> Color3::Color3(const Vector3&) and Color4::Color4(const Vector4&)
- <LI> Moved hashCode(const Vector3&) and hashCode(const Vector4&) to the global namespace [Kevin]
- <LI> isValidPointer now returns false for 0xCCCCCCCC and 0xDEADBEEF
- <LI> Fix: RenderDevice::setPolygonOffset now affects polygons rendered in line and point mode
- <LI> Fix: Sun is now invisible after it goes below the horizon
- <LI> Fix: BinaryInput now supports endian-ness correctly in memory read mode
- <LI> Fix: Table.copyFrom and copy constructor now work
- </UL>
-
-<hr>
- <P>
- Changes in 3.02
- <UL>
- <LI> Built libraries using "Multithreaded DLL" [Kevin & Darius]
- <LI> Added depth, color, and stencil bit depth preferences to G3D::RenderDevice
- <LI> G3D::Sky (plus sky directory in the data distribution)
- <LI> Sky cube data [Jauhn Dabz, jauhn@yahoo.com, http://nullpoint.fragland.net]
- <LI> G3D::UserInput
- <LI> G3D::ManualCameraController
- <LI> G3D::SkyParameters
- <LI> G3D::toSeconds, G3D::AMPM, G3D::GameTime, G3D::RealTime
- <LI> G3D::RenderDevice::project
- <LI> G3D::linearSpline
- <LI> G3D::Color3::fromARGB and G3D::Color4::fromARGB
- <LI> Added non-const G3D::Array::last() [Kevin]
- <LI> Modified G3D::RenderDevice::configureDirectionalLight to operate in world space
- <LI> Fix: Flipped the y-axis of G3D::RenderDevice::getDepthBufferValue so it matches the documentation.
- <LI> Removed brief descriptions from documentation
- <LI> Removed sqrt, sin, cos, etc. that conflict with standard library names
- <LI> Removed TWO_PI constant
- <LI> Removed G3D::Matrix3 virtual destructor
- <LI> Removed G3D::Quat virtual destructor [Kevin]
- </UL>
-
- <hr>
- Changes in 3.01
- <UL>
- <LI> Changed an assert() to debugAssert() in Queue.h
- <LI> G3D::Table doesn't grow the number of buckets under bad hash codes [Morgan & Darius]
- <LI> G3D::Table allocates only 10 initial buckets
- <LI> G3D::Table::debugGetLoad()
- <LI> G3D::CollisionDetection::collisionTimeForMovingPointFixedRectangle
- <LI> G3D::CollisionDetection::collisionTimeForMovingPointFixedBox
- <LI> G3D::Ray::intersectionTime, G3D::Ray::unit()
- <LI> G3D::Log [Morgan & Aaron]
- <LI> G3D::RenderDevice (OpenGL state abstraction. VertexBuffer support is beta only)
- <LI> G3D::Texture (includes texture compression, image loading, and texture rectangle)
- <LI> Added a comment to the vector classes noting that they can't be sublcassed [Kevin Egan]
- </UL>
-<hr>
- Changes in 3.00
- <UL>
- <LI> G3D::NEWLINE
- <LI> writeStringToFile
- <LI> Fixed empty stringJoin bug
- <LI> Fixed parseFilename with no path bug
- <LI> Vector3::INF3, Vector3::ZERO3
- <LI> G3D::PhysicsFrame (beta-- this interface is going to change in 4.00)
- <LI> G3D::Vector4
- <LI> G3D::Queue
- <LI> Default constructor for G3D::CImage
- <LI> G3D::isValidHeapPointer, G3D::isValidPointer
- <LI> G3D::Ray
- <LI> CImage copy constructor, CImage::load
- <LI> Removed \#pragma once for gcc compatibility
- <LI> Renamed several hashcode methods to hashCode
- <LI> Fixed fuzzy math to work with infinite numbers
- <LI> Fixed Table::remove(), Set::remove() bug [Darius Jazayeri]
- <LI> G3D::CoordinateFrame.toObjectSpace(Vector4), G3D::CoordinateFrame.toWorldSpace(Vector4)
- <LI> Added the data directory
- <LI> G3D::CollisionDetection
- <LI> G3D::Sphere::culledBy()
- <LI> Added the GLG3D library [Morgan McGuire & Seth Block]
- <LI> Changed SDL_GL_Demo to use GLG3D, rotate triangle, and use color blending
- <LI> Fixed debugPrintf to handle long strings on Win32
- <LI> Wrapped the MMX headers with \#ifdefs [Nate Miller]
- <LI> Moved OpenGL code out of CoordinateFrame.h/cpp
- <LI> Fixed BinaryInput readVector*, readColor* to read in correct order [Nate Miller]
- <LI> BinaryInput::readVector4, BinaryInput::readColor4, BinaryOutput::writeVector4, BinaryOutput::writeColor4
- <LI> IFS_Demo for loading IFS files, dealing with models in OpenGL [Nate Miller]
- </UL>
-
-<hr>
- <P>
- Changes in 2.00
- <UL>
- <LI> Vector2 members renamed to x,y from s,t
- <LI> Added SDL_GL_Demo and Win32_Demo
- <LI> Removed Group
- </UL>
-
-<hr>
- <P>
- Changes in 1.10
- <UL>
- <LI> CImage, color conversion routines [Morgan McGuire, John Chisholm, and Edward Resnick]
- <LI> Array dereference for BinaryInput
- <LI> BinaryInput from memory
- <LI> BinaryOutput to memory
- <LI> toUpper(std::string), toLower(std::string)
- <LI> Group::clear()
- <LI> inf, nan as global constants (double precision)
- <LI> Can iterate over const Tables
- <LI> Table::deleteValues()
- <LI> Fixed an off-by-one bug in BinaryInput::readString()
- <LI> beginsWith() and wordWrap() string utilities
- <LI> prompt dialogs have fixed width font [Kurt Miller]
- <LI> iMax(), iMin()
- <LI> Array::sort()
- <LI> stringCompare(), stringPtrCompare()
- <LI> readFileAsString()
- <LI> Fixed textPrompt() to wait for input
- <LI> BinaryInput.getFilename(), BinaryOutput.getFilename()
- <LI> ReferenceCount [Justin Miller]
- <LI> endsWith()
- <LI> stringSplit(), stringJoin()
- <LI> Renamed format.* to stringutils.*
- <LI> fileExists(), parseFilename(), createDirectory(), copyFile()
- <LI> highestBit() [Jukka Liimatta]
- <LI> flipRGBVertical()
- <LI> Changed all header guards to use G3D_ prefix
- <LI> ConvexPolyhedron
- <LI> Virtual destructors on almost all objects.
- <LI> RGBtoBGR()
- <LI> Color4
- <LI> Array::pop(bool shrinkArray=true)
- <LI> Vector2::isFinite, Vector2::fuzzyEq, Vector::fuzzyNe
- </UL>
- <P>
-
-<hr>
- Changes in 1.09
- <UL>
- <LI> Removed pointer hash [Aaron Orenstein]
- <LI> Changed some includes from quotes to pointy brackets [Aaron Orenstein]
- <LI> Sphere::toString()
- <LI> Plane::toString()
- <LI> Added a change log
- </UL>
-
- */
diff --git a/externals/g3dlite/doc-files/contributors.dox b/externals/g3dlite/doc-files/contributors.dox
deleted file mode 100644
index 3cd946a0bf1..00000000000
--- a/externals/g3dlite/doc-files/contributors.dox
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
-@page contributors G3D Developer Credits
-
- <b>Team Members</b>
- <br><i>7.01 Release Team</i>
- <br>Morgan McGuire [Williams College] - Project Manager
- <br>Corey Taylor [EA] - Assistant Project Manager and Linux Lead
- <br>Casey O'Donnell [RPI] - OS X Lead
- <br>Dan Keefe [Brown University] - Developer
- <br>Kyle Whitson [Williams College] - Developer
- <br>Danny Yuxing Huang [Williams College] - Developer
-
- <b>Previous Contributors and Cited Sources</b> <br>This library
- contains code and resources contributed by the following people, or
- based open code and articles by them. Starred (*) developers are
- previous members of the %G3D team.
-
- <p>David Baszucki
- <BR>Seth Block
- <BR>Nicholas Bray
- <BR>Nick Capens
- <BR>Erik Cassel
- <BR>John Chisholm*
- <BR>Jauhn Dabz
- <BR>Erik de Castro Lopo
- <br>Rich Deeson*
- <BR>Chris Demetriou
- <BR>L. Peter Deutsch
- <br>Dmitri*
- <BR>Dave Eberly
- <BR>Kevin Egan*
- <BR>Cass Everitt
- <BR>Dan Fast*
- <BR>Andi Fein
- <BR>Jakob Fischer
- <BR>Dan Keefe*
- <BR>Harishabd Khalsa
- <BR>Nicolai Haehnle
- <BR>Michael Herf
- <br>Daniel Hilferty*
- <BR>Pete Hopkins
- <br>Danny Yuxing Huang
- <BR>Peter Hunt
- <BR>Robert Hunter
- <BR>Ed Johnson
- <BR>Benjamin Jurke
- <BR>Chris Kern
- <BR>Independent JPEG Group
- <BR>Darius Jazayeri
- <BR>Ben Landon*
- <BR>Thomas G. Lane
- <BR>Ray Larabie
- <BR>Jukka Liimatta
- <BR>Giulio Mainardi
- <BR>Jeff Marsceill
- <BR>Max McGuire
- <BR>Morgan McGuire
- <BR>Justin Miller
- <BR>Kurt Miller
- <BR>Nate Miller
- <BR>Tomas Moller
- <BR>Eric Muller*
- <BR>Nick Musurca
- <BR>Akita Noek
- <BR>James O'Sullivan*
- <BR>Aaron Orenstein
- <BR>Jordan Parker
- <BR>Edward Resnick
- <BR>Alex Rice
- <BR>Jack Ritter
- <BR>Nate Robbins
- <BR>Joshua Schpok*
- <BR>Sebastian Schubert
- <BR>SGI
- <BR>Ben Shine*
- <BR>Peter Sibley*
- <br>Gabe Taubman*
- <BR>Corey Taylor*
- <BR>Pierre Terdiman
- <BR>Ben Trumbore
- <BR>Matthew Welch
- <BR>Simon Winkelbach
- <BR>Laura Wollstadt
- <BR>Andrew Woo
-*/
diff --git a/externals/g3dlite/doc-files/license.dox b/externals/g3dlite/doc-files/license.dox
deleted file mode 100644
index b4302651fbf..00000000000
--- a/externals/g3dlite/doc-files/license.dox
+++ /dev/null
@@ -1,120 +0,0 @@
-/** @page license License
-
-\htmlonly
-<TABLE BORDER=0 WIDTH=80%><TR><TD><I><FONT FACE="Arial">
-<A HREF="guideintro.html"><IMG SRC="backarrow.gif" BORDER=0 ALIGN=MIDDLE>
-Introduction</A></I></FONT></TD><TD ALIGN=RIGHT><FONT FACE="Arial"><I>
-<A HREF="guideinstall.html">
-Installation <IMG SRC="forwardarrow.gif" BORDER=0 ALIGN=MIDDLE></A></I></FONT></TD></TR></TABLE>
-\endhtmlonly
-
-@section intent Intent of License
- (This section is informal and not legally binding.)
-
- <BR> This library is free code-- you can use it without charge and
- it is minimally legally encumbered. Unlike some other free libraries,
- we <B>do not</B> require you to release
- your source code or make your own program open source.
-
- <P> I intend the license (below) to protect me and the other
- contributors from liability and allow you to use the source however
- you want. You can make your own closed or open-source programs,
- sell them, give them away, whatever.
-
- <P>
- You have an obligation to say "this software is based in part on
- the work of the Independent JPEG Group" in your documentation or
- application help if you use the G3D::GImage class because it is based on
- the IJG library. The OpenGL headers and ZLib headers included may
- be freely distributed provided their copyright notices remain
- intact.
-
- <P>
- For convenience, G3D::license is a function that returns the license
- string you must put in your documentation. G3D::GApp will automatically
- write a file (g3d-license.txt) to disk with the contents of this
- license unless you tell it not to.
-
- <P>
- Most of the data resources have either entered the public domain and have
- been in several published papers or are data that I have explicitly
- received permission to distribute with G3D. The G3D fonts are actually font
- images, not TrueType font descriptions and may be freely
- distributed. As a rule of thumb, you can freely use and distribute
- anything you find in the data directory but may need permission to use
- it in a commercial product. Check the various copyright.txt files
- in the data directories for specific information.
-
- <P>
-
- You are required by the BSD license to acknowledge G3D in your
- documentation. This can be as minimal as a note buried in the
- fine print at the end of a manual or a text file accompanying
- your program. I appreciate it if you acknowledged the library
- more publicly but you aren't required to.
-
- <P>
-
- Likewise, you are encouraged but not required to submit patches to
- improve the library for the benefit of all. E-mail me with bugs,
- patches, and questions. <P>
-
- -Morgan McGuire
- &lt;<I><A HREF="mailto:matrix@graphics3d.com">matrix@graphics3d.com</A></I>&gt;
-
- <HR>
-
- @section reallicense License
-
- <I>G3D is licensed under the <A HREF="http://www.opensource.org/licenses/bsd-license.php">BSD license</A>,
- with portions controlled by the <A HREF="IJG-README.TXT">IJG license</A>,
- <A HREF="libpng-LICENSE.txt">PNG Reference Library license</A> and
- <A HREF="http://www.gnu.org/copyleft/lesser.html">GNU Lesser General Public License (LGPL)</A>.</I>
-
- <CODE>
- <IMG SRC="http://opensource.org/trademarks/osi-certified/web/osi-certified-120x100.gif">
- <DT>This product uses software from the G3D project (http://g3d-cpp.sf.net)
- <DT>Copyright &copy; 2000-2008, Morgan McGuire
- <DT>All rights reserved.
- <P>
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- <P>
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- <P>
- Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- <P>
- Neither the name of Morgan McGuire, Williams College, Brown University, nor the names of
- its contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- <P>
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- THE POSSIBILITY OF SUCH DAMAGE.
- </CODE>
-
- <P>
- You must also agree to be bound by the terms of the Independent JPEG
- Group license for the portions of this library that are based
- on the work of the Independent JPEG Group, <B>if you use those
- portions</B>. Note: if you do not use the G3D::GImage class,
- this clause does not apply to you because the linker will
- strip that code from your project. The <A
- HREF="IJG-README.TXT">IJG-README.TXT</A> file contains the
- Independent JPEG Group license.
-
- </OL>
-
- */ \ No newline at end of file
diff --git a/externals/g3dlite/win/VC90/g3dlite.vcproj b/externals/g3dlite/win/VC90/g3dlite.vcproj
deleted file mode 100644
index e76d610ab69..00000000000
--- a/externals/g3dlite/win/VC90/g3dlite.vcproj
+++ /dev/null
@@ -1,463 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9,00"
- Name="g3dlite"
- ProjectGUID="{8072769E-CF10-48BF-B9E1-12752A5DAC6E}"
- RootNamespace="sockets"
- Keyword="Win32Proj"
- TargetFrameworkVersion="196613"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- <Platform
- Name="x64"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="..\..\bin\$(PlatformName)_$(ConfigurationName)"
- IntermediateDirectory=".\g3dlite__$(PlatformName)_$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/MP"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\zip.lib\include;..\..\G3D.lib\include;..\..\..\zlib;"
- AdditionalUsingDirectories=""
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="false"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- BufferSecurityCheck="true"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- ObjectFile=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- ProgramDataBaseFileName=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/g3dlite.lib"
- IgnoreAllDefaultLibraries="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Debug|x64"
- OutputDirectory="..\..\bin\$(PlatformName)_$(ConfigurationName)"
- IntermediateDirectory=".\g3dlite__$(PlatformName)_$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/MP"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\zip.lib\include;..\..\G3D.lib\include;..\..\..\zlib;"
- AdditionalUsingDirectories=""
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- MinimalRebuild="false"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- BufferSecurityCheck="true"
- EnableFunctionLevelLinking="true"
- UsePrecompiledHeader="0"
- AssemblerListingLocation=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- ObjectFile=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- ProgramDataBaseFileName=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/g3dlite.lib"
- IgnoreAllDefaultLibraries="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="..\..\bin\$(PlatformName)_$(ConfigurationName)"
- IntermediateDirectory=".\g3dlite__$(PlatformName)_$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/MP"
- AdditionalIncludeDirectories="..\..\zip.lib\include;..\..\G3D.lib\include;..\..\..\zlib;"
- AdditionalUsingDirectories=""
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_SECURE_SCL=0"
- RuntimeLibrary="2"
- EnableEnhancedInstructionSet="1"
- UsePrecompiledHeader="0"
- AssemblerListingLocation=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- ObjectFile=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- ProgramDataBaseFileName=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/g3dlite.lib"
- IgnoreAllDefaultLibraries="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|x64"
- OutputDirectory="..\..\bin\$(PlatformName)_$(ConfigurationName)"
- IntermediateDirectory=".\g3dlite__$(PlatformName)_$(ConfigurationName)"
- ConfigurationType="4"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- TargetEnvironment="3"
- />
- <Tool
- Name="VCCLCompilerTool"
- AdditionalOptions="/MP"
- AdditionalIncludeDirectories="..\..\zip.lib\include;..\..\G3D.lib\include;..\..\..\zlib;"
- AdditionalUsingDirectories=""
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_SECURE_SCL=0"
- RuntimeLibrary="2"
- EnableEnhancedInstructionSet="0"
- UsePrecompiledHeader="0"
- AssemblerListingLocation=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- ObjectFile=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- ProgramDataBaseFileName=".\g3dlite__$(PlatformName)_$(ConfigurationName)\"
- WarningLevel="3"
- Detect64BitPortabilityProblems="false"
- DebugInformationFormat="3"
- CallingConvention="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="$(OutDir)/g3dlite.lib"
- IgnoreAllDefaultLibraries="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- >
- </Filter>
- <Filter
- Name="Source Files"
- >
- <File
- RelativePath="..\..\G3D.lib\source\AABox.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\AnyVal.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\BinaryFormat.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\BinaryInput.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\BinaryOutput.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Box.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Capsule.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\CollisionDetection.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\CoordinateFrame.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Crypto.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Cylinder.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\debugAssert.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\fileutils.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\format.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\g3dmath.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Line.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\LineSegment.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Log.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Matrix3.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Matrix4.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Plane.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\prompt.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Quat.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Ray.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\RegistryUtil.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Sphere.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\stringutils.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\System.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\TextInput.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\TextOutput.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Triangle.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\UprightFrame.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Vector2.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Vector3.cpp"
- >
- </File>
- <File
- RelativePath="..\..\G3D.lib\source\Vector4.cpp"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/externals/g3dlite/win/g3dlite.sln b/externals/g3dlite/win/g3dlite.sln
deleted file mode 100644
index 875374e3944..00000000000
--- a/externals/g3dlite/win/g3dlite.sln
+++ /dev/null
@@ -1,25 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "g3dlite", "VC90\g3dlite.vcproj", "{8072769E-CF10-48BF-B9E1-12752A5DAC6E}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Debug|x64 = Debug|x64
- Release|Win32 = Release|Win32
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.ActiveCfg = Debug|Win32
- {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|Win32.Build.0 = Debug|Win32
- {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|x64.ActiveCfg = Debug|x64
- {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Debug|x64.Build.0 = Debug|x64
- {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.ActiveCfg = Release|Win32
- {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|Win32.Build.0 = Release|Win32
- {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|x64.ActiveCfg = Release|x64
- {8072769E-CF10-48BF-B9E1-12752A5DAC6E}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/externals/g3dlite/zip.lib/include/zip/ioapi.h b/externals/g3dlite/zip.lib/include/zip/ioapi.h
deleted file mode 100644
index 7d457baab34..00000000000
--- a/externals/g3dlite/zip.lib/include/zip/ioapi.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-*/
-
-#ifndef _ZLIBIOAPI_H
-#define _ZLIBIOAPI_H
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ (1)
-#define ZLIB_FILEFUNC_MODE_WRITE (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE (8)
-
-
-#ifndef ZCALLBACK
-
-#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-#define ZCALLBACK CALLBACK
-#else
-#define ZCALLBACK
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
-typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
-typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
-typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef struct zlib_filefunc_def_s
-{
- open_file_func zopen_file;
- read_file_func zread_file;
- write_file_func zwrite_file;
- tell_file_func ztell_file;
- seek_file_func zseek_file;
- close_file_func zclose_file;
- testerror_file_func zerror_file;
- voidpf opaque;
-} zlib_filefunc_def;
-
-
-
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
-#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
-#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
-#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
-#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
-#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/externals/g3dlite/zip.lib/include/zip/unzip.h b/externals/g3dlite/zip.lib/include/zip/unzip.h
deleted file mode 100644
index b247937c807..00000000000
--- a/externals/g3dlite/zip.lib/include/zip/unzip.h
+++ /dev/null
@@ -1,354 +0,0 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
-
- Multi volume ZipFile (span) are not supported.
- Encryption compatible with pkzip 2.04g only supported
- Old compressions used by old PKZip 1.x are not supported
-
-
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
-
- Condition of use and distribution are the same than zlib :
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
-
-*/
-
-/* for more info about .ZIP format, see
- http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
- http://www.info-zip.org/pub/infozip/doc/
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _unz_H
-#define _unz_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK (0)
-#define UNZ_END_OF_LIST_OF_FILE (-100)
-#define UNZ_ERRNO (Z_ERRNO)
-#define UNZ_EOF (0)
-#define UNZ_PARAMERROR (-102)
-#define UNZ_BADZIPFILE (-103)
-#define UNZ_INTERNALERROR (-104)
-#define UNZ_CRCERROR (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
- These data comes from the end of central dir */
-typedef struct unz_global_info_s
-{
- uLong number_entry; /* total number of entries in
- the central dir on this disk */
- uLong size_comment; /* size of the global comment of the zipfile */
-} unz_global_info;
-
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info_s
-{
- uLong version; /* version made by 2 bytes */
- uLong version_needed; /* version needed to extract 2 bytes */
- uLong flag; /* general purpose bit flag 2 bytes */
- uLong compression_method; /* compression method 2 bytes */
- uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
- uLong crc; /* crc-32 4 bytes */
- uLong compressed_size; /* compressed size 4 bytes */
- uLong uncompressed_size; /* uncompressed size 4 bytes */
- uLong size_filename; /* filename length 2 bytes */
- uLong size_file_extra; /* extra field length 2 bytes */
- uLong size_file_comment; /* file comment length 2 bytes */
-
- uLong disk_num_start; /* disk number start 2 bytes */
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-
- tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
- const char* fileName2,
- int iCaseSensitivity));
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((const char *path));
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
- "zlib/zlib113.zip".
- If the zipfile cannot be opened (file don't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-
-extern unzFile ZEXPORT unzOpen2 OF((const char *path,
- zlib_filefunc_def* pzlib_filefunc_def));
-/*
- Open a Zip file, like unzOpen, but provide a set of file low level API
- for read/write the zip file (see ioapi.h)
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
- unz_global_info *pglobal_info));
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-
-
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
- char *szComment,
- uLong uSizeBuf));
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
- const char *szFileName,
- int iCaseSensitivity));
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-/* ****************************************** */
-/* Ryan supplied functions */
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; /* offset in zip file directory */
- uLong num_of_file; /* # of file */
-} unz_file_pos;
-
-extern int ZEXPORT unzGetFilePos(
- unzFile file,
- unz_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos(
- unzFile file,
- unz_file_pos* file_pos);
-
-/* ****************************************** */
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
- unz_file_info *pfile_info,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-/*
- Get Info about the current file
- if pfile_info!=NULL, the *pfile_info structure will contain somes info about
- the current file
- if szFileName!=NULL, the filemane string will be copied in szFileName
- (fileNameBufferSize is the size of the buffer)
- if extraField!=NULL, the extra field information will be copied in extraField
- (extraFieldBufferSize is the size of the buffer).
- This is the Central-header version of the extra field
- if szComment!=NULL, the comment string of the file will be copied in szComment
- (commentBufferSize is the size of the buffer)
-*/
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
- from it, and close it (you can close it before reading all the file)
- */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
- Open for reading data the current file in the zipfile.
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
- const char* password));
-/*
- Open for reading data the current file in the zipfile.
- password is a crypting password
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
- int* method,
- int* level,
- int raw));
-/*
- Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
- if raw==1
- *method will receive method of compression, *level will receive level of
- compression
- note : you can set level parameter as NULL (if you did not want known level,
- but you CANNOT set method parameter as NULL
-*/
-
-extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
- int* method,
- int* level,
- int raw,
- const char* password));
-/*
- Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
- if raw==1
- *method will receive method of compression, *level will receive level of
- compression
- note : you can set level parameter as NULL (if you did not want known level,
- but you CANNOT set method parameter as NULL
-*/
-
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
- Close the file in zip opened with unzOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read bytes from the current file (opened by unzOpenCurrentFile)
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-/*
- Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-
-/***************************************************************************/
-
-/* Get the current file offset */
-extern uLong ZEXPORT unzGetOffset (unzFile file);
-
-/* Set the current file offset */
-extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _unz_H */
diff --git a/externals/g3dlite/zip.lib/include/zip/zip.h b/externals/g3dlite/zip.lib/include/zip/zip.h
deleted file mode 100644
index acacce83b9b..00000000000
--- a/externals/g3dlite/zip.lib/include/zip/zip.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/* zip.h -- IO for compress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
- Multi volume ZipFile (span) are not supported.
- Encryption compatible with pkzip 2.04g only supported
- Old compressions used by old PKZip 1.x are not supported
-
- For uncompress .zip file, look at unzip.h
-
-
- I WAIT FEEDBACK at mail info@winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
-
- Condition of use and distribution are the same than zlib :
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
-
-*/
-
-/* for more info about .ZIP format, see
- http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
- http://www.info-zip.org/pub/infozip/doc/
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _zip_H
-#define _zip_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK (0)
-#define ZIP_EOF (0)
-#define ZIP_ERRNO (Z_ERRNO)
-#define ZIP_PARAMERROR (-102)
-#define ZIP_BADZIPFILE (-103)
-#define ZIP_INTERNALERROR (-104)
-
-#ifndef DEF_MEM_LEVEL
-# if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-# else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-# endif
-#endif
-/* default memLevel */
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
- tm_zip tmz_date; /* date in understandable format */
- uLong dosDate; /* if dos_date == 0, tmu_date is used */
-/* uLong flag; */ /* general purpose bit flag 2 bytes */
-
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-} zip_fileinfo;
-
-typedef const char* zipcharpc;
-
-
-#define APPEND_STATUS_CREATE (0)
-#define APPEND_STATUS_CREATEAFTER (1)
-#define APPEND_STATUS_ADDINZIP (2)
-
-extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
-/*
- Create a zipfile.
- pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
- an Unix computer "zlib/zlib113.zip".
- if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
- will be created at the end of the file.
- (useful if the file contain a self extractor code)
- if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
- add files in existing zip (be sure you don't add file that doesn't exist)
- If the zipfile cannot be opened, the return value is NULL.
- Else, the return value is a zipFile Handle, usable with other function
- of this zip package.
-*/
-
-/* Note : there is no delete function into a zipfile.
- If you want delete file into a zipfile, you must open a zipfile, and create another
- Of couse, you can use RAW reading and writing to copy the file you did not want delte
-*/
-
-extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
- int append,
- zipcharpc* globalcomment,
- zlib_filefunc_def* pzlib_filefunc_def));
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level));
-/*
- Open a file in the ZIP for writing.
- filename : the filename in zip (if NULL, '-' without quote will be used
- *zipfi contain supplemental information
- if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
- contains the extrafield data the the local header
- if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
- contains the extrafield data the the local header
- if comment != NULL, comment contain the comment string
- method contain the compression method (0 for store, Z_DEFLATED for deflate)
- level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-*/
-
-
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw));
-
-/*
- Same than zipOpenNewFileInZip, except if raw=1, we write raw file
- */
-
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw,
- int windowBits,
- int memLevel,
- int strategy,
- const char* password,
- uLong crcForCtypting));
-
-/*
- Same than zipOpenNewFileInZip2, except
- windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
- password : crypting password (NULL for no crypting)
- crcForCtypting : crc of file to compress (needed for crypting)
- */
-
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
- const void* buf,
- unsigned len));
-/*
- Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
- Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
- uLong uncompressed_size,
- uLong crc32));
-/*
- Close the current file in the zipfile, for fiel opened with
- parameter raw=1 in zipOpenNewFileInZip2
- uncompressed_size and crc32 are value for the uncompressed size
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
- const char* global_comment));
-/*
- Close the zipfile
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip_H */
diff --git a/externals/g3dlite/zip.lib/source/crypt.h b/externals/g3dlite/zip.lib/source/crypt.h
deleted file mode 100644
index 622f4bc2ec4..00000000000
--- a/externals/g3dlite/zip.lib/source/crypt.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This code is a modified version of crypting code in Infozip distribution
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
-
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
-
- If you don't need crypting in your application, just define symbols
- NOCRYPT and NOUNCRYPT.
-
- This code support the "Traditional PKWARE Encryption".
-
- The new AES encryption added on Zip format by Winzip (see the page
- http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
- Encryption is not supported.
-*/
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
-{
- unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
- * unpredictable manner on 16-bit systems; not a problem
- * with any known compiler so far, though */
-
- temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
- return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
-{
- (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
- (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
- (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
- {
- register int keyshift = (int)((*(pkeys+1)) >> 24);
- (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
- }
- return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
-{
- *(pkeys+0) = 305419896L;
- *(pkeys+1) = 591751049L;
- *(pkeys+2) = 878082192L;
- while (*passwd != '\0') {
- update_keys(pkeys,pcrc_32_tab,(int)*passwd);
- passwd++;
- }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
- (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
- (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN 12
- /* "last resort" source for second part of crypt seed pattern */
-# ifndef ZCR_SEED2
-# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
-# endif
-
-static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
- const char *passwd; /* password string */
- unsigned char *buf; /* where to write header */
- int bufSize;
- unsigned long* pkeys;
- const unsigned long* pcrc_32_tab;
- unsigned long crcForCrypting;
-{
- int n; /* index in random header */
- int t; /* temporary */
- int c; /* random byte */
- unsigned char header[RAND_HEAD_LEN-2]; /* random header */
- static unsigned calls = 0; /* ensure different random header each time */
-
- if (bufSize<RAND_HEAD_LEN)
- return 0;
-
- /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
- * output of rand() to get less predictability, since rand() is
- * often poorly implemented.
- */
- if (++calls == 1)
- {
- srand((unsigned)(time(NULL) ^ ZCR_SEED2));
- }
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- c = (rand() >> 7) & 0xff;
- header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
- }
- /* Encrypt random header (last two bytes is high word of crc) */
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
- }
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
- return n;
-}
-
-#endif
diff --git a/externals/g3dlite/zip.lib/source/ioapi.c b/externals/g3dlite/zip.lib/source/ioapi.c
deleted file mode 100644
index f1bee23e64b..00000000000
--- a/externals/g3dlite/zip.lib/source/ioapi.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* ioapi.c -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-
-
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-voidpf ZCALLBACK fopen_file_func OF((
- voidpf opaque,
- const char* filename,
- int mode));
-
-uLong ZCALLBACK fread_file_func OF((
- voidpf opaque,
- voidpf stream,
- void* buf,
- uLong size));
-
-uLong ZCALLBACK fwrite_file_func OF((
- voidpf opaque,
- voidpf stream,
- const void* buf,
- uLong size));
-
-long ZCALLBACK ftell_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-long ZCALLBACK fseek_file_func OF((
- voidpf opaque,
- voidpf stream,
- uLong offset,
- int origin));
-
-int ZCALLBACK fclose_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-int ZCALLBACK ferror_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-
-voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
- voidpf opaque;
- const char* filename;
- int mode;
-{
- FILE* file = NULL;
- const char* mode_fopen = NULL;
- if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
- mode_fopen = "rb";
- else
- if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
- mode_fopen = "r+b";
- else
- if (mode & ZLIB_FILEFUNC_MODE_CREATE)
- mode_fopen = "wb";
-
- if ((filename!=NULL) && (mode_fopen != NULL))
- file = fopen(filename, mode_fopen);
- return file;
-}
-
-
-uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- void* buf;
- uLong size;
-{
- uLong ret;
- ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
- return ret;
-}
-
-
-uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- const void* buf;
- uLong size;
-{
- uLong ret;
- ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
- return ret;
-}
-
-long ZCALLBACK ftell_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- long ret;
- ret = ftell((FILE *)stream);
- return ret;
-}
-
-long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
- voidpf opaque;
- voidpf stream;
- uLong offset;
- int origin;
-{
- int fseek_origin=0;
- long ret;
- switch (origin)
- {
- case ZLIB_FILEFUNC_SEEK_CUR :
- fseek_origin = SEEK_CUR;
- break;
- case ZLIB_FILEFUNC_SEEK_END :
- fseek_origin = SEEK_END;
- break;
- case ZLIB_FILEFUNC_SEEK_SET :
- fseek_origin = SEEK_SET;
- break;
- default: return -1;
- }
- ret = 0;
- fseek((FILE *)stream, offset, fseek_origin);
- return ret;
-}
-
-int ZCALLBACK fclose_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret;
- ret = fclose((FILE *)stream);
- return ret;
-}
-
-int ZCALLBACK ferror_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret;
- ret = ferror((FILE *)stream);
- return ret;
-}
-
-void fill_fopen_filefunc (pzlib_filefunc_def)
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- pzlib_filefunc_def->zopen_file = fopen_file_func;
- pzlib_filefunc_def->zread_file = fread_file_func;
- pzlib_filefunc_def->zwrite_file = fwrite_file_func;
- pzlib_filefunc_def->ztell_file = ftell_file_func;
- pzlib_filefunc_def->zseek_file = fseek_file_func;
- pzlib_filefunc_def->zclose_file = fclose_file_func;
- pzlib_filefunc_def->zerror_file = ferror_file_func;
- pzlib_filefunc_def->opaque = NULL;
-}
diff --git a/externals/g3dlite/zip.lib/source/iowin32.c b/externals/g3dlite/zip.lib/source/iowin32.c
deleted file mode 100644
index ce911e3636e..00000000000
--- a/externals/g3dlite/zip.lib/source/iowin32.c
+++ /dev/null
@@ -1,272 +0,0 @@
-#ifdef _MSC_VER
-/* iowin32.c -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
- This IO API version uses the Win32 API (for Microsoft Windows)
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-*/
-
-#include <stdlib.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-#include "iowin32.h"
-
-#ifndef INVALID_HANDLE_VALUE
-#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
-#endif
-
-#ifndef INVALID_SET_FILE_POINTER
-#define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-voidpf ZCALLBACK win32_open_file_func OF((
- voidpf opaque,
- const char* filename,
- int mode));
-
-uLong ZCALLBACK win32_read_file_func OF((
- voidpf opaque,
- voidpf stream,
- void* buf,
- uLong size));
-
-uLong ZCALLBACK win32_write_file_func OF((
- voidpf opaque,
- voidpf stream,
- const void* buf,
- uLong size));
-
-long ZCALLBACK win32_tell_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-long ZCALLBACK win32_seek_file_func OF((
- voidpf opaque,
- voidpf stream,
- uLong offset,
- int origin));
-
-int ZCALLBACK win32_close_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-int ZCALLBACK win32_error_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-typedef struct
-{
- HANDLE hf;
- int error;
-} WIN32FILE_IOWIN;
-
-voidpf ZCALLBACK win32_open_file_func (opaque, filename, mode)
- voidpf opaque;
- const char* filename;
- int mode;
-{
- const char* mode_fopen = NULL;
- DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
- HANDLE hFile = 0;
- voidpf ret=NULL;
-
- dwDesiredAccess = dwShareMode = dwFlagsAndAttributes = 0;
-
- if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
- {
- dwDesiredAccess = GENERIC_READ;
- dwCreationDisposition = OPEN_EXISTING;
- dwShareMode = FILE_SHARE_READ;
- }
- else
- if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
- {
- dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
- dwCreationDisposition = OPEN_EXISTING;
- }
- else
- if (mode & ZLIB_FILEFUNC_MODE_CREATE)
- {
- dwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
- dwCreationDisposition = CREATE_ALWAYS;
- }
-
- if ((filename!=NULL) && (dwDesiredAccess != 0))
- hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL,
- dwCreationDisposition, dwFlagsAndAttributes, NULL);
-
- if (hFile == INVALID_HANDLE_VALUE)
- hFile = NULL;
-
- if (hFile != NULL)
- {
- WIN32FILE_IOWIN w32fiow;
- w32fiow.hf = hFile;
- w32fiow.error = 0;
- ret = malloc(sizeof(WIN32FILE_IOWIN));
- if (ret==NULL)
- CloseHandle(hFile);
- else *((WIN32FILE_IOWIN*)ret) = w32fiow;
- }
- return ret;
-}
-
-
-uLong ZCALLBACK win32_read_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- void* buf;
- uLong size;
-{
- uLong ret=0;
- HANDLE hFile = NULL;
- if (stream!=NULL)
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
- if (hFile != NULL)
- if (!ReadFile(hFile, buf, size, &ret, NULL))
- {
- DWORD dwErr = GetLastError();
- if (dwErr == ERROR_HANDLE_EOF)
- dwErr = 0;
- ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
- }
-
- return ret;
-}
-
-
-uLong ZCALLBACK win32_write_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- const void* buf;
- uLong size;
-{
- uLong ret=0;
- HANDLE hFile = NULL;
- if (stream!=NULL)
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
-
- if (hFile !=NULL)
- if (!WriteFile(hFile, buf, size, &ret, NULL))
- {
- DWORD dwErr = GetLastError();
- if (dwErr == ERROR_HANDLE_EOF)
- dwErr = 0;
- ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
- }
-
- return ret;
-}
-
-long ZCALLBACK win32_tell_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- long ret=-1;
- HANDLE hFile = NULL;
- if (stream!=NULL)
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
- if (hFile != NULL)
- {
- DWORD dwSet = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
- if (dwSet == INVALID_SET_FILE_POINTER)
- {
- DWORD dwErr = GetLastError();
- ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
- ret = -1;
- }
- else
- ret=(long)dwSet;
- }
- return ret;
-}
-
-long ZCALLBACK win32_seek_file_func (opaque, stream, offset, origin)
- voidpf opaque;
- voidpf stream;
- uLong offset;
- int origin;
-{
- DWORD dwMoveMethod=0xFFFFFFFF;
- HANDLE hFile = NULL;
-
- long ret=-1;
- if (stream!=NULL)
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
- switch (origin)
- {
- case ZLIB_FILEFUNC_SEEK_CUR :
- dwMoveMethod = FILE_CURRENT;
- break;
- case ZLIB_FILEFUNC_SEEK_END :
- dwMoveMethod = FILE_END;
- break;
- case ZLIB_FILEFUNC_SEEK_SET :
- dwMoveMethod = FILE_BEGIN;
- break;
- default: return -1;
- }
-
- if (hFile != NULL)
- {
- DWORD dwSet = SetFilePointer(hFile, offset, NULL, dwMoveMethod);
- if (dwSet == INVALID_SET_FILE_POINTER)
- {
- DWORD dwErr = GetLastError();
- ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
- ret = -1;
- }
- else
- ret=0;
- }
- return ret;
-}
-
-int ZCALLBACK win32_close_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret=-1;
-
- if (stream!=NULL)
- {
- HANDLE hFile;
- hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
- if (hFile != NULL)
- {
- CloseHandle(hFile);
- ret=0;
- }
- free(stream);
- }
- return ret;
-}
-
-int ZCALLBACK win32_error_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret=-1;
- if (stream!=NULL)
- {
- ret = ((WIN32FILE_IOWIN*)stream) -> error;
- }
- return ret;
-}
-
-void fill_win32_filefunc (pzlib_filefunc_def)
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- pzlib_filefunc_def->zopen_file = win32_open_file_func;
- pzlib_filefunc_def->zread_file = win32_read_file_func;
- pzlib_filefunc_def->zwrite_file = win32_write_file_func;
- pzlib_filefunc_def->ztell_file = win32_tell_file_func;
- pzlib_filefunc_def->zseek_file = win32_seek_file_func;
- pzlib_filefunc_def->zclose_file = win32_close_file_func;
- pzlib_filefunc_def->zerror_file = win32_error_file_func;
- pzlib_filefunc_def->opaque=NULL;
-}
-#endif
diff --git a/externals/g3dlite/zip.lib/source/iowin32.h b/externals/g3dlite/zip.lib/source/iowin32.h
deleted file mode 100644
index 1978f6152dd..00000000000
--- a/externals/g3dlite/zip.lib/source/iowin32.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifdef _MSC_VER
-/* iowin32.h -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
- This IO API version uses the Win32 API (for Microsoft Windows)
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-*/
-
-#include <windows.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/externals/g3dlite/zip.lib/source/unzip.c b/externals/g3dlite/zip.lib/source/unzip.c
deleted file mode 100644
index e80bc5bde7c..00000000000
--- a/externals/g3dlite/zip.lib/source/unzip.c
+++ /dev/null
@@ -1,1604 +0,0 @@
-/* unzip.c -- IO for uncompress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- Read unzip.h for more info
-*/
-
-/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
-compatibility with older software. The following is from the original crypt.c. Code
-woven in by Terry Thorsen 1/2003.
-*/
-/*
- Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
-
- See the accompanying file LICENSE, version 2000-Apr-09 or later
- (the contents of which are also included in zip.h) for terms of use.
- If, for some reason, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
-*/
-/*
- crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
- */
-
-/*
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "unzip.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-
-#ifndef CASESENSITIVITYDEFAULT_NO
-# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
-# define CASESENSITIVITYDEFAULT_NO
-# endif
-#endif
-
-
-#ifndef UNZ_BUFSIZE
-#define UNZ_BUFSIZE (16384)
-#endif
-
-#ifndef UNZ_MAXFILENAMEINZIP
-#define UNZ_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-
-
-
-
-const char unz_copyright[] =
- " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-/* unz_file_info_interntal contain internal info about a file in zipfile*/
-typedef struct unz_file_info_internal_s
-{
- uLong offset_curfile;/* relative offset of local header 4 bytes */
-} unz_file_info_internal;
-
-
-/* file_in_zip_read_info_s contain internal information about a file in zipfile,
- when reading and decompress it */
-typedef struct
-{
- char *read_buffer; /* internal buffer for compressed data */
- z_stream stream; /* zLib stream structure for inflate */
-
- uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
- uLong stream_initialised; /* flag set if stream structure is initialised*/
-
- uLong offset_local_extrafield;/* offset of the local extra field */
- uInt size_local_extrafield;/* size of the local extra field */
- uLong pos_local_extrafield; /* position in the local extra field in read*/
-
- uLong crc32; /* crc32 of all data uncompressed */
- uLong crc32_wait; /* crc32 we must obtain after decompress all */
- uLong rest_read_compressed; /* number of byte to be decompressed */
- uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- uLong compression_method; /* compression method (0==store) */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- int raw;
-} file_in_zip_read_info_s;
-
-
-/* unz_s contain internal information about the zipfile
-*/
-typedef struct
-{
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- unz_global_info gi; /* public global information */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- uLong num_file; /* number of the current file in the zipfile*/
- uLong pos_in_central_dir; /* pos of the current file in the central dir*/
- uLong current_file_ok; /* flag about the usability of the current file*/
- uLong central_pos; /* position of the beginning of the central dir*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory with
- respect to the starting disk number */
-
- unz_file_info cur_file_info; /* public info about the current file in zip*/
- unz_file_info_internal cur_file_info_internal; /* private info about it*/
- file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
- file if we are decompressing it */
- int encrypted;
-# ifndef NOUNCRYPT
- unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
-# endif
-} unz_s;
-
-
-#ifndef NOUNCRYPT
-#include "crypt.h"
-#endif
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-
-
-local int unzlocal_getByte OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- int *pi;
-{
- unsigned char c;
- int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
- {
- *pi = (int)c;
- return UNZ_OK;
- }
- else
- {
- if (ZERROR(*pzlib_filefunc_def,filestream))
- return UNZ_ERRNO;
- else
- return UNZ_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unzlocal_getShort OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x = 0;
- int i = 0;
- int err = 0;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int unzlocal_getLong OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x = 0;
- int i = 0;
- int err = 0;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<16;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (fileName1,fileName2)
- const char* fileName1;
- const char* fileName2;
-{
- for (;;)
- {
- char c1=*(fileName1++);
- char c2=*(fileName2++);
- if ((c1>='a') && (c1<='z'))
- c1 -= 0x20;
- if ((c2>='a') && (c2<='z'))
- c2 -= 0x20;
- if (c1=='\0')
- return ((c2=='\0') ? 0 : -1);
- if (c2=='\0')
- return 1;
- if (c1<c2)
- return -1;
- if (c1>c2)
- return 1;
- }
-}
-
-
-#ifdef CASESENSITIVITYDEFAULT_NO
-#define CASESENSITIVITYDEFAULTVALUE 2
-#else
-#define CASESENSITIVITYDEFAULTVALUE 1
-#endif
-
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-
-*/
-extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
- const char* fileName1;
- const char* fileName2;
- int iCaseSensitivity;
-{
- if (iCaseSensitivity==0)
- iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
-
- if (iCaseSensitivity==1)
- return strcmp(fileName1,fileName2);
-
- return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong unzlocal_SearchCentralDir OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream));
-
-local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
- uLong uReadSize,uReadPos ;
- int i;
- if (uBackRead+BUFREADCOMMENT>uMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- break;
-
- if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
- "zlib/zlib114.zip".
- If the zipfile cannot be opened (file doesn't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
- const char *path;
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- unz_s us;
- unz_s *s;
- uLong central_pos,uL;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
-
- int err=UNZ_OK;
-
- if (unz_copyright[0]!=' ')
- return NULL;
-
- if (pzlib_filefunc_def==NULL)
- fill_fopen_filefunc(&us.z_filefunc);
- else
- us.z_filefunc = *pzlib_filefunc_def;
-
- us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
- path,
- ZLIB_FILEFUNC_MODE_READ |
- ZLIB_FILEFUNC_MODE_EXISTING);
- if (us.filestream==NULL)
- return NULL;
-
- central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
- if (central_pos==0)
- err=UNZ_ERRNO;
-
- if (ZSEEK(us.z_filefunc, us.filestream,
- central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
- /* the signature, already checked */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((number_entry_CD!=us.gi.number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=UNZ_BADZIPFILE;
-
- /* size of the central directory */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* zipfile comment length */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
- (err==UNZ_OK))
- err=UNZ_BADZIPFILE;
-
- if (err!=UNZ_OK)
- {
- ZCLOSE(us.z_filefunc, us.filestream);
- return NULL;
- }
-
- us.byte_before_the_zipfile = central_pos -
- (us.offset_central_dir+us.size_central_dir);
- us.central_pos = central_pos;
- us.pfile_in_zip_read = NULL;
- us.encrypted = 0;
-
-
- s=(unz_s*)ALLOC(sizeof(unz_s));
- *s=us;
- unzGoToFirstFile((unzFile)s);
- return (unzFile)s;
-}
-
-
-extern unzFile ZEXPORT unzOpen (path)
- const char *path;
-{
- return unzOpen2(path, NULL);
-}
-
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzClose (file)
- unzFile file;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- if (s->pfile_in_zip_read!=NULL)
- unzCloseCurrentFile(file);
-
- ZCLOSE(s->z_filefunc, s->filestream);
- TRYFREE(s);
- return UNZ_OK;
-}
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
- unzFile file;
- unz_global_info *pglobal_info;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- *pglobal_info=s->gi;
- return UNZ_OK;
-}
-
-
-/*
- Translate date/time from Dos format to tm_unz (readable more easilty)
-*/
-local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
- uLong ulDosDate;
- tm_unz* ptm;
-{
- uLong uDate;
- uDate = (uLong)(ulDosDate>>16);
- ptm->tm_mday = (uInt)(uDate&0x1f) ;
- ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
- ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
-
- ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
- ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
- ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
-}
-
-/*
- Get Info about the current file in the zipfile, with internal only info
-*/
-local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
- unz_file_info *pfile_info,
- unz_file_info_internal
- *pfile_info_internal,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-
-local int unzlocal_GetCurrentFileInfoInternal (file,
- pfile_info,
- pfile_info_internal,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- unz_file_info_internal *pfile_info_internal;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- unz_s* s;
- unz_file_info file_info;
- unz_file_info_internal file_info_internal;
- int err=UNZ_OK;
- uLong uMagic;
- long lSeek=0;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pos_in_central_dir+s->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
-
- /* we check the magic */
- if (err==UNZ_OK)
- {
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x02014b50)
- err=UNZ_BADZIPFILE;
- }
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
- err=UNZ_ERRNO;
-
- unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
- err=UNZ_ERRNO;
-
- lSeek+=file_info.size_filename;
- if ((err==UNZ_OK) && (szFileName!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_filename<fileNameBufferSize)
- {
- *(szFileName+file_info.size_filename)='\0';
- uSizeRead = file_info.size_filename;
- }
- else
- uSizeRead = fileNameBufferSize;
-
- if ((file_info.size_filename>0) && (fileNameBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek -= uSizeRead;
- }
-
-
- if ((err==UNZ_OK) && (extraField!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_extra<extraFieldBufferSize)
- uSizeRead = file_info.size_file_extra;
- else
- uSizeRead = extraFieldBufferSize;
-
- if (lSeek!=0)
- {
- if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- }
- if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek += file_info.size_file_extra - uSizeRead;
- }
- else
- lSeek+=file_info.size_file_extra;
-
-
- if ((err==UNZ_OK) && (szComment!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_comment<commentBufferSize)
- {
- *(szComment+file_info.size_file_comment)='\0';
- uSizeRead = file_info.size_file_comment;
- }
- else
- uSizeRead = commentBufferSize;
-
- if (lSeek!=0)
- {
- if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- }
- if ((file_info.size_file_comment>0) && (commentBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek+=file_info.size_file_comment - uSizeRead;
- }
- else
- lSeek+=file_info.size_file_comment;
-
- if ((err==UNZ_OK) && (pfile_info!=NULL))
- *pfile_info=file_info;
-
- if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
- *pfile_info_internal=file_info_internal;
-
- return err;
-}
-
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem.
-*/
-extern int ZEXPORT unzGetCurrentFileInfo (file,
- pfile_info,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
- szFileName,fileNameBufferSize,
- extraField,extraFieldBufferSize,
- szComment,commentBufferSize);
-}
-
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-extern int ZEXPORT unzGoToFirstFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- s->pos_in_central_dir=s->offset_central_dir;
- s->num_file=0;
- err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-extern int ZEXPORT unzGoToNextFile (file)
- unzFile file;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
- if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
- if (s->num_file+1==s->gi.number_entry)
- return UNZ_END_OF_LIST_OF_FILE;
-
- s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
- s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
- s->num_file++;
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzipStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
- unzFile file;
- const char *szFileName;
- int iCaseSensitivity;
-{
- unz_s* s;
- int err;
-
- /* We remember the 'current' position in the file so that we can jump
- * back there if we fail.
- */
- unz_file_info cur_file_infoSaved;
- unz_file_info_internal cur_file_info_internalSaved;
- uLong num_fileSaved;
- uLong pos_in_central_dirSaved;
-
-
- if (file==NULL)
- return UNZ_PARAMERROR;
-
- if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
- return UNZ_PARAMERROR;
-
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- /* Save the current state */
- num_fileSaved = s->num_file;
- pos_in_central_dirSaved = s->pos_in_central_dir;
- cur_file_infoSaved = s->cur_file_info;
- cur_file_info_internalSaved = s->cur_file_info_internal;
-
- err = unzGoToFirstFile(file);
-
- while (err == UNZ_OK)
- {
- char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
- err = unzGetCurrentFileInfo(file,NULL,
- szCurrentFileName,sizeof(szCurrentFileName)-1,
- NULL,0,NULL,0);
- if (err == UNZ_OK)
- {
- if (unzStringFileNameCompare(szCurrentFileName,
- szFileName,iCaseSensitivity)==0)
- return UNZ_OK;
- err = unzGoToNextFile(file);
- }
- }
-
- /* We failed, so restore the state of the 'current file' to where we
- * were.
- */
- s->num_file = num_fileSaved ;
- s->pos_in_central_dir = pos_in_central_dirSaved ;
- s->cur_file_info = cur_file_infoSaved;
- s->cur_file_info_internal = cur_file_info_internalSaved;
- return err;
-}
-
-
-/*
-///////////////////////////////////////////
-// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
-// I need random access
-//
-// Further optimization could be realized by adding an ability
-// to cache the directory in memory. The goal being a single
-// comprehensive file read to put the file I need in a memory.
-*/
-
-/*
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; // offset in file
- uLong num_of_file; // # of file
-} unz_file_pos;
-*/
-
-extern int ZEXPORT unzGetFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- file_pos->pos_in_zip_directory = s->pos_in_central_dir;
- file_pos->num_of_file = s->num_file;
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzGoToFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- /* jump to the right spot */
- s->pos_in_central_dir = file_pos->pos_in_zip_directory;
- s->num_file = file_pos->num_of_file;
-
- /* set the current file */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- /* return results */
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
-// Unzip Helper Functions - should be here?
-///////////////////////////////////////////
-*/
-
-/*
- Read the local header of the current zipfile
- Check the coherency of the local header and info in the end of central
- directory about this file
- store in *piSizeVar the size of extra info in local header
- (filename and size of extra field data)
-*/
-local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
- poffset_local_extrafield,
- psize_local_extrafield)
- unz_s* s;
- uInt* piSizeVar;
- uLong *poffset_local_extrafield;
- uInt *psize_local_extrafield;
-{
- uLong uMagic,uData,uFlags;
- uLong size_filename;
- uLong size_extra_field;
- int err=UNZ_OK;
-
- *piSizeVar = 0;
- *poffset_local_extrafield = 0;
- *psize_local_extrafield = 0;
-
- if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
- s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
-
- if (err==UNZ_OK)
- {
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x04034b50)
- err=UNZ_BADZIPFILE;
- }
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
-/*
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
- err=UNZ_BADZIPFILE;
-*/
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
- err=UNZ_BADZIPFILE;
-
- if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
- err=UNZ_BADZIPFILE;
-
- *piSizeVar += (uInt)size_filename;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
- err=UNZ_ERRNO;
- *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
- SIZEZIPLOCALHEADER + size_filename;
- *psize_local_extrafield = (uInt)size_extra_field;
-
- *piSizeVar += (uInt)size_extra_field;
-
- return err;
-}
-
-/*
- Open for reading data the current file in the zipfile.
- If there is no error and the file is opened, the return value is UNZ_OK.
-*/
-extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
- unzFile file;
- int* method;
- int* level;
- int raw;
- const char* password;
-{
- int err=UNZ_OK;
- uInt iSizeVar;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uLong offset_local_extrafield; /* offset of the local extra field */
- uInt size_local_extrafield; /* size of the local extra field */
-# ifndef NOUNCRYPT
- char source[12];
-# else
- if (password != NULL)
- return UNZ_PARAMERROR;
-# endif
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_PARAMERROR;
-
- if (s->pfile_in_zip_read != NULL)
- unzCloseCurrentFile(file);
-
- if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
- &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
- return UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info = (file_in_zip_read_info_s*)
- ALLOC(sizeof(file_in_zip_read_info_s));
- if (pfile_in_zip_read_info==NULL)
- return UNZ_INTERNALERROR;
-
- pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
- pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
- pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
- pfile_in_zip_read_info->pos_local_extrafield=0;
- pfile_in_zip_read_info->raw=raw;
-
- if (pfile_in_zip_read_info->read_buffer==NULL)
- {
- TRYFREE(pfile_in_zip_read_info);
- return UNZ_INTERNALERROR;
- }
-
- pfile_in_zip_read_info->stream_initialised=0;
-
- if (method!=NULL)
- *method = (int)s->cur_file_info.compression_method;
-
- if (level!=NULL)
- {
- *level = 6;
- switch (s->cur_file_info.flag & 0x06)
- {
- case 6 : *level = 1; break;
- case 4 : *level = 2; break;
- case 2 : *level = 9; break;
- }
- }
-
- if ((s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
- pfile_in_zip_read_info->crc32=0;
- pfile_in_zip_read_info->compression_method =
- s->cur_file_info.compression_method;
- pfile_in_zip_read_info->filestream=s->filestream;
- pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
- pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
-
- pfile_in_zip_read_info->stream.total_out = 0;
-
- if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
- (!raw))
- {
- pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
- pfile_in_zip_read_info->stream.zfree = (free_func)0;
- pfile_in_zip_read_info->stream.opaque = (voidpf)0;
- pfile_in_zip_read_info->stream.next_in = (voidpf)0;
- pfile_in_zip_read_info->stream.avail_in = 0;
-
- err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
- if (err == Z_OK)
- pfile_in_zip_read_info->stream_initialised=1;
- else
- {
- TRYFREE(pfile_in_zip_read_info);
- return err;
- }
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END.
- * In unzip, i don't wait absolutely Z_STREAM_END because I known the
- * size of both compressed and uncompressed data
- */
- }
- pfile_in_zip_read_info->rest_read_compressed =
- s->cur_file_info.compressed_size ;
- pfile_in_zip_read_info->rest_read_uncompressed =
- s->cur_file_info.uncompressed_size ;
-
-
- pfile_in_zip_read_info->pos_in_zipfile =
- s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
- iSizeVar;
-
- pfile_in_zip_read_info->stream.avail_in = (uInt)0;
-
- s->pfile_in_zip_read = pfile_in_zip_read_info;
-
-# ifndef NOUNCRYPT
- if (password != NULL)
- {
- int i;
- s->pcrc_32_tab = get_crc_table();
- init_keys(password,s->keys,s->pcrc_32_tab);
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pfile_in_zip_read->pos_in_zipfile +
- s->pfile_in_zip_read->byte_before_the_zipfile,
- SEEK_SET)!=0)
- return UNZ_INTERNALERROR;
- if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
- return UNZ_INTERNALERROR;
-
- for (i = 0; i<12; i++)
- zdecode(s->keys,s->pcrc_32_tab,source[i]);
-
- s->pfile_in_zip_read->pos_in_zipfile+=12;
- s->encrypted=1;
- }
-# endif
-
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzOpenCurrentFile (file)
- unzFile file;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
-}
-
-extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
- unzFile file;
- const char* password;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
-}
-
-extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
- unzFile file;
- int* method;
- int* level;
- int raw;
-{
- return unzOpenCurrentFile3(file, method, level, raw, NULL);
-}
-
-/*
- Read bytes from the current file.
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-extern int ZEXPORT unzReadCurrentFile (file, buf, len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- int err=UNZ_OK;
- uInt iRead = 0;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->read_buffer == NULL))
- return UNZ_END_OF_LIST_OF_FILE;
- if (len==0)
- return 0;
-
- pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
-
- pfile_in_zip_read_info->stream.avail_out = (uInt)len;
-
- if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
- (!(pfile_in_zip_read_info->raw)))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
-
- if ((len>pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in) &&
- (pfile_in_zip_read_info->raw))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in;
-
- while (pfile_in_zip_read_info->stream.avail_out>0)
- {
- if ((pfile_in_zip_read_info->stream.avail_in==0) &&
- (pfile_in_zip_read_info->rest_read_compressed>0))
- {
- uInt uReadThis = UNZ_BUFSIZE;
- if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
- uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
- if (uReadThis == 0)
- return UNZ_EOF;
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->pos_in_zipfile +
- pfile_in_zip_read_info->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->read_buffer,
- uReadThis)!=uReadThis)
- return UNZ_ERRNO;
-
-
-# ifndef NOUNCRYPT
- if(s->encrypted)
- {
- uInt i;
- for(i=0;i<uReadThis;i++)
- pfile_in_zip_read_info->read_buffer[i] =
- zdecode(s->keys,s->pcrc_32_tab,
- pfile_in_zip_read_info->read_buffer[i]);
- }
-# endif
-
-
- pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
-
- pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
-
- pfile_in_zip_read_info->stream.next_in =
- (Bytef*)pfile_in_zip_read_info->read_buffer;
- pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
- }
-
- if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
- {
- uInt uDoCopy,i ;
-
- if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- return (iRead==0) ? UNZ_EOF : iRead;
-
- if (pfile_in_zip_read_info->stream.avail_out <
- pfile_in_zip_read_info->stream.avail_in)
- uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
- else
- uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
-
- for (i=0;i<uDoCopy;i++)
- *(pfile_in_zip_read_info->stream.next_out+i) =
- *(pfile_in_zip_read_info->stream.next_in+i);
-
- pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
- pfile_in_zip_read_info->stream.next_out,
- uDoCopy);
- pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
- pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
- pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
- pfile_in_zip_read_info->stream.next_out += uDoCopy;
- pfile_in_zip_read_info->stream.next_in += uDoCopy;
- pfile_in_zip_read_info->stream.total_out += uDoCopy;
- iRead += uDoCopy;
- }
- else
- {
- uLong uTotalOutBefore,uTotalOutAfter;
- const Bytef *bufBefore;
- uLong uOutThis;
- int flush=Z_SYNC_FLUSH;
-
- uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
- bufBefore = pfile_in_zip_read_info->stream.next_out;
-
- /*
- if ((pfile_in_zip_read_info->rest_read_uncompressed ==
- pfile_in_zip_read_info->stream.avail_out) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- flush = Z_FINISH;
- */
- err=inflate(&pfile_in_zip_read_info->stream,flush);
-
- if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
- err = Z_DATA_ERROR;
-
- uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
- uOutThis = uTotalOutAfter-uTotalOutBefore;
-
- pfile_in_zip_read_info->crc32 =
- crc32(pfile_in_zip_read_info->crc32,bufBefore,
- (uInt)(uOutThis));
-
- pfile_in_zip_read_info->rest_read_uncompressed -=
- uOutThis;
-
- iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
- if (err==Z_STREAM_END)
- return (iRead==0) ? UNZ_EOF : iRead;
- if (err!=Z_OK)
- break;
- }
- }
-
- if (err==Z_OK)
- return iRead;
- return err;
-}
-
-
-/*
- Give the current position in uncompressed data
-*/
-extern z_off_t ZEXPORT unztell (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- return (z_off_t)pfile_in_zip_read_info->stream.total_out;
-}
-
-
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-extern int ZEXPORT unzeof (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
- return 1;
- else
- return 0;
-}
-
-
-
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field that can be read
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uInt read_now;
- uLong size_to_read;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
- pfile_in_zip_read_info->pos_local_extrafield);
-
- if (buf==NULL)
- return (int)size_to_read;
-
- if (len>size_to_read)
- read_now = (uInt)size_to_read;
- else
- read_now = (uInt)len ;
-
- if (read_now==0)
- return 0;
-
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->offset_local_extrafield +
- pfile_in_zip_read_info->pos_local_extrafield,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- buf,read_now)!=read_now)
- return UNZ_ERRNO;
-
- return (int)read_now;
-}
-
-/*
- Close the file in zip opened with unzipOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-extern int ZEXPORT unzCloseCurrentFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
-
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
- (!pfile_in_zip_read_info->raw))
- {
- if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
- err=UNZ_CRCERROR;
- }
-
-
- TRYFREE(pfile_in_zip_read_info->read_buffer);
- pfile_in_zip_read_info->read_buffer = NULL;
- if (pfile_in_zip_read_info->stream_initialised)
- inflateEnd(&pfile_in_zip_read_info->stream);
-
- pfile_in_zip_read_info->stream_initialised = 0;
- TRYFREE(pfile_in_zip_read_info);
-
- s->pfile_in_zip_read=NULL;
-
- return err;
-}
-
-
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
- unzFile file;
- char *szComment;
- uLong uSizeBuf;
-{
- unz_s* s;
- uLong uReadThis ;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- uReadThis = uSizeBuf;
- if (uReadThis>s->gi.size_comment)
- uReadThis = s->gi.size_comment;
-
- if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (uReadThis>0)
- {
- *szComment='\0';
- if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
- return UNZ_ERRNO;
- }
-
- if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
- *(szComment+s->gi.size_comment)='\0';
- return (int)uReadThis;
-}
-
-/* Additions by RX '2004 */
-extern uLong ZEXPORT unzGetOffset (file)
- unzFile file;
-{
- unz_s* s;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return 0;
- if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
- if (s->num_file==s->gi.number_entry)
- return 0;
- return s->pos_in_central_dir;
-}
-
-extern int ZEXPORT unzSetOffset (file, pos)
- unzFile file;
- uLong pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- s->pos_in_central_dir = pos;
- s->num_file = s->gi.number_entry; /* hack */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
diff --git a/externals/g3dlite/zip.lib/source/zip.c b/externals/g3dlite/zip.lib/source/zip.c
deleted file mode 100644
index d5f9fe53d26..00000000000
--- a/externals/g3dlite/zip.lib/source/zip.c
+++ /dev/null
@@ -1,1221 +0,0 @@
-/* zip.c -- IO on .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- 27 Dec 2004 Rolf Kalbermatter
- Modification to zipOpen2 to support globalComment retrieval.
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- Read zip.h for more info
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "zlib.h"
-#include "zip.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#ifndef VERSIONMADEBY
-# define VERSIONMADEBY (0x0) /* platform depedent */
-#endif
-
-#ifndef Z_BUFSIZE
-#define Z_BUFSIZE (16384)
-#endif
-
-#ifndef Z_MAXFILENAMEINZIP
-#define Z_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-/*
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-*/
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-#ifndef DEF_MEM_LEVEL
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-#endif
-const char zip_copyright[] =
- " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-
-#define SIZEDATA_INDATABLOCK (4096-(4*4))
-
-#define LOCALHEADERMAGIC (0x04034b50)
-#define CENTRALHEADERMAGIC (0x02014b50)
-#define ENDHEADERMAGIC (0x06054b50)
-
-#define FLAG_LOCALHEADER_OFFSET (0x06)
-#define CRC_LOCALHEADER_OFFSET (0x0e)
-
-#define SIZECENTRALHEADER (0x2e) /* 46 */
-
-typedef struct linkedlist_datablock_internal_s
-{
- struct linkedlist_datablock_internal_s* next_datablock;
- uLong avail_in_this_block;
- uLong filled_in_this_block;
- uLong unused; /* for future use and alignement */
- unsigned char data[SIZEDATA_INDATABLOCK];
-} linkedlist_datablock_internal;
-
-typedef struct linkedlist_data_s
-{
- linkedlist_datablock_internal* first_block;
- linkedlist_datablock_internal* last_block;
-} linkedlist_data;
-
-
-typedef struct
-{
- z_stream stream; /* zLib stream structure for inflate */
- int stream_initialised; /* 1 is stream is initialised */
- uInt pos_in_buffered_data; /* last written byte in buffered_data */
-
- uLong pos_local_header; /* offset of the local header of the file
- currenty writing */
- char* central_header; /* central header data for the current file */
- uLong size_centralheader; /* size of the central header for cur file */
- uLong flag; /* flag of the file currently writing */
-
- int method; /* compression method of file currenty wr.*/
- int raw; /* 1 for directly writing raw data */
- Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
- uLong dosDate;
- uLong crc32;
- int encrypt;
-#ifndef NOCRYPT
- unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
- int crypt_header_size;
-#endif
-} curfile_info;
-
-typedef struct
-{
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- linkedlist_data central_dir;/* datablock with central dir in construction*/
- int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
- curfile_info ci; /* info on the file curretly writing */
-
- uLong begin_pos; /* position of the beginning of the zipfile */
- uLong add_position_when_writting_offset;
- uLong number_entry;
-#ifndef NO_ADDFILEINEXISTINGZIP
- char *globalcomment;
-#endif
-} zip_internal;
-
-
-
-#ifndef NOCRYPT
-#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-#include "crypt.h"
-#endif
-
-local linkedlist_datablock_internal* allocate_new_datablock()
-{
- linkedlist_datablock_internal* ldi;
- ldi = (linkedlist_datablock_internal*)
- ALLOC(sizeof(linkedlist_datablock_internal));
- if (ldi!=NULL)
- {
- ldi->next_datablock = NULL ;
- ldi->filled_in_this_block = 0 ;
- ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
- }
- return ldi;
-}
-
-local void free_datablock(ldi)
- linkedlist_datablock_internal* ldi;
-{
- while (ldi!=NULL)
- {
- linkedlist_datablock_internal* ldinext = ldi->next_datablock;
- TRYFREE(ldi);
- ldi = ldinext;
- }
-}
-
-local void init_linkedlist(ll)
- linkedlist_data* ll;
-{
- ll->first_block = ll->last_block = NULL;
-}
-
-/*
-// Never used!
-local void free_linkedlist(ll)
- linkedlist_data* ll;
-{
- free_datablock(ll->first_block);
- ll->first_block = ll->last_block = NULL;
-}
-*/
-
-local int add_data_in_datablock(ll,buf,len)
- linkedlist_data* ll;
- const void* buf;
- uLong len;
-{
- linkedlist_datablock_internal* ldi;
- const unsigned char* from_copy;
-
- if (ll==NULL)
- return ZIP_INTERNALERROR;
-
- if (ll->last_block == NULL)
- {
- ll->first_block = ll->last_block = allocate_new_datablock();
- if (ll->first_block == NULL)
- return ZIP_INTERNALERROR;
- }
-
- ldi = ll->last_block;
- from_copy = (unsigned char*)buf;
-
- while (len>0)
- {
- uInt copy_this;
- uInt i;
- unsigned char* to_copy;
-
- if (ldi->avail_in_this_block==0)
- {
- ldi->next_datablock = allocate_new_datablock();
- if (ldi->next_datablock == NULL)
- return ZIP_INTERNALERROR;
- ldi = ldi->next_datablock ;
- ll->last_block = ldi;
- }
-
- if (ldi->avail_in_this_block < len)
- copy_this = (uInt)ldi->avail_in_this_block;
- else
- copy_this = (uInt)len;
-
- to_copy = &(ldi->data[ldi->filled_in_this_block]);
-
- for (i=0;i<copy_this;i++)
- *(to_copy+i)=*(from_copy+i);
-
- ldi->filled_in_this_block += copy_this;
- ldi->avail_in_this_block -= copy_this;
- from_copy += copy_this ;
- len -= copy_this;
- }
- return ZIP_OK;
-}
-
-
-
-/****************************************************************************/
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-/* ===========================================================================
- Inputs a long in LSB order to the given file
- nbByte == 1, 2 or 4 (byte, short or long)
-*/
-
-local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream, uLong x, int nbByte));
-local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong x;
- int nbByte;
-{
- unsigned char buf[4];
- int n;
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = (unsigned char)(x & 0xff);
- x >>= 8;
- }
- if (x != 0)
- { /* data overflow - hack for ZIP64 (X Roche) */
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = 0xff;
- }
- }
-
- if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
- return ZIP_ERRNO;
- else
- return ZIP_OK;
-}
-
-local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
-local void ziplocal_putValue_inmemory (dest, x, nbByte)
- void* dest;
- uLong x;
- int nbByte;
-{
- unsigned char* buf=(unsigned char*)dest;
- int n;
- for (n = 0; n < nbByte; n++) {
- buf[n] = (unsigned char)(x & 0xff);
- x >>= 8;
- }
-
- if (x != 0)
- { /* data overflow - hack for ZIP64 */
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = 0xff;
- }
- }
-}
-
-/****************************************************************************/
-
-
-local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
- const tm_zip* ptm;
- uLong dosDate;
-{
- uLong year = (uLong)ptm->tm_year;
- if (year>1980)
- year-=1980;
- else if (year>80)
- year-=80;
- return
- (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
- ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
-}
-
-
-/****************************************************************************/
-
-local int ziplocal_getByte OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- int *pi;
-{
- unsigned char c;
- int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
- {
- *pi = (int)c;
- return ZIP_OK;
- }
- else
- {
- if (ZERROR(*pzlib_filefunc_def,filestream))
- return ZIP_ERRNO;
- else
- return ZIP_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int ziplocal_getShort OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x = 0;
- int i = 0;
- int err = 0;
-
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==ZIP_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int ziplocal_getLong OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x = 0;
- int i = 0;
- int err = 0;
-
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<16;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==ZIP_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong ziplocal_SearchCentralDir OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream));
-
-local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
- uLong uReadSize,uReadPos ;
- int i;
- if (uBackRead+BUFREADCOMMENT>uMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- break;
-
- if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-#endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-/************************************************************/
-extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
- const char *pathname;
- int append;
- zipcharpc* globalcomment;
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- zip_internal ziinit;
- zip_internal* zi;
- int err=ZIP_OK;
-
-
- if (pzlib_filefunc_def==NULL)
- fill_fopen_filefunc(&ziinit.z_filefunc);
- else
- ziinit.z_filefunc = *pzlib_filefunc_def;
-
- ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
- (ziinit.z_filefunc.opaque,
- pathname,
- (append == APPEND_STATUS_CREATE) ?
- (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
- (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
-
- if (ziinit.filestream == NULL)
- return NULL;
- ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
- ziinit.in_opened_file_inzip = 0;
- ziinit.ci.stream_initialised = 0;
- ziinit.number_entry = 0;
- ziinit.add_position_when_writting_offset = 0;
- init_linkedlist(&(ziinit.central_dir));
-
-
- zi = (zip_internal*)ALLOC(sizeof(zip_internal));
- if (zi==NULL)
- {
- ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
- return NULL;
- }
-
- /* now we add file in a zipfile */
-# ifndef NO_ADDFILEINEXISTINGZIP
- ziinit.globalcomment = NULL;
- if (append == APPEND_STATUS_ADDINZIP)
- {
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory */
- uLong central_pos,uL;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry;
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
- uLong size_comment;
-
- central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
- if (central_pos==0)
- err=ZIP_ERRNO;
-
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=ZIP_ERRNO;
-
- /* the signature, already checked */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* number of this disk */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* total number of entries in the central dir */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- if ((number_entry_CD!=number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=ZIP_BADZIPFILE;
-
- /* size of the central directory */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* zipfile global comment length */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- if ((central_pos<offset_central_dir+size_central_dir) &&
- (err==ZIP_OK))
- err=ZIP_BADZIPFILE;
-
- if (err!=ZIP_OK)
- {
- ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
- return NULL;
- }
-
- if (size_comment>0)
- {
- ziinit.globalcomment = ALLOC(size_comment+1);
- if (ziinit.globalcomment)
- {
- size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
- ziinit.globalcomment[size_comment]=0;
- }
- }
-
- byte_before_the_zipfile = central_pos -
- (offset_central_dir+size_central_dir);
- ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
-
- {
- uLong size_central_dir_to_read = size_central_dir;
- size_t buf_size = SIZEDATA_INDATABLOCK;
- void* buf_read = (void*)ALLOC(buf_size);
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- offset_central_dir + byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET) != 0)
- err=ZIP_ERRNO;
-
- while ((size_central_dir_to_read>0) && (err==ZIP_OK))
- {
- uLong read_this = SIZEDATA_INDATABLOCK;
- if (read_this > size_central_dir_to_read)
- read_this = size_central_dir_to_read;
- if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
- err=ZIP_ERRNO;
-
- if (err==ZIP_OK)
- err = add_data_in_datablock(&ziinit.central_dir,buf_read,
- (uLong)read_this);
- size_central_dir_to_read-=read_this;
- }
- TRYFREE(buf_read);
- }
- ziinit.begin_pos = byte_before_the_zipfile;
- ziinit.number_entry = number_entry_CD;
-
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=ZIP_ERRNO;
- }
-
- if (globalcomment)
- {
- *globalcomment = ziinit.globalcomment;
- }
-# endif /* !NO_ADDFILEINEXISTINGZIP*/
-
- if (err != ZIP_OK)
- {
-# ifndef NO_ADDFILEINEXISTINGZIP
- TRYFREE(ziinit.globalcomment);
-# endif /* !NO_ADDFILEINEXISTINGZIP*/
- TRYFREE(zi);
- return NULL;
- }
- else
- {
- *zi = ziinit;
- return (zipFile)zi;
- }
-}
-
-extern zipFile ZEXPORT zipOpen (pathname, append)
- const char *pathname;
- int append;
-{
- return zipOpen2(pathname,append,NULL,NULL);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- windowBits, memLevel, strategy,
- password, crcForCrypting)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
- int raw;
- int windowBits;
- int memLevel;
- int strategy;
- const char* password;
- uLong crcForCrypting;
-{
- zip_internal* zi;
- uInt size_filename;
- uInt size_comment;
- uInt i;
- int err = ZIP_OK;
-
-# ifdef NOCRYPT
- if (password != NULL)
- return ZIP_PARAMERROR;
-# endif
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- if ((method!=0) && (method!=Z_DEFLATED))
- return ZIP_PARAMERROR;
-
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 1)
- {
- err = zipCloseFileInZip (file);
- if (err != ZIP_OK)
- return err;
- }
-
-
- if (filename==NULL)
- filename="-";
-
- if (comment==NULL)
- size_comment = 0;
- else
- size_comment = (uInt)strlen(comment);
-
- size_filename = (uInt)strlen(filename);
-
- if (zipfi == NULL)
- zi->ci.dosDate = 0;
- else
- {
- if (zipfi->dosDate != 0)
- zi->ci.dosDate = zipfi->dosDate;
- else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
- }
-
- zi->ci.flag = 0;
- if ((level==8) || (level==9))
- zi->ci.flag |= 2;
- if ((level==2))
- zi->ci.flag |= 4;
- if ((level==1))
- zi->ci.flag |= 6;
- if (password != NULL)
- zi->ci.flag |= 1;
-
- zi->ci.crc32 = 0;
- zi->ci.method = method;
- zi->ci.encrypt = 0;
- zi->ci.stream_initialised = 0;
- zi->ci.pos_in_buffered_data = 0;
- zi->ci.raw = raw;
- zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
- zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
- size_extrafield_global + size_comment;
- zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
-
- ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
- /* version info */
- ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
- ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
- ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
-
- if (zipfi==NULL)
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
- else
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
-
- if (zipfi==NULL)
- ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
- else
- ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
-
- ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
-
- for (i=0;i<size_filename;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
-
- for (i=0;i<size_extrafield_global;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
- *(((const char*)extrafield_global)+i);
-
- for (i=0;i<size_comment;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
- size_extrafield_global+i) = *(comment+i);
- if (zi->ci.central_header == NULL)
- return ZIP_INTERNALERROR;
-
- /* write the local header */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
-
- if ((err==ZIP_OK) && (size_filename>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
- err = ZIP_ERRNO;
-
- if ((err==ZIP_OK) && (size_extrafield_local>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
- !=size_extrafield_local)
- err = ZIP_ERRNO;
-
- zi->ci.stream.avail_in = (uInt)0;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- zi->ci.stream.total_in = 0;
- zi->ci.stream.total_out = 0;
-
- if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- zi->ci.stream.zalloc = (alloc_func)0;
- zi->ci.stream.zfree = (free_func)0;
- zi->ci.stream.opaque = (voidpf)0;
-
- if (windowBits>0)
- windowBits = -windowBits;
-
- err = deflateInit2(&zi->ci.stream, level,
- Z_DEFLATED, windowBits, memLevel, strategy);
-
- if (err==Z_OK)
- zi->ci.stream_initialised = 1;
- }
-# ifndef NOCRYPT
- zi->ci.crypt_header_size = 0;
- if ((err==Z_OK) && (password != NULL))
- {
- unsigned char bufHead[RAND_HEAD_LEN];
- unsigned int sizeHead;
- zi->ci.encrypt = 1;
- zi->ci.pcrc_32_tab = get_crc_table();
- /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
-
- sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
- zi->ci.crypt_header_size = sizeHead;
-
- if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
- err = ZIP_ERRNO;
- }
-# endif
-
- if (err==Z_OK)
- zi->in_opened_file_inzip = 1;
- return err;
-}
-
-extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
- int raw;
-{
- return zipOpenNewFileInZip3 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- NULL, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
-{
- return zipOpenNewFileInZip2 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, 0);
-}
-
-local int zipFlushWriteBuffer(zi)
- zip_internal* zi;
-{
- int err=ZIP_OK;
-
- if (zi->ci.encrypt != 0)
- {
-#ifndef NOCRYPT
- uInt i;
- int t;
- for (i=0;i<zi->ci.pos_in_buffered_data;i++)
- zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
- zi->ci.buffered_data[i],t);
-#endif
- }
- if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
- !=zi->ci.pos_in_buffered_data)
- err = ZIP_ERRNO;
- zi->ci.pos_in_buffered_data = 0;
- return err;
-}
-
-extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
- zipFile file;
- const void* buf;
- unsigned len;
-{
- zip_internal* zi;
- int err=ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 0)
- return ZIP_PARAMERROR;
-
- zi->ci.stream.next_in = (void*)buf;
- zi->ci.stream.avail_in = len;
- zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
-
- while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
- {
- if (zi->ci.stream.avail_out == 0)
- {
- if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
- err = ZIP_ERRNO;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
-
-
- if(err != ZIP_OK)
- break;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- uLong uTotalOutBefore = zi->ci.stream.total_out;
- err=deflate(&zi->ci.stream, Z_NO_FLUSH);
- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-
- }
- else
- {
- uInt copy_this,i;
- if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
- copy_this = zi->ci.stream.avail_in;
- else
- copy_this = zi->ci.stream.avail_out;
- for (i=0;i<copy_this;i++)
- *(((char*)zi->ci.stream.next_out)+i) =
- *(((const char*)zi->ci.stream.next_in)+i);
- {
- zi->ci.stream.avail_in -= copy_this;
- zi->ci.stream.avail_out-= copy_this;
- zi->ci.stream.next_in+= copy_this;
- zi->ci.stream.next_out+= copy_this;
- zi->ci.stream.total_in+= copy_this;
- zi->ci.stream.total_out+= copy_this;
- zi->ci.pos_in_buffered_data += copy_this;
- }
- }
- }
-
- return err;
-}
-
-extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
- zipFile file;
- uLong uncompressed_size;
- uLong crc32;
-{
- zip_internal* zi;
- uLong compressed_size;
- int err=ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 0)
- return ZIP_PARAMERROR;
- zi->ci.stream.avail_in = 0;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- while (err==ZIP_OK)
- {
- uLong uTotalOutBefore;
- if (zi->ci.stream.avail_out == 0)
- {
- if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
- err = ZIP_ERRNO;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
- uTotalOutBefore = zi->ci.stream.total_out;
- err=deflate(&zi->ci.stream, Z_FINISH);
- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
- }
-
- if (err==Z_STREAM_END)
- err=ZIP_OK; /* this is normal */
-
- if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
- if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
- err = ZIP_ERRNO;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- err=deflateEnd(&zi->ci.stream);
- zi->ci.stream_initialised = 0;
- }
-
- if (!zi->ci.raw)
- {
- crc32 = (uLong)zi->ci.crc32;
- uncompressed_size = (uLong)zi->ci.stream.total_in;
- }
- compressed_size = (uLong)zi->ci.stream.total_out;
-# ifndef NOCRYPT
- compressed_size += zi->ci.crypt_header_size;
-# endif
-
- ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
- ziplocal_putValue_inmemory(zi->ci.central_header+20,
- compressed_size,4); /*compr size*/
- if (zi->ci.stream.data_type == Z_ASCII)
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+24,
- uncompressed_size,4); /*uncompr size*/
-
- if (err==ZIP_OK)
- err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
- (uLong)zi->ci.size_centralheader);
- free(zi->ci.central_header);
-
- if (err==ZIP_OK)
- {
- long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
- if (ZSEEK(zi->z_filefunc,zi->filestream,
- zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err = ZIP_ERRNO;
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
-
- if (err==ZIP_OK) /* compressed size, unknown */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
-
- if (err==ZIP_OK) /* uncompressed size, unknown */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
-
- if (ZSEEK(zi->z_filefunc,zi->filestream,
- cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err = ZIP_ERRNO;
- }
-
- zi->number_entry ++;
- zi->in_opened_file_inzip = 0;
-
- return err;
-}
-
-extern int ZEXPORT zipCloseFileInZip (file)
- zipFile file;
-{
- return zipCloseFileInZipRaw (file,0,0);
-}
-
-extern int ZEXPORT zipClose (file, global_comment)
- zipFile file;
- const char* global_comment;
-{
- zip_internal* zi;
- int err = 0;
- uLong size_centraldir = 0;
- uLong centraldir_pos_inzip;
- uInt size_global_comment;
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 1)
- {
- err = zipCloseFileInZip (file);
- }
-
-#ifndef NO_ADDFILEINEXISTINGZIP
- if (global_comment==NULL)
- global_comment = zi->globalcomment;
-#endif
- if (global_comment==NULL)
- size_global_comment = 0;
- else
- size_global_comment = (uInt)strlen(global_comment);
-
- centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
- if (err==ZIP_OK)
- {
- linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
- while (ldi!=NULL)
- {
- if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,
- ldi->data,ldi->filled_in_this_block)
- !=ldi->filled_in_this_block )
- err = ZIP_ERRNO;
-
- size_centraldir += ldi->filled_in_this_block;
- ldi = ldi->next_datablock;
- }
- }
- free_datablock(zi->central_dir.first_block);
-
- if (err==ZIP_OK) /* Magic End */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
-
- if (err==ZIP_OK) /* number of this disk */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
- if (err==ZIP_OK) /* number of the disk with the start of the central directory */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
- if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-
- if (err==ZIP_OK) /* total number of entries in the central dir */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-
- if (err==ZIP_OK) /* size of the central directory */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
-
- if (err==ZIP_OK) /* offset of start of central directory with respect to the
- starting disk number */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
- (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
-
- if (err==ZIP_OK) /* zipfile comment length */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
-
- if ((err==ZIP_OK) && (size_global_comment>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,
- global_comment,size_global_comment) != size_global_comment)
- err = ZIP_ERRNO;
-
- if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
- if (err == ZIP_OK)
- err = ZIP_ERRNO;
-
-#ifndef NO_ADDFILEINEXISTINGZIP
- TRYFREE(zi->globalcomment);
-#endif
- TRYFREE(zi);
-
- return err;
-}
diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h
index 2ee4e207c19..d4d41a66d30 100644
--- a/src/server/collision/BoundingIntervalHierarchy.h
+++ b/src/server/collision/BoundingIntervalHierarchy.h
@@ -19,11 +19,11 @@
#ifndef _BIH_H
#define _BIH_H
-#include "Vector3.h"
-#include "Ray.h"
-#include "AABox.h"
+#include "G3D/Vector3.h"
+#include "G3D/Ray.h"
+#include "G3D/AABox.h"
-#include <Define.h>
+#include "Define.h"
#include <stdexcept>
#include <vector>
diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt
index a67cd8d660a..913ec7ecd01 100644
--- a/src/server/collision/CMakeLists.txt
+++ b/src/server/collision/CMakeLists.txt
@@ -24,13 +24,12 @@ SET(collision_STAT_SRCS
include_directories(
${ACE_INCLUDE_DIR}
${CMAKE_SOURCE_DIR}/externals/g3dlite
- ${CMAKE_SOURCE_DIR}/externals/g3dlite/G3D.lib
- ${CMAKE_SOURCE_DIR}/externals/g3dlite/G3D.lib/include
- ${CMAKE_SOURCE_DIR}/externals/g3dlite/G3D.lib/include/G3D
${CMAKE_SOURCE_DIR}/src/server/shared
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
${CMAKE_SOURCE_DIR}/src/server/collision
+ ${CMAKE_SOURCE_DIR}/src/server/collision/Management
${CMAKE_SOURCE_DIR}/src/server/collision/Maps
+ ${CMAKE_SOURCE_DIR}/src/server/collision/Models
)
add_library(collision STATIC ${collision_STAT_SRCS})
diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h
index 5f03b87b07f..953a8f11fa7 100644
--- a/src/server/collision/Management/VMapManager2.h
+++ b/src/server/collision/Management/VMapManager2.h
@@ -20,8 +20,8 @@
#define _VMAPMANAGER2_H
#include "IVMapManager.h"
-#include "Utilities/UnorderedMap.h"
-#include "Platform/Define.h"
+#include "Dynamic/UnorderedMap.h"
+#include "Define.h"
#include <G3D/Vector3.h>
//===========================================================
diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp
index d01b54a7564..0b9780130ed 100644
--- a/src/server/collision/Maps/TileAssembler.cpp
+++ b/src/server/collision/Maps/TileAssembler.cpp
@@ -19,7 +19,7 @@
#include "WorldModel.h"
#include "TileAssembler.h"
#include "MapTree.h"
-#include "BIH.h"
+#include "BoundingIntervalHierarchy.h"
#include "VMapDefinitions.h"
#include <set>