Get g3dlib, zlib and jemalloc to build again

--HG--
branch : trunk
rename : opt/cleanup/tab2spaces.sh => contrib/cleanup/tab2spaces.sh
rename : opt/cleanup/whitespace.sh => contrib/cleanup/whitespace.sh
rename : opt/conf_merge/README => contrib/conf_merge/README
rename : opt/conf_merge/index.php => contrib/conf_merge/index.php
rename : opt/conf_merge/merge.php => contrib/conf_merge/merge.php
rename : doc/AuctionHouseBot.txt => docs/AuctionHouseBot.txt
rename : doc/DocStructure.dox => docs/DocStructure.dox
rename : doc/Doxyfile.in => docs/Doxyfile.in
rename : doc/EventAI.txt => docs/EventAI.txt
rename : doc/HowToScript.txt => docs/HowToScript.txt
rename : doc/TextTables.txt => docs/TextTables.txt
rename : doc/UnixInstall.txt => docs/UnixInstall.txt
rename : externals/jemalloc/include/internal/arena.h => externals/jemalloc/jemalloc/internal/arena.h
rename : externals/jemalloc/include/internal/base.h => externals/jemalloc/jemalloc/internal/base.h
rename : externals/jemalloc/include/internal/chunk.h => externals/jemalloc/jemalloc/internal/chunk.h
rename : externals/jemalloc/include/internal/chunk_dss.h => externals/jemalloc/jemalloc/internal/chunk_dss.h
rename : externals/jemalloc/include/internal/chunk_mmap.h => externals/jemalloc/jemalloc/internal/chunk_mmap.h
rename : externals/jemalloc/include/internal/chunk_swap.h => externals/jemalloc/jemalloc/internal/chunk_swap.h
rename : externals/jemalloc/include/internal/ckh.h => externals/jemalloc/jemalloc/internal/ckh.h
rename : externals/jemalloc/include/internal/ctl.h => externals/jemalloc/jemalloc/internal/ctl.h
rename : externals/jemalloc/include/internal/extent.h => externals/jemalloc/jemalloc/internal/extent.h
rename : externals/jemalloc/include/internal/hash.h => externals/jemalloc/jemalloc/internal/hash.h
rename : externals/jemalloc/include/internal/huge.h => externals/jemalloc/jemalloc/internal/huge.h
rename : externals/jemalloc/include/internal/jemalloc_internal.h => externals/jemalloc/jemalloc/internal/jemalloc_internal.h
rename : externals/jemalloc/include/internal/jemalloc_internal.h.in => externals/jemalloc/jemalloc/internal/jemalloc_internal.h.in
rename : externals/jemalloc/include/internal/mb.h => externals/jemalloc/jemalloc/internal/mb.h
rename : externals/jemalloc/include/internal/mutex.h => externals/jemalloc/jemalloc/internal/mutex.h
rename : externals/jemalloc/include/internal/prof.h => externals/jemalloc/jemalloc/internal/prof.h
rename : externals/jemalloc/include/internal/ql.h => externals/jemalloc/jemalloc/internal/ql.h
rename : externals/jemalloc/include/internal/qr.h => externals/jemalloc/jemalloc/internal/qr.h
rename : externals/jemalloc/include/internal/rb.h => externals/jemalloc/jemalloc/internal/rb.h
rename : externals/jemalloc/include/internal/stats.h => externals/jemalloc/jemalloc/internal/stats.h
rename : externals/jemalloc/include/internal/tcache.h => externals/jemalloc/jemalloc/internal/tcache.h
rename : externals/jemalloc/include/internal/totally_not_p_r_n.h => externals/jemalloc/jemalloc/internal/totally_not_p_r_n.h
rename : externals/jemalloc/include/jemalloc.h => externals/jemalloc/jemalloc/jemalloc.h
rename : externals/jemalloc/include/jemalloc.h.in => externals/jemalloc/jemalloc/jemalloc.h.in
rename : externals/jemalloc/include/jemalloc_defs.h => externals/jemalloc/jemalloc/jemalloc_defs.h
rename : externals/jemalloc/include/jemalloc_defs.h.in => externals/jemalloc/jemalloc/jemalloc_defs.h.in
This commit is contained in:
click
2010-06-08 08:04:26 +02:00
parent c08a7d6348
commit f867f6d7a8
93 changed files with 19176 additions and 1813 deletions

View File

@@ -12,19 +12,22 @@ include(cmake/PCH.cmake)
# Force out-of-source build
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" BUILDING_IN_SOURCE)
if(BUILDING_IN_SOURCE)
message(FATAL_ERROR "This project requires an out of source build. Remove the file 'CMakeCache.txt' found in this directory before continuing, and create a separate build directory and run 'cmake path_to_project [options]' from there.")
message(FATAL_ERROR "This project requires an out of source build. Remove the file 'CMakeCache.txt' found in this directory before continuing, and create a separate build directory and run 'cmake path_to_project [options]' from there.")
endif(BUILDING_IN_SOURCE)
# Select the Release build configuration by default.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_BUILD_TYPE "Release")
endif(NOT CMAKE_BUILD_TYPE)
CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
)
option(CENTOS "CENTOS" 0)
option(DO_CLI "With CLI" 1)
@@ -38,49 +41,49 @@ option(DO_TOOLS "Compile tools" 0)
option(DO_WARN "Enable all compile warnings" 0)
set(GENREV_SRC
src/genrevision/genrevision.cpp
src/genrevision/genrevision.cpp
)
if(DO_DEBUG)
add_executable(genrev
add_executable(genrev
${GENREV_SRC}
)
add_custom_target("revision.h" ALL
COMMAND "${CMAKE_BINARY_DIR}/genrev"
${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/shared"
DEPENDS genrev
)
)
add_custom_target("revision.h" ALL
COMMAND "${CMAKE_BINARY_DIR}/genrev"
${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/server/shared"
DEPENDS genrev
)
else (DO_DEBUG)
add_executable(genrev
add_executable(genrev
${GENREV_SRC}
)
add_custom_target("revision.h" ALL
COMMAND "${CMAKE_BINARY_DIR}/genrev"
${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/server/shared"
DEPENDS genrev
)
)
add_custom_target("revision.h" ALL
COMMAND "${CMAKE_BINARY_DIR}/genrev"
${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/src/server/shared"
DEPENDS genrev
)
endif(DO_DEBUG)
execute_process(
COMMAND hg tip --template {rev}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE HG_REVISION
COMMAND hg tip --template {rev}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE HG_REVISION
)
message("* TrinityCore revision: ${HG_REVISION}")
if(PREFIX)
set(CMAKE_INSTALL_PREFIX ${PREFIX})
set(CMAKE_INSTALL_PREFIX ${PREFIX})
endif(PREFIX)
if(CONF_DIR)
else(CONF_DIR)
set(CONF_DIR ${PREFIX}/etc)
set(CONF_DIR ${PREFIX}/etc)
endif(CONF_DIR)
set(LIBSDIR ${CMAKE_INSTALL_PREFIX}/lib)
message("* Will install to: ${CMAKE_INSTALL_PREFIX}")
@@ -91,98 +94,97 @@ find_library(SSLLIB NAMES ssl DOC "SSL library")
find_library(ZLIB z "Zlib library")
if(DO_MYSQL)
message("* With MySQL")
FIND_MYSQL()
ADD_DEFINITIONS(-DDO_MYSQL)
message("* With MySQL")
FIND_MYSQL()
ADD_DEFINITIONS(-DDO_MYSQL)
endif(DO_MYSQL)
if(DO_SCRIPTS)
message("* With Trinity Scripts")
ADD_DEFINITIONS(-DDO_SCRIPTS)
add_definitions(-D_TRINITY_SCRIPT_CONFIG='"${CONF_DIR}/trinitycore.conf"')
message("* With Trinity Scripts")
ADD_DEFINITIONS(-DDO_SCRIPTS)
add_definitions(-D_TRINITY_SCRIPT_CONFIG='"${CONF_DIR}/trinitycore.conf"')
else (DO_SCRIPTS)
message("* Without Trinity Scripts")
message("* Without Trinity Scripts")
endif(DO_SCRIPTS)
message("-- Miscellaneus options:")
if(DO_CLI)
message("* With CLI")
add_definitions(-DENABLE_CLI)
message("* With CLI")
add_definitions(-DENABLE_CLI)
else (DO_CLI)
message(* Without CLI)
message(* Without CLI)
endif(DO_CLI)
if(DO_RA)
message("* With RA")
add_definitions(-DENABLE_RA)
message("* With RA")
add_definitions(-DENABLE_RA)
else(DO_RA)
message("* Without RA")
message("* Without RA")
endif(DO_RA)
if(DO_DEBUG)
message("* Debug mode ON")
add_definitions(-g -DTRINITY_DEBUG)
message("* Debug mode ON")
add_definitions(-g -DTRINITY_DEBUG)
endif(DO_DEBUG)
if(DO_WARN)
message("* All warnings mode")
add_definitions(-Wall -Wfatal-errors -Wextra)
message("* All warnings mode")
add_definitions(-Wall -Wfatal-errors -Wextra)
endif(DO_WARN)
if(DO_SQL)
message("* Installing SQL files")
message("* Installing SQL files")
else (DO_SQL)
message("* NOT installing SQL files")
message("* NOT installing SQL files")
endif(DO_SQL)
if(DO_PCH)
message("* Using precompiled headers")
message("* Using precompiled headers")
else (DO_PCH)
message("* NOT using precompiled headers")
message("* NOT using precompiled headers")
endif(DO_PCH)
if(DO_TOOLS)
message("* With Tools")
message("* With Tools")
else (DO_TOOLS)
message("* Without Tools")
message("* Without Tools")
endif(DO_TOOLS)
if(UNIX)
if(CENTOS)
add_definitions(-DCENTOS)
message("* Building with termcap")
FIND_TERMCAP()
else(CENTOS)
message("* Building with readline")
FIND_READLINE()
endif(CENTOS)
if(CENTOS)
add_definitions(-DCENTOS)
message("* Building with termcap")
FIND_TERMCAP()
else(CENTOS)
message("* Building with readline")
FIND_READLINE()
endif(CENTOS)
endif(UNIX)
FIND_ACE(ACE)
if(ACE_FOUND)
message(STATUS "Found ACE library: ${ACE_LIBRARY}")
message(STATUS "Include dir is: ${ACE_INCLUDE_DIR}")
message(STATUS "Found ACE library: ${ACE_LIBRARY}")
message(STATUS "Include dir is: ${ACE_INCLUDE_DIR}")
else(ACE_FOUND)
message(SEND_ERROR "** ACE library not found! Trinity Core cannot be compiled!")
message(SEND_ERROR "** Please build ACE from http://www.cs.wustl.edu/~schmidt/ACE.html")
#For now remove msg about install from repo, as ubuntu/debian don't have needed ver in repos.
#message(SEND_ERROR "** your distro may provide a binary for ACE e.g. for ubuntu try apt-get install libace-dev")
return()
#set(BUILD_ACE 1)
#set(ACE_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/dep/ACE_wrappers ${CMAKE_BINARY_DIR}/dep/ACE_wrappers")
#set(ACE_LIBRARY ACE)
#message(STATUS "I will try to build ACE from: ${ACE_INCLUDE_DIR}")
#message(STATUS "And link using: ${ACE_LIBRARY}")
message(SEND_ERROR "** ACE library not found! Trinity Core cannot be compiled!")
message(SEND_ERROR "** Please build ACE from http://www.cs.wustl.edu/~schmidt/ACE.html")
#For now remove msg about install from repo, as ubuntu/debian don't have needed ver in repos.
#message(SEND_ERROR "** your distro may provide a binary for ACE e.g. for ubuntu try apt-get install libace-dev")
return()
#set(BUILD_ACE 1)
#set(ACE_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/dep/ACE_wrappers ${CMAKE_BINARY_DIR}/dep/ACE_wrappers")
#set(ACE_LIBRARY ACE)
#message(STATUS "I will try to build ACE from: ${ACE_INCLUDE_DIR}")
#message(STATUS "And link using: ${ACE_LIBRARY}")
endif(ACE_FOUND)
#somehow line below don't work. so for now change it to if exist
#check_include_files(${ACE_INCLUDE_DIR}/ace/Stack_Trace.h HAVE_ACE_STACK_TRACE_H)
if(EXISTS ${ACE_INCLUDE_DIR}/ace/Stack_Trace.h)
set(HAVE_ACE_STACK_TRACE_H 1)
set(HAVE_ACE_STACK_TRACE_H 1)
else(EXISTS ${ACE_INCLUDE_DIR}/ace/Stack_Trace.h)
message(STATUS "** Your libace is out of date. Please update your libace!")
message(STATUS "** Your libace is out of date. Please update your libace!")
endif(EXISTS ${ACE_INCLUDE_DIR}/ace/Stack_Trace.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
@@ -201,8 +203,10 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
add_subdirectory(externals)
add_subdirectory(src)
if(DO_SQL)
message("* Copy SQL files ON")
add_subdirectory(sql)
message("* Copy SQL files ON")
add_subdirectory(sql)
endif(DO_SQL)

7
externals/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,7 @@
add_subdirectory(ace)
#add_subdirectory(bzip2)
add_subdirectory(g3dlite)
add_subdirectory(jemalloc)
#add_subdirectory(libmpq)
add_subdirectory(sockets)
add_subdirectory(zlib)

View File

@@ -2,39 +2,52 @@ TrinityCore uses (parts of or in whole) the following opensource software :
ACE (ADAPTIVE Communication Environment)
http://www.cs.wustl.edu/~schmidt/ACE.html
Version: UNKNOWN
bzip2 (a freely available, patent free, high-quality data compressor)
http://www.bzip.org/
Version: 1.0.5
G3D 6.09 (a commercial-grade C++ 3D engine available as Open Source (BSD License)
G3D (a commercial-grade C++ 3D engine available as Open Source (BSD License)
http://g3d.sourceforge.net/
Version: 6.09
jemalloc (a general-purpose scalable concurrent malloc-implementation)
http://www.canonware.com/jemalloc/
Version: UNKNOWN
libMPQ (a library for reading MPQ files)
https://libmpq.org/
Version: 1.0.4
MersenneTwister (a very fast random number generator)
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
Version: 0.4.2
SFMT (SIMD-oriented Fast Mersenne Twister)
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html
Version: 1.3.3
MySQL (the world's most popular open source database software)
http://www.mysql.com/about/
Version: UNKNOWN
OpenSSL (an opensource toolkit implementing SSL v2/v3 and TLS v1 protocols)
http://www.openssl.org/
Version: UNKNOWN
sockets (a GPL licensed C++ class library wrapping the berkeley sockets C API)
http://www.alhem.net/Sockets/
Version: UNKNOWN
utf8-cpp (UTF-8 with C++ in a Portable Way)
http://utfcpp.sourceforge.net/
Version: 2.3
vld (a free open-source memory leak detection system for Visual C++)
http://sites.google.com/site/dmoulding/vld
Version: 1.0
zlib (A Massively Spiffy Yet Delicately Unobtrusive Compression Library)
http://www.zlib.net/
Version: 1.2.5

View File

@@ -1,319 +0,0 @@
------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.
bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
Please read the WARNING, DISCLAIMER and PATENTS sections in the
README file.
This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------
0.9.0
~~~~~
First version.
0.9.0a
~~~~~~
Removed 'ranlib' from Makefile, since most modern Unix-es
don't need it, or even know about it.
0.9.0b
~~~~~~
Fixed a problem with error reporting in bzip2.c. This does not effect
the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the
program proper) compress and decompress correctly, but give misleading
error messages (internal panics) when an I/O error occurs, instead of
reporting the problem correctly. This shouldn't give any data loss
(as far as I can see), but is confusing.
Made the inline declarations disappear for non-GCC compilers.
0.9.0c
~~~~~~
Fixed some problems in the library pertaining to some boundary cases.
This makes the library behave more correctly in those situations. The
fixes apply only to features (calls and parameters) not used by
bzip2.c, so the non-fixedness of them in previous versions has no
effect on reliability of bzip2.c.
In bzlib.c:
* made zero-length BZ_FLUSH work correctly in bzCompress().
* fixed bzWrite/bzRead to ignore zero-length requests.
* fixed bzread to correctly handle read requests after EOF.
* wrong parameter order in call to bzDecompressInit in
bzBuffToBuffDecompress. Fixed.
In compress.c:
* changed setting of nGroups in sendMTFValues() so as to
do a bit better on small files. This _does_ effect
bzip2.c.
0.9.5a
~~~~~~
Major change: add a fallback sorting algorithm (blocksort.c)
to give reasonable behaviour even for very repetitive inputs.
Nuked --repetitive-best and --repetitive-fast since they are
no longer useful.
Minor changes: mostly a whole bunch of small changes/
bugfixes in the driver (bzip2.c). Changes pertaining to the
user interface are:
allow decompression of symlink'd files to stdout
decompress/test files even without .bz2 extension
give more accurate error messages for I/O errors
when compressing/decompressing to stdout, don't catch control-C
read flags from BZIP2 and BZIP environment variables
decline to break hard links to a file unless forced with -f
allow -c flag even with no filenames
preserve file ownerships as far as possible
make -s -1 give the expected block size (100k)
add a flag -q --quiet to suppress nonessential warnings
stop decoding flags after --, so files beginning in - can be handled
resolved inconsistent naming: bzcat or bz2cat ?
bzip2 --help now returns 0
Programming-level changes are:
fixed syntax error in GET_LL4 for Borland C++ 5.02
let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC}
fix overshoot of mode-string end in bzopen_or_bzdopen
wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... }
close file handles under all error conditions
added minor mods so it compiles with DJGPP out of the box
fixed Makefile so it doesn't give problems with BSD make
fix uninitialised memory reads in dlltest.c
0.9.5b
~~~~~~
Open stdin/stdout in binary mode for DJGPP.
0.9.5c
~~~~~~
Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1
version could cause the sorted order to be wrong in some extremely
obscure cases. Also changed setting of quadrant in blocksort.c.
0.9.5d
~~~~~~
The only functional change is to make bzlibVersion() in the library
return the correct string. This has no effect whatsoever on the
functioning of the bzip2 program or library. Added a couple of casts
so the library compiles without warnings at level 3 in MS Visual
Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other
changes are minor documentation changes.
1.0
~~~
Several minor bugfixes and enhancements:
* Large file support. The library uses 64-bit counters to
count the volume of data passing through it. bzip2.c
is now compiled with -D_FILE_OFFSET_BITS=64 to get large
file support from the C library. -v correctly prints out
file sizes greater than 4 gigabytes. All these changes have
been made without assuming a 64-bit platform or a C compiler
which supports 64-bit ints, so, except for the C library
aspect, they are fully portable.
* Decompression robustness. The library/program should be
robust to any corruption of compressed data, detecting and
handling _all_ corruption, instead of merely relying on
the CRCs. What this means is that the program should
never crash, given corrupted data, and the library should
always return BZ_DATA_ERROR.
* Fixed an obscure race-condition bug only ever observed on
Solaris, in which, if you were very unlucky and issued
control-C at exactly the wrong time, both input and output
files would be deleted.
* Don't run out of file handles on test/decompression when
large numbers of files have invalid magic numbers.
* Avoid library namespace pollution. Prefix all exported
symbols with BZ2_.
* Minor sorting enhancements from my DCC2000 paper.
* Advance the version number to 1.0, so as to counteract the
(false-in-this-case) impression some people have that programs
with version numbers less than 1.0 are in some way, experimental,
pre-release versions.
* Create an initial Makefile-libbz2_so to build a shared library.
Yes, I know I should really use libtool et al ...
* Make the program exit with 2 instead of 0 when decompression
fails due to a bad magic number (ie, an invalid bzip2 header).
Also exit with 1 (as the manual claims :-) whenever a diagnostic
message would have been printed AND the corresponding operation
is aborted, for example
bzip2: Output file xx already exists.
When a diagnostic message is printed but the operation is not
aborted, for example
bzip2: Can't guess original name for wurble -- using wurble.out
then the exit value 0 is returned, unless some other problem is
also detected.
I think it corresponds more closely to what the manual claims now.
1.0.1
~~~~~
* Modified dlltest.c so it uses the new BZ2_ naming scheme.
* Modified makefile-msc to fix minor build probs on Win2k.
* Updated README.COMPILATION.PROBLEMS.
There are no functionality changes or bug fixes relative to version
1.0.0. This is just a documentation update + a fix for minor Win32
build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is
utterly pointless. Don't bother.
1.0.2
~~~~~
A bug fix release, addressing various minor issues which have appeared
in the 18 or so months since 1.0.1 was released. Most of the fixes
are to do with file-handling or documentation bugs. To the best of my
knowledge, there have been no data-loss-causing bugs reported in the
compression/decompression engine of 1.0.0 or 1.0.1.
Note that this release does not improve the rather crude build system
for Unix platforms. The general plan here is to autoconfiscate/
libtoolise 1.0.2 soon after release, and release the result as 1.1.0
or perhaps 1.2.0. That, however, is still just a plan at this point.
Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in
parentheses.
* Fix an infinite segfault loop in 1.0.1 when a directory is
encountered in -f (force) mode.
(Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt)
* Avoid double fclose() of output file on certain I/O error paths.
(Solar Designer)
* Don't fail with internal error 1007 when fed a long stream (> 48MB)
of byte 251. Also print useful message suggesting that 1007s may be
caused by bad memory.
(noticed by Juan Pedro Vallejo, fixed by me)
* Fix uninitialised variable silly bug in demo prog dlltest.c.
(Jorj Bauer)
* Remove 512-MB limitation on recovered file size for bzip2recover
on selected platforms which support 64-bit ints. At the moment
all GCC supported platforms, and Win32.
(me, Alson van der Meulen)
* Hard-code header byte values, to give correct operation on platforms
using EBCDIC as their native character set (IBM's OS/390).
(Leland Lucius)
* Copy file access times correctly.
(Marty Leisner)
* Add distclean and check targets to Makefile.
(Michael Carmack)
* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS).
(Rich Ireland, Bo Thorsen)
* Pass -p (create parent dirs as needed) to mkdir during make install.
(Jeremy Fusco)
* Dereference symlinks when copying file permissions in -f mode.
(Volker Schmidt)
* Majorly simplify implementation of uInt64_qrm10.
(Bo Lindbergh)
* Check the input file still exists before deleting the output one,
when aborting in cleanUpAndFail().
(Joerg Prante, Robert Linden, Matthias Krings)
Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer
of bzip2:
* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore.
* Spelling changes and minor enhancements in bzip2.1.
* Avoid race condition between creating the output file and setting its
interim permissions safely, by using fopen_output_safely().
No changes to bzip2recover since there is no issue with file
permissions there.
* do not print senseless report with -v when compressing an empty
file.
* bzcat -f works on non-bzip2 files.
* do not try to escape shell meta-characters on unix (the shell takes
care of these).
* added --fast and --best aliases for -1 -9 for gzip compatibility.
1.0.3 (15 Feb 05)
~~~~~~~~~~~~~~~~~
Fixes some minor bugs since the last version, 1.0.2.
* Further robustification against corrupted compressed data.
There are currently no known bitstreams which can cause the
decompressor to crash, loop or access memory which does not
belong to it. If you are using bzip2 or the library to
decompress bitstreams from untrusted sources, an upgrade
to 1.0.3 is recommended. This fixes CAN-2005-1260.
* The documentation has been converted to XML, from which html
and pdf can be derived.
* Various minor bugs in the documentation have been fixed.
* Fixes for various compilation warnings with newer versions of
gcc, and on 64-bit platforms.
* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2.
This has been fixed.
1.0.4 (20 Dec 06)
~~~~~~~~~~~~~~~~~
Fixes some minor bugs since the last version, 1.0.3.
* Fix file permissions race problem (CAN-2005-0953).
* Avoid possible segfault in BZ2_bzclose. From Coverity's NetBSD
scan.
* 'const'/prototype cleanups in the C code.
* Change default install location to /usr/local, and handle multiple
'make install's without error.
* Sanitise file names more carefully in bzgrep. Fixes CAN-2005-0758
to the extent that applies to bzgrep.
* Use 'mktemp' rather than 'tempfile' in bzdiff.
* Tighten up a couple of assertions in blocksort.c following automated
analysis.
* Fix minor doc/comment bugs.
1.0.5 (10 Dec 07)
~~~~~~~~~~~~~~~~~
Security fix only. Fixes CERT-FI 20469 as it applies to bzip2.

10
externals/bzip2/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,10 @@
file(GLOB sources *.cpp)
set(bzip2_STAT_SRCS
${sources}
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(bzip2 STATIC ${bzip2_STAT_SRCS})

View File

@@ -1,42 +0,0 @@
--------------------------------------------------------------------------
This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2007 Julian R Seward. 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. 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.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
Julian Seward, jseward@bzip.org
bzip2/libbzip2 version 1.0.5 of 10 December 2007
--------------------------------------------------------------------------

366
externals/g3dlite/AABox.cpp vendored Normal file
View File

@@ -0,0 +1,366 @@
/**
@file AABox.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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 {
const AABox& AABox::maxFinite() {
static const AABox b = AABox(Vector3::minFinite(),
Vector3::maxFinite());
return b;
}
const AABox& AABox::large() {
static const AABox b = AABox(Vector3::minFinite() * 0.5f,
Vector3::maxFinite() * 0.5f);
return b;
}
const AABox& AABox::inf() {
static const AABox b = AABox(-Vector3::inf(), Vector3::inf());
return b;
}
const AABox& AABox::zero() {
static const AABox b = AABox(Vector3::zero(), Vector3::zero());
return b;
}
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::finf()) &&
(abs(hi.x) < G3D::finf()) &&
(abs(lo.y) < G3D::finf()) &&
(abs(hi.y) < G3D::finf()) &&
(abs(lo.z) < G3D::finf()) &&
(abs(hi.z) < G3D::finf());
// 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::finf()) &&
(abs(hi.x) < G3D::finf()) &&
(abs(lo.y) < G3D::finf()) &&
(abs(hi.y) < G3D::finf()) &&
(abs(lo.z) < G3D::finf()) &&
(abs(hi.z) < G3D::finf());
// 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;
}
}

1237
externals/g3dlite/Any.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

81
externals/g3dlite/BinaryFormat.cpp vendored Normal file
View File

@@ -0,0 +1,81 @@
/**
@file BinaryFormat.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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;
}
}
}

568
externals/g3dlite/BinaryInput.cpp vendored Normal file
View File

@@ -0,0 +1,568 @@
/**
@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;
}
}

522
externals/g3dlite/BinaryOutput.cpp vendored Normal file
View File

@@ -0,0 +1,522 @@
/**
@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 + "'");
if (m_buffer != NULL) {
m_alreadyWritten += m_bufferLen;
int success = fwrite(m_buffer, m_bufferLen, 1, file);
(void)success;
debugAssertM(success == 1, std::string("Could not write to '") + m_filename + "'");
}
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;
}
}

393
externals/g3dlite/Box.cpp vendored Normal file
View File

@@ -0,0 +1,393 @@
/**
@file Box.cpp
Box class
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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::finf();
}
debugAssert(! isNaN(_extent.x));
_area = 2 *
(_extent.x * _extent.y +
_extent.y * _extent.z +
_extent.z * _extent.x);
_center = (max + min) * 0.5f;
// 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

11
externals/g3dlite/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,11 @@
file(GLOB sources *.cpp)
SET(g3dlib_STAT_SRCS
${sources}
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(g3dlib STATIC ${g3dlib_STAT_SRCS})

179
externals/g3dlite/Capsule.cpp vendored Normal file
View File

@@ -0,0 +1,179 @@
/**
@file Capsule.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-02-07
@edited 2005-08-18
Copyright 2000-2009, 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

2455
externals/g3dlite/CollisionDetection.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

436
externals/g3dlite/CoordinateFrame.cpp vendored Normal file
View File

@@ -0,0 +1,436 @@
/**
@file CoordinateFrame.cpp
Coordinate frame class
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-06-02
@edited 2009-11-13
Copyright 2000-2010, Morgan McGuire.
All rights reserved.
*/
#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"
#include "G3D/Any.h"
#include "G3D/stringutils.h"
namespace G3D {
CoordinateFrame::CoordinateFrame(const Any& any) {
any.verifyName("CFrame");
if (toUpper(any.name()) == "CFRAME") {
any.verifyType(Any::TABLE, Any::ARRAY);
if (any.type() == Any::TABLE) {
rotation = any["rotation"];
translation = any["translation"];
} else {
any.verifySize(2);
rotation = any[0];
translation = any[1];
}
} else {
any.verifyName("CFrame::fromXYZYPRDegrees");
any.verifyType(Any::ARRAY);
any.verifySize(3, 6);
int s = any.size();
*this = fromXYZYPRDegrees(any[0], any[1], any[2],
(s > 3) ? any[3].number() : 0.0f,
(s > 4) ? any[4].number() : 0.0f,
(s > 5) ? any[5].number() : 0.0f);
}
}
CoordinateFrame::operator Any() const {
float x, y, z, yaw, pitch, roll;
getXYZYPRDegrees(x, y, z, yaw, pitch, roll);
Any a(Any::ARRAY, "CFrame::fromXYZYPRDegrees");
a.append(x, y, z, yaw);
if ( ! G3D::fuzzyEq(yaw, 0.0f) || ! G3D::fuzzyEq(pitch, 0.0f) || ! G3D::fuzzyEq(roll, 0.0f)) {
a.append(yaw);
if (! G3D::fuzzyEq(pitch, 0.0f) || ! G3D::fuzzyEq(roll, 0.0f)) {
a.append(pitch);
if (! G3D::fuzzyEq(roll, 0.0f)) {
a.append(roll);
}
}
}
return a;
}
CoordinateFrame::CoordinateFrame(const class UprightFrame& f) {
*this = f.toCoordinateFrame();
}
CoordinateFrame::CoordinateFrame() :
rotation(Matrix3::identity()), translation(Vector3::zero()) {
}
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 {
Box b2(b);
return toWorldSpace(b2);
}
Box CoordinateFrame::toWorldSpace(const Box& b) const {
Box out(b);
for (int i = 0; i < 8; ++i) {
out._corner[i] = pointToWorldSpace(b._corner[i]);
debugAssert(! isNaN(out._corner[i].x));
}
for (int i = 0; i < 3; ++i) {
out._axis[i] = vectorToWorldSpace(b._axis[i]);
}
out._center = pointToWorldSpace(b._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

70
externals/g3dlite/Crypto.cpp vendored Normal file
View File

@@ -0,0 +1,70 @@
/**
@file Crypto.cpp
@author Morgan McGuire, http://graphics.cs.williams.edu
@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

176
externals/g3dlite/Cylinder.cpp vendored Normal file
View File

@@ -0,0 +1,176 @@
/**
@file Cylinder.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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

89
externals/g3dlite/Line.cpp vendored Normal file
View File

@@ -0,0 +1,89 @@
/**
@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;
}
}

236
externals/g3dlite/LineSegment.cpp vendored Normal file
View File

@@ -0,0 +1,236 @@
/**
@file LineSegment.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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;
}
}

146
externals/g3dlite/Log.cpp vendored Normal file
View File

@@ -0,0 +1,146 @@
/**
@file Log.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-08-04
@edited 2009-01-15
*/
#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);
}
void logLazyPrintf(const char* fmt, ...) {
va_list arg_list;
va_start(arg_list, fmt);
Log::common()->lazyvprintf(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");
}
// Use a large buffer (although we flush in logPrintf)
setvbuf(logFile, NULL, _IOFBF, 2048);
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, ...) {
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);
fflush(logFile);
}
void __cdecl Log::lazyvprintf(const char* fmt, va_list argPtr) {
vfprintf(logFile, fmt, argPtr);
}
void Log::print(const std::string& s) {
fprintf(logFile, "%s", s.c_str());
fflush(logFile);
}
void Log::println(const std::string& s) {
fprintf(logFile, "%s\n", s.c_str());
fflush(logFile);
}
}

1927
externals/g3dlite/Matrix3.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

523
externals/g3dlite/Matrix4.cpp vendored Normal file
View File

@@ -0,0 +1,523 @@
/**
@file Matrix4.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2003-10-02
@edited 2010-01-29
*/
#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"
#include "G3D/Any.h"
#include "G3D/stringutils.h"
namespace G3D {
Matrix4::Matrix4(const Any& any) {
any.verifyName("Matrix4");
any.verifyType(Any::ARRAY);
const std::string& name = toLower(any.name());
if (name == "matrix4") {
any.verifySize(16);
for (int r = 0; r < 4; ++r) {
for (int c = 0; c < 4; ++c) {
elt[r][c] = any[r * 4 + c];
}
}
} else if (name == "matrix4::scale") {
if (any.size() == 1) {
*this = scale(any[0].number());
} else if (any.size() == 3) {
*this = scale(any[0], any[1], any[2]);
} else {
any.verify(false, "Matrix4::scale() takes either 1 or 3 arguments");
}
} else {
any.verify(false, "Expected Matrix4 constructor");
}
}
Matrix4::operator Any() const {
Any any(Any::ARRAY, "Matrix4");
any.resize(16);
for (int r = 0; r < 4; ++r) {
for (int c = 0; c < 4; ++c) {
any[r * 4 + c] = elt[r][c];
}
}
return any;
}
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,
float upDirection) {
return Matrix4::orthogonalProjection(rect.x0(), rect.x1(), rect.y1(), rect.y0(), nearval, farval, upDirection);
}
Matrix4 Matrix4::orthogonalProjection(
float left,
float right,
float bottom,
float top,
float nearval,
float farval,
float upDirection) {
// 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);
y *= upDirection;
ty *= upDirection;
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 upDirection) {
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 (farval >= finf()) {
// Infinite view frustum
c = -1.0f;
d = -2.0f * nearval;
} else {
c = -(farval+nearval) / (farval-nearval);
d = -(2.0f*farval*nearval) / (farval-nearval);
}
debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");
y *= upDirection;
b *= upDirection;
return Matrix4(
x, 0, a, 0,
0, y, b, 0,
0, 0, c, d,
0, 0, -1, 0);
}
void Matrix4::getPerspectiveProjectionParameters(
float& left,
float& right,
float& bottom,
float& top,
float& nearval,
float& farval,
float upDirection) const {
debugAssertM(abs(upDirection) == 1.0f, "upDirection must be -1 or +1");
float x = elt[0][0];
float y = elt[1][1] * upDirection;
float a = elt[0][2];
float b = elt[1][2] * upDirection;
float c = elt[2][2];
float d = elt[2][3];
// Verify that this really is a projection matrix
debugAssertM(elt[3][2] == -1, "Not a projection matrix");
debugAssertM(elt[0][1] == 0, "Not a projection matrix");
debugAssertM(elt[0][3] == 0, "Not a projection matrix");
debugAssertM(elt[1][3] == 0, "Not a projection matrix");
debugAssertM(elt[3][3] == 0, "Not a projection matrix");
debugAssertM(elt[1][0] == 0, "Not a projection matrix");
debugAssertM(elt[2][0] == 0, "Not a projection matrix");
debugAssertM(elt[2][1] == 0, "Not a projection matrix");
debugAssertM(elt[3][0] == 0, "Not a projection matrix");
debugAssertM(elt[3][1] == 0, "Not a projection matrix");
if (c == -1) {
farval = finf();
nearval = -d / 2.0f;
} else {
nearval = d * ((c - 1.0f) / (c + 1.0f) - 1.0f) / (-2.0f * (c - 1.0f) / (c + 1.0f));
farval = nearval * ((c - 1.0f) / (c + 1.0f));
}
left = (a - 1.0f) * nearval / x;
right = 2.0f * nearval / x + left;
bottom = (b - 1.0f) * nearval / y;
top = 2.0f * nearval / y + bottom;
}
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];
}
}
const Vector4& Matrix4::row(int r) const {
return reinterpret_cast<const Vector4*>(elt[r])[0];
}
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().row(0).dot(row(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.column(0).dot(row(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

91
externals/g3dlite/MemoryManager.cpp vendored Normal file
View File

@@ -0,0 +1,91 @@
/**
@file MemoryManager.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2009-04-20
@edited 2009-05-29
Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
#include "G3D/MemoryManager.h"
#include "G3D/System.h"
namespace G3D {
MemoryManager::MemoryManager() {}
void* MemoryManager::alloc(size_t s) {
return System::malloc(s);
}
void MemoryManager::free(void* ptr) {
System::free(ptr);
}
bool MemoryManager::isThreadsafe() const {
return true;
}
MemoryManager::Ref MemoryManager::create() {
static MemoryManager::Ref m = new MemoryManager();
return m;
}
///////////////////////////////////////////////////
AlignedMemoryManager::AlignedMemoryManager() {}
void* AlignedMemoryManager::alloc(size_t s) {
return System::alignedMalloc(s, 16);
}
void AlignedMemoryManager::free(void* ptr) {
System::alignedFree(ptr);
}
bool AlignedMemoryManager::isThreadsafe() const {
return true;
}
AlignedMemoryManager::Ref AlignedMemoryManager::create() {
static AlignedMemoryManager::Ref m = new AlignedMemoryManager();
return m;
}
///////////////////////////////////////////////////
CRTMemoryManager::CRTMemoryManager() {}
void* CRTMemoryManager::alloc(size_t s) {
return ::malloc(s);
}
void CRTMemoryManager::free(void* ptr) {
return ::free(ptr);
}
bool CRTMemoryManager::isThreadsafe() const {
return true;
}
CRTMemoryManager::Ref CRTMemoryManager::create() {
static CRTMemoryManager::Ref m = new CRTMemoryManager();
return m;
}
}

149
externals/g3dlite/Plane.cpp vendored Normal file
View File

@@ -0,0 +1,149 @@
/**
@file Plane.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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);
}
}

583
externals/g3dlite/Quat.cpp vendored Normal file
View File

@@ -0,0 +1,583 @@
/**
@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); }
}

212
externals/g3dlite/Random.cpp vendored Normal file
View File

@@ -0,0 +1,212 @@
/**
@file Random.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2009-01-02
@edited 2009-03-29
Copyright 2000-2009, Morgan McGuire.
All rights reserved.
*/
#include "G3D/Random.h"
namespace G3D {
Random& Random::common() {
static Random r;
return r;
}
Random::Random(void* x) : state(NULL), m_threadsafe(false) {
(void)x;
}
Random::Random(uint32 seed, bool threadsafe) : m_threadsafe(threadsafe) {
const uint32 X = 1812433253UL;
state = new uint32[N];
state[0] = seed;
for (index = 1; index < (int)N; ++index) {
state[index] = X * (state[index - 1] ^ (state[index - 1] >> 30)) + index;
}
}
Random::~Random() {
delete[] state;
state = NULL;
}
uint32 Random::bits() {
// See http://en.wikipedia.org/wiki/Mersenne_twister
// Make a local copy of the index variable to ensure that it
// is not out of bounds
int localIndex = index;
// Automatically checks for index < 0 if corrupted
// by unsynchronized threads.
if ((unsigned int)localIndex >= (unsigned int)N) {
generate();
localIndex = 0;
}
// Increment the global index. It may go out of bounds on
// multiple threads, but the above check ensures that the
// array index actually used never goes out of bounds.
// It doesn't matter if we grab the same array index twice
// on two threads, since the distribution of random numbers
// will still be uniform.
++index;
// Return the next random in the sequence
uint32 r = state[localIndex];
// Temper the result
r ^= r >> U;
r ^= (r << S) & B;
r ^= (r << T) & C;
r ^= r >> L;
return r;
}
/** Generate the next N ints, and store them for readback later */
void Random::generate() {
// Lower R bits
static const uint32 LOWER_MASK = (1LU << R) - 1;
// Upper (32 - R) bits
static const uint32 UPPER_MASK = 0xFFFFFFFF << R;
static const uint32 mag01[2] = {0UL, (uint32)A};
if (m_threadsafe) {
bool contention = ! lock.lock();
if (contention) {
// Another thread just generated a set of numbers; no need for
// this thread to do it too
lock.unlock();
return;
}
}
// First N - M
for (unsigned int i = 0; i < N - M; ++i) {
uint32 x = (state[i] & UPPER_MASK) | (state[i + 1] & LOWER_MASK);
state[i] = state[i + M] ^ (x >> 1) ^ mag01[x & 1];
}
// Rest
for (unsigned int i = N - M + 1; i < N - 1; ++i) {
uint32 x = (state[i] & UPPER_MASK) | (state[i + 1] & LOWER_MASK);
state[i] = state[i + (M - N)] ^ (x >> 1) ^ mag01[x & 1];
}
uint32 y = (state[N - 1] & UPPER_MASK) | (state[0] & LOWER_MASK);
state[N - 1] = state[M - 1] ^ (y >> 1) ^ mag01[y & 1];
index = 0;
if (m_threadsafe) {
lock.unlock();
}
}
int Random::integer(int low, int high) {
int r = iFloor(low + (high - low + 1) * (double)bits() / 0xFFFFFFFFUL);
// There is a *very small* chance of generating
// a number larger than high.
if (r > high) {
return high;
} else {
return r;
}
}
float Random::gaussian(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 = uniform(-1.0, 1.0);
x2 = uniform(-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;
}
void Random::cosHemi(float& x, float& y, float& z) {
const float e1 = uniform();
const float e2 = uniform();
// Jensen's method
const float sin_theta = sqrtf(1.0f - e1);
const float cos_theta = sqrtf(e1);
const float phi = 6.28318531f * e2;
x = cos(phi) * sin_theta;
y = sin(phi) * sin_theta;
z = cos_theta;
// We could also use Malley's method (pbrt p.657), since they are the same cost:
//
// r = sqrt(e1);
// t = 2*pi*e2;
// x = cos(t)*r;
// y = sin(t)*r;
// z = sqrt(1.0 - x*x + y*y);
}
void Random::cosPowHemi(const float k, float& x, float& y, float& z) {
const float e1 = uniform();
const float e2 = uniform();
const float cos_theta = pow(e1, 1.0f / (k + 1.0f));
const float sin_theta = sqrtf(1.0f - square(cos_theta));
const float phi = 6.28318531f * e2;
x = cos(phi) * sin_theta;
y = sin(phi) * sin_theta;
z = cos_theta;
}
void Random::hemi(float& x, float& y, float& z) {
sphere(x, y, z);
z = fabsf(z);
}
void Random::sphere(float& x, float& y, float& z) {
// Squared magnitude
float m2;
// Rejection sample
do {
x = uniform() * 2.0f - 1.0f,
y = uniform() * 2.0f - 1.0f,
z = uniform() * 2.0f - 1.0f;
m2 = x*x + y*y + z*z;
} while (m2 >= 1.0f);
// Divide by magnitude to produce a unit vector
float s = rsqrt(m2);
x *= s;
y *= s;
z *= s;
}
} // G3D

218
externals/g3dlite/Ray.cpp vendored Normal file
View File

@@ -0,0 +1,218 @@
/**
@file Ray.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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 {
void Ray::set(const Vector3& origin, const Vector3& direction) {
m_origin = origin;
m_direction = direction;
debugAssert(direction.isUnit());
m_invDirection = Vector3::one() / direction;
// ray slope
ibyj = m_direction.x * m_invDirection.y;
jbyi = m_direction.y * m_invDirection.x;
jbyk = m_direction.y * m_invDirection.z;
kbyj = m_direction.z * m_invDirection.y;
ibyk = m_direction.x * m_invDirection.z;
kbyi = m_direction.z * m_invDirection.x;
// precomputed terms
c_xy = m_origin.y - jbyi * m_origin.x;
c_xz = m_origin.z - kbyi * m_origin.x;
c_yx = m_origin.x - ibyj * m_origin.y;
c_yz = m_origin.z - kbyj * m_origin.y;
c_zx = m_origin.x - ibyk * m_origin.z;
c_zy = m_origin.y - jbyk * m_origin.z;
//ray slope classification
if (m_direction.x < 0) {
if (m_direction.y < 0) {
if (m_direction.z < 0) {
classification = MMM;
} else if (m_direction.z > 0) {
classification = MMP;
} else { //(m_direction.z >= 0)
classification = MMO;
}
} else { //(m_direction.y >= 0)
if (m_direction.z < 0) {
if (m_direction.y == 0) {
classification = MOM;
} else {
classification = MPM;
}
} else { //(m_direction.z >= 0)
if ((m_direction.y == 0) && (m_direction.z == 0)) {
classification = MOO;
} else if (m_direction.z == 0) {
classification = MPO;
} else if (m_direction.y == 0) {
classification = MOP;
} else {
classification = MPP;
}
}
}
} else { //(m_direction.x >= 0)
if (m_direction.y < 0) {
if (m_direction.z < 0) {
if (m_direction.x == 0) {
classification = OMM;
} else {
classification = PMM;
}
} else { //(m_direction.z >= 0)
if ((m_direction.x == 0) && (m_direction.z == 0)) {
classification = OMO;
} else if (m_direction.z == 0) {
classification = PMO;
} else if (m_direction.x == 0) {
classification = OMP;
} else {
classification = PMP;
}
}
} else { //(m_direction.y >= 0)
if (m_direction.z < 0) {
if ((m_direction.x == 0) && (m_direction.y == 0)) {
classification = OOM;
} else if (m_direction.x == 0) {
classification = OPM;
} else if (m_direction.y == 0) {
classification = POM;
} else {
classification = PPM;
}
} else { //(m_direction.z > 0)
if (m_direction.x == 0) {
if (m_direction.y == 0) {
classification = OOP;
} else if (m_direction.z == 0) {
classification = OPO;
} else {
classification = OPP;
}
} else {
if ((m_direction.y == 0) && (m_direction.z == 0)) {
classification = POO;
} else if (m_direction.y == 0) {
classification = POP;
} else if (m_direction.z == 0) {
classification = PPO;
} else {
classification = PPP;
}
}
}
}
}
}
Ray::Ray(class BinaryInput& b) {
deserialize(b);
}
void Ray::serialize(class BinaryOutput& b) const {
m_origin.serialize(b);
m_direction.serialize(b);
}
void Ray::deserialize(class BinaryInput& b) {
m_origin.deserialize(b);
m_direction.deserialize(b);
set(m_origin, m_direction);
}
Ray Ray::refract(
const Vector3& newOrigin,
const Vector3& normal,
float iInside,
float iOutside) const {
Vector3 D = m_direction.refractionDirection(normal, iInside, iOutside);
return Ray(newOrigin + (m_direction + normal * (float)sign(m_direction.dot(normal))) * 0.001f, D);
}
Ray Ray::reflect(
const Vector3& newOrigin,
const Vector3& normal) const {
Vector3 D = m_direction.reflectionDirection(normal);
return Ray(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 = m_direction.dot(normal);
if (rate >= 0.0f) {
return Vector3::inf();
} else {
float t = -(d + m_origin.dot(normal)) / rate;
return m_origin + m_direction * t;
}
}
float Ray::intersectionTime(const class Sphere& sphere, bool solid) const {
Vector3 dummy;
return CollisionDetection::collisionTimeForMovingPointFixedSphere(
m_origin, m_direction, sphere, dummy, dummy, solid);
}
float Ray::intersectionTime(const class Plane& plane) const {
Vector3 dummy;
return CollisionDetection::collisionTimeForMovingPointFixedPlane(
m_origin, m_direction, plane, dummy);
}
float Ray::intersectionTime(const class Box& box) const {
Vector3 dummy;
float time = CollisionDetection::collisionTimeForMovingPointFixedBox(
m_origin, m_direction, box, dummy);
if ((time == finf()) && (box.contains(m_origin))) {
return 0.0f;
} else {
return time;
}
}
float Ray::intersectionTime(const class AABox& box) const {
Vector3 dummy;
bool inside;
float time = CollisionDetection::collisionTimeForMovingPointFixedAABox(
m_origin, m_direction, box, dummy, inside);
if ((time == finf()) && inside) {
return 0.0f;
} else {
return time;
}
}
}

61
externals/g3dlite/ReferenceCount.cpp vendored Normal file
View File

@@ -0,0 +1,61 @@
/**
@file ReferenceCount.cpp
Reference Counting Garbage Collector for C++
@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 2009-04-25
*/
#include "G3D/platform.h"
#include "G3D/ReferenceCount.h"
namespace G3D {
ReferenceCountedObject::ReferenceCountedObject() :
ReferenceCountedObject_refCount(0),
ReferenceCountedObject_weakPointer(0) {
debugAssertM(isValidHeapPointer(this),
"Reference counted objects must be allocated on the heap.");
}
void ReferenceCountedObject::ReferenceCountedObject_zeroWeakPointers() {
// Tell all of my weak pointers that I'm gone.
_WeakPtrLinkedList* node = ReferenceCountedObject_weakPointer;
while (node != NULL) {
// 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;
}
}
ReferenceCountedObject::~ReferenceCountedObject() {}
ReferenceCountedObject::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& 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;
}
} // G3D

223
externals/g3dlite/Sphere.cpp vendored Normal file
View File

@@ -0,0 +1,223 @@
/**
@file Sphere.cpp
Sphere class
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-04-17
@edited 2009-01-20
*/
#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 {
float distance = (center - point).squaredMagnitude();
return distance <= square(radius);
}
bool Sphere::contains(const Sphere& other) const {
float distance = (center - other.center).squaredMagnitude();
return (radius >= other.radius) && (distance <= square(radius - other.radius));
}
bool Sphere::intersects(const Sphere& other) const {
return (other.center - center).length() <= (radius + other.radius);
}
void Sphere::merge(const Sphere& other) {
if (other.contains(*this)) {
*this = other;
} else if (! contains(other)) {
// The farthest distance is along the axis between the centers, which
// must not be colocated since neither contains the other.
Vector3 toMe = center - other.center;
// Get a point on the axis from each
toMe = toMe.direction();
const Vector3& A = center + toMe * radius;
const Vector3& B = other.center - toMe * other.radius;
// Now just bound the A->B segment
center = (A + B) * 0.5f;
radius = (A - B).length();
}
// (if this contains other, we're done)
}
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 == finf()) {
// 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

1746
externals/g3dlite/System.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

1136
externals/g3dlite/TextInput.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

452
externals/g3dlite/TextOutput.cpp vendored Normal file
View File

@@ -0,0 +1,452 @@
/**
@file TextOutput.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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");
debugAssertM(f, "Could not open \"" + filename + "\"");
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);
}
}

186
externals/g3dlite/Triangle.cpp vendored Normal file
View File

@@ -0,0 +1,186 @@
/**
@file Triangle.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-04-06
@edited 2008-12-28
Copyright 2000-2009, 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"
#include "G3D/Ray.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);
}
bool Triangle::intersect(const Ray& ray, float& distance, float baryCoord[3]) const {
static const float EPS = 1e-5f;
// See RTR2 ch. 13.7 for the algorithm.
const Vector3& e1 = edge01();
const Vector3& e2 = edge02();
const Vector3 p(ray.direction().cross(e2));
const float a = e1.dot(p);
if (abs(a) < EPS) {
// Determinant is ill-conditioned; abort early
return false;
}
const float f = 1.0f / a;
const Vector3 s(ray.origin() - vertex(0));
const float u = f * s.dot(p);
if ((u < 0.0f) || (u > 1.0f)) {
// We hit the plane of the m_geometry, but outside the m_geometry
return false;
}
const Vector3 q(s.cross(e1));
const float v = f * ray.direction().dot(q);
if ((v < 0.0f) || ((u + v) > 1.0f)) {
// We hit the plane of the triangle, but outside the triangle
return false;
}
const float t = f * e2.dot(q);
if ((t > 0.0f) && (t < distance)) {
// This is a new hit, closer than the previous one
distance = t;
baryCoord[0] = 1.0 - u - v;
baryCoord[1] = u;
baryCoord[2] = v;
return true;
} else {
// This hit is after the previous hit, so ignore it
return false;
}
}
} // G3D

132
externals/g3dlite/UprightFrame.cpp vendored Normal file
View File

@@ -0,0 +1,132 @@
/**
@file UprightFrame.cpp
Box class
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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;
}
}
}
}

224
externals/g3dlite/Vector2.cpp vendored Normal file
View File

@@ -0,0 +1,224 @@
/**
@file Vector2.cpp
2D vector class, used for texture coordinates primarily.
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Portions based on Dave Eberly'x Magic Software Library
at http://www.magic-software.com
@created 2001-06-02
@edited 2009-11-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"
#include "G3D/Any.h"
namespace G3D {
Vector2::Vector2(const Any& any) {
any.verifyName("Vector2");
any.verifyType(Any::TABLE, Any::ARRAY);
any.verifySize(2);
if (any.type() == Any::ARRAY) {
x = any[0];
y = any[1];
} else {
// Table
x = any["x"];
y = any["y"];
}
}
Vector2::operator Any() const {
Any any(Any::ARRAY, "Vector2");
any.append(x, y);
return any;
}
const Vector2& Vector2::one() {
static const Vector2 v(1, 1); return v;
}
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::finf(), (float)G3D::finf());
return v;
}
const Vector2& Vector2::nan() {
static Vector2 v((float)G3D::fnan(), (float)G3D::fnan());
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(G3D::Random& r) {
Vector2 result;
do {
result = Vector2(r.uniform(-1, 1), r.uniform(-1, 1));
} while (result.squaredLength() >= 1.0f);
result.unitize();
return result;
}
Vector2 Vector2::operator/ (float k) const {
return *this * (1.0f / k);
}
Vector2& Vector2::operator/= (float k) {
this->x /= k;
this->y /= k;
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

507
externals/g3dlite/Vector3.cpp vendored Normal file
View File

@@ -0,0 +1,507 @@
/**
@file Vector3.cpp
3D vector class
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
@created 2001-06-02
@edited 2009-11-27
*/
#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/Color3.h"
#include "G3D/Vector4int8.h"
#include "G3D/Vector3int32.h"
#include "G3D/Any.h"
namespace G3D {
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"];
}
}
Vector3::operator Any() const {
Any any(Any::ARRAY, "Vector3");
any.append(x, y, z);
return any;
}
Vector3::Vector3(const class Color3& v) : x(v.r), y(v.g), z(v.b) {}
Vector3::Vector3(const class Vector3int32& v) : x((float)v.x), y((float)v.y), z((float)v.z) {}
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& Vector3::ignore() {
static Vector3 v;
return v;
}
const Vector3& Vector3::zero() { static const Vector3 v(0, 0, 0); return v; }
const Vector3& Vector3::one() { static const Vector3 v(1, 1, 1); return v; }
const Vector3& Vector3::unitX() { static const Vector3 v(1, 0, 0); return v; }
const Vector3& Vector3::unitY() { static const Vector3 v(0, 1, 0); return v; }
const Vector3& Vector3::unitZ() { static const Vector3 v(0, 0, 1); return v; }
const Vector3& Vector3::inf() { static const Vector3 v((float)G3D::finf(), (float)G3D::finf(), (float)G3D::finf()); return v; }
const Vector3& Vector3::nan() { static const Vector3 v((float)G3D::fnan(), (float)G3D::fnan(), (float)G3D::fnan()); return v; }
const Vector3& Vector3::minFinite(){ static const Vector3 v(-FLT_MAX, -FLT_MAX, -FLT_MAX); return v; }
const Vector3& Vector3::maxFinite(){ static const Vector3 v(FLT_MAX, FLT_MAX, FLT_MAX); return v; }
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(Random& r) {
Vector3 result;
r.sphere(result.x, result.y, result.z);
return result;
}
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::cosHemiRandom(const Vector3& normal, Random& r) {
debugAssertM(G3D::fuzzyEq(normal.length(), 1.0f),
"cosHemiRandom requires its argument to have unit length");
float x, y, z;
r.cosHemi(x, y, z);
// Make a coordinate system
const Vector3& Z = normal;
Vector3 X, Y;
normal.getTangents(X, Y);
return
x * X +
y * Y +
z * Z;
}
Vector3 Vector3::cosPowHemiRandom(const Vector3& normal, const float k, Random& r) {
debugAssertM(G3D::fuzzyEq(normal.length(), 1.0f),
"cosPowHemiRandom requires its argument to have unit length");
float x, y, z;
r.cosPowHemi(k, x, y, z);
// Make a coordinate system
const Vector3& Z = normal;
Vector3 X, Y;
normal.getTangents(X, Y);
return
x * X +
y * Y +
z * Z;
}
Vector3 Vector3::hemiRandom(const Vector3& normal, Random& r) {
const Vector3& V = Vector3::random(r);
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

520
externals/g3dlite/Vector4.cpp vendored Normal file
View File

@@ -0,0 +1,520 @@
/**
@file Vector4.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2001-07-09
@edited 2009-11-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"
#include "G3D/Any.h"
namespace G3D {
Vector4::Vector4(const Any& any) {
any.verifyName("Vector4");
any.verifyType(Any::TABLE, Any::ARRAY);
any.verifySize(4);
if (any.type() == Any::ARRAY) {
x = any[0];
y = any[1];
z = any[2];
w = any[3];
} else {
// Table
x = any["x"];
y = any["y"];
z = any["z"];
w = any["w"];
}
}
Vector4::operator Any() const {
Any any(Any::ARRAY, "Vector4");
any.append(x, y, z, w);
return any;
}
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) {
}
const Vector4& Vector4::inf() {
static const Vector4 v((float)G3D::finf(), (float)G3D::finf(), (float)G3D::finf(), (float)G3D::finf());
return v;
}
const Vector4& Vector4::zero() {
static const Vector4 v(0,0,0,0);
return v;
}
const Vector4& Vector4::nan() {
static Vector4 v((float)G3D::fnan(), (float)G3D::fnan(), (float)G3D::fnan(), (float)G3D::fnan());
return v;
}
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

389
externals/g3dlite/debugAssert.cpp vendored Normal file
View File

@@ -0,0 +1,389 @@
/**
@file debugAssert.cpp
Windows implementation of assertion routines.
@maintainer Morgan McGuire, graphics3d.com
@created 2001-08-26
@edited 2009-06-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
#if SOMEONE_MADE_THIS_USEFUL
Display* x11Display = NULL;
Window x11Window = 0;
#endif
#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 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 cAbort = 2;
static const char* choices[] = {"Debug", "Ignore", "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, 3, 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 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 useGuiPrompt) {
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();
(void)lastErr;
postToClipboard(dialogText.c_str());
debugPrintf("\n%s\n", dialogText.c_str());
#endif
static const char* choices[] = {"Ok"};
const std::string& m =
std::string("An internal error has occured in this program and it will now close. "
"The specific error is below. More information has been saved in \"") +
Log::getCommonLogFilename() + "\".\n" + dialogText;
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 SOMEONE_MADE_THIS_USEFUL
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);
}
#endif
#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(s);
// 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

1165
externals/g3dlite/fileutils.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

164
externals/g3dlite/format.cpp vendored Normal file
View File

@@ -0,0 +1,164 @@
/**
@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

204
externals/g3dlite/g3dfnmatch.cpp vendored Normal file
View File

@@ -0,0 +1,204 @@
/*-
* 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.cpp,v 1.2 2010/02/06 10:03:24 corey_taylor Exp $
*/
#include "G3D/g3dfnmatch.h"
#ifdef G3D_WIN32
#include <ctype.h>
#include <string.h>
#include <stdio.h>
namespace G3D {
#define EOS '\0'
static const char *rangematch(const char *, char, int);
int g3dfnmatch(const char *pattern, const char *string, int flags)
{
const char *stringstart;
char c, test;
for (stringstart = string;;)
switch (c = *pattern++) {
case EOS:
if ((flags & FNM_LEADING_DIR) && *string == '/')
return (0);
return (*string == EOS ? 0 : FNM_NOMATCH);
case '?':
if (*string == EOS)
return (FNM_NOMATCH);
if (*string == '/' && (flags & FNM_PATHNAME))
return (FNM_NOMATCH);
if (*string == '.' && (flags & FNM_PERIOD) &&
(string == stringstart ||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
return (FNM_NOMATCH);
++string;
break;
case '*':
c = *pattern;
/* Collapse multiple stars. */
while (c == '*')
c = *++pattern;
if (*string == '.' && (flags & FNM_PERIOD) &&
(string == stringstart ||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
return (FNM_NOMATCH);
/* Optimize for pattern with * at end or before /. */
if (c == EOS)
if (flags & FNM_PATHNAME)
return ((flags & FNM_LEADING_DIR) ||
strchr(string, '/') == NULL ?
0 : FNM_NOMATCH);
else
return (0);
else if (c == '/' && flags & FNM_PATHNAME) {
if ((string = strchr(string, '/')) == NULL)
return (FNM_NOMATCH);
break;
}
/* General case, use recursion. */
while ((test = *string) != EOS) {
if (!rangematch(pattern, *string, flags & ~FNM_PERIOD))
return (0);
if (test == '/' && flags & FNM_PATHNAME)
break;
++string;
}
return (FNM_NOMATCH);
case '[':
if (*string == EOS)
return (FNM_NOMATCH);
if (*string == '/' && flags & FNM_PATHNAME)
return (FNM_NOMATCH);
if ((pattern =
rangematch(pattern, *string, flags)) == NULL)
return (FNM_NOMATCH);
++string;
break;
case '\\':
if (!(flags & FNM_NOESCAPE)) {
if ((c = *pattern++) == EOS) {
c = '\\';
--pattern;
}
}
/* FALLTHROUGH */
default:
if (c == *string)
;
else if ((flags & FNM_CASEFOLD) &&
(tolower((unsigned char)c) ==
tolower((unsigned char)*string)))
;
else if ((flags & FNM_PREFIX_DIRS) && *string == EOS &&
((c == '/' && string != stringstart) ||
(string == stringstart+1 && *stringstart == '/')))
return (0);
else
return (FNM_NOMATCH);
string++;
break;
}
/* NOTREACHED */
}
static const char *
rangematch(const char *pattern, char test, int flags)
{
int negate, ok;
char c, c2;
/*
* A bracket expression starting with an unquoted circumflex
* character produces unspecified results (IEEE 1003.2-1992,
* 3.13.2). This implementation treats it like '!', for
* consistency with the regular expression syntax.
* J.T. Conklin (conklin@ngai.kaleida.com)
*/
if ( (negate = (*pattern == '!' || *pattern == '^')) )
++pattern;
if (flags & FNM_CASEFOLD)
test = tolower((unsigned char)test);
for (ok = 0; (c = *pattern++) != ']';) {
if (c == '\\' && !(flags & FNM_NOESCAPE))
c = *pattern++;
if (c == EOS)
return (NULL);
if (flags & FNM_CASEFOLD)
c = tolower((unsigned char)c);
if (*pattern == '-'
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
pattern += 2;
if (c2 == '\\' && !(flags & FNM_NOESCAPE))
c2 = *pattern++;
if (c2 == EOS)
return (NULL);
if (flags & FNM_CASEFOLD)
c2 = tolower((unsigned char)c2);
if ((unsigned char)c <= (unsigned char)test &&
(unsigned char)test <= (unsigned char)c2)
ok = 1;
} else if (c == test)
ok = 1;
}
return (ok == negate ? NULL : pattern);
}
}
#else
namespace G3D {
int g3dfnmatch(const char * a, const char *b, int c) {
return fnmatch(a, b, c);
}
}
#endif

108
externals/g3dlite/g3dmath.cpp vendored Normal file
View File

@@ -0,0 +1,108 @@
/**
@file g3dmath.cpp
@author Morgan McGuire, graphics3d.com
@created 2001-06-02
@edited 2004-02-24
*/
#include "G3D/g3dmath.h"
#include <cstdlib>
#include <cstring>
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;
}
/**
This value should not be tested against directly, instead
G3D::isNan() and G3D::isFinite() will return reliable results. */
double inf() {
return std::numeric_limits<double>::infinity();
}
bool isNaN(float x) {
static const float n = nan();
return memcmp(&x, &n, sizeof(float)) == 0;
}
bool isNaN(double x) {
static const double n = nan();
return memcmp(&x, &n, sizeof(double)) == 0;
}
/**
This value should not be tested against directly, instead
G3D::isNan() and G3D::isFinite() will return reliable results. */
float finf() {
return std::numeric_limits<float>::infinity();
}
/** This value should not be tested against directly, instead
G3D::isNan() and G3D::isFinite() will return reliable results. */
double nan() {
// double is a standard type and should have quiet NaN
return std::numeric_limits<double>::quiet_NaN();
}
float fnan() {
// double is a standard type and should have quiet NaN
return std::numeric_limits<float>::quiet_NaN();
}
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;
}
}
}

729
externals/g3dlite/prompt.cpp vendored Normal file
View File

@@ -0,0 +1,729 @@
/**
@file prompt.cpp
@author Morgan McGuire, http://graphics.cs.williams.edu
@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
/*#ifdef __LP64__
# undef __LP64__
#endif
*/
# include <Carbon/Carbon.h>
/*
#ifdef G3D_64BIT
# define __LP64__
#endif
*/
#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

275
externals/g3dlite/stringutils.cpp vendored Normal file
View File

@@ -0,0 +1,275 @@
/**
@file stringutils.cpp
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
@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' || ch=='\r'); }
#endif
void parseCommaSeparated(const std::string s, Array<std::string>& array, bool stripQuotes) {
array.fastClear();
if (s == "") {
return;
}
size_t begin = 0;
const char delimiter = ',';
const char quote = '\"';
do {
size_t end = begin;
// Find the next comma, or the end of the string
bool inQuotes = false;
while ((end < s.length()) && (inQuotes || (s[end] != delimiter))) {
if (s[end] == quote) {
if ((end < s.length() - 2) && (s[end + 1] == quote) && (s[end + 2]) == quote) {
// Skip over the superquote
end += 2;
}
inQuotes = ! inQuotes;
}
++end;
}
array.append(s.substr(begin, end - begin));
begin = end + 1;
} while (begin < s.length());
if (stripQuotes) {
for (int i = 0; i < array.length(); ++i) {
std::string& t = array[i];
int L = t.length();
if ((L > 1) && (t[0] == quote) && (t[L - 1] == quote)) {
if ((L > 6) && (t[1] == quote) && (t[2] == quote) && (t[L - 3] == quote) && (t[L - 2] == quote)) {
// Triple-quote
t = t.substr(3, L - 6);
} else {
// Double-quote
t = t.substr(1, L - 2);
}
}
}
}
}
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

View File

@@ -1,27 +1,15 @@
SET(jmalloc_STAT_SRC
arena.c
chunk.c
chunk_mmap.c
ckh.c
extent.c
huge.c
mb.c
prof.c
tcache.c
base.c
chunk_dss.c
chunk_swap.c
ctl.c
hash.c
jemalloc.c
mutex.c
stats.c
)
file(GLOB sources *.c)
set(jemalloc_STAT_SRC
${sources}
)
include_directories(
${CMAKE_SOURCE_DIR}/dep/include
)
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/include/internal
)
add_definitions(-D_GNU_SOURCE -D_REENTRANT)
add_library(jmalloc STATIC ${jmalloc_STAT_SRC})
add_library(jemalloc STATIC ${sources})

View File

View File

@@ -1,26 +1,10 @@
SET(trinitysockets_STAT_SRCS
Base64.cpp
Exception.cpp
Ipv4Address.cpp
Ipv6Address.cpp
Lock.cpp
Mutex.cpp
Parse.cpp
ResolvServer.cpp
ResolvSocket.cpp
Socket.cpp
SocketHandler.cpp
StdoutLog.cpp
StreamSocket.cpp
TcpSocket.cpp
Thread.cpp
UdpSocket.cpp
Utility.cpp
socket_include.cpp
file(GLOB sources *.cpp)
set(trinitysockets_STAT_SRCS
${sources}
)
include_directories(
${CMAKE_SOURCE_DIR}/dep/include/sockets
${CMAKE_CURRENT_SOURCE_DIR}/include
)
add_library(trinitysockets STATIC ${trinitysockets_STAT_SRCS})

136
externals/sockets/Makefile vendored Normal file
View File

@@ -0,0 +1,136 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 2.6
# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target
#=============================================================================
# Special targets provided by cmake.
# Disable implicit rules so canoncical targets will work.
.SUFFIXES:
# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =
.SUFFIXES: .hpux_make_needs_suffix_list
# Suppress display of executed commands.
$(VERBOSE).SILENT:
# A target that is always out of date.
cmake_force:
.PHONY : cmake_force
#=============================================================================
# Set environment variables for the build.
# The shell in which to execute make rules.
SHELL = /bin/sh
# The CMake executable.
CMAKE_COMMAND = /usr/bin/cmake
# The command to remove a file.
RM = /usr/bin/cmake -E remove -f
# The program to use to edit the cache.
CMAKE_EDIT_COMMAND = /usr/bin/ccmake
# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /home/trinity/dev/trinitycore/externals/sockets
# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /home/trinity/dev/trinitycore/externals/sockets
#=============================================================================
# Targets provided globally by CMake.
# Special rule for the target edit_cache
edit_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
/usr/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : edit_cache
# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast
# Special rule for the target rebuild_cache
rebuild_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
/usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache
# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast
# The main all target
all: cmake_check_build_system
$(CMAKE_COMMAND) -E cmake_progress_start /home/trinity/dev/trinitycore/externals/sockets/CMakeFiles /home/trinity/dev/trinitycore/externals/sockets/CMakeFiles/progress.make
$(MAKE) -f CMakeFiles/Makefile2 all
$(CMAKE_COMMAND) -E cmake_progress_start /home/trinity/dev/trinitycore/externals/sockets/CMakeFiles 0
.PHONY : all
# The main clean target
clean:
$(MAKE) -f CMakeFiles/Makefile2 clean
.PHONY : clean
# The main clean target
clean/fast: clean
.PHONY : clean/fast
# Prepare targets for installation.
preinstall: all
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall
# Prepare targets for installation.
preinstall/fast:
$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast
# clear depends
depend:
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend
#=============================================================================
# Target rules for targets named trinitysockets
# Build rule for target.
trinitysockets: cmake_check_build_system
$(MAKE) -f CMakeFiles/Makefile2 trinitysockets
.PHONY : trinitysockets
# fast build rule for target.
trinitysockets/fast:
$(MAKE) -f CMakeFiles/trinitysockets.dir/build.make CMakeFiles/trinitysockets.dir/build
.PHONY : trinitysockets/fast
# Help Target
help:
@echo "The following are some of the valid targets for this Makefile:"
@echo "... all (the default if no target is provided)"
@echo "... clean"
@echo "... depend"
@echo "... edit_cache"
@echo "... rebuild_cache"
@echo "... trinitysockets"
.PHONY : help
#=============================================================================
# Special targets to cleanup operation of make.
# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system

12
externals/zlib/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,12 @@
file(GLOB sources *.c)
file(GLOB headers *.h)
SET(zlib_STAT_SRCS
${sources}
)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(zlib STATIC ${zlib_STAT_SRCS})

1208
externals/zlib/ChangeLog vendored

File diff suppressed because it is too large Load Diff

115
externals/zlib/README vendored
View File

@@ -1,115 +0,0 @@
ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.5 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
and rfc1952.txt (gzip format).
All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
of the library is given in the file example.c which also tests that the library
is working correctly. Another example is given in the file minigzip.c. The
compression library itself is composed of all source files except example.c and
minigzip.c.
To compile all files and run the test program, follow the instructions given at
the top of Makefile.in. In short "./configure; make test", and if that goes
well, "make install" should work for most flavors of Unix. For Windows, use one
of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
make_vms.com.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> for the Windows DLL version. The zlib home page is
http://zlib.net/ . Before reporting a problem, please check this site to
verify that you have the latest version of zlib; otherwise get the latest
version and check whether the problem still exists or not.
PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available at
http://marknelson.us/1997/01/01/zlib-engine/ .
The changes made in version 1.2.5 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory contrib/ .
zlib is available in Java using the java.util.zip package, documented at
http://java.sun.com/developer/technicalArticles/Programming/compression/ .
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
at CPAN (Comprehensive Perl Archive Network) sites, including
http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html .
zlib is built into tcl: http://wiki.tcl.tk/4610 .
An experimental package to read and write files in .zip format, written on top
of zlib by Gilles Vollant <info@winimage.com>, is available in the
contrib/minizip directory of zlib.
Notes for some targets:
- For Windows DLL versions, please see win32/DLL_FAQ.txt
- For 64-bit Irix, deflate.c must be compiled without any optimization. With
-O, one libpng test fails. The test works in 32 bit mode (with the -n32
compiler flag). The compiler bug has been reported to SGI.
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
when compiled with cc.
- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
necessary to get gzprintf working correctly. This is done by configure.
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
other compilers. Use "make test" to check your compiler.
- gzdopen is not supported on RISCOS or BEOS.
- For PalmOs, see http://palmzlib.sourceforge.net/
Acknowledgments:
The deflate format used by zlib was defined by Phil Katz. The deflate and
zlib specifications were written by L. Peter Deutsch. Thanks to all the
people who reported problems and suggested various improvements in zlib; they
are too numerous to cite here.
Copyright notice:
(C) 1995-2010 Jean-loup Gailly and Mark Adler
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.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
If you use the zlib library in a product, we would appreciate *not* receiving
lengthy legal documents to sign. The sources are provided for free but without
warranty of any kind. The library has been entirely written by Jean-loup
Gailly and Mark Adler; it does not include third-party code.
If you redistribute modified sources, we would appreciate that you include in
the file ChangeLog history information documenting your changes. Please read
the FAQ for more information on the distribution of modified source versions.

View File

@@ -4,21 +4,21 @@
SET(collision_STAT_SRCS
BoundingIntervalHierarchy.h
BoundingIntervalHierarchy.cpp
Management/IVMapManager.h
Maps/MapTree.cpp
Maps/MapTree.h
Models/ModelInstance.cpp
Models/ModelInstance.h
Maps/TileAssembler.cpp
Maps/TileAssembler.h
VMapDefinitions.h
Models/ModelInstance.cpp
Models/ModelInstance.h
Models/WorldModel.cpp
Models/WorldModel.h
Management/IVMapManager.h
Management/VMapFactory.cpp
Management/VMapFactory.h
Management/VMapManager2.cpp
Management/VMapManager2.h
VMapDefinitions.h
VMapTools.h
Models/WorldModel.cpp
Models/WorldModel.h
)
include_directories(

View File

@@ -404,6 +404,8 @@ include_directories(
if(NOT DO_SCRIPTS)
SET(game_STAT_SRCS ${game_STAT_SRCS}
PrecompiledHeaders/ScriptPCH.cpp
PrecompiledHeaders/ScriptPCH.h
AI/ScriptedAI/ScriptedEscortAI.cpp
AI/ScriptedAI/ScriptedEscortAI.h
AI/ScriptedAI/ScriptedCreature.cpp
@@ -416,8 +418,6 @@ if(NOT DO_SCRIPTS)
AI/ScriptedAI/ScriptedInstance.h
AI/ScriptedAI/ScriptedSimpleAI.cpp
AI/ScriptedAI/ScriptedSimpleAI.h
PrecompiledHeaders/ScriptPCH.cpp
PrecompiledHeaders/ScriptPCH.h
)
message("-- Added Script Engine to GAME lib")
endif(NOT DO_SCRIPTS)

View File

@@ -133,10 +133,14 @@ target_link_libraries(
trinity-core
game
shared
zlib
trinitysockets
trinitydatabase
trinityauth
trinityconfig
collision
g3dlib
jemalloc
${SCRIPT_LIB}
${READLINE_LIBRARY}
${TERMCAP_LIBRARY}