mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-12 23:54:27 +00:00
Add dlight codebase to zdray
This commit is contained in:
parent
b4f22e7959
commit
405bb743a0
35 changed files with 13189 additions and 1 deletions
|
@ -144,6 +144,26 @@ set( SOURCES
|
||||||
src/nodebuilder/nodebuild_gl.cpp
|
src/nodebuilder/nodebuild_gl.cpp
|
||||||
src/nodebuilder/nodebuild_utility.cpp
|
src/nodebuilder/nodebuild_utility.cpp
|
||||||
src/nodebuilder/nodebuild_classify_nosse2.cpp
|
src/nodebuilder/nodebuild_classify_nosse2.cpp
|
||||||
|
src/lightmap/lightmap.cpp
|
||||||
|
src/lightmap/lightsurface.cpp
|
||||||
|
src/lightmap/mapdata.cpp
|
||||||
|
src/lightmap/surfaces.cpp
|
||||||
|
src/lightmap/trace.cpp
|
||||||
|
src/lightmap/wad.cpp
|
||||||
|
src/lightmap/worker.cpp
|
||||||
|
src/lightmap/kexlib/binfile.cpp
|
||||||
|
src/lightmap/kexlib/kstring.cpp
|
||||||
|
src/lightmap/kexlib/memheap.cpp
|
||||||
|
src/lightmap/kexlib/parser.cpp
|
||||||
|
src/lightmap/kexlib/math/angle.cpp
|
||||||
|
src/lightmap/kexlib/math/bounds.cpp
|
||||||
|
src/lightmap/kexlib/math/mathlib.cpp
|
||||||
|
src/lightmap/kexlib/math/matrix.cpp
|
||||||
|
src/lightmap/kexlib/math/plane.cpp
|
||||||
|
src/lightmap/kexlib/math/pluecker.cpp
|
||||||
|
src/lightmap/kexlib/math/quaternion.cpp
|
||||||
|
src/lightmap/kexlib/math/random.cpp
|
||||||
|
src/lightmap/kexlib/math/vector.cpp
|
||||||
)
|
)
|
||||||
if( WIN32 )
|
if( WIN32 )
|
||||||
set( SOURCES "${SOURCES}" src/viewer/view.cpp )
|
set( SOURCES "${SOURCES}" src/viewer/view.cpp )
|
||||||
|
@ -164,7 +184,22 @@ set( HEADERS
|
||||||
src/framework/tarray.h
|
src/framework/tarray.h
|
||||||
src/framework/templates.h
|
src/framework/templates.h
|
||||||
src/framework/zdray.h
|
src/framework/zdray.h
|
||||||
src/framework/xs_Float.h )
|
src/framework/xs_Float.h
|
||||||
|
src/lightmap/common.h
|
||||||
|
src/lightmap/lightmap.h
|
||||||
|
src/lightmap/lightsurface.h
|
||||||
|
src/lightmap/mapdata.h
|
||||||
|
src/lightmap/surfaces.h
|
||||||
|
src/lightmap/trace.h
|
||||||
|
src/lightmap/wad.h
|
||||||
|
src/lightmap/worker.h
|
||||||
|
src/lightmap/kexlib/array.h
|
||||||
|
src/lightmap/kexlib/binfile.h
|
||||||
|
src/lightmap/kexlib/kstring.h
|
||||||
|
src/lightmap/kexlib/memheap.h
|
||||||
|
src/lightmap/kexlib/parser.h
|
||||||
|
src/lightmap/kexlib/math/mathlib.h
|
||||||
|
)
|
||||||
|
|
||||||
if( SSE_MATTERS )
|
if( SSE_MATTERS )
|
||||||
if( FULL_SSE2 )
|
if( FULL_SSE2 )
|
||||||
|
@ -233,3 +268,6 @@ source_group("Sources\\Platform" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR
|
||||||
source_group("Sources\\Platform\\Windows" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/.+")
|
source_group("Sources\\Platform\\Windows" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/.+")
|
||||||
source_group("Sources\\Viewer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/viewer/.+")
|
source_group("Sources\\Viewer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/viewer/.+")
|
||||||
source_group("Sources\\Wad" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/wad/.+")
|
source_group("Sources\\Wad" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/wad/.+")
|
||||||
|
source_group("Sources\\Lightmap" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/lightmap/.+")
|
||||||
|
source_group("Sources\\Lightmap\\kexlib" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/lightmap/kexlib/.+")
|
||||||
|
source_group("Sources\\Lightmap\\kexlib\\math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/src/lightmap/kexlib/math/.+")
|
||||||
|
|
166
src/lightmap/common.h
Normal file
166
src/lightmap/common.h
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __COMMON_H__
|
||||||
|
#define __COMMON_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable: 4267) // warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
|
||||||
|
#pragma warning(disable: 4244) // warning C4244: '=': conversion from '__int64' to 'int', possible loss of data
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// narrow down the windows preprocessor bullshit down to just one macro define
|
||||||
|
#if defined(__WIN32__) || defined(__WIN32) || defined(_WIN32_) || defined(_WIN32) || defined(WIN32)
|
||||||
|
#define KEX_WIN32
|
||||||
|
#else
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
// lets us know what version of Mac OS X we're compiling on
|
||||||
|
#include "AvailabilityMacros.h"
|
||||||
|
#include "TargetConditionals.h"
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
// if compiling for iPhone
|
||||||
|
#define KEX_IPHONE
|
||||||
|
#else
|
||||||
|
// if not compiling for iPhone
|
||||||
|
#define KEX_MACOSX
|
||||||
|
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
|
||||||
|
# error KexLIB for Mac OS X only supports deploying on 10.5 and above.
|
||||||
|
#endif // MAC_OS_X_VERSION_MIN_REQUIRED < 1050
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
|
||||||
|
# error KexLIB for Mac OS X must be built with a 10.6 SDK or above.
|
||||||
|
#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1060
|
||||||
|
#endif // TARGET_OS_IPHONE
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
#ifdef KEX_WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_FILEPATH 256
|
||||||
|
#define MAX_HASH 2048
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
typedef unsigned short word;
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned int dtexture;
|
||||||
|
typedef unsigned int rcolor;
|
||||||
|
typedef char filepath_t[MAX_FILEPATH];
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float f;
|
||||||
|
} fint_t;
|
||||||
|
|
||||||
|
#define ASCII_SLASH 47
|
||||||
|
#define ASCII_BACKSLASH 92
|
||||||
|
|
||||||
|
#ifdef KEX_WIN32
|
||||||
|
#define DIR_SEPARATOR '\\'
|
||||||
|
#define PATH_SEPARATOR ';'
|
||||||
|
#else
|
||||||
|
#define DIR_SEPARATOR '/'
|
||||||
|
#define PATH_SEPARATOR ':'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#define D_MININT INT_MIN
|
||||||
|
#define D_MAXINT INT_MAX
|
||||||
|
|
||||||
|
#ifndef MAX
|
||||||
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BETWEEN
|
||||||
|
#define BETWEEN(l,u,x) ((l)>(x)?(l):(x)>(u)?(u):(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BIT
|
||||||
|
#define BIT(num) (1<<(num))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(KEX_WIN32) && !defined(__GNUC__)
|
||||||
|
#define KDECL __cdecl
|
||||||
|
#else
|
||||||
|
#define KDECL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALIGNED
|
||||||
|
#undef ALIGNED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define ALIGNED(x) __declspec(align(x))
|
||||||
|
#define PACKED
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define ALIGNED(x) __attribute__ ((aligned(x)))
|
||||||
|
#define PACKED __attribute__((packed))
|
||||||
|
#else
|
||||||
|
#define ALIGNED(x)
|
||||||
|
#define PACKED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// function inlining is available on most platforms, however,
|
||||||
|
// the GNU C __inline__ is too common and conflicts with a
|
||||||
|
// definition in other dependencies, so it needs to be factored
|
||||||
|
// out into a custom macro definition
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__APPLE__)
|
||||||
|
#define d_inline __inline__
|
||||||
|
#elif defined(_MSC_VER) || defined(KEX_WIN32)
|
||||||
|
#define d_inline __forceinline
|
||||||
|
#else
|
||||||
|
#define d_inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "kexlib/memHeap.h"
|
||||||
|
#include "kexlib/kstring.h"
|
||||||
|
#include "kexlib/math/mathlib.h"
|
||||||
|
|
||||||
|
void Error(const char *error, ...);
|
||||||
|
char *Va(const char *str, ...);
|
||||||
|
void Delay(int ms);
|
||||||
|
const int64_t GetSeconds(void);
|
||||||
|
const kexStr &FilePath(void);
|
||||||
|
|
||||||
|
#endif
|
312
src/lightmap/kexlib/array.h
Normal file
312
src/lightmap/kexlib/array.h
Normal file
|
@ -0,0 +1,312 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __KEXARRAY_H__
|
||||||
|
#define __KEXARRAY_H__
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
template<class type>
|
||||||
|
class kexArray
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexArray(void);
|
||||||
|
~kexArray(void);
|
||||||
|
|
||||||
|
typedef int compare_t(const type*, const type*);
|
||||||
|
|
||||||
|
void Push(type o);
|
||||||
|
void Pop(void);
|
||||||
|
void Empty(void);
|
||||||
|
void Init(void);
|
||||||
|
void Resize(unsigned int size);
|
||||||
|
type IndexOf(unsigned int index) const;
|
||||||
|
bool Contains(const type check) const;
|
||||||
|
void Splice(const unsigned int start, unsigned int len);
|
||||||
|
void Sort(compare_t *function);
|
||||||
|
void Sort(compare_t *function, unsigned int count);
|
||||||
|
|
||||||
|
const unsigned int Length(void) const { return length; }
|
||||||
|
type GetData(const int index) { return data[index]; }
|
||||||
|
|
||||||
|
type &operator[](unsigned int index);
|
||||||
|
kexArray<type> &operator=(const kexArray<type> &arr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
type *data;
|
||||||
|
unsigned int length;
|
||||||
|
unsigned int aidx;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::kexArray
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
kexArray<type>::kexArray(void)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::~kexArray
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
kexArray<type>::~kexArray(void)
|
||||||
|
{
|
||||||
|
Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Init
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
void kexArray<type>::Init(void)
|
||||||
|
{
|
||||||
|
data = NULL;
|
||||||
|
length = 0;
|
||||||
|
aidx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Resize
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
void kexArray<type>::Resize(unsigned int size)
|
||||||
|
{
|
||||||
|
type *tmp;
|
||||||
|
|
||||||
|
if(size == length)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(size <= 0 && length != 0)
|
||||||
|
{
|
||||||
|
delete[] data;
|
||||||
|
data = NULL;
|
||||||
|
length = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length == 0)
|
||||||
|
{
|
||||||
|
data = new type[size];
|
||||||
|
length = size;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = data;
|
||||||
|
data = new type[size];
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
data[i] = tmp[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
length = size;
|
||||||
|
delete[] tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Push
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
void kexArray<type>::Push(type o)
|
||||||
|
{
|
||||||
|
Resize(length+1);
|
||||||
|
data[aidx++] = o;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Pop
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
void kexArray<type>::Pop(void)
|
||||||
|
{
|
||||||
|
if(length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Resize(length-1);
|
||||||
|
aidx--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Empty
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
void kexArray<type>::Empty(void)
|
||||||
|
{
|
||||||
|
if(data && length > 0)
|
||||||
|
{
|
||||||
|
delete[] data;
|
||||||
|
data = NULL;
|
||||||
|
length = 0;
|
||||||
|
aidx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::IndexOf
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
type kexArray<type>::IndexOf(unsigned int index) const
|
||||||
|
{
|
||||||
|
if(index >= length)
|
||||||
|
{
|
||||||
|
index = length-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Contains
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
bool kexArray<type>::Contains(const type check) const
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
if(data[i] == check)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Splice
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
void kexArray<type>::Splice(const unsigned int start, unsigned int len)
|
||||||
|
{
|
||||||
|
if(length == 0 || len == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(len >= length)
|
||||||
|
{
|
||||||
|
len = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
type *tmp = new type[len];
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
tmp[i] = data[start+i];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] data;
|
||||||
|
data = tmp;
|
||||||
|
length = length - len;
|
||||||
|
aidx = length-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Sort
|
||||||
|
//
|
||||||
|
// Note that data will be shuffled around, so this could invalidate any
|
||||||
|
// pointers that relies on the array/data
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
void kexArray<type>::Sort(compare_t *function)
|
||||||
|
{
|
||||||
|
if(data == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int compareCast(const void*, const void*);
|
||||||
|
compareCast *cmpFunc = (compareCast*)function;
|
||||||
|
|
||||||
|
qsort((void*)data, length, sizeof(type), cmpFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::Sort
|
||||||
|
//
|
||||||
|
// Note that data will be shuffled around, so this could invalidate any
|
||||||
|
// pointers that relies on the array/data
|
||||||
|
//
|
||||||
|
template<class type>
|
||||||
|
void kexArray<type>::Sort(compare_t *function, unsigned int count)
|
||||||
|
{
|
||||||
|
if(data == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int compareCast(const void*, const void*);
|
||||||
|
compareCast *cmpFunc = (compareCast*)function;
|
||||||
|
|
||||||
|
qsort((void*)data, count, sizeof(type), cmpFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::operator[]
|
||||||
|
//
|
||||||
|
template <class type>
|
||||||
|
type &kexArray<type>::operator[](unsigned int index)
|
||||||
|
{
|
||||||
|
assert(index < length);
|
||||||
|
return data[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexArray::operator=
|
||||||
|
//
|
||||||
|
template <class type>
|
||||||
|
kexArray<type> &kexArray<type>::operator=(const kexArray<type> &arr)
|
||||||
|
{
|
||||||
|
if(data)
|
||||||
|
{
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = NULL;
|
||||||
|
length = arr.length;
|
||||||
|
aidx = arr.aidx;
|
||||||
|
|
||||||
|
if(arr.length > 0)
|
||||||
|
{
|
||||||
|
data = new type[arr.length];
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < arr.length; i++)
|
||||||
|
{
|
||||||
|
data[i] = arr.data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
399
src/lightmap/kexlib/binfile.cpp
Normal file
399
src/lightmap/kexlib/binfile.cpp
Normal file
|
@ -0,0 +1,399 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Binary file operations
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "lightmap/common.h"
|
||||||
|
#include "lightmap/kexlib/binFile.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::kexBinFile
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBinFile::kexBinFile(void)
|
||||||
|
{
|
||||||
|
this->handle = NULL;
|
||||||
|
this->buffer = NULL;
|
||||||
|
this->bufferOffset = 0;
|
||||||
|
this->bOpened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::~kexBinFile
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBinFile::~kexBinFile(void)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Open
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexBinFile::Open(const char *file, kexHeapBlock &heapBlock)
|
||||||
|
{
|
||||||
|
if((handle = fopen(file, "rb")))
|
||||||
|
{
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
fseek(handle, 0, SEEK_END);
|
||||||
|
length = ftell(handle);
|
||||||
|
fseek(handle, 0, SEEK_SET);
|
||||||
|
|
||||||
|
buffer = (byte*)Mem_Calloc(length+1, heapBlock);
|
||||||
|
|
||||||
|
if(fread(buffer, 1, length, handle) == length)
|
||||||
|
{
|
||||||
|
if(length > 0)
|
||||||
|
{
|
||||||
|
bOpened = true;
|
||||||
|
bufferOffset = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem_Free(buffer);
|
||||||
|
buffer = NULL;
|
||||||
|
fclose(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Create
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexBinFile::Create(const char *file)
|
||||||
|
{
|
||||||
|
if((handle = fopen(file, "wb")))
|
||||||
|
{
|
||||||
|
bOpened = true;
|
||||||
|
bufferOffset = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Close
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBinFile::Close(void)
|
||||||
|
{
|
||||||
|
if(bOpened == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(handle)
|
||||||
|
{
|
||||||
|
fclose(handle);
|
||||||
|
handle = NULL;
|
||||||
|
if(buffer)
|
||||||
|
{
|
||||||
|
Mem_Free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bOpened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Exists
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexBinFile::Exists(const char *file)
|
||||||
|
{
|
||||||
|
FILE *fstream;
|
||||||
|
|
||||||
|
fstream = fopen(file, "r");
|
||||||
|
|
||||||
|
if(fstream != NULL)
|
||||||
|
{
|
||||||
|
fclose(fstream);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#ifdef KEX_WIN32
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we can't open because the file is a directory, the
|
||||||
|
// "file" exists at least!
|
||||||
|
if(errno == 21)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Duplicate
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBinFile::Duplicate(const char *newFileName)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if(bOpened == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(newFileName, "wb");
|
||||||
|
|
||||||
|
if(f == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(buffer, Length(), 1, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Length
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexBinFile::Length(void)
|
||||||
|
{
|
||||||
|
long savedpos;
|
||||||
|
long length;
|
||||||
|
|
||||||
|
if(bOpened == false)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save the current position in the file
|
||||||
|
savedpos = ftell(handle);
|
||||||
|
|
||||||
|
// jump to the end and find the length
|
||||||
|
fseek(handle, 0, SEEK_END);
|
||||||
|
length = ftell(handle);
|
||||||
|
|
||||||
|
// go back to the old location
|
||||||
|
fseek(handle, savedpos, SEEK_SET);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Read8
|
||||||
|
//
|
||||||
|
|
||||||
|
byte kexBinFile::Read8(void)
|
||||||
|
{
|
||||||
|
byte result;
|
||||||
|
result = buffer[bufferOffset++];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Read16
|
||||||
|
//
|
||||||
|
|
||||||
|
short kexBinFile::Read16(void)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
result = Read8();
|
||||||
|
result |= Read8() << 8;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Read32
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexBinFile::Read32(void)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
result = Read8();
|
||||||
|
result |= Read8() << 8;
|
||||||
|
result |= Read8() << 16;
|
||||||
|
result |= Read8() << 24;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::ReadFloat
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexBinFile::ReadFloat(void)
|
||||||
|
{
|
||||||
|
fint_t fi;
|
||||||
|
fi.i = Read32();
|
||||||
|
return fi.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::ReadVector
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 kexBinFile::ReadVector(void)
|
||||||
|
{
|
||||||
|
kexVec3 vec;
|
||||||
|
|
||||||
|
vec.x = ReadFloat();
|
||||||
|
vec.y = ReadFloat();
|
||||||
|
vec.z = ReadFloat();
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::ReadString
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr kexBinFile::ReadString(void)
|
||||||
|
{
|
||||||
|
kexStr str;
|
||||||
|
char c = 0;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(!(c = Read8()))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
str += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Write8
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBinFile::Write8(const byte val)
|
||||||
|
{
|
||||||
|
if(bOpened)
|
||||||
|
{
|
||||||
|
fwrite(&val, 1, 1, handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer[bufferOffset] = val;
|
||||||
|
}
|
||||||
|
bufferOffset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Write16
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBinFile::Write16(const short val)
|
||||||
|
{
|
||||||
|
Write8(val & 0xff);
|
||||||
|
Write8((val >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::Write32
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBinFile::Write32(const int val)
|
||||||
|
{
|
||||||
|
Write8(val & 0xff);
|
||||||
|
Write8((val >> 8) & 0xff);
|
||||||
|
Write8((val >> 16) & 0xff);
|
||||||
|
Write8((val >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::WriteFloat
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBinFile::WriteFloat(const float val)
|
||||||
|
{
|
||||||
|
fint_t fi;
|
||||||
|
fi.f = val;
|
||||||
|
Write32(fi.i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::WriteVector
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBinFile::WriteVector(const kexVec3 &val)
|
||||||
|
{
|
||||||
|
WriteFloat(val.x);
|
||||||
|
WriteFloat(val.y);
|
||||||
|
WriteFloat(val.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::WriteString
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBinFile::WriteString(const kexStr &val)
|
||||||
|
{
|
||||||
|
const char *c = val.c_str();
|
||||||
|
|
||||||
|
for(int i = 0; i < val.Length(); i++)
|
||||||
|
{
|
||||||
|
Write8(c[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Write8(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::GetOffsetValue
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexBinFile::GetOffsetValue(int id)
|
||||||
|
{
|
||||||
|
return *(int*)(buffer + (id << 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBinFile::GetOffset
|
||||||
|
//
|
||||||
|
|
||||||
|
byte *kexBinFile::GetOffset(int id, byte *subdata, int *count)
|
||||||
|
{
|
||||||
|
byte *data = (subdata == NULL) ? buffer : subdata;
|
||||||
|
|
||||||
|
bufferOffset = GetOffsetValue(id);
|
||||||
|
byte *dataOffs = &data[bufferOffset];
|
||||||
|
|
||||||
|
if(count)
|
||||||
|
{
|
||||||
|
*count = *(int*)(dataOffs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataOffs;
|
||||||
|
}
|
79
src/lightmap/kexlib/binfile.h
Normal file
79
src/lightmap/kexlib/binfile.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __BINFILE_H__
|
||||||
|
#define __BINFILE_H__
|
||||||
|
|
||||||
|
#include "lightmap/kexlib/math/mathlib.h"
|
||||||
|
|
||||||
|
class kexBinFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexBinFile(void);
|
||||||
|
~kexBinFile(void);
|
||||||
|
|
||||||
|
bool Open(const char *file, kexHeapBlock &heapBlock = hb_static);
|
||||||
|
bool Create(const char *file);
|
||||||
|
void Close(void);
|
||||||
|
bool Exists(const char *file);
|
||||||
|
int Length(void);
|
||||||
|
void Duplicate(const char *newFileName);
|
||||||
|
|
||||||
|
byte Read8(void);
|
||||||
|
short Read16(void);
|
||||||
|
int Read32(void);
|
||||||
|
float ReadFloat(void);
|
||||||
|
kexVec3 ReadVector(void);
|
||||||
|
kexStr ReadString(void);
|
||||||
|
|
||||||
|
void Write8(const byte val);
|
||||||
|
void Write16(const short val);
|
||||||
|
void Write32(const int val);
|
||||||
|
void WriteFloat(const float val);
|
||||||
|
void WriteVector(const kexVec3 &val);
|
||||||
|
void WriteString(const kexStr &val);
|
||||||
|
|
||||||
|
int GetOffsetValue(int id);
|
||||||
|
byte *GetOffset(int id,
|
||||||
|
byte *subdata = NULL,
|
||||||
|
int *count = NULL);
|
||||||
|
|
||||||
|
FILE *Handle(void) const { return handle; }
|
||||||
|
byte *Buffer(void) const { return buffer; }
|
||||||
|
void SetBuffer(byte *ptr) { buffer = ptr; }
|
||||||
|
byte *BufferAt(void) const { return &buffer[bufferOffset]; }
|
||||||
|
bool Opened(void) const { return bOpened; }
|
||||||
|
void SetOffset(const int offset) { bufferOffset = offset; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE *handle;
|
||||||
|
byte *buffer;
|
||||||
|
unsigned int bufferOffset;
|
||||||
|
bool bOpened;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
804
src/lightmap/kexlib/kstring.cpp
Normal file
804
src/lightmap/kexlib/kstring.cpp
Normal file
|
@ -0,0 +1,804 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: String Class
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "kstring.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Init
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexStr::Init(void)
|
||||||
|
{
|
||||||
|
length = 0;
|
||||||
|
bufferLength = STRING_DEFAULT_SIZE;
|
||||||
|
charPtr = defaultBuffer;
|
||||||
|
charPtr[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::CheckSize
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexStr::CheckSize(int size, bool bKeepString)
|
||||||
|
{
|
||||||
|
if(size <= bufferLength)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Resize(size, bKeepString);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::CopyNew
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexStr::CopyNew(const char *string, int len)
|
||||||
|
{
|
||||||
|
CheckSize(len+1, false);
|
||||||
|
strcpy(charPtr, string);
|
||||||
|
length = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::kexStr
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr::kexStr(void)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::kexStr
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr::kexStr(const char *string)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
|
||||||
|
if(string == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyNew(string, strlen(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::kexStr
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr::kexStr(const char *string, const int length)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
|
||||||
|
if(string == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyNew(string, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::kexStr
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr::kexStr(const kexStr &string)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
|
||||||
|
if(string.charPtr == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyNew(string.charPtr, string.Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::~kexStr
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr::~kexStr(void)
|
||||||
|
{
|
||||||
|
if(charPtr != defaultBuffer)
|
||||||
|
{
|
||||||
|
delete[] charPtr;
|
||||||
|
charPtr = defaultBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
charPtr[0] = '\0';
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Concat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::Concat(const char *string)
|
||||||
|
{
|
||||||
|
return Concat(string, strlen(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Concat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::Concat(const char c)
|
||||||
|
{
|
||||||
|
CheckSize((length + 1)+1, true);
|
||||||
|
charPtr[length++] = c;
|
||||||
|
charPtr[length] = '\0';
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Concat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::Concat(const char *string, int len)
|
||||||
|
{
|
||||||
|
CheckSize((length + len)+1, true);
|
||||||
|
|
||||||
|
for(int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
charPtr[length+i] = string[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
length += len;
|
||||||
|
charPtr[length] = '\0';
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Copy
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::Copy(const kexStr &src, int len)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
const char *p = src;
|
||||||
|
CheckSize((length + len)+1, true);
|
||||||
|
|
||||||
|
while((len--) >= 0)
|
||||||
|
{
|
||||||
|
charPtr[i] = p[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Copy
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::Copy(const kexStr &src)
|
||||||
|
{
|
||||||
|
return Copy(src, src.Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::operator=(const kexStr &str)
|
||||||
|
{
|
||||||
|
int len = str.Length();
|
||||||
|
|
||||||
|
CheckSize(len+1, false);
|
||||||
|
strncpy(charPtr, str.charPtr, len);
|
||||||
|
length = len;
|
||||||
|
charPtr[length] = '\0';
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::operator=(const char *str)
|
||||||
|
{
|
||||||
|
int len = strlen(str);
|
||||||
|
|
||||||
|
CheckSize(len+1, false);
|
||||||
|
strncpy(charPtr, str, len);
|
||||||
|
length = len;
|
||||||
|
charPtr[length] = '\0';
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::operator=(const bool b)
|
||||||
|
{
|
||||||
|
const char *str = b ? "true" : "false";
|
||||||
|
int len = strlen(str);
|
||||||
|
|
||||||
|
CheckSize(len+1, false);
|
||||||
|
strncpy(charPtr, str, len);
|
||||||
|
length = len;
|
||||||
|
charPtr[length] = '\0';
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr kexStr::operator+(const kexStr &str)
|
||||||
|
{
|
||||||
|
kexStr out(*this);
|
||||||
|
|
||||||
|
return out.Concat(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr kexStr::operator+(const char *str)
|
||||||
|
{
|
||||||
|
kexStr out(*this);
|
||||||
|
|
||||||
|
return out.Concat(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr kexStr::operator+(const bool b)
|
||||||
|
{
|
||||||
|
kexStr out(*this);
|
||||||
|
|
||||||
|
return out.Concat(b ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr kexStr::operator+(const int i)
|
||||||
|
{
|
||||||
|
kexStr out(*this);
|
||||||
|
|
||||||
|
char tmp[64];
|
||||||
|
sprintf(tmp, "%i", i);
|
||||||
|
|
||||||
|
return out.Concat(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr kexStr::operator+(const float f)
|
||||||
|
{
|
||||||
|
kexStr out(*this);
|
||||||
|
|
||||||
|
char tmp[64];
|
||||||
|
sprintf(tmp, "%f", f);
|
||||||
|
|
||||||
|
return out.Concat(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::operator+=(const kexStr &str)
|
||||||
|
{
|
||||||
|
return Concat(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::operator+=(const char *str)
|
||||||
|
{
|
||||||
|
return Concat(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::operator+=(const char c)
|
||||||
|
{
|
||||||
|
return Concat(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator+=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::operator+=(const bool b)
|
||||||
|
{
|
||||||
|
return Concat(b ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::operator[]
|
||||||
|
//
|
||||||
|
|
||||||
|
const char kexStr::operator[](int index) const
|
||||||
|
{
|
||||||
|
assert(index >= 0 && index < length);
|
||||||
|
return charPtr[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Resize
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexStr::Resize(int size, bool bKeepString)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(size <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int newsize = size + ((32 - (size & 31)) & 31);
|
||||||
|
char *newbuffer = new char[newsize];
|
||||||
|
|
||||||
|
if(bKeepString)
|
||||||
|
{
|
||||||
|
strncpy(newbuffer, charPtr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(charPtr != defaultBuffer)
|
||||||
|
{
|
||||||
|
delete[] charPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
charPtr = newbuffer;
|
||||||
|
bufferLength = newsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::IndexOf
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexStr::IndexOf(const char *pattern) const
|
||||||
|
{
|
||||||
|
int patlen = strlen(pattern);
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
while(i + j < Length())
|
||||||
|
{
|
||||||
|
if(charPtr[i + j] == pattern[j])
|
||||||
|
{
|
||||||
|
if(++j == patlen)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::IndexOf
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexStr::IndexOf(const char *string, const char *pattern)
|
||||||
|
{
|
||||||
|
int patlen = strlen(pattern);
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
while(i + j < (int)strlen(string))
|
||||||
|
{
|
||||||
|
if(string[i + j] == pattern[j])
|
||||||
|
{
|
||||||
|
if(++j == patlen)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::IndexOf
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexStr::IndexOf(const kexStr &pattern) const
|
||||||
|
{
|
||||||
|
return IndexOf(pattern.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::NormalizeSlashes
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::NormalizeSlashes(void)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if((charPtr[i] == '/' || charPtr[i] == '\\') && charPtr[i] != DIR_SEPARATOR)
|
||||||
|
{
|
||||||
|
charPtr[i] = DIR_SEPARATOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::StripPath
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::StripPath(void)
|
||||||
|
{
|
||||||
|
int pos = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
pos = length;
|
||||||
|
|
||||||
|
for(i = length - 1; charPtr[i] != '\\' && charPtr[i] != '/'; i--, pos--)
|
||||||
|
{
|
||||||
|
if(pos <= 0)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
length = length - pos;
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
charPtr[i] = charPtr[pos+i];
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckSize(length, true);
|
||||||
|
charPtr[length] = '\0';
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::StripExtension
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::StripExtension(void)
|
||||||
|
{
|
||||||
|
int pos = IndexOf(".");
|
||||||
|
|
||||||
|
if(pos == -1)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = pos;
|
||||||
|
CheckSize(length, true);
|
||||||
|
charPtr[length] = '\0';
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::StripFile
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::StripFile(void)
|
||||||
|
{
|
||||||
|
int pos = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if(IndexOf(".") == -1)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = length;
|
||||||
|
|
||||||
|
for(i = length - 1; charPtr[i] != '\\' && charPtr[i] != '/'; i--, pos--)
|
||||||
|
{
|
||||||
|
if(pos <= 0)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
length = pos;
|
||||||
|
CheckSize(length, true);
|
||||||
|
charPtr[length] = '\0';
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Hash
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexStr::Hash(void)
|
||||||
|
{
|
||||||
|
unsigned int hash = 0;
|
||||||
|
char *str = (char*)charPtr;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
while((c = *str++))
|
||||||
|
{
|
||||||
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash & (MAX_HASH-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Hash
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexStr::Hash(const char *s)
|
||||||
|
{
|
||||||
|
unsigned int hash = 0;
|
||||||
|
char *str = (char*)s;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
while((c = *str++))
|
||||||
|
{
|
||||||
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash & (MAX_HASH-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Format
|
||||||
|
//
|
||||||
|
|
||||||
|
char *kexStr::Format(const char *str, ...)
|
||||||
|
{
|
||||||
|
va_list v;
|
||||||
|
static char vastr[1024];
|
||||||
|
|
||||||
|
va_start(v, str);
|
||||||
|
vsprintf(vastr, str,v);
|
||||||
|
va_end(v);
|
||||||
|
|
||||||
|
return vastr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Substr
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr kexStr::Substr(int start, int len) const
|
||||||
|
{
|
||||||
|
kexStr str;
|
||||||
|
int l = Length();
|
||||||
|
|
||||||
|
if(l <= 0 || start >= l)
|
||||||
|
{
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(start + len >= l)
|
||||||
|
{
|
||||||
|
len = l - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.Concat((const char*)&charPtr[start], len);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Split
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexStr::Split(kexStrList &list, const char seperator)
|
||||||
|
{
|
||||||
|
int splitLen = 0;
|
||||||
|
int startOffs = 0;
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if(charPtr[i] == seperator)
|
||||||
|
{
|
||||||
|
if(splitLen == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Push(kexStr(&charPtr[startOffs], splitLen));
|
||||||
|
startOffs += (splitLen+1);
|
||||||
|
splitLen = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
splitLen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(splitLen != 0 && startOffs != 0)
|
||||||
|
{
|
||||||
|
list.Push(kexStr(&charPtr[startOffs], splitLen));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Atoi
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexStr::Atoi(void)
|
||||||
|
{
|
||||||
|
return atoi(charPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Atof
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexStr::Atof(void)
|
||||||
|
{
|
||||||
|
return (float)atof(charPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::WriteToFile
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexStr::WriteToFile(const char *file)
|
||||||
|
{
|
||||||
|
if(length <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen(file, "w");
|
||||||
|
fprintf(f, "%s", charPtr);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::ToUpper
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::ToUpper(void)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
c = charPtr[i];
|
||||||
|
if(c >= 'a' && c <= 'z')
|
||||||
|
{
|
||||||
|
c -= 'a'-'A';
|
||||||
|
}
|
||||||
|
charPtr[i] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::ToLower
|
||||||
|
//
|
||||||
|
|
||||||
|
kexStr &kexStr::ToLower(void)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
for(int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
c = charPtr[i];
|
||||||
|
if(c >= 'A' && c <= 'Z')
|
||||||
|
{
|
||||||
|
c += 32;
|
||||||
|
}
|
||||||
|
charPtr[i] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::CompareCase
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexStr::CompareCase(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
while(*s1 && *s2)
|
||||||
|
{
|
||||||
|
if(*s1 != *s2)
|
||||||
|
{
|
||||||
|
return (*s2 - *s1) != 0;
|
||||||
|
}
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
if(*s1 != *s2)
|
||||||
|
{
|
||||||
|
return (*s2 - *s1) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::CompareCase
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexStr::CompareCase(const kexStr &a, const kexStr &b)
|
||||||
|
{
|
||||||
|
return CompareCase(a.c_str(), b.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Compare
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexStr::Compare(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
const byte *us1 = (const byte*)s1;
|
||||||
|
const byte *us2 = (const byte*)s2;
|
||||||
|
|
||||||
|
while(tolower(*us1) == tolower(*us2))
|
||||||
|
{
|
||||||
|
if(*us1++ == '\0')
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
us2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tolower(*us1) - tolower(*us2)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexStr::Compare
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexStr::Compare(const kexStr &a, const kexStr &b)
|
||||||
|
{
|
||||||
|
return Compare(a.c_str(), b.c_str());
|
||||||
|
}
|
131
src/lightmap/kexlib/kstring.h
Normal file
131
src/lightmap/kexlib/kstring.h
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __KSTRING_H__
|
||||||
|
#define __KSTRING_H__
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "lightmap/common.h"
|
||||||
|
#include "array.h"
|
||||||
|
|
||||||
|
class kexStr;
|
||||||
|
|
||||||
|
typedef kexArray<kexStr> kexStrList;
|
||||||
|
|
||||||
|
class kexStr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexStr(void);
|
||||||
|
kexStr(const char *string);
|
||||||
|
kexStr(const char *string, const int length);
|
||||||
|
kexStr(const kexStr &string);
|
||||||
|
~kexStr(void);
|
||||||
|
|
||||||
|
void CheckSize(int size, bool bKeepString);
|
||||||
|
int IndexOf(const char *pattern) const;
|
||||||
|
int IndexOf(const kexStr &pattern) const;
|
||||||
|
kexStr &Concat(const char *string);
|
||||||
|
kexStr &Concat(const char *string, int len);
|
||||||
|
kexStr &Concat(const char c);
|
||||||
|
kexStr &NormalizeSlashes(void);
|
||||||
|
kexStr &StripPath(void);
|
||||||
|
kexStr &StripExtension(void);
|
||||||
|
kexStr &StripFile(void);
|
||||||
|
kexStr &Copy(const kexStr &src, int len);
|
||||||
|
kexStr &Copy(const kexStr &src);
|
||||||
|
kexStr &ToUpper(void);
|
||||||
|
kexStr &ToLower(void);
|
||||||
|
int Hash(void);
|
||||||
|
kexStr Substr(int start, int len) const;
|
||||||
|
void Split(kexStrList &list, const char seperator);
|
||||||
|
int Atoi(void);
|
||||||
|
float Atof(void);
|
||||||
|
void WriteToFile(const char *file);
|
||||||
|
|
||||||
|
int Length(void) const { return length; }
|
||||||
|
const char *c_str(void) const { return charPtr; }
|
||||||
|
|
||||||
|
kexStr &operator=(const kexStr &str);
|
||||||
|
kexStr &operator=(const char *str);
|
||||||
|
kexStr &operator=(const bool b);
|
||||||
|
kexStr operator+(const kexStr &str);
|
||||||
|
kexStr operator+(const char *str);
|
||||||
|
kexStr operator+(const bool b);
|
||||||
|
kexStr operator+(const int i);
|
||||||
|
kexStr operator+(const float f);
|
||||||
|
kexStr &operator+=(const kexStr &str);
|
||||||
|
kexStr &operator+=(const char *str);
|
||||||
|
kexStr &operator+=(const char c);
|
||||||
|
kexStr &operator+=(const bool b);
|
||||||
|
const char operator[](int index) const;
|
||||||
|
|
||||||
|
friend bool operator==(const kexStr &a, const kexStr &b);
|
||||||
|
friend bool operator==(const char *a, const kexStr &b);
|
||||||
|
friend bool operator==(const kexStr &a, const char *b);
|
||||||
|
|
||||||
|
operator const char *(void) const { return c_str(); }
|
||||||
|
operator const char *(void) { return c_str(); }
|
||||||
|
|
||||||
|
static bool CompareCase(const char *s1, const char *s2);
|
||||||
|
static bool CompareCase(const kexStr &a, const kexStr &b);
|
||||||
|
static bool Compare(const char *s1, const char *s2);
|
||||||
|
static bool Compare(const kexStr &a, const kexStr &b);
|
||||||
|
static int IndexOf(const char *string, const char *pattern);
|
||||||
|
static int Hash(const char *s);
|
||||||
|
static char *Format(const char *str, ...);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Resize(int size, bool bKeepString);
|
||||||
|
void CopyNew(const char *string, int len);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Init(void);
|
||||||
|
|
||||||
|
static const int STRING_DEFAULT_SIZE = 32;
|
||||||
|
|
||||||
|
char *charPtr;
|
||||||
|
char defaultBuffer[STRING_DEFAULT_SIZE];
|
||||||
|
int length;
|
||||||
|
int bufferLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
d_inline bool operator==(const kexStr &a, const kexStr &b)
|
||||||
|
{
|
||||||
|
return (!strcmp(a.charPtr, b.charPtr));
|
||||||
|
}
|
||||||
|
|
||||||
|
d_inline bool operator==(const char *a, const kexStr &b)
|
||||||
|
{
|
||||||
|
return (!strcmp(a, b.charPtr));
|
||||||
|
}
|
||||||
|
|
||||||
|
d_inline bool operator==(const kexStr &a, const char *b)
|
||||||
|
{
|
||||||
|
return (!strcmp(a.charPtr, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
405
src/lightmap/kexlib/math/angle.cpp
Normal file
405
src/lightmap/kexlib/math/angle.cpp
Normal file
|
@ -0,0 +1,405 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Angle operations
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
#define FULLCIRCLE (M_PI * 2)
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::kexAngle
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle::kexAngle(void)
|
||||||
|
{
|
||||||
|
this->yaw = 0;
|
||||||
|
this->pitch = 0;
|
||||||
|
this->roll = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::kexAngle
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle::kexAngle(const float yaw, const float pitch, const float roll)
|
||||||
|
{
|
||||||
|
this->yaw = yaw;
|
||||||
|
this->pitch = pitch;
|
||||||
|
this->roll = roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::kexAngle
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle::kexAngle(const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
this->yaw = vector.x;
|
||||||
|
this->pitch = vector.y;
|
||||||
|
this->roll = vector.z;
|
||||||
|
|
||||||
|
Clamp180();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::kexAngle
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle::kexAngle(const kexAngle &an)
|
||||||
|
{
|
||||||
|
this->yaw = an.yaw;
|
||||||
|
this->pitch = an.pitch;
|
||||||
|
this->roll = an.roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::Clamp180
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::Clamp180(void)
|
||||||
|
{
|
||||||
|
#define CLAMP180(x) \
|
||||||
|
if(x < -M_PI) for(; x < -M_PI; x = x + FULLCIRCLE); \
|
||||||
|
if(x > M_PI) for(; x > M_PI; x = x - FULLCIRCLE)
|
||||||
|
CLAMP180(yaw);
|
||||||
|
CLAMP180(pitch);
|
||||||
|
CLAMP180(roll);
|
||||||
|
#undef CLAMP180
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::Clamp180Invert
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::Clamp180Invert(void)
|
||||||
|
{
|
||||||
|
#define CLAMP180(x) \
|
||||||
|
for(; x < -M_PI; x = x + FULLCIRCLE); \
|
||||||
|
for(; x > M_PI; x = x - FULLCIRCLE)
|
||||||
|
CLAMP180(yaw);
|
||||||
|
CLAMP180(pitch);
|
||||||
|
CLAMP180(roll);
|
||||||
|
#undef CLAMP180
|
||||||
|
|
||||||
|
yaw = -yaw;
|
||||||
|
pitch = -pitch;
|
||||||
|
roll = -roll;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::Clamp180InvertSum
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::Clamp180InvertSum(const kexAngle &angle)
|
||||||
|
{
|
||||||
|
kexAngle an = angle;
|
||||||
|
|
||||||
|
an.Clamp180Invert();
|
||||||
|
|
||||||
|
an.yaw += this->yaw;
|
||||||
|
an.pitch += this->pitch;
|
||||||
|
an.roll += this->roll;
|
||||||
|
|
||||||
|
an.Clamp180Invert();
|
||||||
|
|
||||||
|
this->yaw = an.yaw;
|
||||||
|
this->pitch = an.pitch;
|
||||||
|
this->roll = an.roll;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::Round
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::Round(void)
|
||||||
|
{
|
||||||
|
#define ROUND(x) \
|
||||||
|
x = DEG2RAD((360.0f / 65536.0f) * \
|
||||||
|
((int)(RAD2DEG(x) * (65536.0f / 360.0f)) & 65535))
|
||||||
|
yaw = ROUND(yaw);
|
||||||
|
pitch = ROUND(pitch);
|
||||||
|
roll = ROUND(roll);
|
||||||
|
#undef ROUND
|
||||||
|
|
||||||
|
return Clamp180();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::Diff
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle kexAngle::Diff(kexAngle &angle)
|
||||||
|
{
|
||||||
|
float an;
|
||||||
|
kexAngle out;
|
||||||
|
|
||||||
|
Clamp180();
|
||||||
|
angle.Clamp180();
|
||||||
|
|
||||||
|
#define DIFF(x) \
|
||||||
|
if(x <= angle.x) { \
|
||||||
|
an = angle.x + FULLCIRCLE; \
|
||||||
|
if(x - angle.x > an - x) { \
|
||||||
|
out.x = x - an; \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
out.x = x - angle.x; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
an = angle.x - FULLCIRCLE; \
|
||||||
|
if(angle.x - x <= x - an) { \
|
||||||
|
out.x = x - angle.x; \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
out.x = x - an; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
DIFF(yaw);
|
||||||
|
DIFF(pitch);
|
||||||
|
DIFF(roll);
|
||||||
|
#undef DIFF
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::ToAxis
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexAngle::ToAxis(kexVec3 *forward, kexVec3 *up, kexVec3 *right)
|
||||||
|
{
|
||||||
|
float sy = kexMath::Sin(yaw);
|
||||||
|
float cy = kexMath::Cos(yaw);
|
||||||
|
float sp = kexMath::Sin(pitch);
|
||||||
|
float cp = kexMath::Cos(pitch);
|
||||||
|
float sr = kexMath::Sin(roll);
|
||||||
|
float cr = kexMath::Cos(roll);
|
||||||
|
|
||||||
|
if(forward)
|
||||||
|
{
|
||||||
|
forward->x = sy * cp;
|
||||||
|
forward->y = sp;
|
||||||
|
forward->z = cy * cp;
|
||||||
|
}
|
||||||
|
if(right)
|
||||||
|
{
|
||||||
|
right->x = sr * sp * sy + cr * cy;
|
||||||
|
right->y = sr * cp;
|
||||||
|
right->z = sr * sp * cy + cr * -sy;
|
||||||
|
}
|
||||||
|
if(up)
|
||||||
|
{
|
||||||
|
up->x = cr * sp * sy + -sr * cy;
|
||||||
|
up->y = cr * cp;
|
||||||
|
up->z = cr * sp * cy + -sr * -sy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::ToForwardAxis
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 kexAngle::ToForwardAxis(void)
|
||||||
|
{
|
||||||
|
kexVec3 vec;
|
||||||
|
|
||||||
|
ToAxis(&vec, NULL, NULL);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::ToUpAxis
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 kexAngle::ToUpAxis(void)
|
||||||
|
{
|
||||||
|
kexVec3 vec;
|
||||||
|
|
||||||
|
ToAxis(NULL, &vec, NULL);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::ToRightAxis
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 kexAngle::ToRightAxis(void)
|
||||||
|
{
|
||||||
|
kexVec3 vec;
|
||||||
|
|
||||||
|
ToAxis(NULL, NULL, &vec);
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::ToVec3
|
||||||
|
//
|
||||||
|
|
||||||
|
const kexVec3 &kexAngle::ToVec3(void) const
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<const kexVec3*>(&yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::ToVec3
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 &kexAngle::ToVec3(void)
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<kexVec3*>(&yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::ToQuat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexAngle::ToQuat(void)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(kexQuat(pitch, kexVec3::vecRight) *
|
||||||
|
(kexQuat(yaw, kexVec3::vecUp) *
|
||||||
|
kexQuat(roll, kexVec3::vecForward)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle kexAngle::operator+(const kexAngle &angle)
|
||||||
|
{
|
||||||
|
return kexAngle(yaw + angle.yaw, pitch + angle.pitch, roll + angle.roll);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator-
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle kexAngle::operator-(const kexAngle &angle)
|
||||||
|
{
|
||||||
|
return kexAngle(yaw - angle.yaw, pitch - angle.pitch, roll - angle.roll);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator-
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle kexAngle::operator-(void)
|
||||||
|
{
|
||||||
|
return kexAngle(-yaw, -pitch, -roll);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator+=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::operator+=(const kexAngle &angle)
|
||||||
|
{
|
||||||
|
yaw += angle.yaw;
|
||||||
|
pitch += angle.pitch;
|
||||||
|
roll += angle.roll;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator-=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::operator-=(const kexAngle &angle)
|
||||||
|
{
|
||||||
|
yaw -= angle.yaw;
|
||||||
|
pitch -= angle.pitch;
|
||||||
|
roll -= angle.roll;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::operator=(const kexAngle &angle)
|
||||||
|
{
|
||||||
|
yaw = angle.yaw;
|
||||||
|
pitch = angle.pitch;
|
||||||
|
roll = angle.roll;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::operator=(const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
yaw = vector.x;
|
||||||
|
pitch = vector.y;
|
||||||
|
roll = vector.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexAngle &kexAngle::operator=(const float *vecs)
|
||||||
|
{
|
||||||
|
yaw = vecs[0];
|
||||||
|
pitch = vecs[1];
|
||||||
|
roll = vecs[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator[]
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexAngle::operator[](int index) const
|
||||||
|
{
|
||||||
|
assert(index >= 0 && index < 3);
|
||||||
|
return (&yaw)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexAngle::operator[]
|
||||||
|
//
|
||||||
|
|
||||||
|
float &kexAngle::operator[](int index)
|
||||||
|
{
|
||||||
|
assert(index >= 0 && index < 3);
|
||||||
|
return (&yaw)[index];
|
||||||
|
}
|
520
src/lightmap/kexlib/math/bounds.cpp
Normal file
520
src/lightmap/kexlib/math/bounds.cpp
Normal file
|
@ -0,0 +1,520 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Bounding box operations
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::kexBBox
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox::kexBBox(void)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::kexBBox
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox::kexBBox(const kexVec3 &vMin, const kexVec3 &vMax)
|
||||||
|
{
|
||||||
|
this->min = vMin;
|
||||||
|
this->max = vMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::Clear
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBBox::Clear(void)
|
||||||
|
{
|
||||||
|
min.Set(M_INFINITY, M_INFINITY, M_INFINITY);
|
||||||
|
max.Set(-M_INFINITY, -M_INFINITY, -M_INFINITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::AddPoint
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBBox::AddPoint(const kexVec3 &vec)
|
||||||
|
{
|
||||||
|
float lowx = min.x;
|
||||||
|
float lowy = min.y;
|
||||||
|
float lowz = min.z;
|
||||||
|
float hix = max.x;
|
||||||
|
float hiy = max.y;
|
||||||
|
float hiz = max.z;
|
||||||
|
|
||||||
|
if(vec.x < lowx) { lowx = vec.x; }
|
||||||
|
if(vec.y < lowy) { lowy = vec.y; }
|
||||||
|
if(vec.z < lowz) { lowz = vec.z; }
|
||||||
|
if(vec.x > hix) { hix = vec.x; }
|
||||||
|
if(vec.y > hiy) { hiy = vec.y; }
|
||||||
|
if(vec.z > hiz) { hiz = vec.z; }
|
||||||
|
|
||||||
|
min.Set(lowx, lowy, lowz);
|
||||||
|
max.Set(hix, hiy, hiz);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::Center
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 kexBBox::Center(void) const
|
||||||
|
{
|
||||||
|
return kexVec3(
|
||||||
|
(max.x + min.x) * 0.5f,
|
||||||
|
(max.y + min.y) * 0.5f,
|
||||||
|
(max.z + min.z) * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::Radius
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexBBox::Radius(void) const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float r = 0;
|
||||||
|
float r1;
|
||||||
|
float r2;
|
||||||
|
|
||||||
|
for(i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
r1 = kexMath::Fabs(min[i]);
|
||||||
|
r2 = kexMath::Fabs(max[i]);
|
||||||
|
|
||||||
|
if(r1 > r2)
|
||||||
|
{
|
||||||
|
r += r1 * r1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r += r2 * r2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kexMath::Sqrt(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::PointInside
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexBBox::PointInside(const kexVec3 &vec) const
|
||||||
|
{
|
||||||
|
return !(vec[0] < min[0] || vec[1] < min[1] || vec[2] < min[2] ||
|
||||||
|
vec[0] > max[0] || vec[1] > max[1] || vec[2] > max[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::IntersectingBox
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexBBox::IntersectingBox(const kexBBox &box) const
|
||||||
|
{
|
||||||
|
return !(box.max[0] < min[0] || box.max[1] < min[1] || box.max[2] < min[2] ||
|
||||||
|
box.min[0] > max[0] || box.min[1] > max[1] || box.min[2] > max[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::IntersectingBox2D
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexBBox::IntersectingBox2D(const kexBBox &box) const
|
||||||
|
{
|
||||||
|
return !(box.max[0] < min[0] || box.max[2] < min[2] ||
|
||||||
|
box.min[0] > max[0] || box.min[2] > max[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::DistanceToPlane
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexBBox::DistanceToPlane(kexPlane &plane)
|
||||||
|
{
|
||||||
|
kexVec3 c;
|
||||||
|
float distStart;
|
||||||
|
float distEnd;
|
||||||
|
float dist = 0;
|
||||||
|
|
||||||
|
c = Center();
|
||||||
|
|
||||||
|
distStart = plane.Distance(c);
|
||||||
|
distEnd = kexMath::Fabs((max.x - c.x) * plane.a) +
|
||||||
|
kexMath::Fabs((max.y - c.y) * plane.b) +
|
||||||
|
kexMath::Fabs((max.z - c.z) * plane.c);
|
||||||
|
|
||||||
|
dist = distStart - distEnd;
|
||||||
|
|
||||||
|
if(dist > 0)
|
||||||
|
{
|
||||||
|
// in front
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
dist = distStart + distEnd;
|
||||||
|
|
||||||
|
if(dist < 0)
|
||||||
|
{
|
||||||
|
// behind
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox kexBBox::operator+(const float radius) const
|
||||||
|
{
|
||||||
|
kexVec3 vmin = min;
|
||||||
|
kexVec3 vmax = max;
|
||||||
|
|
||||||
|
vmin.x -= radius;
|
||||||
|
vmin.y -= radius;
|
||||||
|
vmin.z -= radius;
|
||||||
|
|
||||||
|
vmax.x += radius;
|
||||||
|
vmax.y += radius;
|
||||||
|
vmax.z += radius;
|
||||||
|
|
||||||
|
return kexBBox(vmin, vmax);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator+=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox &kexBBox::operator+=(const float radius)
|
||||||
|
{
|
||||||
|
min.x -= radius;
|
||||||
|
min.y -= radius;
|
||||||
|
min.z -= radius;
|
||||||
|
max.x += radius;
|
||||||
|
max.y += radius;
|
||||||
|
max.z += radius;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox kexBBox::operator+(const kexVec3 &vec) const
|
||||||
|
{
|
||||||
|
kexVec3 vmin = min;
|
||||||
|
kexVec3 vmax = max;
|
||||||
|
|
||||||
|
vmin.x += vec.x;
|
||||||
|
vmin.y += vec.y;
|
||||||
|
vmin.z += vec.z;
|
||||||
|
|
||||||
|
vmax.x += vec.x;
|
||||||
|
vmax.y += vec.y;
|
||||||
|
vmax.z += vec.z;
|
||||||
|
|
||||||
|
return kexBBox(vmin, vmax);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator-
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox kexBBox::operator-(const float radius) const
|
||||||
|
{
|
||||||
|
kexVec3 vmin = min;
|
||||||
|
kexVec3 vmax = max;
|
||||||
|
|
||||||
|
vmin.x += radius;
|
||||||
|
vmin.y += radius;
|
||||||
|
vmin.z += radius;
|
||||||
|
|
||||||
|
vmax.x -= radius;
|
||||||
|
vmax.y -= radius;
|
||||||
|
vmax.z -= radius;
|
||||||
|
|
||||||
|
return kexBBox(vmin, vmax);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator-
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox kexBBox::operator-(const kexVec3 &vec) const
|
||||||
|
{
|
||||||
|
kexVec3 vmin = min;
|
||||||
|
kexVec3 vmax = max;
|
||||||
|
|
||||||
|
vmin.x -= vec.x;
|
||||||
|
vmin.y -= vec.y;
|
||||||
|
vmin.z -= vec.z;
|
||||||
|
|
||||||
|
vmax.x -= vec.x;
|
||||||
|
vmax.y -= vec.y;
|
||||||
|
vmax.z -= vec.z;
|
||||||
|
|
||||||
|
return kexBBox(vmin, vmax);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator-=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox &kexBBox::operator-=(const float radius)
|
||||||
|
{
|
||||||
|
min.x += radius;
|
||||||
|
min.y += radius;
|
||||||
|
min.z += radius;
|
||||||
|
max.x -= radius;
|
||||||
|
max.y -= radius;
|
||||||
|
max.z -= radius;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator*
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox kexBBox::operator*(const kexMatrix &matrix) const
|
||||||
|
{
|
||||||
|
kexVec3 c = Center();
|
||||||
|
kexVec3 ct = c * matrix;
|
||||||
|
kexBBox box(ct, ct);
|
||||||
|
|
||||||
|
kexMatrix mtx(matrix);
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
mtx.vectors[i].x = kexMath::Fabs(mtx.vectors[i].x);
|
||||||
|
mtx.vectors[i].y = kexMath::Fabs(mtx.vectors[i].y);
|
||||||
|
mtx.vectors[i].z = kexMath::Fabs(mtx.vectors[i].z);
|
||||||
|
}
|
||||||
|
|
||||||
|
kexVec3 ht = (max - c) * mtx;
|
||||||
|
box.min -= ht;
|
||||||
|
box.max += ht;
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator*=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox &kexBBox::operator*=(const kexMatrix &matrix)
|
||||||
|
{
|
||||||
|
kexVec3 c = Center();
|
||||||
|
kexVec3 ct = c * matrix;
|
||||||
|
|
||||||
|
kexMatrix mtx(matrix);
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
mtx.vectors[i].x = kexMath::Fabs(mtx.vectors[i].x);
|
||||||
|
mtx.vectors[i].y = kexMath::Fabs(mtx.vectors[i].y);
|
||||||
|
mtx.vectors[i].z = kexMath::Fabs(mtx.vectors[i].z);
|
||||||
|
}
|
||||||
|
|
||||||
|
kexVec3 ht = (max - c) * mtx;
|
||||||
|
|
||||||
|
min = (ct - ht);
|
||||||
|
max = (ct + ht);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator*
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox kexBBox::operator*(const kexVec3 &vec) const
|
||||||
|
{
|
||||||
|
kexBBox box = *this;
|
||||||
|
|
||||||
|
if(vec.x < 0) { box.min.x += (vec.x-1); }
|
||||||
|
else { box.max.x += (vec.x+1); }
|
||||||
|
if(vec.y < 0) { box.min.y += (vec.y-1); }
|
||||||
|
else { box.max.y += (vec.y+1); }
|
||||||
|
if(vec.z < 0) { box.min.z += (vec.z-1); }
|
||||||
|
else { box.max.z += (vec.z+1); }
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator*=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox &kexBBox::operator*=(const kexVec3 &vec)
|
||||||
|
{
|
||||||
|
if(vec.x < 0) { min.x += (vec.x-1); }
|
||||||
|
else { max.x += (vec.x+1); }
|
||||||
|
if(vec.y < 0) { min.y += (vec.y-1); }
|
||||||
|
else { max.y += (vec.y+1); }
|
||||||
|
if(vec.z < 0) { min.z += (vec.z-1); }
|
||||||
|
else { max.z += (vec.z+1); }
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexBBox &kexBBox::operator=(const kexBBox &bbox)
|
||||||
|
{
|
||||||
|
min = bbox.min;
|
||||||
|
max = bbox.max;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator[]
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 kexBBox::operator[](int index) const
|
||||||
|
{
|
||||||
|
assert(index >= 0 && index < 2);
|
||||||
|
return index == 0 ? min : max;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::operator[]
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 &kexBBox::operator[](int index)
|
||||||
|
{
|
||||||
|
assert(index >= 0 && index < 2);
|
||||||
|
return index == 0 ? min : max;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox:LineIntersect
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexBBox::LineIntersect(const kexVec3 &start, const kexVec3 &end)
|
||||||
|
{
|
||||||
|
float ld[3];
|
||||||
|
kexVec3 center = Center();
|
||||||
|
kexVec3 extents = max - center;
|
||||||
|
kexVec3 lineDir = (end - start) * 0.5f;
|
||||||
|
kexVec3 lineCenter = lineDir + start;
|
||||||
|
kexVec3 dir = lineCenter - center;
|
||||||
|
|
||||||
|
ld[0] = kexMath::Fabs(lineDir.x);
|
||||||
|
if(kexMath::Fabs(dir.x) > extents.x + ld[0]) { return false; }
|
||||||
|
ld[1] = kexMath::Fabs(lineDir.y);
|
||||||
|
if(kexMath::Fabs(dir.y) > extents.y + ld[1]) { return false; }
|
||||||
|
ld[2] = kexMath::Fabs(lineDir.z);
|
||||||
|
if(kexMath::Fabs(dir.z) > extents.z + ld[2]) { return false; }
|
||||||
|
|
||||||
|
kexVec3 cross = lineDir.Cross(dir);
|
||||||
|
|
||||||
|
if(kexMath::Fabs(cross.x) > extents.y * ld[2] + extents.z * ld[1]) { return false; }
|
||||||
|
if(kexMath::Fabs(cross.y) > extents.x * ld[2] + extents.z * ld[0]) { return false; }
|
||||||
|
if(kexMath::Fabs(cross.z) > extents.x * ld[1] + extents.y * ld[0]) { return false; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::ToPoints
|
||||||
|
//
|
||||||
|
// Assumes points is an array of 24
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBBox::ToPoints(float *points) const
|
||||||
|
{
|
||||||
|
points[0 * 3 + 0] = max[0];
|
||||||
|
points[0 * 3 + 1] = min[1];
|
||||||
|
points[0 * 3 + 2] = min[2];
|
||||||
|
points[1 * 3 + 0] = max[0];
|
||||||
|
points[1 * 3 + 1] = min[1];
|
||||||
|
points[1 * 3 + 2] = max[2];
|
||||||
|
points[2 * 3 + 0] = min[0];
|
||||||
|
points[2 * 3 + 1] = min[1];
|
||||||
|
points[2 * 3 + 2] = max[2];
|
||||||
|
points[3 * 3 + 0] = min[0];
|
||||||
|
points[3 * 3 + 1] = min[1];
|
||||||
|
points[3 * 3 + 2] = min[2];
|
||||||
|
points[4 * 3 + 0] = max[0];
|
||||||
|
points[4 * 3 + 1] = max[1];
|
||||||
|
points[4 * 3 + 2] = min[2];
|
||||||
|
points[5 * 3 + 0] = max[0];
|
||||||
|
points[5 * 3 + 1] = max[1];
|
||||||
|
points[5 * 3 + 2] = max[2];
|
||||||
|
points[6 * 3 + 0] = min[0];
|
||||||
|
points[6 * 3 + 1] = max[1];
|
||||||
|
points[6 * 3 + 2] = max[2];
|
||||||
|
points[7 * 3 + 0] = min[0];
|
||||||
|
points[7 * 3 + 1] = max[1];
|
||||||
|
points[7 * 3 + 2] = min[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexBBox::ToVectors
|
||||||
|
//
|
||||||
|
// Assumes vectors is an array of 8
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexBBox::ToVectors(kexVec3 *vectors) const
|
||||||
|
{
|
||||||
|
vectors[0][0] = max[0];
|
||||||
|
vectors[0][1] = min[1];
|
||||||
|
vectors[0][2] = min[2];
|
||||||
|
vectors[1][0] = max[0];
|
||||||
|
vectors[1][1] = min[1];
|
||||||
|
vectors[1][2] = max[2];
|
||||||
|
vectors[2][0] = min[0];
|
||||||
|
vectors[2][1] = min[1];
|
||||||
|
vectors[2][2] = max[2];
|
||||||
|
vectors[3][0] = min[0];
|
||||||
|
vectors[3][1] = min[1];
|
||||||
|
vectors[3][2] = min[2];
|
||||||
|
vectors[4][0] = max[0];
|
||||||
|
vectors[4][1] = max[1];
|
||||||
|
vectors[4][2] = min[2];
|
||||||
|
vectors[5][0] = max[0];
|
||||||
|
vectors[5][1] = max[1];
|
||||||
|
vectors[5][2] = max[2];
|
||||||
|
vectors[6][0] = min[0];
|
||||||
|
vectors[6][1] = max[1];
|
||||||
|
vectors[6][2] = max[2];
|
||||||
|
vectors[7][0] = min[0];
|
||||||
|
vectors[7][1] = max[1];
|
||||||
|
vectors[7][2] = min[2];
|
||||||
|
}
|
99
src/lightmap/kexlib/math/mathlib.cpp
Normal file
99
src/lightmap/kexlib/math/mathlib.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Math functions
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "lightmap/common.h"
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::RoundPowerOfTwo
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexMath::RoundPowerOfTwo(int x)
|
||||||
|
{
|
||||||
|
int mask = 1;
|
||||||
|
|
||||||
|
while(mask < 0x40000000)
|
||||||
|
{
|
||||||
|
if(x == mask || (x & (mask-1)) == x)
|
||||||
|
{
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::CubicCurve
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexMath::CubicCurve(const kexVec3 &start, const kexVec3 &end, const float time,
|
||||||
|
const kexVec3 &point, kexVec3 *vec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float xyz[3];
|
||||||
|
|
||||||
|
for(i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
xyz[i] = kexMath::Pow(1-time, 2) * start[i] +
|
||||||
|
(2 * (1-time)) * time * point[i] + kexMath::Pow(time, 2) * end[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
vec->x = xyz[0];
|
||||||
|
vec->y = xyz[1];
|
||||||
|
vec->z = xyz[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::QuadraticCurve
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexMath::QuadraticCurve(const kexVec3 &start, const kexVec3 &end, const float time,
|
||||||
|
const kexVec3 &pt1, const kexVec3 &pt2, kexVec3 *vec)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float xyz[3];
|
||||||
|
|
||||||
|
for(i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
xyz[i] = kexMath::Pow(1-time, 3) * start[i] + (3 * kexMath::Pow(1-time, 2)) *
|
||||||
|
time * pt1[i] + (3 * (1-time)) * kexMath::Pow(time, 2) * pt2[i] +
|
||||||
|
kexMath::Pow(time, 3) * end[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
vec->x = xyz[0];
|
||||||
|
vec->y = xyz[1];
|
||||||
|
vec->z = xyz[2];
|
||||||
|
}
|
||||||
|
|
661
src/lightmap/kexlib/math/mathlib.h
Normal file
661
src/lightmap/kexlib/math/mathlib.h
Normal file
|
@ -0,0 +1,661 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __MATHLIB_H__
|
||||||
|
#define __MATHLIB_H__
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "lightmap/common.h"
|
||||||
|
|
||||||
|
#ifdef M_PI
|
||||||
|
#undef M_PI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define M_PI 3.1415926535897932384626433832795f
|
||||||
|
#define M_RAD (M_PI / 180.0f)
|
||||||
|
#define M_DEG (180.0f / M_PI)
|
||||||
|
#define M_INFINITY 1e30f
|
||||||
|
|
||||||
|
#define DEG2RAD(x) ((x) * M_RAD)
|
||||||
|
#define RAD2DEG(x) ((x) * M_DEG)
|
||||||
|
|
||||||
|
#define FLOATSIGNBIT(f) (reinterpret_cast<const unsigned int&>(f) >> 31)
|
||||||
|
|
||||||
|
class kexVec2;
|
||||||
|
class kexVec3;
|
||||||
|
class kexVec4;
|
||||||
|
class kexMatrix;
|
||||||
|
class kexAngle;
|
||||||
|
class kexStr;
|
||||||
|
|
||||||
|
class kexMath
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static float Sin(float x);
|
||||||
|
static float Cos(float x);
|
||||||
|
static float Tan(float x);
|
||||||
|
static float ATan2(float x, float y);
|
||||||
|
static float ACos(float x);
|
||||||
|
static float Sqrt(float x);
|
||||||
|
static float Pow(float x, float y);
|
||||||
|
static float Log(float x);
|
||||||
|
static float Floor(float x);
|
||||||
|
static float Ceil(float x);
|
||||||
|
static float Deg2Rad(float x);
|
||||||
|
static float Rad2Deg(float x);
|
||||||
|
|
||||||
|
static int Abs(int x);
|
||||||
|
static float Fabs(float x);
|
||||||
|
static int RoundPowerOfTwo(int x);
|
||||||
|
static float InvSqrt(float x);
|
||||||
|
static void Clamp(float &f, const float min, const float max);
|
||||||
|
static void Clamp(int &i, const int min, const int max);
|
||||||
|
static void Clamp(byte &b, const byte min, const byte max);
|
||||||
|
static void Clamp(kexVec3 &f, const float min, const float max);
|
||||||
|
|
||||||
|
static void CubicCurve(const kexVec3 &start, const kexVec3 &end, const float time,
|
||||||
|
const kexVec3 &point, kexVec3 *vec);
|
||||||
|
static void QuadraticCurve(const kexVec3 &start, const kexVec3 &end, const float time,
|
||||||
|
const kexVec3 &pt1, const kexVec3 &pt2, kexVec3 *vec);
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexRand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void SetSeed(const int randSeed);
|
||||||
|
static int SysRand(void);
|
||||||
|
static int Int(void);
|
||||||
|
static int Max(const int max);
|
||||||
|
static float Float(void);
|
||||||
|
static float CFloat(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int seed;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexQuat
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexQuat(void);
|
||||||
|
|
||||||
|
explicit kexQuat(const float angle, const float x, const float y, const float z);
|
||||||
|
explicit kexQuat(const float angle, kexVec3 &vector);
|
||||||
|
explicit kexQuat(const float angle, const kexVec3 &vector);
|
||||||
|
|
||||||
|
void Set(const float x, const float y, const float z, const float w);
|
||||||
|
void Clear(void);
|
||||||
|
float Dot(const kexQuat &quat) const;
|
||||||
|
float UnitSq(void) const;
|
||||||
|
float Unit(void) const;
|
||||||
|
kexQuat &Normalize(void);
|
||||||
|
kexQuat Slerp(const kexQuat &quat, float movement) const;
|
||||||
|
kexQuat RotateFrom(const kexVec3 &location, const kexVec3 &target, float maxAngle);
|
||||||
|
kexQuat Inverse(void) const;
|
||||||
|
|
||||||
|
kexQuat operator+(const kexQuat &quat);
|
||||||
|
kexQuat &operator+=(const kexQuat &quat);
|
||||||
|
kexQuat operator-(const kexQuat &quat);
|
||||||
|
kexQuat &operator-=(const kexQuat &quat);
|
||||||
|
kexQuat operator*(const kexQuat &quat);
|
||||||
|
kexQuat operator*(const float val) const;
|
||||||
|
kexQuat &operator*=(const kexQuat &quat);
|
||||||
|
kexQuat &operator*=(const float val);
|
||||||
|
kexQuat &operator=(const kexQuat &quat);
|
||||||
|
kexQuat &operator=(const kexVec4 &vec);
|
||||||
|
kexQuat &operator=(const float *vecs);
|
||||||
|
kexVec3 operator|(const kexVec3 &vector);
|
||||||
|
|
||||||
|
const kexVec3 &ToVec3(void) const;
|
||||||
|
kexVec3 &ToVec3(void);
|
||||||
|
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexVec2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexVec2(void);
|
||||||
|
explicit kexVec2(const float x, const float y);
|
||||||
|
|
||||||
|
void Set(const float x, const float y);
|
||||||
|
void Clear(void);
|
||||||
|
float Dot(const kexVec2 &vec) const;
|
||||||
|
static float Dot(const kexVec2 &vec1, const kexVec2 &vec2);
|
||||||
|
float CrossScalar(const kexVec2 &vec) const;
|
||||||
|
kexVec2 Cross(const kexVec2 &vec) const;
|
||||||
|
kexVec2 &Cross(const kexVec2 &vec1, const kexVec2 &vec2);
|
||||||
|
float Dot(const kexVec3 &vec) const;
|
||||||
|
static float Dot(const kexVec3 &vec1, const kexVec3 &vec2);
|
||||||
|
kexVec2 Cross(const kexVec3 &vec) const;
|
||||||
|
kexVec2 &Cross(const kexVec3 &vec1, const kexVec3 &vec2);
|
||||||
|
float UnitSq(void) const;
|
||||||
|
float Unit(void) const;
|
||||||
|
float DistanceSq(const kexVec2 &vec) const;
|
||||||
|
float Distance(const kexVec2 &vec) const;
|
||||||
|
kexVec2 &Normalize(void);
|
||||||
|
kexVec2 Lerp(const kexVec2 &next, float movement) const;
|
||||||
|
kexVec2 &Lerp(const kexVec2 &next, const float movement);
|
||||||
|
kexVec2 &Lerp(const kexVec2 &start, const kexVec2 &next, float movement);
|
||||||
|
kexStr ToString(void) const;
|
||||||
|
float ToYaw(void) const;
|
||||||
|
float *ToFloatPtr(void);
|
||||||
|
kexVec3 ToVec3(void);
|
||||||
|
|
||||||
|
kexVec2 operator+(const kexVec2 &vec);
|
||||||
|
kexVec2 operator+(const kexVec2 &vec) const;
|
||||||
|
kexVec2 operator+(kexVec2 &vec);
|
||||||
|
kexVec2 operator-(void) const;
|
||||||
|
kexVec2 operator-(const kexVec2 &vec) const;
|
||||||
|
kexVec2 operator*(const kexVec2 &vec);
|
||||||
|
kexVec2 operator*(const float val);
|
||||||
|
kexVec2 operator*(const float val) const;
|
||||||
|
kexVec2 operator/(const kexVec2 &vec);
|
||||||
|
kexVec2 operator/(const float val);
|
||||||
|
kexVec2 &operator=(kexVec3 &vec);
|
||||||
|
kexVec2 &operator=(const kexVec2 &vec);
|
||||||
|
kexVec2 &operator=(const kexVec3 &vec);
|
||||||
|
kexVec2 &operator=(const float *vecs);
|
||||||
|
kexVec2 &operator+=(const kexVec2 &vec);
|
||||||
|
kexVec2 &operator-=(const kexVec2 &vec);
|
||||||
|
kexVec2 &operator*=(const kexVec2 &vec);
|
||||||
|
kexVec2 &operator*=(const float val);
|
||||||
|
kexVec2 &operator/=(const kexVec2 &vec);
|
||||||
|
kexVec2 &operator/=(const float val);
|
||||||
|
kexVec2 operator*(const kexMatrix &mtx);
|
||||||
|
kexVec2 operator*(const kexMatrix &mtx) const;
|
||||||
|
kexVec2 &operator*=(const kexMatrix &mtx);
|
||||||
|
float operator[](int index) const;
|
||||||
|
float &operator[](int index);
|
||||||
|
bool operator==(const kexVec2 &vec);
|
||||||
|
|
||||||
|
operator float *(void) { return reinterpret_cast<float*>(&x); }
|
||||||
|
|
||||||
|
static kexVec2 vecZero;
|
||||||
|
static const kexVec2 vecRight;
|
||||||
|
static const kexVec2 vecUp;
|
||||||
|
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexVec3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexVec3(void);
|
||||||
|
explicit kexVec3(const float x, const float y, const float z);
|
||||||
|
|
||||||
|
void Set(const float x, const float y, const float z);
|
||||||
|
void Clear(void);
|
||||||
|
float Dot(const kexVec3 &vec) const;
|
||||||
|
static float Dot(const kexVec3 &vec1, const kexVec3 &vec2);
|
||||||
|
kexVec3 Cross(const kexVec3 &vec) const;
|
||||||
|
kexVec3 &Cross(const kexVec3 &vec1, const kexVec3 &vec2);
|
||||||
|
float UnitSq(void) const;
|
||||||
|
float Unit(void) const;
|
||||||
|
float DistanceSq(const kexVec3 &vec) const;
|
||||||
|
float Distance(const kexVec3 &vec) const;
|
||||||
|
kexVec3 &Normalize(void);
|
||||||
|
kexAngle PointAt(kexVec3 &location) const;
|
||||||
|
kexVec3 Lerp(const kexVec3 &next, float movement) const;
|
||||||
|
kexVec3 &Lerp(const kexVec3 &start, const kexVec3 &next, float movement);
|
||||||
|
kexQuat ToQuat(void);
|
||||||
|
float ToYaw(void) const;
|
||||||
|
float ToPitch(void) const;
|
||||||
|
kexStr ToString(void) const;
|
||||||
|
float *ToFloatPtr(void);
|
||||||
|
kexVec2 ToVec2(void);
|
||||||
|
kexVec2 ToVec2(void) const;
|
||||||
|
kexVec3 ScreenProject(kexMatrix &proj, kexMatrix &model,
|
||||||
|
const int width, const int height,
|
||||||
|
const int wx, const int wy);
|
||||||
|
|
||||||
|
kexVec3 operator+(const kexVec3 &vec);
|
||||||
|
kexVec3 operator+(const kexVec3 &vec) const;
|
||||||
|
kexVec3 operator+(kexVec3 &vec);
|
||||||
|
kexVec3 operator-(void) const;
|
||||||
|
kexVec3 operator-(const kexVec3 &vec) const;
|
||||||
|
kexVec3 operator*(const kexVec3 &vec);
|
||||||
|
kexVec3 operator*(const float val);
|
||||||
|
kexVec3 operator*(const float val) const;
|
||||||
|
kexVec3 operator/(const kexVec3 &vec);
|
||||||
|
kexVec3 operator/(const float val);
|
||||||
|
kexVec3 operator*(const kexQuat &quat);
|
||||||
|
kexVec3 operator*(const kexMatrix &mtx);
|
||||||
|
kexVec3 operator*(const kexMatrix &mtx) const;
|
||||||
|
kexVec3 &operator=(const kexVec3 &vec);
|
||||||
|
kexVec3 &operator=(const float *vecs);
|
||||||
|
kexVec3 &operator+=(const kexVec3 &vec);
|
||||||
|
kexVec3 &operator-=(const kexVec3 &vec);
|
||||||
|
kexVec3 &operator*=(const kexVec3 &vec);
|
||||||
|
kexVec3 &operator*=(const float val);
|
||||||
|
kexVec3 &operator/=(const kexVec3 &vec);
|
||||||
|
kexVec3 &operator/=(const float val);
|
||||||
|
kexVec3 &operator*=(const kexQuat &quat);
|
||||||
|
kexVec3 &operator*=(const kexMatrix &mtx);
|
||||||
|
float operator[](int index) const;
|
||||||
|
float &operator[](int index);
|
||||||
|
|
||||||
|
operator float *(void) { return reinterpret_cast<float*>(&x); }
|
||||||
|
|
||||||
|
static const kexVec3 vecForward;
|
||||||
|
static const kexVec3 vecUp;
|
||||||
|
static const kexVec3 vecRight;
|
||||||
|
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexVec4
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexVec4(void);
|
||||||
|
explicit kexVec4(const float x, const float y, const float z, const float w);
|
||||||
|
|
||||||
|
void Set(const float x, const float y, const float z, const float w);
|
||||||
|
void Clear(void);
|
||||||
|
float *ToFloatPtr(void);
|
||||||
|
|
||||||
|
const kexVec3 &ToVec3(void) const;
|
||||||
|
kexVec3 &ToVec3(void);
|
||||||
|
kexVec4 operator|(const kexMatrix &mtx);
|
||||||
|
kexVec4 &operator|=(const kexMatrix &mtx);
|
||||||
|
float operator[](int index) const;
|
||||||
|
float &operator[](int index);
|
||||||
|
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexMatrix
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexMatrix(void);
|
||||||
|
kexMatrix(const kexMatrix &mtx);
|
||||||
|
kexMatrix(const float x, const float y, const float z);
|
||||||
|
kexMatrix(const kexQuat &quat);
|
||||||
|
kexMatrix(const float angle, const int axis);
|
||||||
|
|
||||||
|
kexMatrix &Identity(void);
|
||||||
|
kexMatrix &Identity(const float x, const float y, const float z);
|
||||||
|
kexMatrix &SetTranslation(const float x, const float y, const float z);
|
||||||
|
kexMatrix &SetTranslation(const kexVec3 &vector);
|
||||||
|
kexMatrix &AddTranslation(const float x, const float y, const float z);
|
||||||
|
kexMatrix &AddTranslation(const kexVec3 &vector);
|
||||||
|
kexMatrix &Scale(const float x, const float y, const float z);
|
||||||
|
kexMatrix &Scale(const kexVec3 &vector);
|
||||||
|
static kexMatrix Scale(const kexMatrix &mtx, const float x, const float y, const float z);
|
||||||
|
kexMatrix &Transpose(void);
|
||||||
|
static kexMatrix Transpose(const kexMatrix &mtx);
|
||||||
|
static kexMatrix Invert(kexMatrix &mtx);
|
||||||
|
kexQuat ToQuat(void);
|
||||||
|
float *ToFloatPtr(void);
|
||||||
|
void SetViewProjection(float aspect, float fov, float zNear, float zFar);
|
||||||
|
void SetOrtho(float left, float right,
|
||||||
|
float bottom, float top,
|
||||||
|
float zNear, float zFar);
|
||||||
|
|
||||||
|
kexMatrix operator*(const kexVec3 &vector);
|
||||||
|
kexMatrix &operator*=(const kexVec3 &vector);
|
||||||
|
kexMatrix operator*(const kexMatrix &matrix);
|
||||||
|
kexMatrix &operator*=(const kexMatrix &matrix);
|
||||||
|
friend kexMatrix operator*(const kexMatrix &m1, const kexMatrix &m2);
|
||||||
|
kexMatrix &operator=(const kexMatrix &matrix);
|
||||||
|
kexMatrix &operator=(const float *m);
|
||||||
|
kexMatrix operator|(const kexMatrix &matrix);
|
||||||
|
|
||||||
|
kexVec4 vectors[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexPluecker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexPluecker(void);
|
||||||
|
kexPluecker(const kexVec3 &start, const kexVec3 &end, bool bRay = false);
|
||||||
|
|
||||||
|
void Clear(void);
|
||||||
|
void SetLine(const kexVec3 &start, const kexVec3 &end);
|
||||||
|
void SetRay(const kexVec3 &start, const kexVec3 &dir);
|
||||||
|
float InnerProduct(const kexPluecker &pluecker) const;
|
||||||
|
|
||||||
|
float p[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexPlane
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexPlane(void);
|
||||||
|
kexPlane(const float a, const float b, const float c, const float d);
|
||||||
|
kexPlane(const kexVec3 &pt1, const kexVec3 &pt2, const kexVec3 &pt3);
|
||||||
|
kexPlane(const kexVec3 &normal, const kexVec3 &point);
|
||||||
|
kexPlane(const kexPlane &plane);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AXIS_YZ = 0,
|
||||||
|
AXIS_XZ,
|
||||||
|
AXIS_XY
|
||||||
|
} planeAxis_t;
|
||||||
|
|
||||||
|
const kexVec3 &Normal(void) const;
|
||||||
|
kexVec3 &Normal(void);
|
||||||
|
kexPlane &SetNormal(const kexVec3 &normal);
|
||||||
|
kexPlane &SetNormal(const kexVec3 &pt1, const kexVec3 &pt2, const kexVec3 &pt3);
|
||||||
|
float Distance(const kexVec3 &point);
|
||||||
|
kexPlane &SetDistance(const kexVec3 &point);
|
||||||
|
bool IsFacing(const float yaw);
|
||||||
|
float ToYaw(void);
|
||||||
|
float ToPitch(void);
|
||||||
|
kexQuat ToQuat(void);
|
||||||
|
const kexVec4 &ToVec4(void) const;
|
||||||
|
kexVec4 &ToVec4(void);
|
||||||
|
const planeAxis_t BestAxis(void) const;
|
||||||
|
kexVec3 GetInclination(void);
|
||||||
|
|
||||||
|
kexPlane &operator|(const kexQuat &quat);
|
||||||
|
kexPlane &operator|=(const kexQuat &quat);
|
||||||
|
kexPlane &operator|(const kexMatrix &mtx);
|
||||||
|
kexPlane &operator|=(const kexMatrix &mtx);
|
||||||
|
|
||||||
|
float a;
|
||||||
|
float b;
|
||||||
|
float c;
|
||||||
|
float d;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexAngle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexAngle(void);
|
||||||
|
kexAngle(const float yaw, const float pitch, const float roll);
|
||||||
|
kexAngle(const kexVec3 &vector);
|
||||||
|
kexAngle(const kexAngle &an);
|
||||||
|
|
||||||
|
kexAngle &Round(void);
|
||||||
|
kexAngle &Clamp180(void);
|
||||||
|
kexAngle &Clamp180Invert(void);
|
||||||
|
kexAngle &Clamp180InvertSum(const kexAngle &angle);
|
||||||
|
kexAngle Diff(kexAngle &angle);
|
||||||
|
void ToAxis(kexVec3 *forward, kexVec3 *up, kexVec3 *right);
|
||||||
|
kexVec3 ToForwardAxis(void);
|
||||||
|
kexVec3 ToUpAxis(void);
|
||||||
|
kexVec3 ToRightAxis(void);
|
||||||
|
const kexVec3 &ToVec3(void) const;
|
||||||
|
kexVec3 &ToVec3(void);
|
||||||
|
kexQuat ToQuat(void);
|
||||||
|
|
||||||
|
kexAngle operator+(const kexAngle &angle);
|
||||||
|
kexAngle operator-(const kexAngle &angle);
|
||||||
|
kexAngle &operator+=(const kexAngle &angle);
|
||||||
|
kexAngle &operator-=(const kexAngle &angle);
|
||||||
|
kexAngle &operator=(const kexAngle &angle);
|
||||||
|
kexAngle &operator=(const kexVec3 &vector);
|
||||||
|
kexAngle &operator=(const float *vecs);
|
||||||
|
kexAngle operator-(void);
|
||||||
|
float operator[](int index) const;
|
||||||
|
float &operator[](int index);
|
||||||
|
|
||||||
|
float yaw;
|
||||||
|
float pitch;
|
||||||
|
float roll;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexBBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexBBox(void);
|
||||||
|
explicit kexBBox(const kexVec3 &vMin, const kexVec3 &vMax);
|
||||||
|
|
||||||
|
void Clear(void);
|
||||||
|
kexVec3 Center(void) const;
|
||||||
|
float Radius(void) const;
|
||||||
|
void AddPoint(const kexVec3 &vec);
|
||||||
|
bool PointInside(const kexVec3 &vec) const;
|
||||||
|
bool IntersectingBox(const kexBBox &box) const;
|
||||||
|
bool IntersectingBox2D(const kexBBox &box) const;
|
||||||
|
float DistanceToPlane(kexPlane &plane);
|
||||||
|
bool LineIntersect(const kexVec3 &start, const kexVec3 &end);
|
||||||
|
void ToPoints(float *points) const;
|
||||||
|
void ToVectors(kexVec3 *vectors) const;
|
||||||
|
|
||||||
|
kexBBox operator+(const float radius) const;
|
||||||
|
kexBBox &operator+=(const float radius);
|
||||||
|
kexBBox operator+(const kexVec3 &vec) const;
|
||||||
|
kexBBox operator-(const float radius) const;
|
||||||
|
kexBBox operator-(const kexVec3 &vec) const;
|
||||||
|
kexBBox &operator-=(const float radius);
|
||||||
|
kexBBox operator*(const kexMatrix &matrix) const;
|
||||||
|
kexBBox &operator*=(const kexMatrix &matrix);
|
||||||
|
kexBBox operator*(const kexVec3 &vec) const;
|
||||||
|
kexBBox &operator*=(const kexVec3 &vec);
|
||||||
|
kexBBox &operator=(const kexBBox &bbox);
|
||||||
|
kexVec3 operator[](int index) const;
|
||||||
|
kexVec3 &operator[](int index);
|
||||||
|
|
||||||
|
kexVec3 min;
|
||||||
|
kexVec3 max;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Sin
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Sin(float x)
|
||||||
|
{
|
||||||
|
return sinf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Cos
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Cos(float x)
|
||||||
|
{
|
||||||
|
return cosf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Tan
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Tan(float x)
|
||||||
|
{
|
||||||
|
return tanf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::ATan2
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::ATan2(float x, float y)
|
||||||
|
{
|
||||||
|
return atan2f(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::ACos
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::ACos(float x)
|
||||||
|
{
|
||||||
|
return acosf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Sqrt
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Sqrt(float x)
|
||||||
|
{
|
||||||
|
return x * InvSqrt(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Pow
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Pow(float x, float y)
|
||||||
|
{
|
||||||
|
return powf(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Log
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Log(float x)
|
||||||
|
{
|
||||||
|
return logf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Floor
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Floor(float x)
|
||||||
|
{
|
||||||
|
return floorf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Ceil
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Ceil(float x)
|
||||||
|
{
|
||||||
|
return ceilf(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Deg2Rad
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Deg2Rad(float x)
|
||||||
|
{
|
||||||
|
return DEG2RAD(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Rad2Deg
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Rad2Deg(float x)
|
||||||
|
{
|
||||||
|
return RAD2DEG(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Abs
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline int kexMath::Abs(int x)
|
||||||
|
{
|
||||||
|
int y = x >> 31;
|
||||||
|
return ((x ^ y) - y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Fabs
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::Fabs(float x)
|
||||||
|
{
|
||||||
|
int tmp = *reinterpret_cast<int*>(&x);
|
||||||
|
tmp &= 0x7FFFFFFF;
|
||||||
|
return *reinterpret_cast<float*>(&tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::InvSqrt
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline float kexMath::InvSqrt(float x)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
float r;
|
||||||
|
float y;
|
||||||
|
|
||||||
|
y = x * 0.5f;
|
||||||
|
i = *reinterpret_cast<unsigned int*>(&x);
|
||||||
|
i = 0x5f3759df - (i >> 1);
|
||||||
|
r = *reinterpret_cast<float*>(&i);
|
||||||
|
r = r * (1.5f - r * r * y);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Clamp
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline void kexMath::Clamp(float &f, const float min, const float max)
|
||||||
|
{
|
||||||
|
if(f < min) { f = min; }
|
||||||
|
if(f > max) { f = max; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Clamp
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline void kexMath::Clamp(byte &b, const byte min, const byte max)
|
||||||
|
{
|
||||||
|
if(b < min) { b = min; }
|
||||||
|
if(b > max) { b = max; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Clamp
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline void kexMath::Clamp(int &i, const int min, const int max)
|
||||||
|
{
|
||||||
|
if(i < min) { i = min; }
|
||||||
|
if(i > max) { i = max; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMath::Clamp
|
||||||
|
//
|
||||||
|
|
||||||
|
d_inline void kexMath::Clamp(kexVec3 &v, const float min, const float max)
|
||||||
|
{
|
||||||
|
if(v.x < min) { v.x = min; }
|
||||||
|
if(v.x > max) { v.x = max; }
|
||||||
|
if(v.y < min) { v.y = min; }
|
||||||
|
if(v.y > max) { v.y = max; }
|
||||||
|
if(v.z < min) { v.z = min; }
|
||||||
|
if(v.z > max) { v.z = max; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
717
src/lightmap/kexlib/math/matrix.cpp
Normal file
717
src/lightmap/kexlib/math/matrix.cpp
Normal file
|
@ -0,0 +1,717 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Matrix (left handed) operations
|
||||||
|
//
|
||||||
|
// Reference:
|
||||||
|
// _________________
|
||||||
|
// | 0 4 8 12 |
|
||||||
|
// | 1 5 9 13 |
|
||||||
|
// | 2 6 10 14 |
|
||||||
|
// | 3 7 11 15 |
|
||||||
|
// _________________
|
||||||
|
//
|
||||||
|
// translation
|
||||||
|
// _________________
|
||||||
|
// | 0 4 8 x |
|
||||||
|
// | 1 5 9 y |
|
||||||
|
// | 2 6 10 z |
|
||||||
|
// | 3 7 11 15 |
|
||||||
|
// _________________
|
||||||
|
//
|
||||||
|
// rotation x
|
||||||
|
// _________________
|
||||||
|
// |(1) 4 8 x |
|
||||||
|
// | 1 xc -xs y |
|
||||||
|
// | 2 xs xs z |
|
||||||
|
// | 3 7 11 (1) |
|
||||||
|
// _________________
|
||||||
|
//
|
||||||
|
// rotation y
|
||||||
|
// _________________
|
||||||
|
// | yc 4 ys 12 |
|
||||||
|
// | 1 (1) 9 13 |
|
||||||
|
// |-ys 6 yc 14 |
|
||||||
|
// | 3 7 11 (1) |
|
||||||
|
// _________________
|
||||||
|
//
|
||||||
|
// rotation z
|
||||||
|
// _________________
|
||||||
|
// | zc -zs 8 12 |
|
||||||
|
// | zs zc 9 13 |
|
||||||
|
// | 2 6 (1) 14 |
|
||||||
|
// | 3 7 11 (1) |
|
||||||
|
// _________________
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::kexMatrix
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix::kexMatrix(void)
|
||||||
|
{
|
||||||
|
Identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::kexMatrix
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix::kexMatrix(const kexMatrix &mtx)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
vectors[i].x = mtx.vectors[i].x;
|
||||||
|
vectors[i].y = mtx.vectors[i].y;
|
||||||
|
vectors[i].z = mtx.vectors[i].z;
|
||||||
|
vectors[i].w = mtx.vectors[i].w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::kexMatrix
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix::kexMatrix(const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
Identity(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::kexMatrix
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix::kexMatrix(const kexQuat &quat)
|
||||||
|
{
|
||||||
|
float xx = quat.x * quat.x;
|
||||||
|
float yx = quat.y * quat.x;
|
||||||
|
float zx = quat.z * quat.x;
|
||||||
|
float wx = quat.w * quat.x;
|
||||||
|
float yy = quat.y * quat.y;
|
||||||
|
float zy = quat.z * quat.y;
|
||||||
|
float wy = quat.w * quat.y;
|
||||||
|
float zz = quat.z * quat.z;
|
||||||
|
float wz = quat.w * quat.z;
|
||||||
|
float ww = quat.w * quat.w;
|
||||||
|
|
||||||
|
vectors[0].Set(
|
||||||
|
((ww + xx) - yy) - zz,
|
||||||
|
(wz + wz) + (yx + yx),
|
||||||
|
(zx + zx) - (wy + wy),
|
||||||
|
0);
|
||||||
|
vectors[1].Set(
|
||||||
|
(yx + yx) - (wz + wz),
|
||||||
|
(yy + (ww - xx)) - zz,
|
||||||
|
(wx + wx) + (zy + zy),
|
||||||
|
0);
|
||||||
|
vectors[2].Set(
|
||||||
|
(wy + wy + zx + zx),
|
||||||
|
(zy + zy) - (wx + wx),
|
||||||
|
((ww - xx) - yy) + zz,
|
||||||
|
0);
|
||||||
|
vectors[3].Set(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::kexMatrix
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix::kexMatrix(const float angle, const int axis)
|
||||||
|
{
|
||||||
|
float s;
|
||||||
|
float c;
|
||||||
|
|
||||||
|
s = kexMath::Sin(angle);
|
||||||
|
c = kexMath::Cos(angle);
|
||||||
|
|
||||||
|
Identity();
|
||||||
|
|
||||||
|
switch(axis)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
this->vectors[0].x = c;
|
||||||
|
this->vectors[0].z = -s;
|
||||||
|
this->vectors[3].x = s;
|
||||||
|
this->vectors[3].z = c;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this->vectors[1].y = c;
|
||||||
|
this->vectors[1].z = s;
|
||||||
|
this->vectors[2].y = -s;
|
||||||
|
this->vectors[2].z = c;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this->vectors[0].x = c;
|
||||||
|
this->vectors[0].y = s;
|
||||||
|
this->vectors[1].x = -s;
|
||||||
|
this->vectors[1].y = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::Identity
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::Identity(void)
|
||||||
|
{
|
||||||
|
vectors[0].Set(1, 0, 0, 0);
|
||||||
|
vectors[1].Set(0, 1, 0, 0);
|
||||||
|
vectors[2].Set(0, 0, 1, 0);
|
||||||
|
vectors[3].Set(0, 0, 0, 1);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::Identity
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::Identity(const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
vectors[0].Set(x, 0, 0, 0);
|
||||||
|
vectors[1].Set(0, y, 0, 0);
|
||||||
|
vectors[2].Set(0, 0, z, 0);
|
||||||
|
vectors[3].Set(0, 0, 0, 1);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::SetTranslation
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::SetTranslation(const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
vectors[3].ToVec3().Set(x, y, z);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::SetTranslation
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::SetTranslation(const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
vectors[3].ToVec3() = vector;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::AddTranslation
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::AddTranslation(const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
vectors[3].x += x;
|
||||||
|
vectors[3].y += y;
|
||||||
|
vectors[3].z += z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::AddTranslation
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::AddTranslation(const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
vectors[3].ToVec3() += vector;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::Scale
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::Scale(const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
vectors[0].ToVec3() *= x;
|
||||||
|
vectors[1].ToVec3() *= y;
|
||||||
|
vectors[2].ToVec3() *= z;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::Scale
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::Scale(const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
vectors[0].ToVec3() *= vector.x;
|
||||||
|
vectors[1].ToVec3() *= vector.y;
|
||||||
|
vectors[2].ToVec3() *= vector.z;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::Scale
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix kexMatrix::Scale(const kexMatrix &mtx, const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
kexMatrix out;
|
||||||
|
|
||||||
|
out.vectors[0].ToVec3() = mtx.vectors[0].ToVec3() * x;
|
||||||
|
out.vectors[1].ToVec3() = mtx.vectors[1].ToVec3() * y;
|
||||||
|
out.vectors[2].ToVec3() = mtx.vectors[2].ToVec3() * z;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::Transpose
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::Transpose(void)
|
||||||
|
{
|
||||||
|
kexVec3 v1 = vectors[1].ToVec3();
|
||||||
|
kexVec3 v2 = vectors[2].ToVec3();
|
||||||
|
|
||||||
|
vectors[1].ToVec3() = v2;
|
||||||
|
vectors[2].ToVec3() = v1;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::Transpose
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix kexMatrix::Transpose(const kexMatrix &mtx)
|
||||||
|
{
|
||||||
|
kexMatrix out;
|
||||||
|
|
||||||
|
out.vectors[0].ToVec3() = mtx.vectors[0].ToVec3();
|
||||||
|
out.vectors[1].ToVec3() = mtx.vectors[2].ToVec3();
|
||||||
|
out.vectors[2].ToVec3() = mtx.vectors[1].ToVec3();
|
||||||
|
out.vectors[3].ToVec3() = mtx.vectors[3].ToVec3();
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::Invert
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix kexMatrix::Invert(kexMatrix &mtx)
|
||||||
|
{
|
||||||
|
float d;
|
||||||
|
float *m;
|
||||||
|
|
||||||
|
m = mtx.ToFloatPtr();
|
||||||
|
|
||||||
|
d = m[ 0] * m[10] * m[ 5] -
|
||||||
|
m[ 0] * m[ 9] * m[ 6] -
|
||||||
|
m[ 1] * m[ 4] * m[10] +
|
||||||
|
m[ 2] * m[ 4] * m[ 9] +
|
||||||
|
m[ 1] * m[ 6] * m[ 8] -
|
||||||
|
m[ 2] * m[ 5] * m[ 8];
|
||||||
|
|
||||||
|
if(d != 0.0f)
|
||||||
|
{
|
||||||
|
kexMatrix inv;
|
||||||
|
|
||||||
|
d = (1.0f / d);
|
||||||
|
|
||||||
|
inv.vectors[0].x = ( m[10] * m[ 5] - m[ 9] * m[ 6]) * d;
|
||||||
|
inv.vectors[0].y = -((m[ 1] * m[10] - m[ 2] * m[ 9]) * d);
|
||||||
|
inv.vectors[0].z = ( m[ 1] * m[ 6] - m[ 2] * m[ 5]) * d;
|
||||||
|
inv.vectors[0].w = 0;
|
||||||
|
inv.vectors[1].x = ( m[ 6] * m[ 8] - m[ 4] * m[10]) * d;
|
||||||
|
inv.vectors[1].y = ( m[ 0] * m[10] - m[ 2] * m[ 8]) * d;
|
||||||
|
inv.vectors[1].z = -((m[ 0] * m[ 6] - m[ 2] * m[ 4]) * d);
|
||||||
|
inv.vectors[1].w = 0;
|
||||||
|
inv.vectors[2].x = -((m[ 5] * m[ 8] - m[ 4] * m[ 9]) * d);
|
||||||
|
inv.vectors[2].y = ( m[ 1] * m[ 8] - m[ 0] * m[ 9]) * d;
|
||||||
|
inv.vectors[2].z = -((m[ 1] * m[ 4] - m[ 0] * m[ 5]) * d);
|
||||||
|
inv.vectors[2].w = 0;
|
||||||
|
inv.vectors[3].x = (
|
||||||
|
( m[13] * m[10] - m[14] * m[ 9]) * m[ 4]
|
||||||
|
+ m[14] * m[ 5] * m[ 8]
|
||||||
|
- m[13] * m[ 6] * m[ 8]
|
||||||
|
- m[12] * m[10] * m[ 5]
|
||||||
|
+ m[12] * m[ 9] * m[ 6]) * d;
|
||||||
|
inv.vectors[3].y = (
|
||||||
|
m[ 0] * m[14] * m[ 9]
|
||||||
|
- m[ 0] * m[13] * m[10]
|
||||||
|
- m[14] * m[ 1] * m[ 8]
|
||||||
|
+ m[13] * m[ 2] * m[ 8]
|
||||||
|
+ m[12] * m[ 1] * m[10]
|
||||||
|
- m[12] * m[ 2] * m[ 9]) * d;
|
||||||
|
inv.vectors[3].z = -(
|
||||||
|
( m[ 0] * m[14] * m[ 5]
|
||||||
|
- m[ 0] * m[13] * m[ 6]
|
||||||
|
- m[14] * m[ 1] * m[ 4]
|
||||||
|
+ m[13] * m[ 2] * m[ 4]
|
||||||
|
+ m[12] * m[ 1] * m[ 6]
|
||||||
|
- m[12] * m[ 2] * m[ 5]) * d);
|
||||||
|
inv.vectors[3].w = 1.0f;
|
||||||
|
|
||||||
|
return inv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::SetViewProjection
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexMatrix::SetViewProjection(float aspect, float fov, float zNear, float zFar)
|
||||||
|
{
|
||||||
|
float top = zNear * kexMath::Tan(fov * M_PI / 360.0f);
|
||||||
|
float bottom = -top;
|
||||||
|
float left = bottom * aspect;
|
||||||
|
float right = top * aspect;
|
||||||
|
|
||||||
|
vectors[0].x = (2 * zNear) / (right - left);
|
||||||
|
vectors[1].y = (2 * zNear) / (top - bottom);
|
||||||
|
vectors[3].z = -(2 * zFar * zNear) / (zFar - zNear);
|
||||||
|
|
||||||
|
vectors[2].x = (right + left) / (right - left);
|
||||||
|
vectors[2].y = (top + bottom) / (top - bottom);
|
||||||
|
vectors[2].z = -(zFar + zNear) / (zFar - zNear);
|
||||||
|
|
||||||
|
vectors[0].y = 0;
|
||||||
|
vectors[0].z = 0;
|
||||||
|
vectors[0].w = 0;
|
||||||
|
vectors[1].x = 0;
|
||||||
|
vectors[1].w = 0;
|
||||||
|
vectors[1].z = 0;
|
||||||
|
vectors[2].w = -1;
|
||||||
|
vectors[3].x = 0;
|
||||||
|
vectors[3].y = 0;
|
||||||
|
vectors[3].w = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::SetOrtho
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexMatrix::SetOrtho(float left, float right,
|
||||||
|
float bottom, float top,
|
||||||
|
float zNear, float zFar)
|
||||||
|
{
|
||||||
|
vectors[0].x = 2 / (right - left);
|
||||||
|
vectors[1].y = 2 / (top - bottom);
|
||||||
|
vectors[2].z = -2 / (zFar - zNear);
|
||||||
|
|
||||||
|
vectors[3].x = -(right + left) / (right - left);
|
||||||
|
vectors[3].y = -(top + bottom) / (top - bottom);
|
||||||
|
vectors[3].z = -(zFar + zNear) / (zFar - zNear);
|
||||||
|
vectors[3].w = 1;
|
||||||
|
|
||||||
|
vectors[0].y = 0;
|
||||||
|
vectors[0].z = 0;
|
||||||
|
vectors[0].w = 0;
|
||||||
|
vectors[1].x = 0;
|
||||||
|
vectors[1].z = 0;
|
||||||
|
vectors[1].w = 0;
|
||||||
|
vectors[2].x = 0;
|
||||||
|
vectors[2].y = 0;
|
||||||
|
vectors[2].w = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::ToQuat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexMatrix::ToQuat(void)
|
||||||
|
{
|
||||||
|
float t;
|
||||||
|
float d;
|
||||||
|
float mx;
|
||||||
|
float my;
|
||||||
|
float mz;
|
||||||
|
float m21;
|
||||||
|
float m20;
|
||||||
|
float m10;
|
||||||
|
kexQuat q;
|
||||||
|
|
||||||
|
mx = vectors[0][0];
|
||||||
|
my = vectors[1][1];
|
||||||
|
mz = vectors[2][2];
|
||||||
|
|
||||||
|
m21 = (vectors[2][1] - vectors[1][2]);
|
||||||
|
m20 = (vectors[2][0] - vectors[0][2]);
|
||||||
|
m10 = (vectors[1][0] - vectors[0][1]);
|
||||||
|
|
||||||
|
t = 1.0f + mx + my + mz;
|
||||||
|
|
||||||
|
if(t > 0)
|
||||||
|
{
|
||||||
|
d = 0.5f / kexMath::Sqrt(t);
|
||||||
|
q.x = m21 * d;
|
||||||
|
q.y = m20 * d;
|
||||||
|
q.z = m10 * d;
|
||||||
|
q.w = 0.25f / d;
|
||||||
|
}
|
||||||
|
else if(mx > my && mx > mz)
|
||||||
|
{
|
||||||
|
d = kexMath::Sqrt(1.0f + mx - my - mz) * 2;
|
||||||
|
q.x = 0.5f / d;
|
||||||
|
q.y = m10 / d;
|
||||||
|
q.z = m20 / d;
|
||||||
|
q.w = m21 / d;
|
||||||
|
}
|
||||||
|
else if(my > mz)
|
||||||
|
{
|
||||||
|
d = kexMath::Sqrt(1.0f + my - mx - mz) * 2;
|
||||||
|
q.x = m10 / d;
|
||||||
|
q.y = 0.5f / d;
|
||||||
|
q.z = m21 / d;
|
||||||
|
q.w = m20 / d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = kexMath::Sqrt(1.0f + mz - mx - my) * 2;
|
||||||
|
q.x = m20 / d;
|
||||||
|
q.y = m21 / d;
|
||||||
|
q.z = 0.5f / d;
|
||||||
|
q.w = m10 / d;
|
||||||
|
}
|
||||||
|
|
||||||
|
q.Normalize();
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::operator*
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix kexMatrix::operator*(const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
kexMatrix out(*this);
|
||||||
|
|
||||||
|
out.vectors[3].ToVec3() +=
|
||||||
|
vectors[0].ToVec3() * vector.x +
|
||||||
|
vectors[1].ToVec3() * vector.y +
|
||||||
|
vectors[2].ToVec3() * vector.z;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::operator*=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::operator*=(const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
vectors[3].ToVec3() +=
|
||||||
|
vectors[0].ToVec3() * vector.x +
|
||||||
|
vectors[1].ToVec3() * vector.y +
|
||||||
|
vectors[2].ToVec3() * vector.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::ToFloatPtr
|
||||||
|
//
|
||||||
|
|
||||||
|
float *kexMatrix::ToFloatPtr(void)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<float*>(vectors);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::operator*
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix kexMatrix::operator*(const kexMatrix &matrix)
|
||||||
|
{
|
||||||
|
kexMatrix out;
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
out.vectors[i].x =
|
||||||
|
vectors[i].x * matrix.vectors[0].x +
|
||||||
|
vectors[i].y * matrix.vectors[1].x +
|
||||||
|
vectors[i].z * matrix.vectors[2].x +
|
||||||
|
vectors[i].w * matrix.vectors[3].x;
|
||||||
|
out.vectors[i].y =
|
||||||
|
vectors[i].x * matrix.vectors[0].y +
|
||||||
|
vectors[i].y * matrix.vectors[1].y +
|
||||||
|
vectors[i].z * matrix.vectors[2].y +
|
||||||
|
vectors[i].w * matrix.vectors[3].y;
|
||||||
|
out.vectors[i].z =
|
||||||
|
vectors[i].x * matrix.vectors[0].z +
|
||||||
|
vectors[i].y * matrix.vectors[1].z +
|
||||||
|
vectors[i].z * matrix.vectors[2].z +
|
||||||
|
vectors[i].w * matrix.vectors[3].z;
|
||||||
|
out.vectors[i].w =
|
||||||
|
vectors[i].x * matrix.vectors[0].w +
|
||||||
|
vectors[i].y * matrix.vectors[1].w +
|
||||||
|
vectors[i].z * matrix.vectors[2].w +
|
||||||
|
vectors[i].w * matrix.vectors[3].w;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::operator*=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::operator*=(const kexMatrix &matrix)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
vectors[i].x =
|
||||||
|
vectors[i].x * matrix.vectors[0].x +
|
||||||
|
vectors[i].y * matrix.vectors[1].x +
|
||||||
|
vectors[i].z * matrix.vectors[2].x +
|
||||||
|
vectors[i].w * matrix.vectors[3].x;
|
||||||
|
vectors[i].y =
|
||||||
|
vectors[i].x * matrix.vectors[0].y +
|
||||||
|
vectors[i].y * matrix.vectors[1].y +
|
||||||
|
vectors[i].z * matrix.vectors[2].y +
|
||||||
|
vectors[i].w * matrix.vectors[3].y;
|
||||||
|
vectors[i].z =
|
||||||
|
vectors[i].x * matrix.vectors[0].z +
|
||||||
|
vectors[i].y * matrix.vectors[1].z +
|
||||||
|
vectors[i].z * matrix.vectors[2].z +
|
||||||
|
vectors[i].w * matrix.vectors[3].z;
|
||||||
|
vectors[i].w =
|
||||||
|
vectors[i].x * matrix.vectors[0].w +
|
||||||
|
vectors[i].y * matrix.vectors[1].w +
|
||||||
|
vectors[i].z * matrix.vectors[2].w +
|
||||||
|
vectors[i].w * matrix.vectors[3].w;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::operator*
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix operator*(const kexMatrix &m1, const kexMatrix &m2)
|
||||||
|
{
|
||||||
|
kexMatrix out;
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
out.vectors[i].x =
|
||||||
|
m1.vectors[i].x * m2.vectors[0].x +
|
||||||
|
m1.vectors[i].y * m2.vectors[1].x +
|
||||||
|
m1.vectors[i].z * m2.vectors[2].x +
|
||||||
|
m1.vectors[i].w * m2.vectors[3].x;
|
||||||
|
out.vectors[i].y =
|
||||||
|
m1.vectors[i].x * m2.vectors[0].y +
|
||||||
|
m1.vectors[i].y * m2.vectors[1].y +
|
||||||
|
m1.vectors[i].z * m2.vectors[2].y +
|
||||||
|
m1.vectors[i].w * m2.vectors[3].y;
|
||||||
|
out.vectors[i].z =
|
||||||
|
m1.vectors[i].x * m2.vectors[0].z +
|
||||||
|
m1.vectors[i].y * m2.vectors[1].z +
|
||||||
|
m1.vectors[i].z * m2.vectors[2].z +
|
||||||
|
m1.vectors[i].w * m2.vectors[3].z;
|
||||||
|
out.vectors[i].w =
|
||||||
|
m1.vectors[i].x * m2.vectors[0].w +
|
||||||
|
m1.vectors[i].y * m2.vectors[1].w +
|
||||||
|
m1.vectors[i].z * m2.vectors[2].w +
|
||||||
|
m1.vectors[i].w * m2.vectors[3].w;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::operator|
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix kexMatrix::operator|(const kexMatrix &matrix)
|
||||||
|
{
|
||||||
|
kexMatrix out;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
out.vectors[i].x =
|
||||||
|
vectors[i].x * matrix.vectors[0].x +
|
||||||
|
vectors[i].y * matrix.vectors[1].x +
|
||||||
|
vectors[i].z * matrix.vectors[2].x;
|
||||||
|
out.vectors[i].y =
|
||||||
|
vectors[i].x * matrix.vectors[0].y +
|
||||||
|
vectors[i].y * matrix.vectors[1].y +
|
||||||
|
vectors[i].z * matrix.vectors[2].y;
|
||||||
|
out.vectors[i].z =
|
||||||
|
vectors[i].x * matrix.vectors[0].z +
|
||||||
|
vectors[i].y * matrix.vectors[1].z +
|
||||||
|
vectors[i].z * matrix.vectors[2].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.vectors[3].x =
|
||||||
|
vectors[3].x * matrix.vectors[0].x +
|
||||||
|
vectors[3].y * matrix.vectors[1].x +
|
||||||
|
vectors[3].z * matrix.vectors[2].x + matrix.vectors[3].x;
|
||||||
|
out.vectors[3].y =
|
||||||
|
vectors[3].x * matrix.vectors[0].y +
|
||||||
|
vectors[3].y * matrix.vectors[1].y +
|
||||||
|
vectors[3].z * matrix.vectors[2].y + matrix.vectors[3].y;
|
||||||
|
out.vectors[3].z =
|
||||||
|
vectors[3].x * matrix.vectors[0].z +
|
||||||
|
vectors[3].y * matrix.vectors[1].z +
|
||||||
|
vectors[3].z * matrix.vectors[2].z + matrix.vectors[3].z;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::operator=(const kexMatrix &matrix)
|
||||||
|
{
|
||||||
|
vectors[0] = matrix.vectors[0];
|
||||||
|
vectors[1] = matrix.vectors[1];
|
||||||
|
vectors[2] = matrix.vectors[2];
|
||||||
|
vectors[3] = matrix.vectors[3];
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexMatrix::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexMatrix &kexMatrix::operator=(const float *m)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
vectors[i][j] = m[i * 4 + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
251
src/lightmap/kexlib/math/plane.cpp
Normal file
251
src/lightmap/kexlib/math/plane.cpp
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Plane operations
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::kexPlane
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPlane::kexPlane(void)
|
||||||
|
{
|
||||||
|
this->a = 0;
|
||||||
|
this->b = 0;
|
||||||
|
this->c = 0;
|
||||||
|
this->d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::kexPlane
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPlane::kexPlane(const float a, const float b, const float c, const float d)
|
||||||
|
{
|
||||||
|
this->a = a;
|
||||||
|
this->b = b;
|
||||||
|
this->c = c;
|
||||||
|
this->d = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::kexPlane
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPlane::kexPlane(const kexVec3 &pt1, const kexVec3 &pt2, const kexVec3 &pt3)
|
||||||
|
{
|
||||||
|
SetNormal(pt1, pt2, pt3);
|
||||||
|
this->d = kexVec3::Dot(pt1, Normal());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::kexPlane
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPlane::kexPlane(const kexVec3 &normal, const kexVec3 &point)
|
||||||
|
{
|
||||||
|
this->a = normal.x;
|
||||||
|
this->b = normal.y;
|
||||||
|
this->c = normal.z;
|
||||||
|
this->d = point.Dot(normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::kexPlane
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPlane::kexPlane(const kexPlane &plane)
|
||||||
|
{
|
||||||
|
this->a = plane.a;
|
||||||
|
this->b = plane.b;
|
||||||
|
this->c = plane.c;
|
||||||
|
this->d = plane.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::SetNormal
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPlane &kexPlane::SetNormal(const kexVec3 &normal)
|
||||||
|
{
|
||||||
|
Normal() = normal;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::SetNormal
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPlane &kexPlane::SetNormal(const kexVec3 &pt1, const kexVec3 &pt2, const kexVec3 &pt3)
|
||||||
|
{
|
||||||
|
Normal() = (pt2 - pt1).Cross(pt3 - pt2).Normalize();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::Normal
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 const &kexPlane::Normal(void) const
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<const kexVec3*>(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::Normal
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 &kexPlane::Normal(void)
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<kexVec3*>(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::Distance
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexPlane::Distance(const kexVec3 &point)
|
||||||
|
{
|
||||||
|
return point.Dot(Normal());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::SetDistance
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPlane &kexPlane::SetDistance(const kexVec3 &point)
|
||||||
|
{
|
||||||
|
this->d = point.Dot(Normal());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::IsFacing
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexPlane::IsFacing(const float yaw)
|
||||||
|
{
|
||||||
|
return -kexMath::Sin(yaw) * a + -kexMath::Cos(yaw) * b < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::ToYaw
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexPlane::ToYaw(void)
|
||||||
|
{
|
||||||
|
float d = Normal().Unit();
|
||||||
|
|
||||||
|
if(d != 0)
|
||||||
|
{
|
||||||
|
float phi;
|
||||||
|
phi = kexMath::ACos(b / d);
|
||||||
|
if(a <= 0)
|
||||||
|
{
|
||||||
|
phi = -phi;
|
||||||
|
}
|
||||||
|
|
||||||
|
return phi;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::ToPitch
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexPlane::ToPitch(void)
|
||||||
|
{
|
||||||
|
return kexMath::ACos(kexVec3::vecUp.Dot(Normal()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::ToQuat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexPlane::ToQuat(void)
|
||||||
|
{
|
||||||
|
kexVec3 cross = kexVec3::vecUp.Cross(Normal()).Normalize();
|
||||||
|
return kexQuat(kexMath::ACos(kexVec3::vecUp.Dot(Normal())), cross);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::ToVec4
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec4 const &kexPlane::ToVec4(void) const
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<const kexVec4*>(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::ToVec4
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec4 &kexPlane::ToVec4(void)
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<kexVec4*>(&a);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::BestAxis
|
||||||
|
//
|
||||||
|
|
||||||
|
const kexPlane::planeAxis_t kexPlane::BestAxis(void) const
|
||||||
|
{
|
||||||
|
float na = kexMath::Fabs(a);
|
||||||
|
float nb = kexMath::Fabs(b);
|
||||||
|
float nc = kexMath::Fabs(c);
|
||||||
|
|
||||||
|
// figure out what axis the plane lies on
|
||||||
|
if(na >= nb && na >= nc)
|
||||||
|
{
|
||||||
|
return AXIS_YZ;
|
||||||
|
}
|
||||||
|
else if(nb >= na && nb >= nc)
|
||||||
|
{
|
||||||
|
return AXIS_XZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AXIS_XY;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPlane::GetInclination
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 kexPlane::GetInclination(void)
|
||||||
|
{
|
||||||
|
kexVec3 dir = Normal() * kexVec3::vecUp.Dot(Normal());
|
||||||
|
return (kexVec3::vecUp - dir).Normalize();
|
||||||
|
}
|
107
src/lightmap/kexlib/math/pluecker.cpp
Normal file
107
src/lightmap/kexlib/math/pluecker.cpp
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Pluecker operations
|
||||||
|
// This stuff makes my brain hurt...
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPluecker::kexPluecker
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPluecker::kexPluecker(void)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPluecker::kexPluecker
|
||||||
|
//
|
||||||
|
|
||||||
|
kexPluecker::kexPluecker(const kexVec3 &start, const kexVec3 &end, bool bRay)
|
||||||
|
{
|
||||||
|
bRay ? SetRay(start, end) : SetLine(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPluecker::Clear
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexPluecker::Clear(void)
|
||||||
|
{
|
||||||
|
p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPluecker::SetLine
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexPluecker::SetLine(const kexVec3 &start, const kexVec3 &end)
|
||||||
|
{
|
||||||
|
p[0] = start.x * end.y - end.x * start.y;
|
||||||
|
p[1] = start.x * end.z - end.x * start.z;
|
||||||
|
p[3] = start.y * end.z - end.y * start.z;
|
||||||
|
|
||||||
|
p[2] = start.x - end.x;
|
||||||
|
p[5] = end.y - start.y;
|
||||||
|
p[4] = start.z - end.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPluecker::SetRay
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexPluecker::SetRay(const kexVec3 &start, const kexVec3 &dir)
|
||||||
|
{
|
||||||
|
p[0] = start.x * dir.y - dir.x * start.y;
|
||||||
|
p[1] = start.x * dir.z - dir.x * start.z;
|
||||||
|
p[3] = start.y * dir.z - dir.y * start.z;
|
||||||
|
|
||||||
|
p[2] = -dir.x;
|
||||||
|
p[5] = dir.y;
|
||||||
|
p[4] = -dir.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexPluecker::InnerProduct
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexPluecker::InnerProduct(const kexPluecker &pluecker) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
p[0] * pluecker.p[4] +
|
||||||
|
p[1] * pluecker.p[5] +
|
||||||
|
p[2] * pluecker.p[3] +
|
||||||
|
p[4] * pluecker.p[0] +
|
||||||
|
p[5] * pluecker.p[1] +
|
||||||
|
p[3] * pluecker.p[2];
|
||||||
|
}
|
446
src/lightmap/kexlib/math/quaternion.cpp
Normal file
446
src/lightmap/kexlib/math/quaternion.cpp
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Quaternion operations
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::kexQuat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat::kexQuat(void)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::kexQuat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat::kexQuat(const float angle, const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
float s = kexMath::Sin(angle * 0.5f);
|
||||||
|
float c = kexMath::Cos(angle * 0.5f);
|
||||||
|
|
||||||
|
this->x = x * s;
|
||||||
|
this->y = y * s;
|
||||||
|
this->z = z * s;
|
||||||
|
this->w = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::kexQuat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat::kexQuat(const float angle, kexVec3 &vector)
|
||||||
|
{
|
||||||
|
float s = kexMath::Sin(angle * 0.5f);
|
||||||
|
float c = kexMath::Cos(angle * 0.5f);
|
||||||
|
|
||||||
|
this->x = vector.x * s;
|
||||||
|
this->y = vector.y * s;
|
||||||
|
this->z = vector.z * s;
|
||||||
|
this->w = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::kexQuat
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat::kexQuat(const float angle, const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
float s = kexMath::Sin(angle * 0.5f);
|
||||||
|
float c = kexMath::Cos(angle * 0.5f);
|
||||||
|
|
||||||
|
this->x = vector.x * s;
|
||||||
|
this->y = vector.y * s;
|
||||||
|
this->z = vector.z * s;
|
||||||
|
this->w = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::Set
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexQuat::Set(const float x, const float y, const float z, const float w)
|
||||||
|
{
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
this->z = z;
|
||||||
|
this->w = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::Clear
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexQuat::Clear(void)
|
||||||
|
{
|
||||||
|
x = y = z = 0.0f;
|
||||||
|
w = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexVec3::UnitSq
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexQuat::UnitSq(void) const
|
||||||
|
{
|
||||||
|
return x * x + y * y + z * z + w * w;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexVec3::Unit
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexQuat::Unit(void) const
|
||||||
|
{
|
||||||
|
return kexMath::Sqrt(UnitSq());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::Normalize
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat &kexQuat::Normalize(void)
|
||||||
|
{
|
||||||
|
float d = Unit();
|
||||||
|
if(d != 0.0f)
|
||||||
|
{
|
||||||
|
d = 1.0f / d;
|
||||||
|
*this *= d;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::Inverse
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexQuat::Inverse(void) const
|
||||||
|
{
|
||||||
|
kexQuat out;
|
||||||
|
out.Set(-x, -y, -z, -w);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator+
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexQuat::operator+(const kexQuat &quat)
|
||||||
|
{
|
||||||
|
kexQuat out;
|
||||||
|
out.x = x + quat.x;
|
||||||
|
out.y = y + quat.y;
|
||||||
|
out.z = z + quat.z;
|
||||||
|
out.w = w + quat.w;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator+=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat &kexQuat::operator+=(const kexQuat &quat)
|
||||||
|
{
|
||||||
|
x += quat.x;
|
||||||
|
y += quat.y;
|
||||||
|
z += quat.z;
|
||||||
|
w += quat.w;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator-
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexQuat::operator-(const kexQuat &quat)
|
||||||
|
{
|
||||||
|
kexQuat out;
|
||||||
|
out.x = x - quat.x;
|
||||||
|
out.y = y - quat.y;
|
||||||
|
out.z = z - quat.z;
|
||||||
|
out.w = w - quat.w;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator-=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat &kexQuat::operator-=(const kexQuat &quat)
|
||||||
|
{
|
||||||
|
x -= quat.x;
|
||||||
|
y -= quat.y;
|
||||||
|
z -= quat.z;
|
||||||
|
w -= quat.w;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator*
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexQuat::operator*(const kexQuat &quat)
|
||||||
|
{
|
||||||
|
kexQuat out;
|
||||||
|
|
||||||
|
out.x = x * quat.w - y * quat.z + quat.x * w + quat.y * z;
|
||||||
|
out.y = x * quat.z + y * quat.w - quat.x * z + w * quat.y;
|
||||||
|
out.z = quat.x * y + w * quat.z + z * quat.w - x * quat.y;
|
||||||
|
out.w = w * quat.w - quat.y * y + z * quat.z + quat.x * x;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator*=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat &kexQuat::operator*=(const kexQuat &quat)
|
||||||
|
{
|
||||||
|
float tx = x;
|
||||||
|
float ty = y;
|
||||||
|
float tz = z;
|
||||||
|
float tw = w;
|
||||||
|
|
||||||
|
x = tx * quat.w - ty * quat.z + quat.x * tw + quat.y * z;
|
||||||
|
y = tx * quat.z + ty * quat.w - quat.x * tz + tw * quat.y;
|
||||||
|
z = quat.x * ty + tw * quat.z + tz * quat.w - tx * quat.y;
|
||||||
|
w = tw * quat.w - quat.y * ty + tz * quat.z + quat.x * x;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator*
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexQuat::operator*(const float val) const
|
||||||
|
{
|
||||||
|
kexQuat out;
|
||||||
|
out.x = x * val;
|
||||||
|
out.y = y * val;
|
||||||
|
out.z = z * val;
|
||||||
|
out.w = w * val;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator*=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat &kexQuat::operator*=(const float val)
|
||||||
|
{
|
||||||
|
x *= val;
|
||||||
|
y *= val;
|
||||||
|
z *= val;
|
||||||
|
w *= val;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator|
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 kexQuat::operator|(const kexVec3 &vector)
|
||||||
|
{
|
||||||
|
float xx = x * x;
|
||||||
|
float yx = y * x;
|
||||||
|
float zx = z * x;
|
||||||
|
float wx = w * x;
|
||||||
|
float yy = y * y;
|
||||||
|
float zy = z * y;
|
||||||
|
float wy = w * y;
|
||||||
|
float zz = z * z;
|
||||||
|
float wz = w * z;
|
||||||
|
float ww = w * w;
|
||||||
|
|
||||||
|
return kexVec3(
|
||||||
|
((yx + yx) - (wz + wz)) * vector.y +
|
||||||
|
((wy + wy + zx + zx)) * vector.z +
|
||||||
|
(((ww + xx) - yy) - zz) * vector.x,
|
||||||
|
((yy + (ww - xx)) - zz) * vector.y +
|
||||||
|
((zy + zy) - (wx + wx)) * vector.z +
|
||||||
|
((wz + wz) + (yx + yx)) * vector.x,
|
||||||
|
((wx + wx) + (zy + zy)) * vector.y +
|
||||||
|
(((ww - xx) - yy) + zz) * vector.z +
|
||||||
|
((zx + zx) - (wy + wy)) * vector.x
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::Dot
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexQuat::Dot(const kexQuat &quat) const
|
||||||
|
{
|
||||||
|
return (x * quat.x + y * quat.y + z * quat.z + w * quat.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::Slerp
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexQuat::Slerp(const kexQuat &quat, float movement) const
|
||||||
|
{
|
||||||
|
kexQuat rdest = quat;
|
||||||
|
float d1 = Dot(quat);
|
||||||
|
float d2 = Dot(quat.Inverse());
|
||||||
|
|
||||||
|
if(d1 < d2)
|
||||||
|
{
|
||||||
|
rdest = quat.Inverse();
|
||||||
|
d1 = d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(d1 <= 0.7071067811865001f)
|
||||||
|
{
|
||||||
|
float halfcos = kexMath::ACos(d1);
|
||||||
|
float halfsin = kexMath::Sin(halfcos);
|
||||||
|
|
||||||
|
if(halfsin == 0)
|
||||||
|
{
|
||||||
|
kexQuat out;
|
||||||
|
out.Set(x, y, z, w);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float d;
|
||||||
|
float ms1;
|
||||||
|
float ms2;
|
||||||
|
|
||||||
|
d = 1.0f / halfsin;
|
||||||
|
ms1 = kexMath::Sin((1.0f - movement) * halfcos) * d;
|
||||||
|
ms2 = kexMath::Sin(halfcos * movement) * d;
|
||||||
|
|
||||||
|
if(ms2 < 0)
|
||||||
|
{
|
||||||
|
rdest = quat.Inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this * ms1 + rdest * ms2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kexQuat out = (rdest - *this) * movement + *this;
|
||||||
|
out.Normalize();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::RotateFrom
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat kexQuat::RotateFrom(const kexVec3 &location, const kexVec3 &target, float maxAngle)
|
||||||
|
{
|
||||||
|
kexVec3 axis;
|
||||||
|
kexVec3 dir;
|
||||||
|
kexVec3 cp;
|
||||||
|
kexQuat prot;
|
||||||
|
float an;
|
||||||
|
|
||||||
|
dir = (*this | kexVec3::vecForward);
|
||||||
|
axis = (target - location).Normalize();
|
||||||
|
cp = dir.Cross(axis).Normalize();
|
||||||
|
|
||||||
|
an = kexMath::ACos(axis.Dot(dir));
|
||||||
|
|
||||||
|
if(maxAngle != 0 && an >= maxAngle)
|
||||||
|
{
|
||||||
|
an = maxAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*this * kexQuat(an, cp));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat &kexQuat::operator=(const kexQuat &quat)
|
||||||
|
{
|
||||||
|
x = quat.x;
|
||||||
|
y = quat.y;
|
||||||
|
z = quat.z;
|
||||||
|
w = quat.w;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat &kexQuat::operator=(const kexVec4 &vec)
|
||||||
|
{
|
||||||
|
x = vec.x;
|
||||||
|
y = vec.y;
|
||||||
|
z = vec.z;
|
||||||
|
w = vec.w;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::operator=
|
||||||
|
//
|
||||||
|
|
||||||
|
kexQuat &kexQuat::operator=(const float *vecs)
|
||||||
|
{
|
||||||
|
x = vecs[0];
|
||||||
|
y = vecs[1];
|
||||||
|
z = vecs[2];
|
||||||
|
w = vecs[3];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::ToVec3
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 const &kexQuat::ToVec3(void) const
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<const kexVec3*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexQuat::ToVec3
|
||||||
|
//
|
||||||
|
|
||||||
|
kexVec3 &kexQuat::ToVec3(void)
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<kexVec3*>(this);
|
||||||
|
}
|
99
src/lightmap/kexlib/math/random.cpp
Normal file
99
src/lightmap/kexlib/math/random.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Random operations
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "mathlib.h"
|
||||||
|
|
||||||
|
#define RANDOM_MAX 0x7FFF
|
||||||
|
|
||||||
|
int kexRand::seed = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexRand::SetSeed
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexRand::SetSeed(const int randSeed)
|
||||||
|
{
|
||||||
|
seed = randSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexRand::SysRand
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexRand::SysRand(void)
|
||||||
|
{
|
||||||
|
return rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexRand::Int
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexRand::Int(void)
|
||||||
|
{
|
||||||
|
seed = 1479838765 - 1471521965 * seed;
|
||||||
|
return seed & RANDOM_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexRand::Max
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexRand::Max(const int max)
|
||||||
|
{
|
||||||
|
if(max == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Int() % max;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexRand::Float
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexRand::Float(void)
|
||||||
|
{
|
||||||
|
return (float)Max(RANDOM_MAX+1) / ((float)RANDOM_MAX+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexRand::CFloat
|
||||||
|
//
|
||||||
|
|
||||||
|
float kexRand::CFloat(void)
|
||||||
|
{
|
||||||
|
return (float)(Max(20000) - 10000) * 0.0001f;
|
||||||
|
}
|
||||||
|
|
1268
src/lightmap/kexlib/math/vector.cpp
Normal file
1268
src/lightmap/kexlib/math/vector.cpp
Normal file
File diff suppressed because it is too large
Load diff
403
src/lightmap/kexlib/memheap.cpp
Normal file
403
src/lightmap/kexlib/memheap.cpp
Normal file
|
@ -0,0 +1,403 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Memory Heap Management
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "lightmap/common.h"
|
||||||
|
|
||||||
|
int kexHeap::numHeapBlocks = 0;
|
||||||
|
int kexHeap::currentHeapBlockID = -1;
|
||||||
|
|
||||||
|
kexHeapBlock *kexHeap::currentHeapBlock = NULL;
|
||||||
|
kexHeapBlock *kexHeap::blockList = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// common heap block types
|
||||||
|
//
|
||||||
|
kexHeapBlock hb_static("static", false, NULL, NULL);
|
||||||
|
kexHeapBlock hb_auto("auto", false, NULL, NULL);
|
||||||
|
kexHeapBlock hb_file("file", false, NULL, NULL);
|
||||||
|
kexHeapBlock hb_object("object", false, NULL, NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeapBlock::kexHeapBlock
|
||||||
|
//
|
||||||
|
|
||||||
|
kexHeapBlock::kexHeapBlock(const char *name, bool bGarbageCollect,
|
||||||
|
blockFunc_t funcFree, blockFunc_t funcGC)
|
||||||
|
{
|
||||||
|
this->name = (char*)name;
|
||||||
|
this->freeFunc = funcFree;
|
||||||
|
this->gcFunc = funcGC;
|
||||||
|
this->blocks = NULL;
|
||||||
|
this->bGC = bGarbageCollect;
|
||||||
|
this->purgeID = kexHeap::numHeapBlocks++;
|
||||||
|
|
||||||
|
// add heap block to main block list
|
||||||
|
if(kexHeap::blockList)
|
||||||
|
{
|
||||||
|
if(kexHeap::blockList->prev)
|
||||||
|
{
|
||||||
|
kexHeap::blockList->prev->next = this;
|
||||||
|
this->prev = kexHeap::blockList->prev;
|
||||||
|
this->next = NULL;
|
||||||
|
kexHeap::blockList->prev = this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kexHeap::blockList->prev = this;
|
||||||
|
kexHeap::blockList->next = this;
|
||||||
|
this->prev = kexHeap::blockList;
|
||||||
|
this->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kexHeap::blockList = this;
|
||||||
|
this->prev = NULL;
|
||||||
|
this->next = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeapBlock::~kexHeapBlock
|
||||||
|
//
|
||||||
|
|
||||||
|
kexHeapBlock::~kexHeapBlock(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeapBlock::operator[]
|
||||||
|
//
|
||||||
|
// Should be used with kexHeap::blockList only
|
||||||
|
//
|
||||||
|
|
||||||
|
kexHeapBlock *kexHeapBlock::operator[](int index)
|
||||||
|
{
|
||||||
|
if(kexHeap::currentHeapBlockID == index)
|
||||||
|
{
|
||||||
|
return kexHeap::currentHeapBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
kexHeapBlock *heapBlock = this;
|
||||||
|
|
||||||
|
for(int i = 0; i < index; i++)
|
||||||
|
{
|
||||||
|
heapBlock = heapBlock->next;
|
||||||
|
if(heapBlock == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kexHeap::currentHeapBlockID = index;
|
||||||
|
kexHeap::currentHeapBlock = heapBlock;
|
||||||
|
|
||||||
|
return heapBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::AddBlock
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexHeap::AddBlock(memBlock_t *block, kexHeapBlock *heapBlock)
|
||||||
|
{
|
||||||
|
block->prev = NULL;
|
||||||
|
block->next = heapBlock->blocks;
|
||||||
|
heapBlock->blocks = block;
|
||||||
|
|
||||||
|
block->heapBlock = heapBlock;
|
||||||
|
|
||||||
|
if(block->next != NULL)
|
||||||
|
{
|
||||||
|
block->next->prev = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::RemoveBlock
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexHeap::RemoveBlock(memBlock_t *block)
|
||||||
|
{
|
||||||
|
if(block->prev == NULL)
|
||||||
|
{
|
||||||
|
block->heapBlock->blocks = block->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
block->prev->next = block->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(block->next != NULL)
|
||||||
|
{
|
||||||
|
block->next->prev = block->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
block->heapBlock = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::GetBlock
|
||||||
|
//
|
||||||
|
|
||||||
|
memBlock_t *kexHeap::GetBlock(void *ptr, const char *file, int line)
|
||||||
|
{
|
||||||
|
memBlock_t* block;
|
||||||
|
|
||||||
|
block = (memBlock_t*)((byte*)ptr - sizeof(memBlock_t));
|
||||||
|
|
||||||
|
if(block->heapTag != kexHeap::HeapTag)
|
||||||
|
{
|
||||||
|
Error("kexHeap::GetBlock: found a pointer without heap tag (%s:%d)", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::Malloc
|
||||||
|
//
|
||||||
|
|
||||||
|
void *kexHeap::Malloc(int size, kexHeapBlock &heapBlock, const char *file, int line)
|
||||||
|
{
|
||||||
|
memBlock_t *newblock;
|
||||||
|
|
||||||
|
assert(size > 0);
|
||||||
|
|
||||||
|
newblock = NULL;
|
||||||
|
|
||||||
|
if(!(newblock = (memBlock_t*)malloc(sizeof(memBlock_t) + size)))
|
||||||
|
{
|
||||||
|
Error("kexHeap::Malloc: failed on allocation of %u bytes (%s:%d)", size, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
newblock->purgeID = heapBlock.purgeID;
|
||||||
|
newblock->heapTag = kexHeap::HeapTag;
|
||||||
|
newblock->size = size;
|
||||||
|
newblock->ptrRef = NULL;
|
||||||
|
|
||||||
|
kexHeap::AddBlock(newblock, &heapBlock);
|
||||||
|
|
||||||
|
return ((byte*)newblock) + sizeof(memBlock_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::Calloc
|
||||||
|
//
|
||||||
|
|
||||||
|
void *kexHeap::Calloc(int size, kexHeapBlock &heapBlock, const char *file, int line)
|
||||||
|
{
|
||||||
|
return memset(kexHeap::Malloc(size, heapBlock, file, line), 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::Realloc
|
||||||
|
//
|
||||||
|
|
||||||
|
void *kexHeap::Realloc(void *ptr, int size, kexHeapBlock &heapBlock, const char *file, int line)
|
||||||
|
{
|
||||||
|
memBlock_t *block;
|
||||||
|
memBlock_t *newblock;
|
||||||
|
|
||||||
|
if(!ptr)
|
||||||
|
{
|
||||||
|
return kexHeap::Malloc(size, heapBlock, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(size >= 0);
|
||||||
|
|
||||||
|
if(size == 0)
|
||||||
|
{
|
||||||
|
kexHeap::Free(ptr, file, line);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
block = kexHeap::GetBlock(ptr, file, line);
|
||||||
|
newblock = NULL;
|
||||||
|
|
||||||
|
kexHeap::RemoveBlock(block);
|
||||||
|
|
||||||
|
block->next = NULL;
|
||||||
|
block->prev = NULL;
|
||||||
|
|
||||||
|
if(block->ptrRef)
|
||||||
|
{
|
||||||
|
*block->ptrRef = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(newblock = (memBlock_t*)realloc(block, sizeof(memBlock_t) + size)))
|
||||||
|
{
|
||||||
|
Error("kexHeap::Realloc: failed on allocation of %u bytes (%s:%d)", size, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
newblock->purgeID = heapBlock.purgeID;
|
||||||
|
newblock->heapTag = kexHeap::HeapTag;
|
||||||
|
newblock->size = size;
|
||||||
|
newblock->ptrRef = NULL;
|
||||||
|
|
||||||
|
kexHeap::AddBlock(newblock, &heapBlock);
|
||||||
|
|
||||||
|
return ((byte*)newblock) + sizeof(memBlock_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::Alloca
|
||||||
|
//
|
||||||
|
|
||||||
|
void *kexHeap::Alloca(int size, const char *file, int line)
|
||||||
|
{
|
||||||
|
return size == 0 ? NULL : kexHeap::Calloc(size, hb_auto, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::Free
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexHeap::Free(void *ptr, const char *file, int line)
|
||||||
|
{
|
||||||
|
memBlock_t* block;
|
||||||
|
|
||||||
|
block = kexHeap::GetBlock(ptr, file, line);
|
||||||
|
if(block->ptrRef)
|
||||||
|
{
|
||||||
|
*block->ptrRef = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
kexHeap::RemoveBlock(block);
|
||||||
|
|
||||||
|
// free back to system
|
||||||
|
free(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::Purge
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexHeap::Purge(kexHeapBlock &heapBlock, const char *file, int line)
|
||||||
|
{
|
||||||
|
memBlock_t *block;
|
||||||
|
memBlock_t *next;
|
||||||
|
|
||||||
|
for(block = heapBlock.blocks; block != NULL;)
|
||||||
|
{
|
||||||
|
next = block->next;
|
||||||
|
|
||||||
|
if(block->heapTag != kexHeap::HeapTag)
|
||||||
|
{
|
||||||
|
Error("kexHeap::Purge: Purging without heap tag (%s:%d)", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(block->ptrRef)
|
||||||
|
{
|
||||||
|
*block->ptrRef = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(block);
|
||||||
|
block = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
heapBlock.blocks = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::SetCacheRef
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexHeap::SetCacheRef(void **ptr, const char *file, int line)
|
||||||
|
{
|
||||||
|
kexHeap::GetBlock(*ptr, file, line)->ptrRef = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::GarbageCollect
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexHeap::GarbageCollect(const char *file, int line)
|
||||||
|
{
|
||||||
|
kexHeap::Purge(hb_auto, file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::CheckBlocks
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexHeap::CheckBlocks(const char *file, int line)
|
||||||
|
{
|
||||||
|
memBlock_t *block;
|
||||||
|
memBlock_t *prev;
|
||||||
|
kexHeapBlock *heapBlock;
|
||||||
|
|
||||||
|
for(heapBlock = kexHeap::blockList; heapBlock; heapBlock = heapBlock->next)
|
||||||
|
{
|
||||||
|
prev = NULL;
|
||||||
|
|
||||||
|
for(block = heapBlock->blocks; block != NULL; block = block->next)
|
||||||
|
{
|
||||||
|
if(block->heapTag != kexHeap::HeapTag)
|
||||||
|
{
|
||||||
|
Error("kexHeap::CheckBlocks: found block without heap tag (%s:%d)", file, line);
|
||||||
|
}
|
||||||
|
if(block->prev != prev)
|
||||||
|
{
|
||||||
|
Error("kexHeap::CheckBlocks: bad link list found (%s:%d)", file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::Touch
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexHeap::Touch(void *ptr, const char *file, int line)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexHeap::Usage
|
||||||
|
//
|
||||||
|
|
||||||
|
int kexHeap::Usage(const kexHeapBlock &heapBlock)
|
||||||
|
{
|
||||||
|
int bytes = 0;
|
||||||
|
memBlock_t *block;
|
||||||
|
|
||||||
|
for(block = heapBlock.blocks; block != NULL; block = block->next)
|
||||||
|
{
|
||||||
|
bytes += block->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
114
src/lightmap/kexlib/memheap.h
Normal file
114
src/lightmap/kexlib/memheap.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __MEM_HEAP_H__
|
||||||
|
#define __MEM_HEAP_H__
|
||||||
|
|
||||||
|
typedef void (*blockFunc_t)(void*);
|
||||||
|
|
||||||
|
class kexHeapBlock;
|
||||||
|
|
||||||
|
typedef struct memBlock_s
|
||||||
|
{
|
||||||
|
int heapTag;
|
||||||
|
int purgeID;
|
||||||
|
int size;
|
||||||
|
kexHeapBlock *heapBlock;
|
||||||
|
void **ptrRef;
|
||||||
|
struct memBlock_s *prev;
|
||||||
|
struct memBlock_s *next;
|
||||||
|
} memBlock_t;
|
||||||
|
|
||||||
|
class kexHeapBlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexHeapBlock(const char *name, bool bGarbageCollect,
|
||||||
|
blockFunc_t funcFree, blockFunc_t funcGC);
|
||||||
|
~kexHeapBlock(void);
|
||||||
|
|
||||||
|
kexHeapBlock *operator[](int index);
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
memBlock_t *blocks;
|
||||||
|
bool bGC;
|
||||||
|
blockFunc_t freeFunc;
|
||||||
|
blockFunc_t gcFunc;
|
||||||
|
int purgeID;
|
||||||
|
kexHeapBlock *prev;
|
||||||
|
kexHeapBlock *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexHeap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void *Malloc(int size, kexHeapBlock &heapBlock, const char *file, int line);
|
||||||
|
static void *Calloc(int size, kexHeapBlock &heapBlock, const char *file, int line);
|
||||||
|
static void *Realloc(void *ptr, int size, kexHeapBlock &heapBlock, const char *file, int line);
|
||||||
|
static void *Alloca(int size, const char *file, int line);
|
||||||
|
static void Free(void *ptr, const char *file, int line);
|
||||||
|
static void Purge(kexHeapBlock &heapBlock, const char *file, int line);
|
||||||
|
static void GarbageCollect(const char *file, int line);
|
||||||
|
static void CheckBlocks(const char *file, int line);
|
||||||
|
static void Touch(void *ptr, const char *file, int line);
|
||||||
|
static int Usage(const kexHeapBlock &heapBlock);
|
||||||
|
static void SetCacheRef(void **ptr, const char *file, int line);
|
||||||
|
|
||||||
|
static int numHeapBlocks;
|
||||||
|
static kexHeapBlock *currentHeapBlock;
|
||||||
|
static int currentHeapBlockID;
|
||||||
|
static kexHeapBlock *blockList;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void AddBlock(memBlock_t *block, kexHeapBlock *heapBlock);
|
||||||
|
static void RemoveBlock(memBlock_t *block);
|
||||||
|
static memBlock_t *GetBlock(void *ptr, const char *file, int line);
|
||||||
|
|
||||||
|
static const int HeapTag = 0x03151983;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern kexHeapBlock hb_static;
|
||||||
|
extern kexHeapBlock hb_auto;
|
||||||
|
extern kexHeapBlock hb_file;
|
||||||
|
extern kexHeapBlock hb_object;
|
||||||
|
|
||||||
|
#define Mem_Malloc(s, hb) (kexHeap::Malloc(s, hb, __FILE__,__LINE__))
|
||||||
|
#define Mem_Calloc(s, hb) (kexHeap::Calloc(s, hb, __FILE__,__LINE__))
|
||||||
|
#define Mem_Realloc(p, s, hb) (kexHeap::Realloc(p, s, hb, __FILE__,__LINE__))
|
||||||
|
#define Mem_Alloca(s) (kexHeap::Alloca(s, __FILE__,__LINE__))
|
||||||
|
#define Mem_Free(p) (kexHeap::Free(p, __FILE__,__LINE__))
|
||||||
|
#define Mem_Purge(hb) (kexHeap::Purge(hb, __FILE__,__LINE__))
|
||||||
|
#define Mem_GC() (kexHeap::GarbageCollect(__FILE__,__LINE__))
|
||||||
|
#define Mem_CheckBlocks() (kexHeap::CheckBlocks(__FILE__,__LINE__))
|
||||||
|
#define Mem_Touch(p) (kexHeap::Touch(p, __FILE__,__LINE__))
|
||||||
|
#define Mem_CacheRef(p) (kexHeap::SetCacheRef(p, __FILE__,__LINE__))
|
||||||
|
|
||||||
|
#define Mem_AllocStatic(s) (Mem_Calloc(s, hb_static))
|
||||||
|
|
||||||
|
#define Mem_Strdup(s, hb) (strcpy((char*)Mem_Malloc(strlen(s)+1, hb), s))
|
||||||
|
#define Mem_Strdupa(s) (strcpy((char*)Mem_Alloca(strlen(s)+1), s))
|
||||||
|
|
||||||
|
#endif
|
1134
src/lightmap/kexlib/parser.cpp
Normal file
1134
src/lightmap/kexlib/parser.cpp
Normal file
File diff suppressed because it is too large
Load diff
175
src/lightmap/kexlib/parser.h
Normal file
175
src/lightmap/kexlib/parser.h
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __PARSER_H__
|
||||||
|
#define __PARSER_H__
|
||||||
|
|
||||||
|
#define MAX_NESTED_PARSERS 128
|
||||||
|
#define MAX_NESTED_FILENAMES 128
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TK_NONE,
|
||||||
|
TK_NUMBER,
|
||||||
|
TK_STRING,
|
||||||
|
TK_POUND,
|
||||||
|
TK_COLON,
|
||||||
|
TK_SEMICOLON,
|
||||||
|
TK_PERIOD,
|
||||||
|
TK_QUOTE,
|
||||||
|
TK_FORWARDSLASH,
|
||||||
|
TK_EQUAL,
|
||||||
|
TK_LBRACK,
|
||||||
|
TK_RBRACK,
|
||||||
|
TK_LPAREN,
|
||||||
|
TK_RPAREN,
|
||||||
|
TK_LSQBRACK,
|
||||||
|
TK_RSQBRACK,
|
||||||
|
TK_COMMA,
|
||||||
|
TK_IDENIFIER,
|
||||||
|
TK_DEFINE,
|
||||||
|
TK_UNDEF,
|
||||||
|
TK_INCLUDE,
|
||||||
|
TK_SETDIR,
|
||||||
|
TK_EOF
|
||||||
|
} tokentype_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AT_SHORT,
|
||||||
|
AT_INTEGER,
|
||||||
|
AT_FLOAT,
|
||||||
|
AT_DOUBLE,
|
||||||
|
AT_VECTOR
|
||||||
|
} arraytype_t;
|
||||||
|
|
||||||
|
#define SC_TOKEN_LEN 512
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
const char *token;
|
||||||
|
} sctokens_t;
|
||||||
|
|
||||||
|
class kexLexer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexLexer(const char *filename, char *buf, int bufSize);
|
||||||
|
~kexLexer(void);
|
||||||
|
|
||||||
|
bool CheckState(void);
|
||||||
|
void CheckKeywords(void);
|
||||||
|
void MustMatchToken(int type);
|
||||||
|
void ExpectNextToken(int type);
|
||||||
|
bool Find(void);
|
||||||
|
char GetChar(void);
|
||||||
|
void Rewind(void);
|
||||||
|
void SkipLine(void);
|
||||||
|
bool Matches(const char *string);
|
||||||
|
int GetNumber(void);
|
||||||
|
double GetFloat(void);
|
||||||
|
kexVec3 GetVector3(void);
|
||||||
|
kexVec4 GetVector4(void);
|
||||||
|
kexVec3 GetVectorString3(void);
|
||||||
|
kexVec4 GetVectorString4(void);
|
||||||
|
void GetString(void);
|
||||||
|
int GetIDForTokenList(const sctokens_t *tokenlist, const char *token);
|
||||||
|
void ExpectTokenListID(const sctokens_t *tokenlist, int id);
|
||||||
|
void AssignFromTokenList(const sctokens_t *tokenlist,
|
||||||
|
char *str, int id, bool expect);
|
||||||
|
void AssignFromTokenList(const sctokens_t *tokenlist,
|
||||||
|
unsigned int *var, int id, bool expect);
|
||||||
|
void AssignFromTokenList(const sctokens_t *tokenlist,
|
||||||
|
unsigned short *var, int id, bool expect);
|
||||||
|
void AssignFromTokenList(const sctokens_t *tokenlist,
|
||||||
|
float *var, int id, bool expect);
|
||||||
|
void AssignVectorFromTokenList(const sctokens_t *tokenlist,
|
||||||
|
float *var, int id, bool expect);
|
||||||
|
void AssignFromTokenList(const sctokens_t *tokenlist,
|
||||||
|
arraytype_t type, void **data, int count,
|
||||||
|
int id, bool expect, kexHeapBlock &hb);
|
||||||
|
|
||||||
|
int LinePos(void) { return linepos; }
|
||||||
|
int RowPos(void) { return rowpos; }
|
||||||
|
int BufferPos(void) { return buffpos; }
|
||||||
|
int BufferSize(void) { return buffsize; }
|
||||||
|
char *Buffer(void) { return buffer; }
|
||||||
|
char *StringToken(void) { return stringToken; }
|
||||||
|
const char *Token(void) const { return token; }
|
||||||
|
const int TokenType(void) const { return tokentype; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ClearToken(void);
|
||||||
|
void GetNumberToken(char initial);
|
||||||
|
void GetLetterToken(char initial);
|
||||||
|
void GetSymbolToken(char c);
|
||||||
|
void GetStringToken(void);
|
||||||
|
|
||||||
|
char token[SC_TOKEN_LEN];
|
||||||
|
char stringToken[MAX_FILEPATH];
|
||||||
|
char* buffer;
|
||||||
|
char* pointer_start;
|
||||||
|
char* pointer_end;
|
||||||
|
int linepos;
|
||||||
|
int rowpos;
|
||||||
|
int buffpos;
|
||||||
|
int buffsize;
|
||||||
|
int tokentype;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kexParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexParser(void);
|
||||||
|
~kexParser(void);
|
||||||
|
|
||||||
|
kexLexer *Open(const char *filename);
|
||||||
|
void Close(void);
|
||||||
|
void HandleError(const char *msg, ...);
|
||||||
|
void PushLexer(const char *filename, char *buf, int bufSize);
|
||||||
|
void PopLexer(void);
|
||||||
|
void PushFileName(const char *name);
|
||||||
|
void PopFileName(void);
|
||||||
|
byte *CharCode(void) { return charcode; }
|
||||||
|
const kexLexer *CurrentLexer(void) const { return currentLexer; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int OpenExternalFile(const char *name, byte **buffer) const;
|
||||||
|
const char *GetNestedFileName(void) const;
|
||||||
|
|
||||||
|
kexLexer *currentLexer;
|
||||||
|
kexLexer *lexers[MAX_NESTED_PARSERS];
|
||||||
|
int numLexers;
|
||||||
|
byte charcode[256];
|
||||||
|
char nestedFilenames[MAX_NESTED_FILENAMES][MAX_FILEPATH];
|
||||||
|
int numNestedFilenames;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern kexParser *parser;
|
||||||
|
|
||||||
|
#endif
|
1213
src/lightmap/lightmap.cpp
Normal file
1213
src/lightmap/lightmap.cpp
Normal file
File diff suppressed because it is too large
Load diff
93
src/lightmap/lightmap.h
Normal file
93
src/lightmap/lightmap.h
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __LIGHTMAP_H__
|
||||||
|
#define __LIGHTMAP_H__
|
||||||
|
|
||||||
|
#include "surfaces.h"
|
||||||
|
|
||||||
|
#define LIGHTMAP_MAX_SIZE 1024
|
||||||
|
|
||||||
|
class kexTrace;
|
||||||
|
|
||||||
|
class kexLightmapBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexLightmapBuilder(void);
|
||||||
|
~kexLightmapBuilder(void);
|
||||||
|
|
||||||
|
void BuildSurfaceParams(surface_t *surface);
|
||||||
|
void TraceSurface(surface_t *surface);
|
||||||
|
void CreateLightGrid(void);
|
||||||
|
void CreateLightmaps(kexDoomMap &doomMap);
|
||||||
|
void LightSurface(const int surfid);
|
||||||
|
void LightGrid(const int gridid);
|
||||||
|
void WriteTexturesToTGA(void);
|
||||||
|
void AddLightGridLump(kexWadFile &wadFile);
|
||||||
|
void AddLightmapLumps(kexWadFile &wadFile);
|
||||||
|
|
||||||
|
int samples;
|
||||||
|
float ambience;
|
||||||
|
int textureWidth;
|
||||||
|
int textureHeight;
|
||||||
|
|
||||||
|
static const kexVec3 gridSize;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void NewTexture(void);
|
||||||
|
bool MakeRoomForBlock(const int width, const int height, int *x, int *y, int *num);
|
||||||
|
kexBBox GetBoundsFromSurface(const surface_t *surface);
|
||||||
|
kexVec3 LightTexelSample(kexTrace &trace, const kexVec3 &origin, surface_t *surface);
|
||||||
|
kexVec3 LightCellSample(const int gridid, kexTrace &trace,
|
||||||
|
const kexVec3 &origin, const mapSubSector_t *sub);
|
||||||
|
bool EmitFromCeiling(kexTrace &trace, const surface_t *surface, const kexVec3 &origin,
|
||||||
|
const kexVec3 &normal, float *dist);
|
||||||
|
void ExportTexelsToObjFile(FILE *f, const kexVec3 &org, int indices);
|
||||||
|
void WriteBlock(FILE *f, const int i, const kexVec3 &org, int indices, kexBBox &box);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
byte marked;
|
||||||
|
byte sunShadow;
|
||||||
|
kexVec3 color;
|
||||||
|
} gridMap_t;
|
||||||
|
|
||||||
|
kexDoomMap *map;
|
||||||
|
kexArray<byte*> textures;
|
||||||
|
int **allocBlocks;
|
||||||
|
int numTextures;
|
||||||
|
int extraSamples;
|
||||||
|
int tracedTexels;
|
||||||
|
int numLightGrids;
|
||||||
|
gridMap_t *gridMap;
|
||||||
|
mapSubSector_t **gridSectors;
|
||||||
|
kexBBox worldGrid;
|
||||||
|
kexBBox gridBound;
|
||||||
|
kexVec3 gridBlock;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
464
src/lightmap/lightsurface.cpp
Normal file
464
src/lightmap/lightsurface.cpp
Normal file
|
@ -0,0 +1,464 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Special surfaces that contains origin points used for
|
||||||
|
// emitting light. Surfaces can be subdivided for more
|
||||||
|
// accurate light casting
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "mapData.h"
|
||||||
|
#include "trace.h"
|
||||||
|
#include "lightSurface.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexLightSurface::kexLightSurface
|
||||||
|
//
|
||||||
|
|
||||||
|
kexLightSurface::kexLightSurface(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexLightSurface::~kexLightSurface
|
||||||
|
//
|
||||||
|
|
||||||
|
kexLightSurface::~kexLightSurface(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexLightSurface::Init
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexLightSurface::Init(const surfaceLightDef_t &lightSurfaceDef,
|
||||||
|
surface_t *surface,
|
||||||
|
const bool bWall,
|
||||||
|
const bool bNoCenterPoint)
|
||||||
|
{
|
||||||
|
this->outerCone = lightSurfaceDef.outerCone;
|
||||||
|
this->innerCone = lightSurfaceDef.innerCone;
|
||||||
|
this->falloff = lightSurfaceDef.falloff;
|
||||||
|
this->intensity = lightSurfaceDef.intensity;
|
||||||
|
this->distance = lightSurfaceDef.distance;
|
||||||
|
this->rgb = lightSurfaceDef.rgb;
|
||||||
|
this->surface = surface;
|
||||||
|
this->bWall = bWall;
|
||||||
|
this->bNoCenterPoint = bNoCenterPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexLightSurface::CreateCenterOrigin
|
||||||
|
//
|
||||||
|
// Creates a single origin point if we're not
|
||||||
|
// intending on subdividing this light surface
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexLightSurface::CreateCenterOrigin(void)
|
||||||
|
{
|
||||||
|
if(!bWall)
|
||||||
|
{
|
||||||
|
kexVec3 center;
|
||||||
|
|
||||||
|
for(int i = 0; i < surface->numVerts; ++i)
|
||||||
|
{
|
||||||
|
center += surface->verts[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
origins.Push(center / (float)surface->numVerts);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
origins.Push(kexVec3((surface->verts[1].x + surface->verts[0].x) * 0.5f,
|
||||||
|
(surface->verts[1].y + surface->verts[0].y) * 0.5f,
|
||||||
|
(surface->verts[2].z + surface->verts[0].z) * 0.5f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexLightSurface::Clip
|
||||||
|
//
|
||||||
|
// Splits surface vertices into two groups while adding new ones
|
||||||
|
// caused by the split
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexLightSurface::Clip(vertexBatch_t &points, const kexVec3 &normal, float dist,
|
||||||
|
vertexBatch_t *frontPoints, vertexBatch_t *backPoints)
|
||||||
|
{
|
||||||
|
kexArray<float> dists;
|
||||||
|
kexArray<char> sides;
|
||||||
|
|
||||||
|
// determines what sides the vertices lies on
|
||||||
|
for(unsigned int i = 0; i < points.Length(); ++i)
|
||||||
|
{
|
||||||
|
float d = points[i].Dot(normal) - dist;
|
||||||
|
|
||||||
|
dists.Push(d);
|
||||||
|
|
||||||
|
if(d > 0.1f)
|
||||||
|
{
|
||||||
|
sides.Push(1); // front
|
||||||
|
}
|
||||||
|
else if(d < -0.1f)
|
||||||
|
{
|
||||||
|
sides.Push(-1); // directly on the split plane
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sides.Push(0); // back
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add points
|
||||||
|
for(unsigned int i = 0; i < points.Length(); ++i)
|
||||||
|
{
|
||||||
|
int next;
|
||||||
|
float frac;
|
||||||
|
kexVec3 pt1, pt2, pt3;
|
||||||
|
|
||||||
|
switch(sides[i])
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
backPoints->Push(points[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
frontPoints->Push(points[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
frontPoints->Push(points[i]);
|
||||||
|
backPoints->Push(points[i]);
|
||||||
|
|
||||||
|
// point is on the split plane so no new split vertex is needed
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the edge crosses the split plane
|
||||||
|
next = (i + 1) % points.Length();
|
||||||
|
|
||||||
|
if(sides[next] == 0 || sides[next] == sides[i])
|
||||||
|
{
|
||||||
|
// didn't cross
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pt1 = points[i];
|
||||||
|
pt2 = points[next];
|
||||||
|
|
||||||
|
// insert a new point caused by the split
|
||||||
|
frac = dists[i] / (dists[i] - dists[next]);
|
||||||
|
pt3 = pt1.Lerp(pt2, frac);
|
||||||
|
|
||||||
|
frontPoints->Push(pt3);
|
||||||
|
backPoints->Push(pt3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexLightSurface::SubdivideRecursion
|
||||||
|
//
|
||||||
|
// Recursively divides the surface
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexLightSurface::SubdivideRecursion(vertexBatch_t &surfPoints, float divide,
|
||||||
|
kexArray<vertexBatch_t*> &points)
|
||||||
|
{
|
||||||
|
kexBBox bounds;
|
||||||
|
kexVec3 splitNormal;
|
||||||
|
float dist;
|
||||||
|
vertexBatch_t *frontPoints;
|
||||||
|
vertexBatch_t *backPoints;
|
||||||
|
|
||||||
|
// get bounds from current set of points
|
||||||
|
for(unsigned int i = 0; i < surfPoints.Length(); ++i)
|
||||||
|
{
|
||||||
|
bounds.AddPoint(surfPoints[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
// check if its large enough to be divided
|
||||||
|
if((bounds.max[i] - bounds.min[i]) > divide)
|
||||||
|
{
|
||||||
|
splitNormal.Clear();
|
||||||
|
splitNormal[i] = 1;
|
||||||
|
|
||||||
|
dist = (bounds.max[i] + bounds.min[i]) * 0.5f;
|
||||||
|
|
||||||
|
frontPoints = new vertexBatch_t;
|
||||||
|
backPoints = new vertexBatch_t;
|
||||||
|
|
||||||
|
// start clipping
|
||||||
|
Clip(surfPoints, splitNormal, dist, frontPoints, backPoints);
|
||||||
|
|
||||||
|
if(!SubdivideRecursion(*frontPoints, divide, points))
|
||||||
|
{
|
||||||
|
points.Push(frontPoints);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete frontPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!SubdivideRecursion(*backPoints, divide, points))
|
||||||
|
{
|
||||||
|
points.Push(backPoints);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete backPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexLightSurface::Subdivide
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexLightSurface::Subdivide(const float divide)
|
||||||
|
{
|
||||||
|
kexArray<vertexBatch_t*> points;
|
||||||
|
vertexBatch_t surfPoints;
|
||||||
|
|
||||||
|
for(int i = 0; i < surface->numVerts; ++i)
|
||||||
|
{
|
||||||
|
surfPoints.Push(surface->verts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
SubdivideRecursion(surfPoints, divide, points);
|
||||||
|
|
||||||
|
// from each group of vertices caused by the split, begin
|
||||||
|
// creating a origin point based on the center of that group
|
||||||
|
for(unsigned int i = 0; i < points.Length(); ++i)
|
||||||
|
{
|
||||||
|
vertexBatch_t *vb = points[i];
|
||||||
|
kexVec3 center;
|
||||||
|
|
||||||
|
for(unsigned int j = 0; j < vb->Length(); ++j)
|
||||||
|
{
|
||||||
|
center += (*vb)[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
origins.Push(center / (float)vb->Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < points.Length(); ++i)
|
||||||
|
{
|
||||||
|
vertexBatch_t *vb = points[i];
|
||||||
|
|
||||||
|
vb->Empty();
|
||||||
|
delete vb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexLightSurface::TraceSurface
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexLightSurface::TraceSurface(kexDoomMap *doomMap, kexTrace &trace, const surface_t *surf,
|
||||||
|
const kexVec3 &origin, float *dist)
|
||||||
|
{
|
||||||
|
kexVec3 normal;
|
||||||
|
kexVec3 lnormal;
|
||||||
|
kexVec3 center;
|
||||||
|
bool bInside;
|
||||||
|
float angle;
|
||||||
|
float curDist;
|
||||||
|
|
||||||
|
*dist = -M_INFINITY;
|
||||||
|
|
||||||
|
// light surface will always be fullbright
|
||||||
|
if(surf == surface)
|
||||||
|
{
|
||||||
|
*dist = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bInside = false;
|
||||||
|
|
||||||
|
// nudge the origin around to see if it's actually in the subsector
|
||||||
|
float nudges[4] = { -2, 2, -4, 4 };
|
||||||
|
|
||||||
|
for(int x = 0; x < 4; x++)
|
||||||
|
{
|
||||||
|
for(int y = 0; y < 4; y++)
|
||||||
|
{
|
||||||
|
if(doomMap->PointInsideSubSector(origin.x + nudges[x],
|
||||||
|
origin.y + nudges[y], surface->subSector))
|
||||||
|
{
|
||||||
|
bInside = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bInside)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lnormal = surface->plane.Normal();
|
||||||
|
|
||||||
|
if(surf)
|
||||||
|
{
|
||||||
|
normal = surf->plane.Normal();
|
||||||
|
|
||||||
|
if(normal.Dot(lnormal) > 0)
|
||||||
|
{
|
||||||
|
// not facing the light surface
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
normal = kexVec3::vecUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need to pick the closest sample point on the light surface. what really sucks is
|
||||||
|
// that we have to trace each one... which could really blow up the compile time
|
||||||
|
for(unsigned int i = 0; i < origins.Length(); ++i)
|
||||||
|
{
|
||||||
|
center = origins[i];
|
||||||
|
|
||||||
|
if(!bWall && origin.z > center.z)
|
||||||
|
{
|
||||||
|
// origin is not going to seen or traced by the light surface
|
||||||
|
// so don't even bother. this also fixes some bizzare light
|
||||||
|
// bleeding issues
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bWall)
|
||||||
|
{
|
||||||
|
angle = (origin - center).ToVec2().Normalize().Dot(lnormal.ToVec2());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kexVec3 dir = (origin - center).Normalize();
|
||||||
|
|
||||||
|
if(surf)
|
||||||
|
{
|
||||||
|
if(normal.Dot(dir) >= 0)
|
||||||
|
{
|
||||||
|
// not even facing the light surface
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
angle = dir.Dot(lnormal);
|
||||||
|
|
||||||
|
if(angle > innerCone)
|
||||||
|
{
|
||||||
|
angle = innerCone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!bInside && angle < outerCone)
|
||||||
|
{
|
||||||
|
// out of the cone range
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bWall)
|
||||||
|
{
|
||||||
|
if(origin.z >= surface->verts[0].z && origin.z <= surface->verts[2].z)
|
||||||
|
{
|
||||||
|
// since walls are always vertically straight, we can cheat a little by adjusting
|
||||||
|
// the sampling point height. this also allows us to do accurate light emitting
|
||||||
|
// while just using one sample point
|
||||||
|
center.z = origin.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trace the origin to the center of the light surface. nudge by the normals in
|
||||||
|
// case the start/end points are directly on or inside the surface
|
||||||
|
trace.Trace(center + lnormal, origin + normal);
|
||||||
|
|
||||||
|
if(trace.fraction != 1)
|
||||||
|
{
|
||||||
|
// something is obstructing it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float d = origin.Distance(center);
|
||||||
|
|
||||||
|
if(d <= 0)
|
||||||
|
{
|
||||||
|
// this origin point must be right on the light surface so just mark it as
|
||||||
|
// full bright if that's the case
|
||||||
|
curDist = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curDist = distance / d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(curDist >= 1)
|
||||||
|
{
|
||||||
|
curDist = 1;
|
||||||
|
|
||||||
|
// might get large unlit gaps near the surface. this looks a lot worse for
|
||||||
|
// non-wall light surfaces so just clamp to full bright and exit out.
|
||||||
|
if(!bWall)
|
||||||
|
{
|
||||||
|
*dist = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine how much to fade out
|
||||||
|
if(angle < innerCone)
|
||||||
|
{
|
||||||
|
float div = (innerCone - outerCone);
|
||||||
|
|
||||||
|
if(div != 0)
|
||||||
|
{
|
||||||
|
curDist *= ((angle - outerCone) / div);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curDist *= angle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(curDist > *dist)
|
||||||
|
{
|
||||||
|
*dist = curDist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *dist > 0;
|
||||||
|
}
|
92
src/lightmap/lightsurface.h
Normal file
92
src/lightmap/lightsurface.h
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __LIGHT_SURFACE_H__
|
||||||
|
#define __LIGHT_SURFACE_H__
|
||||||
|
|
||||||
|
#include "surfaces.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int tag;
|
||||||
|
float outerCone;
|
||||||
|
float innerCone;
|
||||||
|
float falloff;
|
||||||
|
float distance;
|
||||||
|
float intensity;
|
||||||
|
bool bIgnoreFloor;
|
||||||
|
bool bIgnoreCeiling;
|
||||||
|
bool bNoCenterPoint;
|
||||||
|
kexVec3 rgb;
|
||||||
|
} surfaceLightDef_t;
|
||||||
|
|
||||||
|
class kexDoomMap;
|
||||||
|
class kexTrace;
|
||||||
|
|
||||||
|
class kexLightSurface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexLightSurface(void);
|
||||||
|
~kexLightSurface(void);
|
||||||
|
|
||||||
|
void Init(const surfaceLightDef_t &lightSurfaceDef, surface_t *surface,
|
||||||
|
const bool bWall, const bool bNoCenterPoint);
|
||||||
|
void Subdivide(const float divide);
|
||||||
|
void CreateCenterOrigin(void);
|
||||||
|
bool TraceSurface(kexDoomMap *doomMap, kexTrace &trace, const surface_t *surface,
|
||||||
|
const kexVec3 &origin, float *dist);
|
||||||
|
|
||||||
|
const float OuterCone(void) const { return outerCone; }
|
||||||
|
const float InnerCone(void) const { return innerCone; }
|
||||||
|
const float FallOff(void) const { return falloff; }
|
||||||
|
const float Distance(void) const { return distance; }
|
||||||
|
const float Intensity(void) const { return intensity; }
|
||||||
|
const kexVec3 GetRGB(void) const { return rgb; }
|
||||||
|
const bool IsAWall(void) const { return bWall; }
|
||||||
|
const bool NoCenterPoint(void) const { return bNoCenterPoint; }
|
||||||
|
const surface_t *Surface(void) const { return surface; }
|
||||||
|
const vertexBatch_t Origins(void) const { return origins; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool SubdivideRecursion(vertexBatch_t &surfPoints, float divide,
|
||||||
|
kexArray<vertexBatch_t*> &points);
|
||||||
|
void Clip(vertexBatch_t &points, const kexVec3 &normal, float dist,
|
||||||
|
vertexBatch_t *frontPoints, vertexBatch_t *backPoints);
|
||||||
|
|
||||||
|
float outerCone;
|
||||||
|
float innerCone;
|
||||||
|
float falloff;
|
||||||
|
float distance;
|
||||||
|
float intensity;
|
||||||
|
kexVec3 rgb;
|
||||||
|
bool bWall;
|
||||||
|
bool bNoCenterPoint;
|
||||||
|
vertexBatch_t origins;
|
||||||
|
surface_t *surface;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
957
src/lightmap/mapdata.cpp
Normal file
957
src/lightmap/mapdata.cpp
Normal file
|
@ -0,0 +1,957 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: General doom map utilities and data preperation
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "wad.h"
|
||||||
|
#include "kexlib/parser.h"
|
||||||
|
#include "mapData.h"
|
||||||
|
#include "lightSurface.h"
|
||||||
|
|
||||||
|
const kexVec3 kexDoomMap::defaultSunColor(1, 1, 1);
|
||||||
|
const kexVec3 kexDoomMap::defaultSunDirection(0.45f, 0.3f, 0.9f);
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::kexDoomMap
|
||||||
|
//
|
||||||
|
|
||||||
|
kexDoomMap::kexDoomMap(void)
|
||||||
|
{
|
||||||
|
this->mapLines = NULL;
|
||||||
|
this->mapVerts = NULL;
|
||||||
|
this->mapSides = NULL;
|
||||||
|
this->mapSectors = NULL;
|
||||||
|
this->mapSegs = NULL;
|
||||||
|
this->mapSSects = NULL;
|
||||||
|
this->nodes = NULL;
|
||||||
|
this->leafs = NULL;
|
||||||
|
this->segLeafLookup = NULL;
|
||||||
|
this->ssLeafLookup = NULL;
|
||||||
|
this->ssLeafCount = NULL;
|
||||||
|
this->segSurfaces[0] = NULL;
|
||||||
|
this->segSurfaces[1] = NULL;
|
||||||
|
this->segSurfaces[2] = NULL;
|
||||||
|
this->leafSurfaces[0] = NULL;
|
||||||
|
this->leafSurfaces[1] = NULL;
|
||||||
|
this->vertexes = NULL;
|
||||||
|
this->mapPVS = NULL;
|
||||||
|
this->mapDef = NULL;
|
||||||
|
|
||||||
|
this->numLeafs = 0;
|
||||||
|
this->numLines = 0;
|
||||||
|
this->numVerts = 0;
|
||||||
|
this->numSides = 0;
|
||||||
|
this->numSectors = 0;
|
||||||
|
this->numSegs = 0;
|
||||||
|
this->numSSects = 0;
|
||||||
|
this->numNodes = 0;
|
||||||
|
this->numVertexes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::~kexDoomMap
|
||||||
|
//
|
||||||
|
|
||||||
|
kexDoomMap::~kexDoomMap(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::BuildMapFromWad
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::BuildMapFromWad(kexWadFile &wadFile)
|
||||||
|
{
|
||||||
|
wadFile.GetMapLump<mapThing_t>(ML_THINGS, &mapThings, &numThings);
|
||||||
|
wadFile.GetMapLump<mapVertex_t>(ML_VERTEXES, &mapVerts, &numVerts);
|
||||||
|
wadFile.GetMapLump<mapLineDef_t>(ML_LINEDEFS, &mapLines, &numLines);
|
||||||
|
wadFile.GetMapLump<mapSideDef_t>(ML_SIDEDEFS, &mapSides, &numSides);
|
||||||
|
wadFile.GetMapLump<mapSector_t>(ML_SECTORS, &mapSectors, &numSectors);
|
||||||
|
|
||||||
|
wadFile.GetGLMapLump<glSeg_t>(ML_GL_SEGS, &mapSegs, &numSegs);
|
||||||
|
wadFile.GetGLMapLump<mapSubSector_t>(ML_GL_SSECT, &mapSSects, &numSSects);
|
||||||
|
wadFile.GetGLMapLump<mapNode_t>(ML_GL_NODES, &nodes, &numNodes);
|
||||||
|
wadFile.GetGLMapLump<byte>(ML_GL_PVS, &mapPVS, 0);
|
||||||
|
|
||||||
|
if(mapSegs == NULL)
|
||||||
|
{
|
||||||
|
Error("kexDoomMap::BuildMapFromWad: SEGS lump not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(mapSSects == NULL)
|
||||||
|
{
|
||||||
|
Error("kexDoomMap::BuildMapFromWad: SSECTORS lump not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(nodes == NULL)
|
||||||
|
{
|
||||||
|
Error("kexDoomMap::BuildMapFromWad: NODES lump not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < mapDefs.Length(); ++i)
|
||||||
|
{
|
||||||
|
if(mapDefs[i].map == wadFile.currentmap)
|
||||||
|
{
|
||||||
|
mapDef = &mapDefs[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("------------- Level Info -------------\n");
|
||||||
|
printf("Vertices: %i\n", numVerts);
|
||||||
|
printf("Segments: %i\n", numSegs);
|
||||||
|
printf("Subsectors: %i\n", numSSects);
|
||||||
|
|
||||||
|
BuildVertexes(wadFile);
|
||||||
|
BuildNodeBounds();
|
||||||
|
BuildLeafs();
|
||||||
|
BuildPVS();
|
||||||
|
CheckSkySectors();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::CheckSkySectors
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::CheckSkySectors(void)
|
||||||
|
{
|
||||||
|
char name[9];
|
||||||
|
|
||||||
|
bSkySectors = (bool*)Mem_Calloc(sizeof(bool) * numSectors, hb_static);
|
||||||
|
bSSectsVisibleToSky = (bool*)Mem_Calloc(sizeof(bool) * numSSects, hb_static);
|
||||||
|
|
||||||
|
for(int i = 0; i < numSectors; ++i)
|
||||||
|
{
|
||||||
|
if(mapDef->sunIgnoreTag != 0 && mapSectors[i].tag == mapDef->sunIgnoreTag)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(name, mapSectors[i].ceilingpic, 8);
|
||||||
|
name[8] = 0;
|
||||||
|
|
||||||
|
if(!strncmp(name, "F_SKY001", 8))
|
||||||
|
{
|
||||||
|
bSkySectors[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to early out by quickly checking which subsector can potentially
|
||||||
|
// see a sky sector
|
||||||
|
for(int i = 0; i < numSSects; ++i)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < numSSects; ++j)
|
||||||
|
{
|
||||||
|
mapSector_t *sec = GetSectorFromSubSector(&mapSSects[j]);
|
||||||
|
|
||||||
|
if(bSkySectors[sec - mapSectors] == false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CheckPVS(&mapSSects[i], &mapSSects[j]))
|
||||||
|
{
|
||||||
|
bSSectsVisibleToSky[i] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::BuildPVS
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::BuildPVS(void)
|
||||||
|
{
|
||||||
|
// don't do anything if already loaded
|
||||||
|
if(mapPVS != NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = ((numSSects + 7) / 8) * numSSects;
|
||||||
|
mapPVS = (byte*)Mem_Malloc(len, hb_static);
|
||||||
|
memset(mapPVS, 0xff, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::CheckPVS
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexDoomMap::CheckPVS(mapSubSector_t *s1, mapSubSector_t *s2)
|
||||||
|
{
|
||||||
|
byte *vis;
|
||||||
|
int n1, n2;
|
||||||
|
|
||||||
|
n1 = s1 - mapSSects;
|
||||||
|
n2 = s2 - mapSSects;
|
||||||
|
|
||||||
|
vis = &mapPVS[(((numSSects + 7) / 8) * n1)];
|
||||||
|
|
||||||
|
return ((vis[n2 >> 3] & (1 << (n2 & 7))) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::BuildVertexes
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::BuildVertexes(kexWadFile &wadFile)
|
||||||
|
{
|
||||||
|
byte *data;
|
||||||
|
int count;
|
||||||
|
glVert_t *verts;
|
||||||
|
lump_t *lump;
|
||||||
|
|
||||||
|
if(!(lump = wadFile.GetGLMapLump(static_cast<glMapLumps_t>(ML_GL_VERTS))))
|
||||||
|
{
|
||||||
|
Error("kexDoomMap::BuildVertexes: GL_VERTS lump not found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = wadFile.GetLumpData(lump);
|
||||||
|
|
||||||
|
if(*((int*)data) != gNd2)
|
||||||
|
{
|
||||||
|
Error("kexDoomMap::BuildVertexes: GL_VERTS must be version 2 only");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
verts = (glVert_t*)(data + GL_VERT_OFFSET);
|
||||||
|
count = (lump->size - GL_VERT_OFFSET) / sizeof(glVert_t);
|
||||||
|
|
||||||
|
numVertexes = numVerts + count;
|
||||||
|
vertexes = (vertex_t*)Mem_Calloc(sizeof(vertex_t) * numVertexes, hb_static);
|
||||||
|
|
||||||
|
for(int i = 0; i < numVerts; i++)
|
||||||
|
{
|
||||||
|
vertexes[i].x = F(mapVerts[i].x << 16);
|
||||||
|
vertexes[i].y = F(mapVerts[i].y << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
vertexes[numVerts + i].x = F(verts[i].x);
|
||||||
|
vertexes[numVerts + i].y = F(verts[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::BuildNodeBounds
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::BuildNodeBounds(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
kexVec3 point;
|
||||||
|
float high = -M_INFINITY;
|
||||||
|
float low = M_INFINITY;
|
||||||
|
|
||||||
|
nodeBounds = (kexBBox*)Mem_Calloc(sizeof(kexBBox) * numNodes, hb_static);
|
||||||
|
|
||||||
|
for(i = 0; i < numSectors; ++i)
|
||||||
|
{
|
||||||
|
if(mapSectors[i].ceilingheight > high)
|
||||||
|
{
|
||||||
|
high = mapSectors[i].ceilingheight;
|
||||||
|
}
|
||||||
|
if(mapSectors[i].floorheight < low)
|
||||||
|
{
|
||||||
|
low = mapSectors[i].floorheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < numNodes; ++i)
|
||||||
|
{
|
||||||
|
nodeBounds[i].Clear();
|
||||||
|
|
||||||
|
for(j = 0; j < 2; ++j)
|
||||||
|
{
|
||||||
|
point.Set(nodes[i].bbox[j][BOXLEFT], nodes[i].bbox[j][BOXBOTTOM], low);
|
||||||
|
nodeBounds[i].AddPoint(point);
|
||||||
|
point.Set(nodes[i].bbox[j][BOXRIGHT], nodes[i].bbox[j][BOXTOP], high);
|
||||||
|
nodeBounds[i].AddPoint(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::BuildLeafs
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::BuildLeafs(void)
|
||||||
|
{
|
||||||
|
mapSubSector_t *ss;
|
||||||
|
leaf_t *lf;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
kexVec3 point;
|
||||||
|
mapSector_t *sector;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
leafs = (leaf_t*)Mem_Calloc(sizeof(leaf_t*) * numSegs * 2, hb_static);
|
||||||
|
numLeafs = numSSects;
|
||||||
|
|
||||||
|
ss = mapSSects;
|
||||||
|
|
||||||
|
segLeafLookup = (int*)Mem_Calloc(sizeof(int) * numSegs, hb_static);
|
||||||
|
ssLeafLookup = (int*)Mem_Calloc(sizeof(int) * numSSects, hb_static);
|
||||||
|
ssLeafCount = (int*)Mem_Calloc(sizeof(int) * numSSects, hb_static);
|
||||||
|
ssLeafBounds = (kexBBox*)Mem_Calloc(sizeof(kexBBox) * numSSects, hb_static);
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < numSSects; ++i, ++ss)
|
||||||
|
{
|
||||||
|
ssLeafCount[i] = ss->numsegs;
|
||||||
|
ssLeafLookup[i] = ss->firstseg;
|
||||||
|
|
||||||
|
ssLeafBounds[i].Clear();
|
||||||
|
sector = GetSectorFromSubSector(ss);
|
||||||
|
|
||||||
|
if(ss->numsegs)
|
||||||
|
{
|
||||||
|
for(j = 0; j < ss->numsegs; ++j)
|
||||||
|
{
|
||||||
|
glSeg_t *seg = &mapSegs[ss->firstseg + j];
|
||||||
|
lf = &leafs[count++];
|
||||||
|
|
||||||
|
segLeafLookup[ss->firstseg + j] = i;
|
||||||
|
|
||||||
|
lf->vertex = GetSegVertex(seg->v1);
|
||||||
|
lf->seg = seg;
|
||||||
|
|
||||||
|
point.Set(lf->vertex->x, lf->vertex->y, sector->floorheight);
|
||||||
|
ssLeafBounds[i].AddPoint(point);
|
||||||
|
|
||||||
|
point.z = sector->ceilingheight;
|
||||||
|
ssLeafBounds[i].AddPoint(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::GetSegVertex
|
||||||
|
//
|
||||||
|
|
||||||
|
vertex_t *kexDoomMap::GetSegVertex(int index)
|
||||||
|
{
|
||||||
|
if(index & 0x8000)
|
||||||
|
{
|
||||||
|
index = (index & 0x7FFF) + numVerts;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &vertexes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::GetSideDef
|
||||||
|
//
|
||||||
|
|
||||||
|
mapSideDef_t *kexDoomMap::GetSideDef(const glSeg_t *seg)
|
||||||
|
{
|
||||||
|
mapLineDef_t *line;
|
||||||
|
|
||||||
|
if(seg->linedef == NO_LINE_INDEX)
|
||||||
|
{
|
||||||
|
// skip minisegs
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
line = &mapLines[seg->linedef];
|
||||||
|
return &mapSides[line->sidenum[seg->side]];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::GetFrontSector
|
||||||
|
//
|
||||||
|
|
||||||
|
mapSector_t *kexDoomMap::GetFrontSector(const glSeg_t *seg)
|
||||||
|
{
|
||||||
|
mapSideDef_t *side = GetSideDef(seg);
|
||||||
|
|
||||||
|
if(side == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &mapSectors[side->sector];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::GetBackSector
|
||||||
|
//
|
||||||
|
|
||||||
|
mapSector_t *kexDoomMap::GetBackSector(const glSeg_t *seg)
|
||||||
|
{
|
||||||
|
mapLineDef_t *line;
|
||||||
|
|
||||||
|
if(seg->linedef == NO_LINE_INDEX)
|
||||||
|
{
|
||||||
|
// skip minisegs
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
line = &mapLines[seg->linedef];
|
||||||
|
|
||||||
|
if(line->flags & ML_TWOSIDED)
|
||||||
|
{
|
||||||
|
mapSideDef_t *backSide = &mapSides[line->sidenum[seg->side^1]];
|
||||||
|
return &mapSectors[backSide->sector];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::GetSectorFromSubSector
|
||||||
|
//
|
||||||
|
|
||||||
|
mapSector_t *kexDoomMap::GetSectorFromSubSector(const mapSubSector_t *sub)
|
||||||
|
{
|
||||||
|
mapSector_t *sector = NULL;
|
||||||
|
|
||||||
|
// try to find a sector that the subsector belongs to
|
||||||
|
for(int i = 0; i < sub->numsegs; i++)
|
||||||
|
{
|
||||||
|
glSeg_t *seg = &mapSegs[sub->firstseg + i];
|
||||||
|
if(seg->side != NO_SIDE_INDEX)
|
||||||
|
{
|
||||||
|
sector = GetFrontSector(seg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sector;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::PointInSubSector
|
||||||
|
//
|
||||||
|
|
||||||
|
mapSubSector_t *kexDoomMap::PointInSubSector(const int x, const int y)
|
||||||
|
{
|
||||||
|
mapNode_t *node;
|
||||||
|
int side;
|
||||||
|
int nodenum;
|
||||||
|
kexVec3 dp1;
|
||||||
|
kexVec3 dp2;
|
||||||
|
float d;
|
||||||
|
|
||||||
|
// single subsector is a special case
|
||||||
|
if(!numNodes)
|
||||||
|
{
|
||||||
|
return &mapSSects[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
nodenum = numNodes - 1;
|
||||||
|
|
||||||
|
while(!(nodenum & NF_SUBSECTOR) )
|
||||||
|
{
|
||||||
|
node = &nodes[nodenum];
|
||||||
|
|
||||||
|
kexVec3 pt1(F(node->x << 16), F(node->y << 16), 0);
|
||||||
|
kexVec3 pt2(F(node->dx << 16), F(node->dy << 16), 0);
|
||||||
|
kexVec3 pos(F(x << 16), F(y << 16), 0);
|
||||||
|
|
||||||
|
dp1 = pt1 - pos;
|
||||||
|
dp2 = (pt2 + pt1) - pos;
|
||||||
|
d = dp1.Cross(dp2).z;
|
||||||
|
|
||||||
|
side = FLOATSIGNBIT(d);
|
||||||
|
|
||||||
|
nodenum = node->children[side ^ 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return &mapSSects[nodenum & ~NF_SUBSECTOR];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::PointInsideSubSector
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexDoomMap::PointInsideSubSector(const float x, const float y, const mapSubSector_t *sub)
|
||||||
|
{
|
||||||
|
surface_t *surf;
|
||||||
|
int i;
|
||||||
|
kexVec2 p(x, y);
|
||||||
|
kexVec2 dp1, dp2;
|
||||||
|
kexVec2 pt1, pt2;
|
||||||
|
|
||||||
|
surf = leafSurfaces[0][sub - mapSSects];
|
||||||
|
|
||||||
|
// check to see if the point is inside the subsector leaf
|
||||||
|
for(i = 0; i < surf->numVerts; i++)
|
||||||
|
{
|
||||||
|
pt1 = surf->verts[i].ToVec2();
|
||||||
|
pt2 = surf->verts[(i+1)%surf->numVerts].ToVec2();
|
||||||
|
|
||||||
|
dp1 = pt1 - p;
|
||||||
|
dp2 = pt2 - p;
|
||||||
|
|
||||||
|
if(dp1.CrossScalar(dp2) < 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this point is outside the subsector leaf
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::LineIntersectSubSector
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexDoomMap::LineIntersectSubSector(const kexVec3 &start, const kexVec3 &end,
|
||||||
|
const mapSubSector_t *sub, kexVec2 &out)
|
||||||
|
{
|
||||||
|
surface_t *surf;
|
||||||
|
kexVec2 p1, p2;
|
||||||
|
kexVec2 s1, s2;
|
||||||
|
kexVec2 pt;
|
||||||
|
kexVec2 v;
|
||||||
|
float d, u;
|
||||||
|
float newX;
|
||||||
|
float ab;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
surf = leafSurfaces[0][sub - mapSSects];
|
||||||
|
p1 = start.ToVec2();
|
||||||
|
p2 = end.ToVec2();
|
||||||
|
|
||||||
|
for(i = 0; i < surf->numVerts; i++)
|
||||||
|
{
|
||||||
|
s1 = surf->verts[i].ToVec2();
|
||||||
|
s2 = surf->verts[(i+1)%surf->numVerts].ToVec2();
|
||||||
|
|
||||||
|
if((p1 == p2) || (s1 == s2))
|
||||||
|
{
|
||||||
|
// zero length
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((p1 == s1) || (p2 == s1) || (p1 == s2) || (p2 == s2))
|
||||||
|
{
|
||||||
|
// shares end point
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// translate to origin
|
||||||
|
pt = p2 - p1;
|
||||||
|
s1 -= p1;
|
||||||
|
s2 -= p1;
|
||||||
|
|
||||||
|
// normalize
|
||||||
|
u = pt.UnitSq();
|
||||||
|
d = kexMath::InvSqrt(u);
|
||||||
|
v = (pt * d);
|
||||||
|
|
||||||
|
// rotate points s1 and s2 so they're on the positive x axis
|
||||||
|
newX = s1.Dot(v);
|
||||||
|
s1.y = s1.CrossScalar(v);
|
||||||
|
s1.x = newX;
|
||||||
|
|
||||||
|
newX = s2.Dot(v);
|
||||||
|
s2.y = s2.CrossScalar(v);
|
||||||
|
s2.x = newX;
|
||||||
|
|
||||||
|
if((s1.y < 0 && s2.y < 0) || (s1.y >= 0 && s2.y >= 0))
|
||||||
|
{
|
||||||
|
// s1 and s2 didn't cross
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ab = s2.x + (s1.x - s2.x) * s2.y / (s2.y - s1.y);
|
||||||
|
|
||||||
|
if(ab < 0 || ab > (u * d))
|
||||||
|
{
|
||||||
|
// s1 and s2 crosses but outside of points p1 and p2
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// intersected
|
||||||
|
out = p1 + (v * ab);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::GetSunColor
|
||||||
|
//
|
||||||
|
|
||||||
|
const kexVec3 &kexDoomMap::GetSunColor(void) const
|
||||||
|
{
|
||||||
|
if(mapDef != NULL)
|
||||||
|
{
|
||||||
|
return mapDef->sunColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultSunColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::GetSunDirection
|
||||||
|
//
|
||||||
|
|
||||||
|
const kexVec3 &kexDoomMap::GetSunDirection(void) const
|
||||||
|
{
|
||||||
|
if(mapDef != NULL)
|
||||||
|
{
|
||||||
|
return mapDef->sunDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultSunDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::ParseConfigFile
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::ParseConfigFile(const char *file)
|
||||||
|
{
|
||||||
|
kexLexer *lexer;
|
||||||
|
|
||||||
|
if(!(lexer = parser->Open(file)))
|
||||||
|
{
|
||||||
|
Error("kexDoomMap::ParseConfigFile: %s not found\n", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(lexer->CheckState())
|
||||||
|
{
|
||||||
|
lexer->Find();
|
||||||
|
|
||||||
|
// check for mapdef block
|
||||||
|
if(lexer->Matches("mapdef"))
|
||||||
|
{
|
||||||
|
mapDef_t mapDef;
|
||||||
|
|
||||||
|
mapDef.map = -1;
|
||||||
|
mapDef.sunIgnoreTag = 0;
|
||||||
|
|
||||||
|
lexer->ExpectNextToken(TK_LBRACK);
|
||||||
|
lexer->Find();
|
||||||
|
|
||||||
|
while(lexer->TokenType() != TK_RBRACK)
|
||||||
|
{
|
||||||
|
if(lexer->Matches("map"))
|
||||||
|
{
|
||||||
|
mapDef.map = lexer->GetNumber();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("sun_ignore_tag"))
|
||||||
|
{
|
||||||
|
mapDef.sunIgnoreTag = lexer->GetNumber();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("sun_direction"))
|
||||||
|
{
|
||||||
|
mapDef.sunDir = lexer->GetVectorString3();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("sun_color"))
|
||||||
|
{
|
||||||
|
mapDef.sunColor = lexer->GetVectorString3();
|
||||||
|
mapDef.sunColor /= 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->Find();
|
||||||
|
}
|
||||||
|
|
||||||
|
mapDefs.Push(mapDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for lightdef block
|
||||||
|
if(lexer->Matches("lightdef"))
|
||||||
|
{
|
||||||
|
lightDef_t lightDef;
|
||||||
|
|
||||||
|
lightDef.doomednum = -1;
|
||||||
|
lightDef.height = 0;
|
||||||
|
lightDef.intensity = 2;
|
||||||
|
lightDef.falloff = 1;
|
||||||
|
lightDef.bCeiling = false;
|
||||||
|
|
||||||
|
lexer->ExpectNextToken(TK_LBRACK);
|
||||||
|
lexer->Find();
|
||||||
|
|
||||||
|
while(lexer->TokenType() != TK_RBRACK)
|
||||||
|
{
|
||||||
|
if(lexer->Matches("doomednum"))
|
||||||
|
{
|
||||||
|
lightDef.doomednum = lexer->GetNumber();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("rgb"))
|
||||||
|
{
|
||||||
|
lightDef.rgb = lexer->GetVectorString3();
|
||||||
|
lightDef.rgb /= 255.0f;
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("height"))
|
||||||
|
{
|
||||||
|
lightDef.height = (float)lexer->GetFloat();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("radius"))
|
||||||
|
{
|
||||||
|
lightDef.radius = (float)lexer->GetFloat();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("intensity"))
|
||||||
|
{
|
||||||
|
lightDef.intensity = (float)lexer->GetFloat();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("falloff"))
|
||||||
|
{
|
||||||
|
lightDef.falloff = (float)lexer->GetFloat();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("ceiling"))
|
||||||
|
{
|
||||||
|
lightDef.bCeiling = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->Find();
|
||||||
|
}
|
||||||
|
|
||||||
|
lightDefs.Push(lightDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lexer->Matches("surfaceLight"))
|
||||||
|
{
|
||||||
|
surfaceLightDef_t surfaceLight;
|
||||||
|
|
||||||
|
surfaceLight.tag = 0;
|
||||||
|
surfaceLight.outerCone = 1.0f;
|
||||||
|
surfaceLight.innerCone = 0;
|
||||||
|
surfaceLight.falloff = 1.0f;
|
||||||
|
surfaceLight.intensity = 1.0f;
|
||||||
|
surfaceLight.distance = 32.0f;
|
||||||
|
surfaceLight.bIgnoreCeiling = false;
|
||||||
|
surfaceLight.bIgnoreFloor = false;
|
||||||
|
surfaceLight.bNoCenterPoint = false;
|
||||||
|
|
||||||
|
lexer->ExpectNextToken(TK_LBRACK);
|
||||||
|
lexer->Find();
|
||||||
|
|
||||||
|
while(lexer->TokenType() != TK_RBRACK)
|
||||||
|
{
|
||||||
|
if(lexer->Matches("tag"))
|
||||||
|
{
|
||||||
|
surfaceLight.tag = lexer->GetNumber();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("rgb"))
|
||||||
|
{
|
||||||
|
surfaceLight.rgb = lexer->GetVectorString3();
|
||||||
|
surfaceLight.rgb /= 255.0f;
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("cone_outer"))
|
||||||
|
{
|
||||||
|
surfaceLight.outerCone = (float)lexer->GetFloat() / 180.0f;
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("cone_inner"))
|
||||||
|
{
|
||||||
|
surfaceLight.innerCone = (float)lexer->GetFloat() / 180.0f;
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("falloff"))
|
||||||
|
{
|
||||||
|
surfaceLight.falloff = (float)lexer->GetFloat();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("intensity"))
|
||||||
|
{
|
||||||
|
surfaceLight.intensity = (float)lexer->GetFloat();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("distance"))
|
||||||
|
{
|
||||||
|
surfaceLight.distance = (float)lexer->GetFloat();
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("bIgnoreCeiling"))
|
||||||
|
{
|
||||||
|
surfaceLight.bIgnoreCeiling = true;
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("bIgnoreFloor"))
|
||||||
|
{
|
||||||
|
surfaceLight.bIgnoreFloor = true;
|
||||||
|
}
|
||||||
|
else if(lexer->Matches("bNoCenterPoint"))
|
||||||
|
{
|
||||||
|
surfaceLight.bNoCenterPoint = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->Find();
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaceLightDefs.Push(surfaceLight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're done with the file
|
||||||
|
parser->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::CreateLights
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::CreateLights(void)
|
||||||
|
{
|
||||||
|
mapThing_t *thing;
|
||||||
|
thingLight_t *thingLight;
|
||||||
|
unsigned int j;
|
||||||
|
int numSurfLights;
|
||||||
|
kexVec2 pt;
|
||||||
|
|
||||||
|
//
|
||||||
|
// add lights from thing sources
|
||||||
|
//
|
||||||
|
for(int i = 0; i < numThings; ++i)
|
||||||
|
{
|
||||||
|
lightDef_t *lightDef = NULL;
|
||||||
|
|
||||||
|
thing = &mapThings[i];
|
||||||
|
|
||||||
|
for(j = 0; j < lightDefs.Length(); ++j)
|
||||||
|
{
|
||||||
|
if(thing->type == lightDefs[j].doomednum)
|
||||||
|
{
|
||||||
|
lightDef = &lightDefs[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!lightDef)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lightDef->radius >= 0)
|
||||||
|
{
|
||||||
|
// ignore if all skills aren't set
|
||||||
|
if(!(thing->options & 7))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thingLight = new thingLight_t;
|
||||||
|
|
||||||
|
thingLight->mapThing = thing;
|
||||||
|
thingLight->rgb = lightDef->rgb;
|
||||||
|
thingLight->intensity = lightDef->intensity;
|
||||||
|
thingLight->falloff = lightDef->falloff;
|
||||||
|
thingLight->radius = lightDef->radius >= 0 ? lightDef->radius : thing->angle;
|
||||||
|
thingLight->height = lightDef->height;
|
||||||
|
thingLight->bCeiling = lightDef->bCeiling;
|
||||||
|
thingLight->ssect = PointInSubSector(thing->x, thing->y);
|
||||||
|
thingLight->sector = GetSectorFromSubSector(thingLight->ssect);
|
||||||
|
|
||||||
|
thingLight->origin.Set(thing->x, thing->y);
|
||||||
|
thingLights.Push(thingLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Thing lights: %i\n", thingLights.Length());
|
||||||
|
|
||||||
|
numSurfLights = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// add surface lights
|
||||||
|
//
|
||||||
|
for(j = 0; j < surfaces.Length(); ++j)
|
||||||
|
{
|
||||||
|
surface_t *surface = surfaces[j];
|
||||||
|
|
||||||
|
for(unsigned int k = 0; k < surfaceLightDefs.Length(); ++k)
|
||||||
|
{
|
||||||
|
surfaceLightDef_t *surfaceLightDef = &surfaceLightDefs[k];
|
||||||
|
|
||||||
|
if(surface->type >= ST_MIDDLESEG && surface->type <= ST_LOWERSEG)
|
||||||
|
{
|
||||||
|
glSeg_t *seg = (glSeg_t*)surface->data;
|
||||||
|
|
||||||
|
if(mapLines[seg->linedef].tag == surfaceLightDef->tag)
|
||||||
|
{
|
||||||
|
kexLightSurface *lightSurface = new kexLightSurface;
|
||||||
|
|
||||||
|
lightSurface->Init(*surfaceLightDef, surface, true, false);
|
||||||
|
lightSurface->CreateCenterOrigin();
|
||||||
|
lightSurfaces.Push(lightSurface);
|
||||||
|
numSurfLights++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mapSubSector_t *sub = surface->subSector;
|
||||||
|
mapSector_t *sector = GetSectorFromSubSector(sub);
|
||||||
|
|
||||||
|
if(!sector || surface->numVerts <= 0)
|
||||||
|
{
|
||||||
|
// eh....
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(surface->type == ST_CEILING && surfaceLightDef->bIgnoreCeiling)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(surface->type == ST_FLOOR && surfaceLightDef->bIgnoreFloor)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sector->tag == surfaceLightDef->tag)
|
||||||
|
{
|
||||||
|
kexLightSurface *lightSurface = new kexLightSurface;
|
||||||
|
|
||||||
|
lightSurface->Init(*surfaceLightDef, surface, false, surfaceLightDef->bNoCenterPoint);
|
||||||
|
lightSurface->Subdivide(16);
|
||||||
|
lightSurfaces.Push(lightSurface);
|
||||||
|
numSurfLights++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Surface lights: %i\n", numSurfLights);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexDoomMap::CleanupThingLights
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexDoomMap::CleanupThingLights(void)
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < thingLights.Length(); i++)
|
||||||
|
{
|
||||||
|
delete thingLights[i];
|
||||||
|
}
|
||||||
|
}
|
276
src/lightmap/mapdata.h
Normal file
276
src/lightmap/mapdata.h
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __MAPDATA_H__
|
||||||
|
#define __MAPDATA_H__
|
||||||
|
|
||||||
|
#include "wad.h"
|
||||||
|
#include "surfaces.h"
|
||||||
|
#include "lightSurface.h"
|
||||||
|
|
||||||
|
#define NO_SIDE_INDEX -1
|
||||||
|
#define NO_LINE_INDEX 0xFFFF
|
||||||
|
#define NF_SUBSECTOR 0x8000
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BOXTOP,
|
||||||
|
BOXBOTTOM,
|
||||||
|
BOXLEFT,
|
||||||
|
BOXRIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ML_BLOCKING = 1, // Solid, is an obstacle.
|
||||||
|
ML_BLOCKMONSTERS = 2, // Blocks monsters only.
|
||||||
|
ML_TWOSIDED = 4, // Backside will not be present at all if not two sided.
|
||||||
|
ML_TRANSPARENT1 = 2048, // 25% or 75% transcluency?
|
||||||
|
ML_TRANSPARENT2 = 4096 // 25% or 75% transcluency?
|
||||||
|
} mapFlags_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
} mapVertex_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
short textureoffset;
|
||||||
|
short rowoffset;
|
||||||
|
char toptexture[8];
|
||||||
|
char bottomtexture[8];
|
||||||
|
char midtexture[8];
|
||||||
|
short sector;
|
||||||
|
} mapSideDef_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
short v1;
|
||||||
|
short v2;
|
||||||
|
short flags;
|
||||||
|
short special;
|
||||||
|
short tag;
|
||||||
|
short sidenum[2]; // sidenum[1] will be -1 if one sided
|
||||||
|
} mapLineDef_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
short floorheight;
|
||||||
|
short ceilingheight;
|
||||||
|
char floorpic[8];
|
||||||
|
char ceilingpic[8];
|
||||||
|
short lightlevel;
|
||||||
|
short special;
|
||||||
|
short tag;
|
||||||
|
} mapSector_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
// Partition line from (x,y) to x+dx,y+dy)
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
short dx;
|
||||||
|
short dy;
|
||||||
|
|
||||||
|
// Bounding box for each child,
|
||||||
|
// clip against view frustum.
|
||||||
|
short bbox[2][4];
|
||||||
|
|
||||||
|
// If NF_SUBSECTOR its a subsector,
|
||||||
|
// else it's a node of another subtree.
|
||||||
|
word children[2];
|
||||||
|
} mapNode_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
word v1;
|
||||||
|
word v2;
|
||||||
|
short angle;
|
||||||
|
word linedef;
|
||||||
|
short side;
|
||||||
|
short offset;
|
||||||
|
} mapSeg_t;
|
||||||
|
|
||||||
|
typedef struct mapSubSector_s
|
||||||
|
{
|
||||||
|
word numsegs;
|
||||||
|
word firstseg;
|
||||||
|
} mapSubSector_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
short angle;
|
||||||
|
short type;
|
||||||
|
short options;
|
||||||
|
} mapThing_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} glVert_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
word v1;
|
||||||
|
word v2;
|
||||||
|
word linedef;
|
||||||
|
int16_t side;
|
||||||
|
word partner;
|
||||||
|
} glSeg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
} vertex_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vertex_t *vertex;
|
||||||
|
glSeg_t *seg;
|
||||||
|
} leaf_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int doomednum;
|
||||||
|
float height;
|
||||||
|
float radius;
|
||||||
|
float intensity;
|
||||||
|
float falloff;
|
||||||
|
bool bCeiling;
|
||||||
|
kexVec3 rgb;
|
||||||
|
} lightDef_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int map;
|
||||||
|
int sunIgnoreTag;
|
||||||
|
kexVec3 sunDir;
|
||||||
|
kexVec3 sunColor;
|
||||||
|
} mapDef_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mapThing_t *mapThing;
|
||||||
|
kexVec2 origin;
|
||||||
|
kexVec3 rgb;
|
||||||
|
float intensity;
|
||||||
|
float falloff;
|
||||||
|
float height;
|
||||||
|
float radius;
|
||||||
|
bool bCeiling;
|
||||||
|
mapSector_t *sector;
|
||||||
|
mapSubSector_t *ssect;
|
||||||
|
} thingLight_t;
|
||||||
|
|
||||||
|
class kexDoomMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexDoomMap(void);
|
||||||
|
~kexDoomMap(void);
|
||||||
|
|
||||||
|
void BuildMapFromWad(kexWadFile &wadFile);
|
||||||
|
mapSideDef_t *GetSideDef(const glSeg_t *seg);
|
||||||
|
mapSector_t *GetFrontSector(const glSeg_t *seg);
|
||||||
|
mapSector_t *GetBackSector(const glSeg_t *seg);
|
||||||
|
mapSector_t *GetSectorFromSubSector(const mapSubSector_t *sub);
|
||||||
|
mapSubSector_t *PointInSubSector(const int x, const int y);
|
||||||
|
bool PointInsideSubSector(const float x, const float y, const mapSubSector_t *sub);
|
||||||
|
bool LineIntersectSubSector(const kexVec3 &start, const kexVec3 &end,
|
||||||
|
const mapSubSector_t *sub, kexVec2 &out);
|
||||||
|
vertex_t *GetSegVertex(int index);
|
||||||
|
bool CheckPVS(mapSubSector_t *s1, mapSubSector_t *s2);
|
||||||
|
|
||||||
|
void ParseConfigFile(const char *file);
|
||||||
|
void CreateLights(void);
|
||||||
|
void CleanupThingLights(void);
|
||||||
|
|
||||||
|
const kexVec3 &GetSunColor(void) const;
|
||||||
|
const kexVec3 &GetSunDirection(void) const;
|
||||||
|
|
||||||
|
mapThing_t *mapThings;
|
||||||
|
mapLineDef_t *mapLines;
|
||||||
|
mapVertex_t *mapVerts;
|
||||||
|
mapSideDef_t *mapSides;
|
||||||
|
mapSector_t *mapSectors;
|
||||||
|
glSeg_t *mapSegs;
|
||||||
|
mapSubSector_t *mapSSects;
|
||||||
|
mapNode_t *nodes;
|
||||||
|
leaf_t *leafs;
|
||||||
|
vertex_t *vertexes;
|
||||||
|
byte *mapPVS;
|
||||||
|
|
||||||
|
bool *bSkySectors;
|
||||||
|
bool *bSSectsVisibleToSky;
|
||||||
|
|
||||||
|
int numThings;
|
||||||
|
int numLines;
|
||||||
|
int numVerts;
|
||||||
|
int numSides;
|
||||||
|
int numSectors;
|
||||||
|
int numSegs;
|
||||||
|
int numSSects;
|
||||||
|
int numNodes;
|
||||||
|
int numLeafs;
|
||||||
|
int numVertexes;
|
||||||
|
|
||||||
|
int *segLeafLookup;
|
||||||
|
int *ssLeafLookup;
|
||||||
|
int *ssLeafCount;
|
||||||
|
kexBBox *ssLeafBounds;
|
||||||
|
|
||||||
|
kexBBox *nodeBounds;
|
||||||
|
|
||||||
|
surface_t **segSurfaces[3];
|
||||||
|
surface_t **leafSurfaces[2];
|
||||||
|
|
||||||
|
kexArray<thingLight_t*> thingLights;
|
||||||
|
kexArray<kexLightSurface*> lightSurfaces;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void BuildLeafs(void);
|
||||||
|
void BuildNodeBounds(void);
|
||||||
|
void CheckSkySectors(void);
|
||||||
|
void BuildVertexes(kexWadFile &wadFile);
|
||||||
|
void BuildPVS(void);
|
||||||
|
|
||||||
|
kexArray<lightDef_t> lightDefs;
|
||||||
|
kexArray<surfaceLightDef_t> surfaceLightDefs;
|
||||||
|
kexArray<mapDef_t> mapDefs;
|
||||||
|
|
||||||
|
mapDef_t *mapDef;
|
||||||
|
|
||||||
|
static const kexVec3 defaultSunColor;
|
||||||
|
static const kexVec3 defaultSunDirection;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
364
src/lightmap/surfaces.cpp
Normal file
364
src/lightmap/surfaces.cpp
Normal file
|
@ -0,0 +1,364 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Prepares geometry from map structures
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "surfaces.h"
|
||||||
|
#include "mapData.h"
|
||||||
|
|
||||||
|
//#define EXPORT_OBJ
|
||||||
|
|
||||||
|
kexArray<surface_t*> surfaces;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Surface_AllocateFromSeg
|
||||||
|
//
|
||||||
|
|
||||||
|
static void Surface_AllocateFromSeg(kexDoomMap &doomMap, glSeg_t *seg)
|
||||||
|
{
|
||||||
|
mapSideDef_t *side;
|
||||||
|
surface_t *surf;
|
||||||
|
float top, bTop;
|
||||||
|
float bottom, bBottom;
|
||||||
|
mapSector_t *front;
|
||||||
|
mapSector_t *back;
|
||||||
|
vertex_t *v1;
|
||||||
|
vertex_t *v2;
|
||||||
|
|
||||||
|
if(seg->linedef == NO_LINE_INDEX)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
side = doomMap.GetSideDef(seg);
|
||||||
|
front = doomMap.GetFrontSector(seg);
|
||||||
|
back = doomMap.GetBackSector(seg);
|
||||||
|
|
||||||
|
top = front->ceilingheight;
|
||||||
|
bottom = front->floorheight;
|
||||||
|
|
||||||
|
v1 = doomMap.GetSegVertex(seg->v1);
|
||||||
|
v2 = doomMap.GetSegVertex(seg->v2);
|
||||||
|
|
||||||
|
if(back)
|
||||||
|
{
|
||||||
|
bTop = back->ceilingheight;
|
||||||
|
bBottom = back->floorheight;
|
||||||
|
|
||||||
|
if(bTop == top && bBottom == bottom)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bottom seg
|
||||||
|
if(bottom < bBottom)
|
||||||
|
{
|
||||||
|
if(side->bottomtexture[0] != '-')
|
||||||
|
{
|
||||||
|
surf = (surface_t*)Mem_Calloc(sizeof(surface_t), hb_static);
|
||||||
|
surf->numVerts = 4;
|
||||||
|
surf->verts = (kexVec3*)Mem_Calloc(sizeof(kexVec3) * 4, hb_static);
|
||||||
|
|
||||||
|
surf->verts[0].x = surf->verts[2].x = v1->x;
|
||||||
|
surf->verts[0].y = surf->verts[2].y = v1->y;
|
||||||
|
surf->verts[1].x = surf->verts[3].x = v2->x;
|
||||||
|
surf->verts[1].y = surf->verts[3].y = v2->y;
|
||||||
|
surf->verts[0].z = surf->verts[1].z = bottom;
|
||||||
|
surf->verts[2].z = surf->verts[3].z = bBottom;
|
||||||
|
|
||||||
|
surf->plane.SetNormal(surf->verts[0], surf->verts[1], surf->verts[2]);
|
||||||
|
surf->plane.SetDistance(surf->verts[0]);
|
||||||
|
surf->type = ST_LOWERSEG;
|
||||||
|
surf->typeIndex = seg - doomMap.mapSegs;
|
||||||
|
surf->subSector = &doomMap.mapSSects[doomMap.segLeafLookup[seg - doomMap.mapSegs]];
|
||||||
|
|
||||||
|
doomMap.segSurfaces[1][surf->typeIndex] = surf;
|
||||||
|
surf->data = (glSeg_t*)seg;
|
||||||
|
|
||||||
|
surfaces.Push(surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
bottom = bBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// top seg
|
||||||
|
if(top > bTop)
|
||||||
|
{
|
||||||
|
bool bSky = false;
|
||||||
|
int frontidx = front-doomMap.mapSectors;
|
||||||
|
int backidx = back-doomMap.mapSectors;
|
||||||
|
|
||||||
|
if(doomMap.bSkySectors[frontidx] && doomMap.bSkySectors[backidx])
|
||||||
|
{
|
||||||
|
if(front->ceilingheight != back->ceilingheight && side->toptexture[0] == '-')
|
||||||
|
{
|
||||||
|
bSky = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(side->toptexture[0] != '-' || bSky)
|
||||||
|
{
|
||||||
|
surf = (surface_t*)Mem_Calloc(sizeof(surface_t), hb_static);
|
||||||
|
surf->numVerts = 4;
|
||||||
|
surf->verts = (kexVec3*)Mem_Calloc(sizeof(kexVec3) * 4, hb_static);
|
||||||
|
|
||||||
|
surf->verts[0].x = surf->verts[2].x = v1->x;
|
||||||
|
surf->verts[0].y = surf->verts[2].y = v1->y;
|
||||||
|
surf->verts[1].x = surf->verts[3].x = v2->x;
|
||||||
|
surf->verts[1].y = surf->verts[3].y = v2->y;
|
||||||
|
surf->verts[0].z = surf->verts[1].z = bTop;
|
||||||
|
surf->verts[2].z = surf->verts[3].z = top;
|
||||||
|
|
||||||
|
surf->plane.SetNormal(surf->verts[0], surf->verts[1], surf->verts[2]);
|
||||||
|
surf->plane.SetDistance(surf->verts[0]);
|
||||||
|
surf->type = ST_UPPERSEG;
|
||||||
|
surf->typeIndex = seg - doomMap.mapSegs;
|
||||||
|
surf->bSky = bSky;
|
||||||
|
surf->subSector = &doomMap.mapSSects[doomMap.segLeafLookup[seg - doomMap.mapSegs]];
|
||||||
|
|
||||||
|
doomMap.segSurfaces[2][surf->typeIndex] = surf;
|
||||||
|
surf->data = (glSeg_t*)seg;
|
||||||
|
|
||||||
|
surfaces.Push(surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
top = bTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// middle seg
|
||||||
|
if(back == NULL)
|
||||||
|
{
|
||||||
|
surf = (surface_t*)Mem_Calloc(sizeof(surface_t), hb_static);
|
||||||
|
surf->numVerts = 4;
|
||||||
|
surf->verts = (kexVec3*)Mem_Calloc(sizeof(kexVec3) * 4, hb_static);
|
||||||
|
|
||||||
|
surf->verts[0].x = surf->verts[2].x = v1->x;
|
||||||
|
surf->verts[0].y = surf->verts[2].y = v1->y;
|
||||||
|
surf->verts[1].x = surf->verts[3].x = v2->x;
|
||||||
|
surf->verts[1].y = surf->verts[3].y = v2->y;
|
||||||
|
surf->verts[0].z = surf->verts[1].z = bottom;
|
||||||
|
surf->verts[2].z = surf->verts[3].z = top;
|
||||||
|
|
||||||
|
surf->plane.SetNormal(surf->verts[0], surf->verts[1], surf->verts[2]);
|
||||||
|
surf->plane.SetDistance(surf->verts[0]);
|
||||||
|
surf->type = ST_MIDDLESEG;
|
||||||
|
surf->typeIndex = seg - doomMap.mapSegs;
|
||||||
|
surf->subSector = &doomMap.mapSSects[doomMap.segLeafLookup[seg - doomMap.mapSegs]];
|
||||||
|
|
||||||
|
doomMap.segSurfaces[0][surf->typeIndex] = surf;
|
||||||
|
surf->data = (glSeg_t*)seg;
|
||||||
|
|
||||||
|
surfaces.Push(surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Surface_AllocateFromLeaf
|
||||||
|
//
|
||||||
|
// Plane normals should almost always be known
|
||||||
|
// unless slopes are involved....
|
||||||
|
//
|
||||||
|
|
||||||
|
static void Surface_AllocateFromLeaf(kexDoomMap &doomMap)
|
||||||
|
{
|
||||||
|
surface_t *surf;
|
||||||
|
leaf_t *leaf;
|
||||||
|
mapSector_t *sector = NULL;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
printf("------------- Building leaf surfaces -------------\n");
|
||||||
|
|
||||||
|
doomMap.leafSurfaces[0] = (surface_t**)Mem_Calloc(sizeof(surface_t*) *
|
||||||
|
doomMap.numSSects, hb_static);
|
||||||
|
doomMap.leafSurfaces[1] = (surface_t**)Mem_Calloc(sizeof(surface_t*) *
|
||||||
|
doomMap.numSSects, hb_static);
|
||||||
|
|
||||||
|
for(i = 0; i < doomMap.numSSects; i++)
|
||||||
|
{
|
||||||
|
printf("subsectors: %i / %i\r", i+1, doomMap.numSSects);
|
||||||
|
|
||||||
|
if(doomMap.ssLeafCount[i] < 3)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sector = doomMap.GetSectorFromSubSector(&doomMap.mapSSects[i]);
|
||||||
|
|
||||||
|
// I will be NOT surprised if some users tries to do something stupid with
|
||||||
|
// sector hacks
|
||||||
|
if(sector == NULL)
|
||||||
|
{
|
||||||
|
Error("Surface_AllocateFromLeaf: subsector %i has no sector\n", i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
surf = (surface_t*)Mem_Calloc(sizeof(surface_t), hb_static);
|
||||||
|
surf->numVerts = doomMap.ssLeafCount[i];
|
||||||
|
surf->verts = (kexVec3*)Mem_Calloc(sizeof(kexVec3) * surf->numVerts, hb_static);
|
||||||
|
surf->subSector = &doomMap.mapSSects[i];
|
||||||
|
|
||||||
|
// floor verts
|
||||||
|
for(j = 0; j < surf->numVerts; j++)
|
||||||
|
{
|
||||||
|
leaf = &doomMap.leafs[doomMap.ssLeafLookup[i] + (surf->numVerts - 1) - j];
|
||||||
|
|
||||||
|
surf->verts[j].x = leaf->vertex->x;
|
||||||
|
surf->verts[j].y = leaf->vertex->y;
|
||||||
|
surf->verts[j].z = sector->floorheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
surf->plane.SetNormal(kexVec3(0, 0, 1));
|
||||||
|
surf->plane.SetDistance(surf->verts[0]);
|
||||||
|
surf->type = ST_FLOOR;
|
||||||
|
surf->typeIndex = i;
|
||||||
|
|
||||||
|
doomMap.leafSurfaces[0][i] = surf;
|
||||||
|
surf->data = (mapSector_t*)sector;
|
||||||
|
|
||||||
|
surfaces.Push(surf);
|
||||||
|
|
||||||
|
surf = (surface_t*)Mem_Calloc(sizeof(surface_t), hb_static);
|
||||||
|
surf->numVerts = doomMap.ssLeafCount[i];
|
||||||
|
surf->verts = (kexVec3*)Mem_Calloc(sizeof(kexVec3) * surf->numVerts, hb_static);
|
||||||
|
surf->subSector = &doomMap.mapSSects[i];
|
||||||
|
|
||||||
|
if(doomMap.bSkySectors[sector-doomMap.mapSectors])
|
||||||
|
{
|
||||||
|
surf->bSky = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ceiling verts
|
||||||
|
for(j = 0; j < surf->numVerts; j++)
|
||||||
|
{
|
||||||
|
leaf = &doomMap.leafs[doomMap.ssLeafLookup[i] + j];
|
||||||
|
|
||||||
|
surf->verts[j].x = leaf->vertex->x;
|
||||||
|
surf->verts[j].y = leaf->vertex->y;
|
||||||
|
surf->verts[j].z = sector->ceilingheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
surf->plane.SetNormal(kexVec3(0, 0, -1));
|
||||||
|
surf->plane.SetDistance(surf->verts[0]);
|
||||||
|
surf->type = ST_CEILING;
|
||||||
|
surf->typeIndex = i;
|
||||||
|
|
||||||
|
doomMap.leafSurfaces[1][i] = surf;
|
||||||
|
surf->data = (mapSector_t*)sector;
|
||||||
|
|
||||||
|
surfaces.Push(surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nLeaf surfaces: %i\n", surfaces.Length() - doomMap.numSSects);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Surface_AllocateFromMap
|
||||||
|
//
|
||||||
|
|
||||||
|
void Surface_AllocateFromMap(kexDoomMap &doomMap)
|
||||||
|
{
|
||||||
|
doomMap.segSurfaces[0] = (surface_t**)Mem_Calloc(sizeof(surface_t*) *
|
||||||
|
doomMap.numSegs, hb_static);
|
||||||
|
doomMap.segSurfaces[1] = (surface_t**)Mem_Calloc(sizeof(surface_t*) *
|
||||||
|
doomMap.numSegs, hb_static);
|
||||||
|
doomMap.segSurfaces[2] = (surface_t**)Mem_Calloc(sizeof(surface_t*) *
|
||||||
|
doomMap.numSegs, hb_static);
|
||||||
|
|
||||||
|
printf("------------- Building seg surfaces -------------\n");
|
||||||
|
|
||||||
|
for(int i = 0; i < doomMap.numSegs; i++)
|
||||||
|
{
|
||||||
|
Surface_AllocateFromSeg(doomMap, &doomMap.mapSegs[i]);
|
||||||
|
printf("segs: %i / %i\r", i+1, doomMap.numSegs);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nSeg surfaces: %i\n", surfaces.Length());
|
||||||
|
|
||||||
|
#ifdef EXPORT_OBJ
|
||||||
|
FILE *f = fopen("level.obj", "w");
|
||||||
|
int curLen = surfaces.Length();
|
||||||
|
for(unsigned int i = 0; i < surfaces.Length(); i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < surfaces[i]->numVerts; j++)
|
||||||
|
{
|
||||||
|
fprintf(f, "v %f %f %f\n",
|
||||||
|
-surfaces[i]->verts[j].y / 256.0f,
|
||||||
|
surfaces[i]->verts[j].z / 256.0f,
|
||||||
|
-surfaces[i]->verts[j].x / 256.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tri;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < surfaces.Length(); i++)
|
||||||
|
{
|
||||||
|
fprintf(f, "o surf%i_seg%i\n", i, i);
|
||||||
|
fprintf(f, "f %i %i %i\n", 0+(i*4)+1, 1+(i*4)+1, 2+(i*4)+1);
|
||||||
|
fprintf(f, "f %i %i %i\n", 1+(i*4)+1, 3+(i*4)+1, 2+(i*4)+1);
|
||||||
|
|
||||||
|
tri = 3+(i*4)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tri++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Surface_AllocateFromLeaf(doomMap);
|
||||||
|
|
||||||
|
printf("Surfaces total: %i\n\n", surfaces.Length());
|
||||||
|
|
||||||
|
#ifdef EXPORT_OBJ
|
||||||
|
for(unsigned int i = curLen; i < surfaces.Length(); i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < surfaces[i]->numVerts; j++)
|
||||||
|
{
|
||||||
|
fprintf(f, "v %f %f %f\n",
|
||||||
|
-surfaces[i]->verts[j].y / 256.0f,
|
||||||
|
surfaces[i]->verts[j].z / 256.0f,
|
||||||
|
-surfaces[i]->verts[j].x / 256.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = curLen; i < surfaces.Length(); i++)
|
||||||
|
{
|
||||||
|
fprintf(f, "o surf%i_ssect%i\n", i, i - curLen);
|
||||||
|
fprintf(f, "f ");
|
||||||
|
for(int j = 0; j < surfaces[i]->numVerts; j++)
|
||||||
|
{
|
||||||
|
fprintf(f, "%i ", tri++);
|
||||||
|
}
|
||||||
|
fprintf(f, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
#endif
|
||||||
|
}
|
73
src/lightmap/surfaces.h
Normal file
73
src/lightmap/surfaces.h
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __SURFACES_H__
|
||||||
|
#define __SURFACES_H__
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ST_UNKNOWN = 0,
|
||||||
|
ST_MIDDLESEG,
|
||||||
|
ST_UPPERSEG,
|
||||||
|
ST_LOWERSEG,
|
||||||
|
ST_CEILING,
|
||||||
|
ST_FLOOR
|
||||||
|
} surfaceType_t;
|
||||||
|
|
||||||
|
typedef kexArray<kexVec3> vertexBatch_t;
|
||||||
|
|
||||||
|
// convert from fixed point(FRACUNIT) to floating point
|
||||||
|
#define F(x) (((float)(x))/65536.0f)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
kexPlane plane;
|
||||||
|
int lightmapNum;
|
||||||
|
int lightmapOffs[2];
|
||||||
|
int lightmapDims[2];
|
||||||
|
kexVec3 lightmapOrigin;
|
||||||
|
kexVec3 lightmapSteps[2];
|
||||||
|
kexVec3 textureCoords[2];
|
||||||
|
kexBBox bounds;
|
||||||
|
int numVerts;
|
||||||
|
kexVec3 *verts;
|
||||||
|
float *lightmapCoords;
|
||||||
|
surfaceType_t type;
|
||||||
|
int typeIndex;
|
||||||
|
void *data;
|
||||||
|
bool bSky;
|
||||||
|
struct mapSubSector_s *subSector;
|
||||||
|
} surface_t;
|
||||||
|
|
||||||
|
extern kexArray<surface_t*> surfaces;
|
||||||
|
|
||||||
|
class kexDoomMap;
|
||||||
|
class kexWadFile;
|
||||||
|
|
||||||
|
void Surface_AllocateFromMap(kexDoomMap &doomMap);
|
||||||
|
|
||||||
|
#endif
|
285
src/lightmap/trace.cpp
Normal file
285
src/lightmap/trace.cpp
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: General class module for handling ray tracing of the
|
||||||
|
// world geometry. Ideally, all of this needs to be revisited...
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "mapData.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexTrace::kexTrace
|
||||||
|
//
|
||||||
|
|
||||||
|
kexTrace::kexTrace(void)
|
||||||
|
{
|
||||||
|
this->map = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexTrace::~kexTrace
|
||||||
|
//
|
||||||
|
|
||||||
|
kexTrace::~kexTrace(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexTrace::Init
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexTrace::Init(kexDoomMap &doomMap)
|
||||||
|
{
|
||||||
|
map = &doomMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexTrace::Trace
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexTrace::Trace(const kexVec3 &startVec, const kexVec3 &endVec)
|
||||||
|
{
|
||||||
|
start = startVec;
|
||||||
|
end = endVec;
|
||||||
|
dir = (end - start).Normalize();
|
||||||
|
hitNormal.Clear();
|
||||||
|
hitVector.Clear();
|
||||||
|
hitSurface = NULL;
|
||||||
|
fraction = 1;
|
||||||
|
|
||||||
|
if(map == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceBSPNode(map->numNodes - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexTrace::TraceSurface
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexTrace::TraceSurface(surface_t *surface)
|
||||||
|
{
|
||||||
|
kexPlane *plane;
|
||||||
|
kexVec3 hit;
|
||||||
|
kexVec3 edge1;
|
||||||
|
kexVec3 edge2;
|
||||||
|
kexVec3 normal;
|
||||||
|
float d1;
|
||||||
|
float d2;
|
||||||
|
float d;
|
||||||
|
float frac;
|
||||||
|
int i;
|
||||||
|
kexPluecker r;
|
||||||
|
|
||||||
|
if(surface == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
plane = &surface->plane;
|
||||||
|
|
||||||
|
d1 = plane->Distance(start) - plane->d;
|
||||||
|
d2 = plane->Distance(end) - plane->d;
|
||||||
|
|
||||||
|
if(d1 <= d2 || d1 < 0 || d2 > 0)
|
||||||
|
{
|
||||||
|
// trace is either completely in front or behind the plane
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frac = (d1 / (d1 - d2));
|
||||||
|
|
||||||
|
if(frac > 1 || frac < 0)
|
||||||
|
{
|
||||||
|
// not a valid contact
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(frac >= fraction)
|
||||||
|
{
|
||||||
|
// farther than the current contact
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hit = start.Lerp(end, frac);
|
||||||
|
normal = plane->Normal();
|
||||||
|
|
||||||
|
r.SetRay(start, dir);
|
||||||
|
|
||||||
|
// segs are always made up of 4 vertices, so its safe to assume 4 edges here
|
||||||
|
if(surface->type >= ST_MIDDLESEG && surface->type <= ST_LOWERSEG)
|
||||||
|
{
|
||||||
|
kexPluecker p1;
|
||||||
|
kexPluecker p2;
|
||||||
|
kexPluecker p3;
|
||||||
|
kexPluecker p4;
|
||||||
|
byte sideBits = 0;
|
||||||
|
|
||||||
|
p1.SetLine(surface->verts[2], surface->verts[3]); // top edge
|
||||||
|
p2.SetLine(surface->verts[1], surface->verts[0]); // bottom edge
|
||||||
|
p3.SetLine(surface->verts[3], surface->verts[1]); // right edge
|
||||||
|
p4.SetLine(surface->verts[0], surface->verts[2]); // left edge
|
||||||
|
|
||||||
|
// this sucks so much..... I am surprised this even works at all
|
||||||
|
d = r.InnerProduct(p1)-0.001f;
|
||||||
|
sideBits |= (FLOATSIGNBIT(d) << 0);
|
||||||
|
d = r.InnerProduct(p2)-0.001f;
|
||||||
|
sideBits |= (FLOATSIGNBIT(d) << 1);
|
||||||
|
d = r.InnerProduct(p3)-0.001f;
|
||||||
|
sideBits |= (FLOATSIGNBIT(d) << 2);
|
||||||
|
d = r.InnerProduct(p4)-0.001f;
|
||||||
|
sideBits |= (FLOATSIGNBIT(d) << 3);
|
||||||
|
|
||||||
|
if(sideBits != 0xF)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(surface->type == ST_FLOOR || surface->type == ST_CEILING)
|
||||||
|
{
|
||||||
|
kexPluecker p;
|
||||||
|
kexVec3 v1;
|
||||||
|
kexVec3 v2;
|
||||||
|
|
||||||
|
for(i = 0; i < surface->numVerts; i++)
|
||||||
|
{
|
||||||
|
v1 = surface->verts[i];
|
||||||
|
v2 = surface->verts[(i+1)%surface->numVerts];
|
||||||
|
|
||||||
|
p.SetLine(v2, v1);
|
||||||
|
|
||||||
|
if(r.InnerProduct(p) > 0.01f)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hitNormal = normal;
|
||||||
|
hitVector = hit;
|
||||||
|
hitSurface = surface;
|
||||||
|
fraction = frac;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexTrace::TraceSubSector
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexTrace::TraceSubSector(int num)
|
||||||
|
{
|
||||||
|
mapSubSector_t *sub;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
sub = &map->mapSSects[num];
|
||||||
|
|
||||||
|
if(!map->ssLeafBounds[num].LineIntersect(start, end))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// test line segments
|
||||||
|
for(i = 0; i < sub->numsegs; i++)
|
||||||
|
{
|
||||||
|
int segnum = sub->firstseg + i;
|
||||||
|
|
||||||
|
for(j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
if(j == 0)
|
||||||
|
{
|
||||||
|
int linenum = map->mapSegs[segnum].linedef;
|
||||||
|
|
||||||
|
if(linenum != NO_LINE_INDEX && map->mapLines[linenum].flags &
|
||||||
|
(ML_TWOSIDED|ML_TRANSPARENT1|ML_TRANSPARENT2))
|
||||||
|
{
|
||||||
|
// don't trace transparent 2-sided lines
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TraceSurface(map->segSurfaces[j][segnum]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test subsector leafs
|
||||||
|
for(j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
TraceSurface(map->leafSurfaces[j][num]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexTrace::TraceBSPNode
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexTrace::TraceBSPNode(int num)
|
||||||
|
{
|
||||||
|
mapNode_t *node;
|
||||||
|
kexVec3 dp1;
|
||||||
|
kexVec3 dp2;
|
||||||
|
float d;
|
||||||
|
byte side;
|
||||||
|
|
||||||
|
if(num & NF_SUBSECTOR)
|
||||||
|
{
|
||||||
|
TraceSubSector(num & (~NF_SUBSECTOR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!map->nodeBounds[num & (~NF_SUBSECTOR)].LineIntersect(start, end))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = &map->nodes[num];
|
||||||
|
|
||||||
|
kexVec3 pt1(F(node->x << 16), F(node->y << 16), 0);
|
||||||
|
kexVec3 pt2(F(node->dx << 16), F(node->dy << 16), 0);
|
||||||
|
|
||||||
|
dp1 = pt1 - start;
|
||||||
|
dp2 = (pt2 + pt1) - start;
|
||||||
|
d = dp1.Cross(dp2).z;
|
||||||
|
|
||||||
|
side = FLOATSIGNBIT(d);
|
||||||
|
|
||||||
|
TraceBSPNode(node->children[side ^ 1]);
|
||||||
|
|
||||||
|
dp1 = pt1 - end;
|
||||||
|
dp2 = (pt2 + pt1) - end;
|
||||||
|
d = dp1.Cross(dp2).z;
|
||||||
|
|
||||||
|
// don't trace if both ends of the ray are on the same side
|
||||||
|
if(side != FLOATSIGNBIT(d))
|
||||||
|
{
|
||||||
|
TraceBSPNode(node->children[side]);
|
||||||
|
}
|
||||||
|
}
|
59
src/lightmap/trace.h
Normal file
59
src/lightmap/trace.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __TRACE_H__
|
||||||
|
#define __TRACE_H__
|
||||||
|
|
||||||
|
class kexDoomMap;
|
||||||
|
|
||||||
|
class kexTrace
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexTrace(void);
|
||||||
|
~kexTrace(void);
|
||||||
|
|
||||||
|
void Init(kexDoomMap &doomMap);
|
||||||
|
void Trace(const kexVec3 &startVec, const kexVec3 &endVec);
|
||||||
|
|
||||||
|
kexVec3 start;
|
||||||
|
kexVec3 end;
|
||||||
|
kexVec3 dir;
|
||||||
|
kexVec3 hitNormal;
|
||||||
|
kexVec3 hitVector;
|
||||||
|
surface_t *hitSurface;
|
||||||
|
float fraction;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void TraceBSPNode(int num);
|
||||||
|
void TraceSubSector(int num);
|
||||||
|
void TraceSurface(surface_t *surface);
|
||||||
|
|
||||||
|
kexDoomMap *map;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
326
src/lightmap/wad.cpp
Normal file
326
src/lightmap/wad.cpp
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: General wad loading mechanics
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "wad.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::~kexWadFile
|
||||||
|
//
|
||||||
|
|
||||||
|
kexWadFile::~kexWadFile(void)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::Open
|
||||||
|
//
|
||||||
|
|
||||||
|
bool kexWadFile::Open(const char *fileName)
|
||||||
|
{
|
||||||
|
if(!file.Open(fileName))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&header, file.Buffer(), sizeof(wadHeader_t));
|
||||||
|
lumps = (lump_t*)file.GetOffset(2);
|
||||||
|
wadName = fileName;
|
||||||
|
bWriting = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::Write
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWadFile::Write(const char *fileName)
|
||||||
|
{
|
||||||
|
assert(bWriting == true);
|
||||||
|
|
||||||
|
file.Create(fileName);
|
||||||
|
file.Write8(header.id[0]);
|
||||||
|
file.Write8(header.id[1]);
|
||||||
|
file.Write8(header.id[2]);
|
||||||
|
file.Write8(header.id[3]);
|
||||||
|
file.Write32(header.lmpcount);
|
||||||
|
file.Write32(header.lmpdirpos);
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < writeLumpList.Length(); i++)
|
||||||
|
{
|
||||||
|
byte *data = writeDataList[i];
|
||||||
|
|
||||||
|
if(!data)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int j = 0; j < writeLumpList[i].size; j++)
|
||||||
|
{
|
||||||
|
file.Write8(data[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < writeLumpList.Length(); i++)
|
||||||
|
{
|
||||||
|
file.Write32(writeLumpList[i].filepos);
|
||||||
|
file.Write32(writeLumpList[i].size);
|
||||||
|
for(int j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
file.Write8(writeLumpList[i].name[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::Close
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWadFile::Close(void)
|
||||||
|
{
|
||||||
|
if(file.Opened())
|
||||||
|
{
|
||||||
|
file.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::GetLumpFromName
|
||||||
|
//
|
||||||
|
|
||||||
|
lump_t *kexWadFile::GetLumpFromName(const char *name)
|
||||||
|
{
|
||||||
|
char n[9];
|
||||||
|
|
||||||
|
for(int i = 0; i < header.lmpcount; i++)
|
||||||
|
{
|
||||||
|
// could be optimized here but I really don't feel like
|
||||||
|
// wasting time on this
|
||||||
|
strncpy(n, lumps[i].name, 8);
|
||||||
|
n[8] = 0;
|
||||||
|
|
||||||
|
if(!strncmp(n, name, 8))
|
||||||
|
{
|
||||||
|
return &lumps[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::GetLumpData
|
||||||
|
//
|
||||||
|
|
||||||
|
byte *kexWadFile::GetLumpData(const lump_t *lump)
|
||||||
|
{
|
||||||
|
file.SetOffset(lump->filepos);
|
||||||
|
return &file.Buffer()[lump->filepos];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::GetLumpData
|
||||||
|
//
|
||||||
|
|
||||||
|
byte *kexWadFile::GetLumpData(const char *name)
|
||||||
|
{
|
||||||
|
lump_t *lump = GetLumpFromName(name);
|
||||||
|
|
||||||
|
if(!lump)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.SetOffset(lump->filepos);
|
||||||
|
return &file.Buffer()[lump->filepos];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::SetCurrentMap
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWadFile::SetCurrentMap(const int map)
|
||||||
|
{
|
||||||
|
lump_t *lump = GetLumpFromName(Va("MAP%02d", map));
|
||||||
|
|
||||||
|
if(lump == NULL)
|
||||||
|
{
|
||||||
|
Error("kexWadFile::SetCurrentMap: MAP%02d not found\n", map);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapLumpID = lump - lumps;
|
||||||
|
|
||||||
|
lump = GetLumpFromName(Va("GL_MAP%02d", map));
|
||||||
|
|
||||||
|
if(lump == NULL)
|
||||||
|
{
|
||||||
|
Error("kexWadFile::SetCurrentMap: GL_MAP%02d not found\n", map);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glMapLumpID = lump - lumps;
|
||||||
|
currentmap = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::GetMapLump
|
||||||
|
//
|
||||||
|
|
||||||
|
lump_t *kexWadFile::GetMapLump(mapLumps_t lumpID)
|
||||||
|
{
|
||||||
|
if(mapLumpID + lumpID >= header.lmpcount)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &lumps[mapLumpID + lumpID];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::GetGLMapLump
|
||||||
|
//
|
||||||
|
|
||||||
|
lump_t *kexWadFile::GetGLMapLump(glMapLumps_t lumpID)
|
||||||
|
{
|
||||||
|
if(glMapLumpID + lumpID >= header.lmpcount)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &lumps[glMapLumpID + lumpID];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::InitForWrite
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWadFile::InitForWrite(void)
|
||||||
|
{
|
||||||
|
header.id[0] = 'P';
|
||||||
|
header.id[1] = 'W';
|
||||||
|
header.id[2] = 'A';
|
||||||
|
header.id[3] = 'D';
|
||||||
|
|
||||||
|
writePos = sizeof(wadHeader_t);
|
||||||
|
bWriting = true;
|
||||||
|
|
||||||
|
header.lmpcount = 0;
|
||||||
|
header.lmpdirpos = writePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::CopyLumpsFromWadFile
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWadFile::CopyLumpsFromWadFile(kexWadFile &wadFile)
|
||||||
|
{
|
||||||
|
lump_t lump;
|
||||||
|
|
||||||
|
assert(bWriting == true);
|
||||||
|
|
||||||
|
for(int i = 0; i < wadFile.header.lmpcount; ++i)
|
||||||
|
{
|
||||||
|
lump = wadFile.lumps[i];
|
||||||
|
AddLump(wadFile.lumps[i].name, lump.size, &wadFile.file.Buffer()[lump.filepos]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::CopyLumpsFromWadFile
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWadFile::CopyLumpsFromWadFile(kexWadFile &wadFile, kexArray<int> &lumpIgnoreList)
|
||||||
|
{
|
||||||
|
lump_t lump;
|
||||||
|
unsigned int j;
|
||||||
|
bool bSkip;
|
||||||
|
|
||||||
|
assert(bWriting == true);
|
||||||
|
|
||||||
|
for(int i = 0; i < wadFile.header.lmpcount; ++i)
|
||||||
|
{
|
||||||
|
lump = wadFile.lumps[i];
|
||||||
|
bSkip = false;
|
||||||
|
|
||||||
|
for(j = 0; j < lumpIgnoreList.Length(); ++j)
|
||||||
|
{
|
||||||
|
if(lumpIgnoreList[j] == i)
|
||||||
|
{
|
||||||
|
bSkip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bSkip)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddLump(wadFile.lumps[i].name, lump.size, &wadFile.file.Buffer()[lump.filepos]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::AddLump
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWadFile::AddLump(const char *name, const int size, byte *data)
|
||||||
|
{
|
||||||
|
lump_t lump;
|
||||||
|
|
||||||
|
assert(bWriting == true);
|
||||||
|
|
||||||
|
lump.filepos = writePos;
|
||||||
|
lump.size = size;
|
||||||
|
strncpy(lump.name, name, 8);
|
||||||
|
|
||||||
|
writeLumpList.Push(lump);
|
||||||
|
writeDataList.Push(data);
|
||||||
|
|
||||||
|
header.lmpcount++;
|
||||||
|
header.lmpdirpos += lump.size;
|
||||||
|
writePos += lump.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWadFile::CreateBackup
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWadFile::CreateBackup(void)
|
||||||
|
{
|
||||||
|
kexStr backupName = wadName;
|
||||||
|
|
||||||
|
backupName.StripExtension();
|
||||||
|
file.Duplicate(backupName + ".wad.bak");
|
||||||
|
}
|
164
src/lightmap/wad.h
Normal file
164
src/lightmap/wad.h
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __WAD_H__
|
||||||
|
#define __WAD_H__
|
||||||
|
|
||||||
|
#include "kexlib/binFile.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ML_HEADER = 0,
|
||||||
|
ML_THINGS,
|
||||||
|
ML_LINEDEFS,
|
||||||
|
ML_SIDEDEFS,
|
||||||
|
ML_VERTEXES,
|
||||||
|
ML_SEGS,
|
||||||
|
ML_SUBSECTORS,
|
||||||
|
ML_NODES,
|
||||||
|
ML_SECTORS,
|
||||||
|
ML_REJECT,
|
||||||
|
ML_BLOCKMAP,
|
||||||
|
ML_LIGHTMAP,
|
||||||
|
ML_NUMLUMPS
|
||||||
|
} mapLumps_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ML_GL_LABEL = 0, // A separator name, GL_ExMx or GL_MAPxx
|
||||||
|
ML_GL_VERTS, // Extra Vertices
|
||||||
|
ML_GL_SEGS, // Segs, from linedefs & minisegs
|
||||||
|
ML_GL_SSECT, // SubSectors, list of segs
|
||||||
|
ML_GL_NODES, // GL BSP nodes
|
||||||
|
ML_GL_PVS // PVS portals
|
||||||
|
} glMapLumps_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ML_LM_LABEL = 0,
|
||||||
|
ML_LM_CELLS,
|
||||||
|
ML_LM_SUN,
|
||||||
|
ML_LM_SURFS,
|
||||||
|
ML_LM_TXCRD,
|
||||||
|
ML_LM_LMAPS
|
||||||
|
} lmMapLumps_t;
|
||||||
|
|
||||||
|
#define gNd2 0x32644E67
|
||||||
|
|
||||||
|
#define GL_VERT_OFFSET 4
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char id[4];
|
||||||
|
int lmpcount;
|
||||||
|
int lmpdirpos;
|
||||||
|
} wadHeader_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int filepos;
|
||||||
|
int size;
|
||||||
|
char name[8];
|
||||||
|
} lump_t;
|
||||||
|
|
||||||
|
class kexWadFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~kexWadFile(void);
|
||||||
|
|
||||||
|
wadHeader_t header;
|
||||||
|
lump_t *lumps;
|
||||||
|
unsigned int size;
|
||||||
|
int mapLumpID;
|
||||||
|
int glMapLumpID;
|
||||||
|
kexStr wadName;
|
||||||
|
int currentmap;
|
||||||
|
|
||||||
|
lump_t *GetLumpFromName(const char *name);
|
||||||
|
lump_t *GetMapLump(mapLumps_t lumpID);
|
||||||
|
lump_t *GetGLMapLump(glMapLumps_t lumpID);
|
||||||
|
byte *GetLumpData(const lump_t *lump);
|
||||||
|
byte *GetLumpData(const char *name);
|
||||||
|
void SetCurrentMap(const int map);
|
||||||
|
bool Open(const char *fileName);
|
||||||
|
void Write(const char *fileName);
|
||||||
|
void Close(void);
|
||||||
|
void CreateBackup(void);
|
||||||
|
void InitForWrite(void);
|
||||||
|
void CopyLumpsFromWadFile(kexWadFile &wadFile);
|
||||||
|
void CopyLumpsFromWadFile(kexWadFile &wadFile, kexArray<int> &lumpIgnoreList);
|
||||||
|
void AddLump(const char *name, const int size, byte *data);
|
||||||
|
|
||||||
|
template<typename type>
|
||||||
|
void GetMapLump(mapLumps_t lumpID, type **ptr, int *count)
|
||||||
|
{
|
||||||
|
if(mapLumpID + lumpID >= header.lmpcount)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lump_t *lump = GetMapLump(lumpID);
|
||||||
|
if(lump == NULL || lump->size == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*ptr = (type*)GetLumpData(lump);
|
||||||
|
|
||||||
|
if(count)
|
||||||
|
{
|
||||||
|
*count = lump->size / sizeof(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename type>
|
||||||
|
void GetGLMapLump(glMapLumps_t lumpID, type **ptr, int *count)
|
||||||
|
{
|
||||||
|
if(glMapLumpID + lumpID >= header.lmpcount)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lump_t *lump = GetGLMapLump(lumpID);
|
||||||
|
if(lump == NULL || lump->size == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*ptr = (type*)GetLumpData(lump);
|
||||||
|
|
||||||
|
if(count)
|
||||||
|
{
|
||||||
|
*count = lump->size / sizeof(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
kexBinFile file;
|
||||||
|
bool bWriting;
|
||||||
|
int writePos;
|
||||||
|
kexArray<lump_t> writeLumpList;
|
||||||
|
kexArray<byte*> writeDataList;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
418
src/lightmap/worker.cpp
Normal file
418
src/lightmap/worker.cpp
Normal file
|
@ -0,0 +1,418 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DESCRIPTION: Worker Threads
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "worker.h"
|
||||||
|
|
||||||
|
int kexWorker::maxWorkThreads = MAX_THREADS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// WorkThread
|
||||||
|
//
|
||||||
|
|
||||||
|
void *WorkThread(void *p)
|
||||||
|
{
|
||||||
|
jobFuncArgs_t *args = (jobFuncArgs_t*)p;
|
||||||
|
kexWorker *worker = args->worker;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int jobid;
|
||||||
|
|
||||||
|
worker->LockMutex();
|
||||||
|
|
||||||
|
if(worker->FinishedAllJobs())
|
||||||
|
{
|
||||||
|
worker->UnlockMutex();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobid = worker->DispatchJob();
|
||||||
|
worker->UnlockMutex();
|
||||||
|
|
||||||
|
worker->RunJob(args->data, jobid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWorker::kexWorker
|
||||||
|
//
|
||||||
|
|
||||||
|
kexWorker::kexWorker(void)
|
||||||
|
{
|
||||||
|
this->numWorkLoad = 0;
|
||||||
|
this->jobsWorked = 0;
|
||||||
|
this->job = NULL;
|
||||||
|
|
||||||
|
memset(this->jobArgs, 0, sizeof(this->jobArgs));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWorker::~kexWorker
|
||||||
|
//
|
||||||
|
|
||||||
|
kexWorker::~kexWorker(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWorker::LockMutex
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWorker::LockMutex(void)
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWorker::UnlockMutex
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWorker::UnlockMutex(void)
|
||||||
|
{
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWorker::Destroy
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWorker::Destroy(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// kexWorker::RunThreads
|
||||||
|
//
|
||||||
|
|
||||||
|
void kexWorker::RunThreads(const int count, void *data, jobFunc_t jobFunc)
|
||||||
|
{
|
||||||
|
job = jobFunc;
|
||||||
|
numWorkLoad = count;
|
||||||
|
jobsWorked = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < kexWorker::maxWorkThreads; ++i)
|
||||||
|
{
|
||||||
|
jobArgs[i].worker = this;
|
||||||
|
jobArgs[i].jobID = i;
|
||||||
|
jobArgs[i].data = data;
|
||||||
|
|
||||||
|
threads[i] = std::thread([=]() { WorkThread(&jobArgs[i]); });
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < kexWorker::maxWorkThreads; ++i)
|
||||||
|
{
|
||||||
|
threads[i].join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Stuff from old main.cpp
|
||||||
|
|
||||||
|
static kexStr basePath;
|
||||||
|
|
||||||
|
void Error(const char *error, ...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
|
||||||
|
va_start(argptr, error);
|
||||||
|
vprintf(error, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
printf("\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *Va(const char *str, ...)
|
||||||
|
{
|
||||||
|
va_list v;
|
||||||
|
static char vastr[1024];
|
||||||
|
|
||||||
|
va_start(v, str);
|
||||||
|
vsprintf(vastr, str, v);
|
||||||
|
va_end(v);
|
||||||
|
|
||||||
|
return vastr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Delay(int ms)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// GetSeconds
|
||||||
|
//
|
||||||
|
|
||||||
|
const int64_t GetSeconds(void)
|
||||||
|
{
|
||||||
|
return time(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FilePath
|
||||||
|
//
|
||||||
|
|
||||||
|
const kexStr &FilePath(void)
|
||||||
|
{
|
||||||
|
return basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main
|
||||||
|
//
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
kexWadFile wadFile;
|
||||||
|
kexWadFile outWadFile;
|
||||||
|
kexDoomMap doomMap;
|
||||||
|
lump_t *lmLump;
|
||||||
|
kexArray<int> ignoreLumps;
|
||||||
|
kexLightmapBuilder builder;
|
||||||
|
kexStr configFile("strife_sve.cfg");
|
||||||
|
bool bWriteTGA;
|
||||||
|
int map = 1;
|
||||||
|
int arg = 1;
|
||||||
|
|
||||||
|
printf("DLight (c) 2013-2014 Samuel Villarreal\n\n");
|
||||||
|
|
||||||
|
if (argc < 1 || argv[1] == NULL)
|
||||||
|
{
|
||||||
|
printf("Usage: dlight [options] [wadfile]\n");
|
||||||
|
printf("Use -help for list of options\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
basePath = argv[0];
|
||||||
|
basePath.StripFile();
|
||||||
|
|
||||||
|
bWriteTGA = false;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!strcmp(argv[arg], "-help"))
|
||||||
|
{
|
||||||
|
printf("Options:\n");
|
||||||
|
printf("-help: displays all known options\n");
|
||||||
|
printf("-map: process lightmap for MAP##\n");
|
||||||
|
printf("-samples: set texel sampling size (lowest = higher quaility but\n");
|
||||||
|
printf(" slow compile time) must be in powers of two\n");
|
||||||
|
printf("-ambience: set global ambience value for lightmaps (0.0 - 1.0)\n");
|
||||||
|
printf("-size: lightmap texture dimentions for width and height\n");
|
||||||
|
printf(" must be in powers of two (1, 2, 4, 8, 16, etc)\n");
|
||||||
|
printf("-threads: set total number of threads (1 min, 128 max)\n");
|
||||||
|
printf("-config: specify a config file to parse (default: strife_sve.cfg)\n");
|
||||||
|
printf("-writetga: dumps lightmaps to targa (.TGA) files\n");
|
||||||
|
arg++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[arg], "-map"))
|
||||||
|
{
|
||||||
|
if (argv[arg + 1] == NULL)
|
||||||
|
{
|
||||||
|
Error("Specify map number for -map\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
map = atoi(argv[++arg]);
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[arg], "-samples"))
|
||||||
|
{
|
||||||
|
if (argv[arg + 1] == NULL)
|
||||||
|
{
|
||||||
|
Error("Specify value for -samples\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.samples = atoi(argv[++arg]);
|
||||||
|
if (builder.samples <= 0)
|
||||||
|
{
|
||||||
|
builder.samples = 1;
|
||||||
|
}
|
||||||
|
if (builder.samples > 128)
|
||||||
|
{
|
||||||
|
builder.samples = 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.samples = kexMath::RoundPowerOfTwo(builder.samples);
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[arg], "-ambience"))
|
||||||
|
{
|
||||||
|
if (argv[arg + 1] == NULL)
|
||||||
|
{
|
||||||
|
Error("Specify value for -ambience\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.ambience = (float)atof(argv[++arg]);
|
||||||
|
if (builder.ambience < 0)
|
||||||
|
{
|
||||||
|
builder.ambience = 0;
|
||||||
|
}
|
||||||
|
if (builder.ambience > 1)
|
||||||
|
{
|
||||||
|
builder.ambience = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[arg], "-size"))
|
||||||
|
{
|
||||||
|
int lmDims;
|
||||||
|
|
||||||
|
if (argv[arg + 1] == NULL)
|
||||||
|
{
|
||||||
|
Error("Specify value for -size\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lmDims = atoi(argv[++arg]);
|
||||||
|
if (lmDims <= 0)
|
||||||
|
{
|
||||||
|
lmDims = 1;
|
||||||
|
}
|
||||||
|
if (lmDims > LIGHTMAP_MAX_SIZE)
|
||||||
|
{
|
||||||
|
lmDims = LIGHTMAP_MAX_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lmDims = kexMath::RoundPowerOfTwo(lmDims);
|
||||||
|
|
||||||
|
builder.textureWidth = lmDims;
|
||||||
|
builder.textureHeight = lmDims;
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[arg], "-threads"))
|
||||||
|
{
|
||||||
|
kexWorker::maxWorkThreads = atoi(argv[++arg]);
|
||||||
|
kexMath::Clamp(kexWorker::maxWorkThreads, 1, MAX_THREADS);
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[arg], "-config"))
|
||||||
|
{
|
||||||
|
configFile = argv[++arg];
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
else if (!strcmp(argv[arg], "-writetga"))
|
||||||
|
{
|
||||||
|
bWriteTGA = true;
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv[arg] == NULL)
|
||||||
|
{
|
||||||
|
printf("Usage: dlight [options] [wadfile]\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wadFile.Open(argv[arg]))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// concat the base path to light def file if there is none
|
||||||
|
if (configFile.IndexOf("\\") == -1 && configFile.IndexOf("/") == -1)
|
||||||
|
{
|
||||||
|
configFile = basePath + configFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
int starttime = (int)GetSeconds();
|
||||||
|
|
||||||
|
printf("---------------- Parsing config file ----------------\n\n");
|
||||||
|
doomMap.ParseConfigFile(configFile.c_str());
|
||||||
|
|
||||||
|
printf("------------- Building level structures -------------\n\n");
|
||||||
|
wadFile.SetCurrentMap(map);
|
||||||
|
doomMap.BuildMapFromWad(wadFile);
|
||||||
|
|
||||||
|
printf("----------- Allocating surfaces from level ----------\n\n");
|
||||||
|
Surface_AllocateFromMap(doomMap);
|
||||||
|
|
||||||
|
printf("---------------- Allocating lights ----------------\n\n");
|
||||||
|
doomMap.CreateLights();
|
||||||
|
|
||||||
|
printf("---------------- Creating lightmaps ---------------\n\n");
|
||||||
|
builder.CreateLightmaps(doomMap);
|
||||||
|
doomMap.CleanupThingLights();
|
||||||
|
|
||||||
|
if (bWriteTGA)
|
||||||
|
{
|
||||||
|
builder.WriteTexturesToTGA();
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("------------------ Rebuilding wad ----------------\n\n");
|
||||||
|
wadFile.CreateBackup();
|
||||||
|
|
||||||
|
lmLump = wadFile.GetLumpFromName(Va("LM_MAP%02d", wadFile.currentmap));
|
||||||
|
|
||||||
|
if (lmLump)
|
||||||
|
{
|
||||||
|
int lumpnum = lmLump - wadFile.lumps;
|
||||||
|
|
||||||
|
ignoreLumps.Push(lumpnum + ML_LM_LABEL);
|
||||||
|
ignoreLumps.Push(lumpnum + ML_LM_CELLS);
|
||||||
|
ignoreLumps.Push(lumpnum + ML_LM_SUN);
|
||||||
|
ignoreLumps.Push(lumpnum + ML_LM_SURFS);
|
||||||
|
ignoreLumps.Push(lumpnum + ML_LM_TXCRD);
|
||||||
|
ignoreLumps.Push(lumpnum + ML_LM_LMAPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
outWadFile.InitForWrite();
|
||||||
|
outWadFile.CopyLumpsFromWadFile(wadFile, ignoreLumps);
|
||||||
|
outWadFile.AddLump(Va("LM_MAP%02d", wadFile.currentmap), 0, NULL);
|
||||||
|
|
||||||
|
builder.AddLightGridLump(outWadFile);
|
||||||
|
builder.AddLightmapLumps(outWadFile);
|
||||||
|
|
||||||
|
printf("------------- Writing %s -------------\n\n", wadFile.wadName.c_str());
|
||||||
|
outWadFile.Write(wadFile.wadName);
|
||||||
|
outWadFile.Close();
|
||||||
|
wadFile.Close();
|
||||||
|
|
||||||
|
printf("----------------- Shutting down -----------------\n\n");
|
||||||
|
Mem_Purge(hb_static);
|
||||||
|
|
||||||
|
int proctime = (int)GetSeconds() - starttime;
|
||||||
|
printf("\nBuild time: %d:%02d:%02d\n",
|
||||||
|
proctime / 3600, (proctime / 60) % 60, proctime % 60);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
76
src/lightmap/worker.h
Normal file
76
src/lightmap/worker.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Note: this is a modified version of dlight. It is not the original software.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013-2014 Samuel Villarreal
|
||||||
|
// svkaiser@gmail.com
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __WORKER_H__
|
||||||
|
#define __WORKER_H__
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#define MAX_THREADS 128
|
||||||
|
|
||||||
|
class kexWorker;
|
||||||
|
|
||||||
|
typedef void(*jobFunc_t)(void*, int);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
kexWorker *worker;
|
||||||
|
void *data;
|
||||||
|
int jobID;
|
||||||
|
} jobFuncArgs_t;
|
||||||
|
|
||||||
|
class kexWorker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
kexWorker(void);
|
||||||
|
~kexWorker(void);
|
||||||
|
|
||||||
|
void RunThreads(const int count, void *data, jobFunc_t jobFunc);
|
||||||
|
void LockMutex(void);
|
||||||
|
void UnlockMutex(void);
|
||||||
|
void Destroy(void);
|
||||||
|
|
||||||
|
bool FinishedAllJobs(void) { return jobsWorked == numWorkLoad; }
|
||||||
|
int DispatchJob(void) { int j = jobsWorked; jobsWorked++; return j; }
|
||||||
|
void RunJob(void *data, const int jobID) { job(data, jobID); }
|
||||||
|
|
||||||
|
jobFuncArgs_t *Args(const int id) { return &jobArgs[id]; }
|
||||||
|
const int JobsWorked(void) const { return jobsWorked; }
|
||||||
|
|
||||||
|
static int maxWorkThreads;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::thread threads[MAX_THREADS];
|
||||||
|
jobFuncArgs_t jobArgs[MAX_THREADS];
|
||||||
|
std::mutex mutex;
|
||||||
|
jobFunc_t job;
|
||||||
|
int jobsWorked;
|
||||||
|
int numWorkLoad;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue