Added initial Smoothed Particle Hydrodynamics implementation (SPH), for CPU and CUDA.
This software is contributed under the ZLib license by Rama Hoetzlein, http://www.rchoetzlein.com We plan to integrate the SPH into the core Bullet library, including interaction with rigid bodies and soft bodies.
This commit is contained in:
35
Extras/sph/READ_ME.txt
Normal file
35
Extras/sph/READ_ME.txt
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
A fast CPU and GPU fluid simulator. See website above for details.
|
||||||
|
|
||||||
|
Notes
|
||||||
|
(April 2009)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Press 'h' for help screen. This shows keyboard cmds available.
|
||||||
|
|
||||||
|
- By default, GPU simulation is off.
|
||||||
|
When running the fluid_gpu.exe, press 'g' to start/stop GPU simulation.
|
||||||
|
|
||||||
|
- Disabling shadows in common_defs.h will greatly speed up the simulation
|
||||||
|
(You can also press 's' to render without shadows)
|
||||||
|
|
||||||
|
- As of April 2009, CUDA builds only under Visual Studio 2005, not VS 2008.
|
||||||
|
To enable the CUDA build in VS2005, set the BUILD_CUDA define in common_defs.h
|
||||||
|
Be sure this is turned off if you build with VS2008.
|
||||||
|
|
||||||
|
- The GPU integrator is not yet complete. Integration always takes place on the CPU, in both CPU and GPU modes. (As a result, this forces a bus transfer to and from the GPU per cycle. Once the integrator is finished, GPU simulation performance should increase significantly.)
|
||||||
|
|
||||||
|
- Occassionally, the GPU simulation with crash cuda, causing the screen to blink and particles to move randomly. This is believed to be due to a not-yet-found out of bounds condition.
|
||||||
|
|
||||||
|
ZLib License
|
||||||
|
-------------------
|
||||||
|
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.
|
||||||
5
Extras/sph/cmp.sh
Normal file
5
Extras/sph/cmp.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
g++ -O3 -L./common -I./common -L./particles -I./particles -lGL -lglut common/matrix.cpp common/mdebug.cpp common/merror.cpp common/vector.cpp common/mtime.cpp particles/particle.cpp particles/particle_system.cpp GLee.c main.cpp
|
||||||
|
g++ -g -L./common -I./common -L./particles -I./particles -lGL -lglut common/matrix.cpp common/mdebug.cpp common/merror.cpp common/vector.cpp common/mtime.cpp particles/particle.cpp particles/particle_system.cpp GLee.c main.cpp -o sph_sim.debug
|
||||||
|
|
||||||
17647
Extras/sph/common/GL/GLee.h
Normal file
17647
Extras/sph/common/GL/GLee.h
Normal file
File diff suppressed because it is too large
Load Diff
18170
Extras/sph/common/GLee.c
Normal file
18170
Extras/sph/common/GLee.c
Normal file
File diff suppressed because it is too large
Load Diff
52
Extras/sph/common/common_defs.h
Normal file
52
Extras/sph/common/common_defs.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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_DEF
|
||||||
|
#define COMMON_DEF
|
||||||
|
|
||||||
|
// Global defs
|
||||||
|
|
||||||
|
//#define USE_SHADOWS // Disable if you don't have FBOs, or to greatly speed up demo.
|
||||||
|
|
||||||
|
// #define USE_JPEG
|
||||||
|
|
||||||
|
#define BUILD_CUDA // CUDA - Visual Studio 2005 only (as of April 2009)
|
||||||
|
|
||||||
|
#define TEX_SIZE 2048
|
||||||
|
#define LIGHT_NEAR 0.5
|
||||||
|
#define LIGHT_FAR 300.0
|
||||||
|
#define DEGtoRAD (3.141592/180.0)
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
typedef unsigned int DWORD;
|
||||||
|
#endif
|
||||||
|
typedef unsigned int uint;
|
||||||
|
|
||||||
|
#define COLOR(r,g,b) ( (DWORD(r*255.0f)<<24) | (DWORD(g*255.0f)<<16) | (DWORD(b*255.0f)<<8) )
|
||||||
|
#define COLORA(r,g,b,a) ( (DWORD(r*255.0f)<<24) | (DWORD(g*255.0f)<<16) | (DWORD(b*255.0f)<<8) | DWORD(a*255.0f) )
|
||||||
|
#define RED(c) (float((c>>24) & 0xFF)/255.0)
|
||||||
|
#define GRN(c) (float((c>>16) & 0xFF)/255.0)
|
||||||
|
#define BLUE(c) (float((c>>8) & 0xFF)/255.0)
|
||||||
|
#define ALPH(c) (float(c & 0xFF)/255.0)
|
||||||
|
#endif
|
||||||
443
Extras/sph/common/geomx.cpp
Normal file
443
Extras/sph/common/geomx.cpp
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector.h>
|
||||||
|
#include "geomx.h"
|
||||||
|
#include "mdebug.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
GeomX::GeomX ()
|
||||||
|
{
|
||||||
|
mHeap = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeomX::FreeBuffers ()
|
||||||
|
{
|
||||||
|
for (int n=0; n < (int) mBuf.size(); n++) {
|
||||||
|
free ( mBuf[n].data );
|
||||||
|
mBuf[n].data = 0x0;
|
||||||
|
}
|
||||||
|
mBuf.clear ();
|
||||||
|
|
||||||
|
if ( mHeap != 0x0 ) free ( mHeap );
|
||||||
|
mHeap = 0x0;
|
||||||
|
mHeapNum = 0;
|
||||||
|
mHeapMax = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeomX::ResetHeap ()
|
||||||
|
{
|
||||||
|
mHeapNum = 0;
|
||||||
|
mHeapFree = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeomX::GetSize ()
|
||||||
|
{
|
||||||
|
int sum = mHeapNum * sizeof(hval) ;
|
||||||
|
for (int n=0; n < (int) mBuf.size(); n++)
|
||||||
|
sum += mBuf[n].size;
|
||||||
|
sum += (int) mAttribute.size() * sizeof(GeomAttr);
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeomX::ClearAttributes ()
|
||||||
|
{
|
||||||
|
mAttribute.clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeomX::CopyBuffer ( uchar bdest, uchar bsrc, GeomX& src )
|
||||||
|
{
|
||||||
|
if ( bsrc >= src.GetNumBuf() ) return -1;
|
||||||
|
|
||||||
|
if ( bdest >= GetNumBuf() ) {
|
||||||
|
for (int n=0; n <= bdest - GetNumBuf(); n++ )
|
||||||
|
AddBuffer ( 0, 0, 0 );
|
||||||
|
}
|
||||||
|
if ( mBuf[bdest].data != 0x0 ) {
|
||||||
|
free ( mBuf[bdest].data );
|
||||||
|
mBuf[bdest].data = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GeomBuf* buf = src.GetBuffer( bsrc );
|
||||||
|
mBuf[bdest].dtype = buf->dtype;
|
||||||
|
mBuf[bdest].max = buf->max;
|
||||||
|
mBuf[bdest].num = buf->num;
|
||||||
|
mBuf[bdest].stride = buf->stride;
|
||||||
|
mBuf[bdest].size = buf->size;
|
||||||
|
mBuf[bdest].data = (char*) malloc ( mBuf[bdest].max * mBuf[bdest].stride );
|
||||||
|
memcpy ( mBuf[bdest].data, buf->data, mBuf[bdest].num * mBuf[bdest].stride );
|
||||||
|
|
||||||
|
return bdest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GeomX::CopyBuffers ( GeomX& src )
|
||||||
|
{
|
||||||
|
FreeBuffers ();
|
||||||
|
for (int n = 0; n < src.GetNumBuf(); n++)
|
||||||
|
CopyBuffer ( n, n, src );
|
||||||
|
CopyHeap ( src );
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeomX::CopyHeap ( GeomX& src )
|
||||||
|
{
|
||||||
|
hpos num, max, freepos;
|
||||||
|
hval* src_data = src.GetHeap ( num, max, freepos );
|
||||||
|
|
||||||
|
if ( mHeap != 0x0 ) {
|
||||||
|
free ( mHeap );
|
||||||
|
mHeap = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHeap = (hval*) malloc ( max * sizeof(hval) );
|
||||||
|
mHeapMax = max;
|
||||||
|
mHeapNum = num;
|
||||||
|
mHeapFree = freepos;
|
||||||
|
|
||||||
|
memcpy ( mHeap, src_data, mHeapNum * sizeof(hval) );
|
||||||
|
}
|
||||||
|
|
||||||
|
hval* GeomX::GetHeap ( hpos& num, hpos& max, hpos& free )
|
||||||
|
{
|
||||||
|
num = mHeapNum;
|
||||||
|
max = mHeapMax;
|
||||||
|
free = mHeapFree;
|
||||||
|
return mHeap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeomX::CopyAttributes ( GeomX& src )
|
||||||
|
{
|
||||||
|
GeomAttr* attr;
|
||||||
|
ClearAttributes ();
|
||||||
|
int a;
|
||||||
|
for (int n = 0; n < src.GetNumAttr(); n++) {
|
||||||
|
attr = src.GetAttribute ( n );
|
||||||
|
a = AddAttribute ( (uchar) attr->buf, attr->name, attr->stride, false );
|
||||||
|
mAttribute[a].offset = attr->offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GeomX::AddHeap ( int max )
|
||||||
|
{
|
||||||
|
mHeap = (hval*) malloc ( max * sizeof(hval ) );
|
||||||
|
mHeapMax = max;
|
||||||
|
mHeapNum = 0;
|
||||||
|
mHeapFree = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeomX::AddAttribute ( uchar b, std::string name, ushort stride )
|
||||||
|
{
|
||||||
|
return AddAttribute ( b, name, stride, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeomX::AddAttribute ( uchar b, std::string name, ushort stride, bool bExtend )
|
||||||
|
{
|
||||||
|
GeomBuf* buf = &mBuf[b];
|
||||||
|
GeomAttr attr;
|
||||||
|
|
||||||
|
attr.buf = b;
|
||||||
|
attr.name = name;
|
||||||
|
attr.offset = buf->stride;
|
||||||
|
attr.stride = stride;
|
||||||
|
|
||||||
|
if ( bExtend ) {
|
||||||
|
int new_stride = buf->stride + attr.stride;
|
||||||
|
char* new_data = (char*) malloc ( buf->max * new_stride );
|
||||||
|
char* old_data = buf->data;
|
||||||
|
for (int n=0; n < buf->num; n++) {
|
||||||
|
memcpy ( new_data, old_data, buf->stride );
|
||||||
|
old_data += buf->stride;
|
||||||
|
new_data += new_stride;
|
||||||
|
}
|
||||||
|
free ( buf->data );
|
||||||
|
buf->data = new_data;
|
||||||
|
buf->stride = new_stride;
|
||||||
|
}
|
||||||
|
mAttribute.push_back ( attr );
|
||||||
|
return (int) mAttribute.size()-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeomX::GetAttribute ( std::string name )
|
||||||
|
{
|
||||||
|
for (int n=0; n < (int) mAttribute.size(); n++) {
|
||||||
|
if ( mAttribute[n].name.compare ( name ) == 0 )
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeomX::GetAttrOffset ( std::string name )
|
||||||
|
{
|
||||||
|
for (int n=0; n < (int) mAttribute.size(); n++) {
|
||||||
|
if ( mAttribute[n].name.compare ( name ) == 0 )
|
||||||
|
return mAttribute[n].offset;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeomX::AddBuffer ( uchar typ, ushort stride, int max )
|
||||||
|
{
|
||||||
|
GeomBuf buf;
|
||||||
|
buf.dtype = typ;
|
||||||
|
buf.stride = stride;
|
||||||
|
buf.max = max;
|
||||||
|
buf.num = 0;
|
||||||
|
buf.size = 0;
|
||||||
|
buf.data = (char*) malloc ( buf.max * buf.stride );
|
||||||
|
mBuf.push_back ( buf );
|
||||||
|
return (int) mBuf.size()-1;
|
||||||
|
}
|
||||||
|
void GeomX::ResetBuffer ( uchar b, int n )
|
||||||
|
{
|
||||||
|
mBuf[b].max = n;
|
||||||
|
|
||||||
|
if ( mBuf[b].data != 0x0 ) free ( mBuf[b].data );
|
||||||
|
|
||||||
|
char* new_data = (char*) malloc ( mBuf[b].max * mBuf[b].stride );
|
||||||
|
|
||||||
|
mBuf[b].data = new_data;
|
||||||
|
|
||||||
|
mBuf[b].num = 0;
|
||||||
|
mBuf[b].size = mBuf[b].num*mBuf[b].stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* GeomX::AddElem ( uchar b, href& ndx )
|
||||||
|
{
|
||||||
|
if ( mBuf[b].num >= mBuf[b].max ) {
|
||||||
|
if ( long(mBuf[b].max) * 2 > ELEM_MAX ) {
|
||||||
|
error.PrintF ( "geom", "Maximum number of elements reached.\n" );
|
||||||
|
error.Exit ();
|
||||||
|
}
|
||||||
|
mBuf[b].max *= 2;
|
||||||
|
char* new_data = (char*) malloc ( mBuf[b].max * mBuf[b].stride );
|
||||||
|
memcpy ( new_data, mBuf[b].data, mBuf[b].num*mBuf[b].stride );
|
||||||
|
free ( mBuf[b].data );
|
||||||
|
mBuf[b].data = new_data;
|
||||||
|
}
|
||||||
|
mBuf[b].num++;
|
||||||
|
mBuf[b].size += mBuf[b].stride;
|
||||||
|
ndx = mBuf[b].num-1;
|
||||||
|
return mBuf[b].data + ndx*mBuf[b].stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* GeomX::RandomElem ( uchar b, href& ndx )
|
||||||
|
{
|
||||||
|
ndx = mBuf[b].num * rand() / RAND_MAX;
|
||||||
|
return mBuf[b].data + ndx*mBuf[b].stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GeomX::AddElem ( uchar b, char* data )
|
||||||
|
{
|
||||||
|
if ( mBuf[b].num >= mBuf[b].max ) {
|
||||||
|
mBuf[b].max *= 2;
|
||||||
|
char* new_data = (char*) malloc ( mBuf[b].max * mBuf[b].stride );
|
||||||
|
memcpy ( new_data, mBuf[b].data, mBuf[b].num*mBuf[b].stride );
|
||||||
|
free ( mBuf[b].data );
|
||||||
|
mBuf[b].data = new_data;
|
||||||
|
}
|
||||||
|
memcpy ( mBuf[b].data + mBuf[b].num*mBuf[b].stride, data, mBuf[b].stride );
|
||||||
|
mBuf[b].num++;
|
||||||
|
mBuf[b].size += mBuf[b].stride;
|
||||||
|
return mBuf[b].num-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GeomX::DelElem ( uchar b, int n )
|
||||||
|
{
|
||||||
|
if ( n >= 0 && n < mBuf[b].num ) {
|
||||||
|
memcpy ( mBuf[b].data + n*mBuf[b].stride, mBuf[b].data + (mBuf[b].num-1)*mBuf[b].stride, mBuf[b].stride );
|
||||||
|
mBuf[b].num--;
|
||||||
|
mBuf[b].size -= mBuf[b].stride;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hpos GeomX::HeapExpand ( ushort size, ushort& ret )
|
||||||
|
{
|
||||||
|
mHeapMax *= 2;
|
||||||
|
if ( mHeapMax > HEAP_MAX ) {
|
||||||
|
error.PrintF ( "geom", "Geom heap size exceeds range of index.\n" );
|
||||||
|
error.Exit ();
|
||||||
|
}
|
||||||
|
hval* pNewHeap = (hval*) malloc ( mHeapMax * sizeof(hval) );
|
||||||
|
if ( pNewHeap == 0x0 ) {
|
||||||
|
error.PrintF ( "geom", "Geom heap out of memory.\n" );
|
||||||
|
error.Exit ();
|
||||||
|
}
|
||||||
|
memcpy ( pNewHeap, mHeap, mHeapNum*sizeof(hval) );
|
||||||
|
free ( mHeap );
|
||||||
|
mHeap = pNewHeap;
|
||||||
|
ret = size;
|
||||||
|
assert ( mHeapNum >= 0 && mHeapNum < mHeapMax );
|
||||||
|
return mHeapNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LIST_INIT 4
|
||||||
|
|
||||||
|
hpos GeomX::HeapAlloc ( ushort size, ushort& ret )
|
||||||
|
{
|
||||||
|
hval* pPrev = 0x0;
|
||||||
|
hval* pCurr = mHeap + mHeapFree;
|
||||||
|
hpos pos = -1;
|
||||||
|
|
||||||
|
if ( mHeapNum + size < mHeapMax ) {
|
||||||
|
// Heap not yet full.
|
||||||
|
pos = mHeapNum;
|
||||||
|
ret = size;
|
||||||
|
mHeapNum += size;
|
||||||
|
} else {
|
||||||
|
// Heap full, search free space
|
||||||
|
if ( mHeapFree == -1 ) {
|
||||||
|
pos = HeapExpand ( size, ret );
|
||||||
|
mHeapNum += ret;
|
||||||
|
} else {
|
||||||
|
while ( *pCurr < size && pCurr != mHeap-1 ) {
|
||||||
|
pPrev = pCurr;
|
||||||
|
pCurr = mHeap + * (hpos*) (pCurr + FPOS);
|
||||||
|
}
|
||||||
|
if ( pCurr != mHeap-1 ) {
|
||||||
|
// Found free space.
|
||||||
|
if ( pPrev == 0x0 ) {
|
||||||
|
mHeapFree = * (hpos*) (pCurr + FPOS);
|
||||||
|
assert ( mHeapFree >= -1 );
|
||||||
|
} else {
|
||||||
|
* (hpos*) (pPrev+FPOS) = * (hpos*) (pCurr+FPOS);
|
||||||
|
}
|
||||||
|
pos = pCurr-mHeap;
|
||||||
|
ret = *pCurr;
|
||||||
|
} else {
|
||||||
|
// Heap full, no free space. Expand heap.
|
||||||
|
pos = HeapExpand ( size, ret );
|
||||||
|
mHeapNum += ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert ( pos >= 0 && pos <= mHeapNum );
|
||||||
|
memset ( mHeap+pos, 0, size*sizeof(hval) );
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeomX::HeapAddFree ( hpos pos, int size )
|
||||||
|
{
|
||||||
|
// memset ( mHeap+pos, 0xFF, size*sizeof(hval) );
|
||||||
|
|
||||||
|
if ( pos < mHeapFree || mHeapFree == -1 ) {
|
||||||
|
// Lowest position. Insert at head of heap.
|
||||||
|
* (hpos*) (mHeap+pos) = size;
|
||||||
|
* (hpos*) (mHeap+pos + FPOS) = mHeapFree;
|
||||||
|
mHeapFree = pos;
|
||||||
|
if ( mHeapFree != -1 && *(hpos*) (mHeap+mHeapFree+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pHeapFree, %d\n", pos ); error.Exit (); }
|
||||||
|
|
||||||
|
assert ( mHeapFree >= -1 );
|
||||||
|
} else {
|
||||||
|
hval* pCurr = mHeap + pos;
|
||||||
|
hval* pPrev = 0x0;
|
||||||
|
hval* pNext = mHeap + mHeapFree;
|
||||||
|
|
||||||
|
if ( pCurr == pNext ) { // Freeing the first block
|
||||||
|
mHeapFree = * (hpos*) (pCurr + FPOS);
|
||||||
|
* (hpos*) (mHeap+mHeapFree + FPOS) = 0xFFFFFFFF;
|
||||||
|
* (hpos*) (pCurr + FPOS) = 0xFFFFFFFF;
|
||||||
|
* (hpos*) pCurr = 0xFFFFFFFF;
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find first block greater than new free pos.
|
||||||
|
while ( pNext < pCurr && pNext != mHeap-1 ) {
|
||||||
|
pPrev = pNext;
|
||||||
|
pNext = mHeap + * (hpos*) (pNext + FPOS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
if ( pPrev + *(pPrev) == pCurr ) { // Prev block touches current one (expand previous)
|
||||||
|
* (hpos*) pPrev += size; // - prev.size = prev.size + curr.size
|
||||||
|
x=1;
|
||||||
|
|
||||||
|
} else if ( pCurr + size == pNext && pNext != mHeap-1 ) { // Curr block touches next one (expand current block)
|
||||||
|
* (hpos*) (pPrev + FPOS) = pos; // - prev.next = curr
|
||||||
|
* (hpos*) (pCurr + FPOS) = * (hpos*) (pNext + FPOS); // - curr.next = next.next
|
||||||
|
* (hpos*) pCurr = size + * (hpos*) pNext; // - curr.size = size + next.size
|
||||||
|
* (hpos*) (pNext) = 0xFFFFFFFF; // - curr = null
|
||||||
|
* (hpos*) (pNext + FPOS) = 0xFFFFFFFF; // - curr.next = null
|
||||||
|
x=2;
|
||||||
|
|
||||||
|
} else { // Otherwise (linked list insert)
|
||||||
|
* (hpos*) (pPrev + FPOS) = pos; // - prev.next = curr
|
||||||
|
if ( pNext != mHeap-1 )
|
||||||
|
* (hpos*) (pCurr + FPOS) = pNext - mHeap; // - curr.next = next
|
||||||
|
else
|
||||||
|
* (hpos*) (pCurr + FPOS) = 0xFFFFFFFF; // - curr.next = null (no next node)
|
||||||
|
* (hpos*) pCurr = size; // - curr.size = size
|
||||||
|
x=3;
|
||||||
|
}
|
||||||
|
if ( pCurr !=mHeap-1 && *(hpos*) (pCurr+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pCurr, %d, %d\n", x, pos ); error.Exit (); }
|
||||||
|
if ( pPrev !=mHeap-1 && *(hpos*) (pPrev+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pPrev, %d, %d\n", x, pos ); error.Exit (); }
|
||||||
|
if ( pNext !=mHeap-1 && *(hpos*) (pNext+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pNext, %d, %d\n", x, pos ); error.Exit (); }
|
||||||
|
if ( *(hpos*) (mHeap+mHeapFree+FPOS) == 0x0 ) { error.PrintF ( "geomx", "ERROR: Heap pointer 0. pHeapFree, %d, %d\n", x, pos ); error.Exit (); }
|
||||||
|
|
||||||
|
// -- check for bugs (remove eventually)
|
||||||
|
pNext = mHeap + mHeapFree;
|
||||||
|
while ( pNext != mHeap-1 ) {
|
||||||
|
pPrev = pNext;
|
||||||
|
pNext = mHeap + * (hpos*) (pNext + FPOS);
|
||||||
|
if ( pNext < pPrev && pNext != mHeap-1 ) {
|
||||||
|
error.PrintF ( "geomx", "ERROR: Heap free space out of order. %d, %d\n", x, pos );
|
||||||
|
error.Exit ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeomX::ClearRefs ( hList& list )
|
||||||
|
{
|
||||||
|
list.cnt = 0;
|
||||||
|
list.max = 0;
|
||||||
|
list.pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hval GeomX::AddRef ( hval r, hList& list, hval delta )
|
||||||
|
{
|
||||||
|
if ( list.max == 0 ) {
|
||||||
|
list.cnt = 1;
|
||||||
|
list.pos = HeapAlloc ( LIST_INIT, list.max );
|
||||||
|
*(mHeap + list.pos) = r+delta;
|
||||||
|
} else {
|
||||||
|
if ( list.cnt >= list.max ) {
|
||||||
|
int siz = list.max;
|
||||||
|
hpos new_pos = HeapAlloc ( siz+LIST_INIT, list.max ); // Alloc new location
|
||||||
|
//printf ( "MOVE %d -> %d\n", list.pos, new_pos );
|
||||||
|
memcpy ( mHeap+new_pos, mHeap+list.pos, list.cnt*sizeof(hval) ); // Copy data to new location
|
||||||
|
HeapAddFree ( list.pos, siz ); // Free old location
|
||||||
|
list.pos = new_pos;
|
||||||
|
|
||||||
|
}
|
||||||
|
*(mHeap + list.pos + list.cnt) = r+delta;
|
||||||
|
list.cnt++;
|
||||||
|
}
|
||||||
|
return list.pos;
|
||||||
|
}
|
||||||
125
Extras/sph/common/geomx.h
Normal file
125
Extras/sph/common/geomx.h
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 DEF_GEOM
|
||||||
|
#define DEF_GEOM
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define HEAP_MAX 2147483640 // largest heap size (range of hpos)
|
||||||
|
|
||||||
|
#define ELEM_MAX 2147483640 // largest number of elements in a buffer (range of hval)
|
||||||
|
//#define ELEM_MAX 32768 // largest number of elements in a buffer (range of hval)
|
||||||
|
|
||||||
|
#define BUF_UNDEF 255
|
||||||
|
|
||||||
|
#define FPOS 2 // free position offsets
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
typedef signed int hpos; // pointers into heap
|
||||||
|
typedef signed int hval; // values in heap
|
||||||
|
typedef hval href; // values are typically references
|
||||||
|
struct hList {
|
||||||
|
ushort cnt;
|
||||||
|
ushort max;
|
||||||
|
hpos pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GeomAttr {
|
||||||
|
public:
|
||||||
|
GeomAttr() { name = ""; buf = 0; stride = 0; offset = 0; }
|
||||||
|
std::string name;
|
||||||
|
ushort buf;
|
||||||
|
ushort stride;
|
||||||
|
ushort offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GeomBuf {
|
||||||
|
public:
|
||||||
|
GeomBuf() { dtype = 0; num = 0; max = 0; stride = 0; data = 0x0; }
|
||||||
|
uchar dtype;
|
||||||
|
hval num;
|
||||||
|
hval max;
|
||||||
|
long size;
|
||||||
|
ushort stride;
|
||||||
|
char* data;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GeomX {
|
||||||
|
public:
|
||||||
|
GeomX ();
|
||||||
|
|
||||||
|
// virtual objType GetType () { return 'geom'; }
|
||||||
|
|
||||||
|
// Basic geometry setup
|
||||||
|
void FreeBuffers ();
|
||||||
|
void ClearAttributes ();
|
||||||
|
void AddHeap ( int max );
|
||||||
|
int CopyBuffer ( uchar bdest, uchar bsrc, GeomX& src );
|
||||||
|
void CopyBuffers ( GeomX& src );
|
||||||
|
void CopyAttributes ( GeomX& src );
|
||||||
|
void CopyHeap ( GeomX& src );
|
||||||
|
void ResetBuffer ( uchar b, int n );
|
||||||
|
void ResetHeap ();
|
||||||
|
int AddBuffer ( uchar typ, ushort stride, int max );
|
||||||
|
int AddAttribute ( uchar b, std::string name, ushort stride );
|
||||||
|
int AddAttribute ( uchar b, std::string name, ushort stride, bool bExtend );
|
||||||
|
int GetAttribute ( std::string name );
|
||||||
|
int GetAttrOffset ( std::string name );
|
||||||
|
int NumElem ( uchar b ) { if ( b==BUF_UNDEF) return 0; else return mBuf[b].num; }
|
||||||
|
int MaxElem ( uchar b ) { if ( b==BUF_UNDEF) return 0; else return mBuf[b].max; }
|
||||||
|
int GetStride ( uchar b ) { return mBuf[b].stride; }
|
||||||
|
char* GetElem ( uchar b, int n ) { return mBuf[b].data + n*mBuf[b].stride; }
|
||||||
|
char* RandomElem ( uchar b, href& ndx );
|
||||||
|
char* AddElem ( uchar b, href& pos );
|
||||||
|
int AddElem ( uchar b, char* data );
|
||||||
|
bool DelElem ( uchar b, int n );
|
||||||
|
char* GetStart ( uchar b ) { return mBuf[b].data; }
|
||||||
|
char* GetEnd ( uchar b ) { return mBuf[b].data + mBuf[b].num*mBuf[b].stride; }
|
||||||
|
GeomBuf* GetBuffer ( uchar b ) { return &mBuf[b]; }
|
||||||
|
GeomAttr* GetAttribute ( int n ) { return &mAttribute[n]; }
|
||||||
|
int GetNumBuf () { return (int) mBuf.size(); }
|
||||||
|
int GetNumAttr () { return (int) mAttribute.size(); }
|
||||||
|
hval* GetHeap ( hpos& num, hpos& max, hpos& free );
|
||||||
|
|
||||||
|
int GetSize ();
|
||||||
|
|
||||||
|
/*int AddRef ( int b, int n, int ref, ushort listpos );
|
||||||
|
int AddRef ( int b, int n, int ref, bool bUseHeap, ushort listpos, ushort width );*/
|
||||||
|
void ClearRefs ( hList& list );
|
||||||
|
hval AddRef ( hval r, hList& list, hval delta );
|
||||||
|
hpos HeapAlloc ( ushort size, ushort& ret );
|
||||||
|
hpos HeapExpand ( ushort size, ushort& ret );
|
||||||
|
void HeapAddFree ( hpos pos, int size );
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector< GeomBuf > mBuf;
|
||||||
|
std::vector< GeomAttr > mAttribute;
|
||||||
|
|
||||||
|
hpos mHeapNum;
|
||||||
|
hpos mHeapMax;
|
||||||
|
hpos mHeapFree;
|
||||||
|
hval* mHeap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
402
Extras/sph/common/gl_helper.cpp
Normal file
402
Extras/sph/common/gl_helper.cpp
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common_defs.h"
|
||||||
|
#include "gl_helper.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Shadow Light
|
||||||
|
float light_proj[16];
|
||||||
|
float light_x, light_y, light_z;
|
||||||
|
float light_tox, light_toy, light_toz;
|
||||||
|
float light_mfov;
|
||||||
|
|
||||||
|
// Fonts
|
||||||
|
void *font = GLUT_BITMAP_8_BY_13;
|
||||||
|
void *fonts[] = {GLUT_BITMAP_9_BY_15,
|
||||||
|
GLUT_BITMAP_TIMES_ROMAN_10,
|
||||||
|
GLUT_BITMAP_TIMES_ROMAN_24};
|
||||||
|
// Timing
|
||||||
|
mint::Time tm_last;
|
||||||
|
int tm_cnt;
|
||||||
|
float tm_fps;
|
||||||
|
|
||||||
|
GLuint glSphere = 65535;
|
||||||
|
float glRadius = 0.0;
|
||||||
|
|
||||||
|
void setSphereRadius ( float r )
|
||||||
|
{
|
||||||
|
if ( glRadius == r ) return;
|
||||||
|
glRadius = r;
|
||||||
|
|
||||||
|
// GL sphere
|
||||||
|
if ( glSphere != 65535 ) glDeleteLists ( glSphere, 1 );
|
||||||
|
glSphere = glGenLists ( 1 );
|
||||||
|
float x, y, z, x1, y1, z1;
|
||||||
|
glNewList ( glSphere, GL_COMPILE );
|
||||||
|
glBegin ( GL_TRIANGLE_STRIP );
|
||||||
|
for ( float tilt=-90; tilt <= 90; tilt += 10.0) {
|
||||||
|
for ( float ang=0; ang <= 360; ang += 30.0) {
|
||||||
|
x = sin ( ang*DEGtoRAD) * cos ( tilt*DEGtoRAD );
|
||||||
|
y = cos ( ang*DEGtoRAD) * cos ( tilt*DEGtoRAD );
|
||||||
|
z = sin ( tilt*DEGtoRAD ) ;
|
||||||
|
x1 = sin ( ang*DEGtoRAD) * cos ( (tilt+10.0)*DEGtoRAD ) ;
|
||||||
|
y1 = cos ( ang*DEGtoRAD) * cos ( (tilt+10.0)*DEGtoRAD ) ;
|
||||||
|
z1 = sin ( (tilt+10.0)*DEGtoRAD );
|
||||||
|
glNormal3f ( x, y, z ); glVertex3f ( x*r, y*r, z*r );
|
||||||
|
glNormal3f ( x1, y1, z1 ); glVertex3f ( x1*r, y1*r, z1*r );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
glEndList ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawSphere ()
|
||||||
|
{
|
||||||
|
if ( glRadius == 0.0 ) setSphereRadius ( 1.0 );
|
||||||
|
glCallList ( glSphere );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there have been any openGL problems
|
||||||
|
void checkOpenGL ()
|
||||||
|
{
|
||||||
|
GLenum errCode = glGetError();
|
||||||
|
if (errCode != GL_NO_ERROR) {
|
||||||
|
const GLubyte* errString = gluErrorString(errCode);
|
||||||
|
fprintf( stderr, "OpenGL error: %s\n", errString );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawText ( int x, int y, char* msg)
|
||||||
|
{
|
||||||
|
int len, i;
|
||||||
|
glRasterPos2f(x, y);
|
||||||
|
len = (int) strlen(msg);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
glutBitmapCharacter(font, msg[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawGrid ()
|
||||||
|
{
|
||||||
|
glColor3f ( 0.3, 0.3, 0.3 );
|
||||||
|
glBegin ( GL_LINES );
|
||||||
|
for (float x=-40; x<=40.0; x+=10.0 ) {
|
||||||
|
glVertex3f ( x, -40.0, 0 );
|
||||||
|
glVertex3f ( x, 40.0, 0 );
|
||||||
|
}
|
||||||
|
for (float y=-40; y<=40.0; y+=10.0 ) {
|
||||||
|
glVertex3f ( -40.0, y, 0 );
|
||||||
|
glVertex3f ( 40.0, y, 0 );
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void measureFPS ()
|
||||||
|
{
|
||||||
|
// Measure FPS
|
||||||
|
mint::Time tm_elaps;
|
||||||
|
if ( ++tm_cnt > 5 ) {
|
||||||
|
tm_elaps.SetSystemTime ( ACC_NSEC ); // get current sytem time - accurate to 1 ns
|
||||||
|
tm_elaps = tm_elaps - tm_last; // get elapsed time from 5 frames ago
|
||||||
|
tm_fps = 5.0 * 1000.0 / tm_elaps.GetMSec (); // compute fps
|
||||||
|
tm_cnt = 0; // reset frame counter
|
||||||
|
tm_last.SetSystemTime ( ACC_NSEC );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkFrameBuffers ()
|
||||||
|
{
|
||||||
|
GLenum status;
|
||||||
|
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||||
|
switch(status) {
|
||||||
|
case GL_FRAMEBUFFER_COMPLETE_EXT: printf ( "FBO complete\n" ); break;
|
||||||
|
case GL_FRAMEBUFFER_UNSUPPORTED_EXT: printf ( "FBO format unsupported\n"); break;
|
||||||
|
default: printf ( "Unknown FBO error\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableShadows ()
|
||||||
|
{
|
||||||
|
glDisable ( GL_TEXTURE_2D );
|
||||||
|
|
||||||
|
glActiveTextureARB( GL_TEXTURE1_ARB );
|
||||||
|
glBindTexture ( GL_TEXTURE_2D, 0 );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_S );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_T );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_R );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_Q );
|
||||||
|
|
||||||
|
glActiveTextureARB( GL_TEXTURE2_ARB );
|
||||||
|
glBindTexture ( GL_TEXTURE_2D, 0 );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_S );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_T );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_R );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_Q );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
// Materials & Textures
|
||||||
|
GLuint shadow1_id = 0; // display buffer shadows
|
||||||
|
GLuint shadow2_id = 0; // display buffer shadows
|
||||||
|
|
||||||
|
// Frame buffer
|
||||||
|
GLuint frameBufferObject = 0; // frame buffer shadows
|
||||||
|
|
||||||
|
void createFrameBuffer ()
|
||||||
|
{
|
||||||
|
//Generate the frame buffer object
|
||||||
|
glGenFramebuffersEXT (1, &frameBufferObject);
|
||||||
|
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferObject); // Turn on frame buffer object
|
||||||
|
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow1_id, 0);
|
||||||
|
glDrawBuffer (GL_NONE); // Set Draw & ReadBuffer to none since we're rendering depth only
|
||||||
|
glReadBuffer (GL_NONE);
|
||||||
|
checkFrameBuffers (); // Check completeness of frame buffer object (no need for stencil and depth attachement)
|
||||||
|
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); // Turn off frame buffer object
|
||||||
|
}
|
||||||
|
|
||||||
|
void createShadowTextures ()
|
||||||
|
{
|
||||||
|
// Create depth texture maps
|
||||||
|
glActiveTextureARB( GL_TEXTURE1_ARB );
|
||||||
|
glGenTextures( 1, &shadow1_id );
|
||||||
|
glBindTexture ( GL_TEXTURE_2D, shadow1_id );
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
|
|
||||||
|
//-- sets region outside shadow to 0
|
||||||
|
//glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_ARB );
|
||||||
|
//glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_ARB );
|
||||||
|
|
||||||
|
//-- sets region outside shadow to 1 (border edge color)
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||||
|
|
||||||
|
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||||
|
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTexImage2D ( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
glActiveTextureARB( GL_TEXTURE2_ARB );
|
||||||
|
glGenTextures( 1, &shadow2_id );
|
||||||
|
glBindTexture ( GL_TEXTURE_2D, shadow2_id );
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
|
//glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_ARB );
|
||||||
|
//glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER_ARB );
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||||
|
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||||
|
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTexImage2D ( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void computeLightMatrix ( int n, int tx, int ty )
|
||||||
|
{
|
||||||
|
int lnum = n;
|
||||||
|
// Construct projective texturing matrix
|
||||||
|
|
||||||
|
// S - light bias matrix
|
||||||
|
glMatrixMode ( GL_MODELVIEW );
|
||||||
|
glLoadIdentity ();
|
||||||
|
glTranslatef ( 0.5, 0.5, 0.5 );
|
||||||
|
glScalef ( 0.5, 0.5, 0.5 );
|
||||||
|
// Plight - light projection matrix
|
||||||
|
gluPerspective ( light_mfov*2.0, float(tx) / ty, LIGHT_NEAR, LIGHT_FAR );
|
||||||
|
// L^-1 - light view inverse matrix
|
||||||
|
gluLookAt ( light_x, light_y, light_z, light_tox, light_toy, light_toz, 0, 0, 1);
|
||||||
|
glPushMatrix ();
|
||||||
|
glGetFloatv ( GL_MODELVIEW_MATRIX, light_proj );
|
||||||
|
glPopMatrix ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderDepthMap_Clear ( float wx, float wy )
|
||||||
|
{
|
||||||
|
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferObject);
|
||||||
|
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow1_id, 0);
|
||||||
|
glActiveTextureARB( GL_TEXTURE1_ARB ); // TEXTURE1 = shadow map stage
|
||||||
|
glViewport (1, 1, TEX_SIZE-2, TEX_SIZE-2); // Note: Avoid artifact cause by drawing into border pixels
|
||||||
|
glClear ( GL_DEPTH_BUFFER_BIT );
|
||||||
|
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
glViewport ( 0, 0, (GLsizei) wx, (GLsizei) wy );
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderDepthMap_FrameBuffer ( int n, float wx, float wy )
|
||||||
|
{
|
||||||
|
float vmat[16];
|
||||||
|
|
||||||
|
computeLightMatrix ( n, TEX_SIZE, TEX_SIZE );
|
||||||
|
|
||||||
|
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, frameBufferObject);
|
||||||
|
|
||||||
|
if ( n == 0 ) {
|
||||||
|
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow1_id, 0);
|
||||||
|
} else {
|
||||||
|
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow2_id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( n == 0 ) glActiveTextureARB( GL_TEXTURE1_ARB ); // TEXTURE1 = shadow map stage
|
||||||
|
else glActiveTextureARB( GL_TEXTURE2_ARB ); // TEXTURE2 = shadow map stage
|
||||||
|
|
||||||
|
glViewport (1, 1, TEX_SIZE-2, TEX_SIZE-2); // Note: Avoid artifact cause by drawing into border pixels
|
||||||
|
glClear ( GL_DEPTH_BUFFER_BIT );
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
// Plight - projection matrix of light
|
||||||
|
glMatrixMode ( GL_PROJECTION ); // Setup projection for depth-map rendering
|
||||||
|
glLoadIdentity ();
|
||||||
|
gluPerspective ( light_mfov*2.0, float(TEX_SIZE) / TEX_SIZE, LIGHT_NEAR, LIGHT_FAR );
|
||||||
|
|
||||||
|
// L^-1 - light view matrix (gluLookAt computes inverse)
|
||||||
|
glMatrixMode ( GL_MODELVIEW); // Setup view for depth-map rendering
|
||||||
|
glLoadIdentity ();
|
||||||
|
gluLookAt ( light_x, light_y, light_z, light_tox, light_toy, light_toz, 0, 0, 1);
|
||||||
|
glPushMatrix (); // Save view matrix for later
|
||||||
|
glGetFloatv ( GL_MODELVIEW_MATRIX, vmat );
|
||||||
|
glPopMatrix ();
|
||||||
|
|
||||||
|
glDisable ( GL_LIGHTING );
|
||||||
|
glColor4f ( 1, 1, 1, 1 );
|
||||||
|
glShadeModel (GL_FLAT); // No shading (faster)
|
||||||
|
|
||||||
|
glEnable ( GL_CULL_FACE );
|
||||||
|
glCullFace ( GL_FRONT );
|
||||||
|
|
||||||
|
glEnable ( GL_POLYGON_OFFSET_FILL );
|
||||||
|
glPolygonOffset ( 50.0, 0.1 ); // Depth bias
|
||||||
|
|
||||||
|
drawScene ( &vmat[0], false ); // Draw scene.
|
||||||
|
|
||||||
|
glDisable ( GL_POLYGON_OFFSET_FILL );
|
||||||
|
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
glViewport ( 0, 0, (GLsizei) wx, (GLsizei) wy );
|
||||||
|
|
||||||
|
//glCullFace (GL_BACK); // Restore render states
|
||||||
|
//glBindTexture ( GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderShadowStage ( int n, float* vmat )
|
||||||
|
{
|
||||||
|
GLfloat pos[4];
|
||||||
|
GLfloat row[4];
|
||||||
|
|
||||||
|
computeLightMatrix ( n, TEX_SIZE, TEX_SIZE );
|
||||||
|
if ( n == 0 ) {
|
||||||
|
glActiveTextureARB( GL_TEXTURE1_ARB ); // TEXTURE1 = shadow map stage #1
|
||||||
|
} else {
|
||||||
|
glActiveTextureARB( GL_TEXTURE2_ARB ); // TEXTURE2 = shadow map stage #2
|
||||||
|
}
|
||||||
|
glEnable ( GL_TEXTURE_2D );
|
||||||
|
if ( n == 0 ) glBindTexture ( GL_TEXTURE_2D, shadow1_id );
|
||||||
|
else glBindTexture ( GL_TEXTURE_2D, shadow2_id );
|
||||||
|
|
||||||
|
glMatrixMode( GL_MODELVIEW );
|
||||||
|
glLoadMatrixf ( vmat );
|
||||||
|
|
||||||
|
row[0] = light_proj[0]; row[1] = light_proj[4]; row[2] = light_proj[8]; row[3] = light_proj[12];
|
||||||
|
glTexGenfv(GL_S, GL_EYE_PLANE, &row[0] );
|
||||||
|
row[0] = light_proj[1]; row[1] = light_proj[5]; row[2] = light_proj[9]; row[3] = light_proj[13];
|
||||||
|
glTexGenfv(GL_T, GL_EYE_PLANE, &row[0] );
|
||||||
|
row[0] = light_proj[2]; row[1] = light_proj[6]; row[2] = light_proj[10]; row[3] = light_proj[14];
|
||||||
|
glTexGenfv(GL_R, GL_EYE_PLANE, &row[0] );
|
||||||
|
row[0] = light_proj[3]; row[1] = light_proj[7]; row[2] = light_proj[11]; row[3] = light_proj[15];
|
||||||
|
glTexGenfv(GL_Q, GL_EYE_PLANE, &row[0] );
|
||||||
|
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
|
||||||
|
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
|
||||||
|
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
|
||||||
|
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
|
||||||
|
glEnable(GL_TEXTURE_GEN_S);
|
||||||
|
glEnable(GL_TEXTURE_GEN_T);
|
||||||
|
glEnable(GL_TEXTURE_GEN_R);
|
||||||
|
glEnable(GL_TEXTURE_GEN_Q);
|
||||||
|
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
|
||||||
|
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE ) ;
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE ) ;
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS ) ;
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT ) ;
|
||||||
|
|
||||||
|
pos[0] = 0.20;
|
||||||
|
pos[1] = 0.20;
|
||||||
|
pos[2] = 0.20;
|
||||||
|
pos[3] = 0.20;
|
||||||
|
glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &pos[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderShadows ( float* vmat )
|
||||||
|
{
|
||||||
|
GLfloat pos[4];
|
||||||
|
|
||||||
|
renderShadowStage ( 0, vmat );
|
||||||
|
// renderShadowStage ( 1, vmat );
|
||||||
|
|
||||||
|
glActiveTextureARB( GL_TEXTURE0_ARB ); // Render Tex 0 - Base render
|
||||||
|
glDisable ( GL_TEXTURE_GEN_S );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_T );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_R );
|
||||||
|
glDisable ( GL_TEXTURE_GEN_Q );
|
||||||
|
glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||||
|
glEnable ( GL_LIGHTING );
|
||||||
|
glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
|
||||||
|
|
||||||
|
glEnable ( GL_LIGHT0 );
|
||||||
|
pos[0] = light_x; pos[1] = light_y; pos[2] = light_z; pos[3] = 1.0;
|
||||||
|
glLightfv ( GL_LIGHT0, GL_POSITION, &pos[0] );
|
||||||
|
|
||||||
|
/* glEnable ( GL_LIGHT1 );
|
||||||
|
pos[0] = light[1].x; pos[1] = light[1].y; pos[2] = light[1].z; pos[3] = 1.0;
|
||||||
|
glLightfv ( GL_LIGHT1, GL_POSITION, &pos[0] );*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setShadowLight ( float fx, float fy, float fz, float tx, float ty, float tz, float fov )
|
||||||
|
{
|
||||||
|
light_x = fx;
|
||||||
|
light_y = fy;
|
||||||
|
light_z = fz;
|
||||||
|
light_tox = tx;
|
||||||
|
light_toy = ty;
|
||||||
|
light_toz = tz;
|
||||||
|
light_mfov = fov;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShadowLightColor ( float dr, float dg, float db, float sr, float sg, float sb )
|
||||||
|
{
|
||||||
|
GLfloat amb[4] = {0.0,0.0,0.0,1};
|
||||||
|
GLfloat dif[4];
|
||||||
|
GLfloat spec[4];
|
||||||
|
GLfloat pos[4] = {0.0,0.0,0.0, 100.0};
|
||||||
|
|
||||||
|
glEnable(GL_LIGHT0);
|
||||||
|
dif[0] = dr; dif[1] = dg; dif[2] = db; dif[3] = 1;
|
||||||
|
spec[0] = sr; spec[1] = sg; spec[2] = sb; spec[3] = 1;
|
||||||
|
glLightfv(GL_LIGHT0, GL_AMBIENT, &amb[0] );
|
||||||
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, &dif[0] );
|
||||||
|
glLightfv(GL_LIGHT0, GL_SPECULAR, &spec[0] );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
89
Extras/sph/common/gl_helper.h
Normal file
89
Extras/sph/common/gl_helper.h
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 GL_HELPER
|
||||||
|
#define GL_HELPER
|
||||||
|
|
||||||
|
#include "common_defs.h"
|
||||||
|
|
||||||
|
#include <gl/glee.h>
|
||||||
|
#include <gl/glext.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER // Windows
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
#include <gl/glee.h>
|
||||||
|
#include <gl/glext.h>
|
||||||
|
#endif
|
||||||
|
#include <gl/glut.h>
|
||||||
|
#else // Linux
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
#include "GLee.h"
|
||||||
|
#endif
|
||||||
|
#include <GL/glext.h>
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "image.h"
|
||||||
|
#include "mtime.h"
|
||||||
|
|
||||||
|
extern void checkOpenGL ();
|
||||||
|
extern void drawText ( int x, int y, char* msg);
|
||||||
|
extern void drawGrid ();
|
||||||
|
extern void measureFPS ();
|
||||||
|
|
||||||
|
extern mint::Time tm_last;
|
||||||
|
extern int tm_cnt;
|
||||||
|
extern float tm_fps;
|
||||||
|
|
||||||
|
|
||||||
|
extern void disableShadows ();
|
||||||
|
extern void checkFrameBuffers ();
|
||||||
|
|
||||||
|
extern GLuint glSphere;
|
||||||
|
extern float glRadius;
|
||||||
|
extern void setSphereRadius ( float f );
|
||||||
|
extern void drawSphere ();
|
||||||
|
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
extern void setShadowLight ( float fx, float fy, float fz, float tx, float ty, float tz, float fov );
|
||||||
|
extern void setShadowLightColor ( float dr, float dg, float db, float sr, float sg, float sb );
|
||||||
|
|
||||||
|
extern void createFrameBuffer ();
|
||||||
|
extern void createShadowTextures ();
|
||||||
|
extern void computeLightMatrix ( int n, int tx, int ty );
|
||||||
|
extern void renderDepthMap_Clear ( float wx, float wy );
|
||||||
|
extern void renderDepthMap_FrameBuffer ( int n, float wx, float wy );
|
||||||
|
extern void renderShadowStage ( int n, float* vmat );
|
||||||
|
extern void renderShadows ( float* vmat );
|
||||||
|
extern void drawScene ( float* view_mat, bool bShaders ); // provided by user
|
||||||
|
|
||||||
|
extern float light_proj[16];
|
||||||
|
extern float light_x, light_y, light_z;
|
||||||
|
extern float light_tox, light_toy, light_toz;
|
||||||
|
extern float light_mfov;
|
||||||
|
|
||||||
|
extern GLuint shadow1_id;
|
||||||
|
extern GLuint shadow2_id;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
7139
Extras/sph/common/glext.h
Normal file
7139
Extras/sph/common/glext.h
Normal file
File diff suppressed because it is too large
Load Diff
791
Extras/sph/common/glut.h
Normal file
791
Extras/sph/common/glut.h
Normal file
@@ -0,0 +1,791 @@
|
|||||||
|
#ifndef __glut_h__
|
||||||
|
#define __glut_h__
|
||||||
|
|
||||||
|
/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998, 2000, 2006. */
|
||||||
|
|
||||||
|
/* This program is freely distributable without licensing fees and is
|
||||||
|
provided without guarantee or warrantee expressed or implied. This
|
||||||
|
program is -not- in the public domain. */
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
|
||||||
|
/* GLUT 3.7 now tries to avoid including <windows.h>
|
||||||
|
to avoid name space pollution, but Win32's <GL/gl.h>
|
||||||
|
needs APIENTRY and WINGDIAPI defined properly. */
|
||||||
|
# if 0
|
||||||
|
/* This would put tons of macros and crap in our clean name space. */
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# include <windows.h>
|
||||||
|
# else
|
||||||
|
/* XXX This is from Win32's <windef.h> */
|
||||||
|
# ifndef APIENTRY
|
||||||
|
# define GLUT_APIENTRY_DEFINED
|
||||||
|
/* Cygwin and MingW32 are two free GNU-based Open Source compilation
|
||||||
|
environments for Win32. Note that __CYGWIN32__ is deprecated
|
||||||
|
in favor of simply __CYGWIN__. */
|
||||||
|
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
|
||||||
|
# if defined(__CYGWIN__)
|
||||||
|
# define APIENTRY __stdcall
|
||||||
|
# else
|
||||||
|
# ifdef i386
|
||||||
|
# define APIENTRY __attribute__((stdcall))
|
||||||
|
# else
|
||||||
|
# define APIENTRY
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
|
||||||
|
# define APIENTRY __stdcall
|
||||||
|
# else
|
||||||
|
# define APIENTRY
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
/* XXX This is from Win32's <winnt.h> */
|
||||||
|
# ifndef CALLBACK
|
||||||
|
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
|
||||||
|
# ifndef __stdcall
|
||||||
|
# define __stdcall __attribute__((stdcall))
|
||||||
|
# endif
|
||||||
|
# define CALLBACK __stdcall
|
||||||
|
# else
|
||||||
|
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
|
||||||
|
# define CALLBACK __stdcall
|
||||||
|
# else
|
||||||
|
# define CALLBACK
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
/* XXX This is from Win32's <wingdi.h> and <winnt.h> */
|
||||||
|
# ifndef WINGDIAPI
|
||||||
|
# define GLUT_WINGDIAPI_DEFINED
|
||||||
|
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
|
||||||
|
# define WINGDIAPI
|
||||||
|
# else
|
||||||
|
# define WINGDIAPI __declspec(dllimport)
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
|
||||||
|
/* Rely on Cygwin32/MingW32 <stddef.h> to set wchar_t. */
|
||||||
|
/* XXX Warning. The Cygwin32/MingW32 definition for wchar_t
|
||||||
|
is an "int" instead of the "short" used by Windows. */
|
||||||
|
# include <stddef.h>
|
||||||
|
# else
|
||||||
|
/* XXX This is from Win32's <ctype.h> */
|
||||||
|
# ifndef _WCHAR_T_DEFINED
|
||||||
|
typedef unsigned short wchar_t;
|
||||||
|
# define _WCHAR_T_DEFINED
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA
|
||||||
|
in your compile preprocessor options (Microsoft Visual C only). */
|
||||||
|
# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA) && defined(_MSC_VER)
|
||||||
|
# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */
|
||||||
|
# pragma comment (lib, "user32.lib") /* link with Windows User lib */
|
||||||
|
# pragma comment (lib, "gdi32.lib") /* link with Windows GDI lib */
|
||||||
|
/* To enable automatic SGI OpenGL for Windows library usage for GLUT,
|
||||||
|
define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */
|
||||||
|
# ifdef GLUT_USE_SGI_OPENGL
|
||||||
|
# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */
|
||||||
|
# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */
|
||||||
|
# if defined(GLUT_STATIC_LIB)
|
||||||
|
# pragma comment (lib, "glutstatic.lib") /* link with static Win32 GLUT lib */
|
||||||
|
# else
|
||||||
|
# pragma comment (lib, "glut.lib") /* link with Win32 GLUT lib */
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */
|
||||||
|
# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */
|
||||||
|
# if defined(GLUT_STATIC_LIB)
|
||||||
|
# pragma comment (lib, "glutstatic.lib") /* link with static Win32 GLUT lib */
|
||||||
|
# else
|
||||||
|
# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* To disable supression of annoying warnings about floats being promoted
|
||||||
|
to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor
|
||||||
|
options. */
|
||||||
|
# if defined(_MSC_VER) && !defined(GLUT_NO_WARNING_DISABLE)
|
||||||
|
# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */
|
||||||
|
# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Win32 has an annoying issue where there are multiple C run-time
|
||||||
|
libraries (CRTs). If the executable is linked with a different CRT
|
||||||
|
from the GLUT DLL, the GLUT DLL will not share the same CRT static
|
||||||
|
data seen by the executable. In particular, atexit callbacks registered
|
||||||
|
in the executable will not be called if GLUT calls its (different)
|
||||||
|
exit routine). GLUT is typically built with the
|
||||||
|
"/MD" option (the CRT with multithreading DLL support), but the Visual
|
||||||
|
C++ linker default is "/ML" (the single threaded CRT).
|
||||||
|
|
||||||
|
One workaround to this issue is requiring users to always link with
|
||||||
|
the same CRT as GLUT is compiled with. That requires users supply a
|
||||||
|
non-standard option. GLUT 3.7 has its own built-in workaround where
|
||||||
|
the executable's "exit" function pointer is covertly passed to GLUT.
|
||||||
|
GLUT then calls the executable's exit function pointer to ensure that
|
||||||
|
any "atexit" calls registered by the application are called if GLUT
|
||||||
|
needs to exit.
|
||||||
|
|
||||||
|
Note that the __glut*WithExit routines should NEVER be called directly.
|
||||||
|
To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
|
||||||
|
|
||||||
|
/* XXX This is from Win32's <process.h> */
|
||||||
|
# if !defined(_MSC_VER) && !defined(__cdecl)
|
||||||
|
/* Define __cdecl for non-Microsoft compilers. */
|
||||||
|
# define __cdecl
|
||||||
|
# define GLUT_DEFINED___CDECL
|
||||||
|
# endif
|
||||||
|
# ifndef _CRTIMP
|
||||||
|
# ifdef _NTSDK
|
||||||
|
/* Definition compatible with NT SDK */
|
||||||
|
# define _CRTIMP
|
||||||
|
# else
|
||||||
|
/* Current definition */
|
||||||
|
# ifdef _DLL
|
||||||
|
# define _CRTIMP __declspec(dllimport)
|
||||||
|
# else
|
||||||
|
# define _CRTIMP
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# define GLUT_DEFINED__CRTIMP
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* GLUT API entry point declarations for Win32. */
|
||||||
|
# ifdef GLUT_BUILDING_LIB
|
||||||
|
/* MSDN article 835326 says "When you build a DLL by using the 64-bit
|
||||||
|
version of the Microsoft Visual C++ Compiler and Linker, you may
|
||||||
|
receive Linker error number LNK4197 if a function has been declared
|
||||||
|
for export more than one time." GLUT builds with glut.def that
|
||||||
|
declares GLUT's EXPORTS list so do not use __declspec(dllexport)
|
||||||
|
to keep 64-bit compiler happy. */
|
||||||
|
# define GLUTAPI /*__declspec(dllexport)*/
|
||||||
|
# else
|
||||||
|
# ifdef _DLL
|
||||||
|
# define GLUTAPI __declspec(dllimport)
|
||||||
|
# else
|
||||||
|
# define GLUTAPI extern
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* GLUT callback calling convention for Win32. */
|
||||||
|
# define GLUTCALLBACK __cdecl
|
||||||
|
|
||||||
|
# if (_MSC_VER >= 800) || defined(__MINGW32__) || defined(_STDCALL_SUPPORTED) || defined(__CYGWIN32__)
|
||||||
|
# define GLUTAPIENTRY __stdcall
|
||||||
|
# else
|
||||||
|
# define GLUTAPIENTRY
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
# ifndef GLUT_BUILDING_LIB
|
||||||
|
# if __BORLANDC__
|
||||||
|
# if defined(_BUILDRTLDLL)
|
||||||
|
void __cdecl __export exit(int __status);
|
||||||
|
# else
|
||||||
|
void __cdecl exit(int __status);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if _MSC_VER >= 1200
|
||||||
|
extern _CRTIMP __declspec(noreturn) void __cdecl exit(int);
|
||||||
|
# else
|
||||||
|
extern _CRTIMP void __cdecl exit(int);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
/* non-Win32 case. */
|
||||||
|
/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */
|
||||||
|
# define APIENTRY
|
||||||
|
# define GLUT_APIENTRY_DEFINED
|
||||||
|
# define CALLBACK
|
||||||
|
/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */
|
||||||
|
# define GLUTAPI extern
|
||||||
|
# define GLUTAPIENTRY
|
||||||
|
# define GLUTCALLBACK
|
||||||
|
/* Prototype exit for the non-Win32 case (see above). */
|
||||||
|
# ifdef __GNUC__
|
||||||
|
extern void exit(int __status) __attribute__((__noreturn__));
|
||||||
|
# else
|
||||||
|
extern void exit(int);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
GLUT API revision history:
|
||||||
|
|
||||||
|
GLUT_API_VERSION is updated to reflect incompatible GLUT
|
||||||
|
API changes (interface changes, semantic changes, deletions,
|
||||||
|
or additions).
|
||||||
|
|
||||||
|
GLUT_API_VERSION=1 First public release of GLUT. 11/29/94
|
||||||
|
|
||||||
|
GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling,
|
||||||
|
extension. Supports new input devices like tablet, dial and button
|
||||||
|
box, and Spaceball. Easy to query OpenGL extensions.
|
||||||
|
|
||||||
|
GLUT_API_VERSION=3 glutMenuStatus added.
|
||||||
|
|
||||||
|
GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer,
|
||||||
|
glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic
|
||||||
|
video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc,
|
||||||
|
glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
|
||||||
|
glutJoystickFunc, glutForceJoystickFunc, glutStrokeWidthf,
|
||||||
|
glutStrokeLengthf (NOT FINALIZED!).
|
||||||
|
**/
|
||||||
|
#ifndef GLUT_API_VERSION /* allow this to be overriden */
|
||||||
|
#define GLUT_API_VERSION 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
GLUT implementation revision history:
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT
|
||||||
|
API revisions and implementation revisions (ie, bug fixes).
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of
|
||||||
|
GLUT Xlib-based implementation. 11/29/94
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of
|
||||||
|
GLUT Xlib-based implementation providing GLUT version 2
|
||||||
|
interfaces.
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner
|
||||||
|
and video resize. 1/3/97
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines.
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release.
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling.
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support.
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface.
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=16 mjk's early GLUT 3.8
|
||||||
|
|
||||||
|
GLUT_XLIB_IMPLEMENTATION=17 mjk's GLUT 3.8 with glutStrokeWidthf and glutStrokeLengthf
|
||||||
|
**/
|
||||||
|
#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */
|
||||||
|
#define GLUT_XLIB_IMPLEMENTATION 17
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Display mode bit masks. */
|
||||||
|
#define GLUT_RGB 0
|
||||||
|
#define GLUT_RGBA GLUT_RGB
|
||||||
|
#define GLUT_INDEX 1
|
||||||
|
#define GLUT_SINGLE 0
|
||||||
|
#define GLUT_DOUBLE 2
|
||||||
|
#define GLUT_ACCUM 4
|
||||||
|
#define GLUT_ALPHA 8
|
||||||
|
#define GLUT_DEPTH 16
|
||||||
|
#define GLUT_STENCIL 32
|
||||||
|
#if (GLUT_API_VERSION >= 2)
|
||||||
|
#define GLUT_MULTISAMPLE 128
|
||||||
|
#define GLUT_STEREO 256
|
||||||
|
#endif
|
||||||
|
#if (GLUT_API_VERSION >= 3)
|
||||||
|
#define GLUT_LUMINANCE 512
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Mouse buttons. */
|
||||||
|
#define GLUT_LEFT_BUTTON 0
|
||||||
|
#define GLUT_MIDDLE_BUTTON 1
|
||||||
|
#define GLUT_RIGHT_BUTTON 2
|
||||||
|
|
||||||
|
/* Mouse button state. */
|
||||||
|
#define GLUT_DOWN 0
|
||||||
|
#define GLUT_UP 1
|
||||||
|
|
||||||
|
#if (GLUT_API_VERSION >= 2)
|
||||||
|
/* function keys */
|
||||||
|
#define GLUT_KEY_F1 1
|
||||||
|
#define GLUT_KEY_F2 2
|
||||||
|
#define GLUT_KEY_F3 3
|
||||||
|
#define GLUT_KEY_F4 4
|
||||||
|
#define GLUT_KEY_F5 5
|
||||||
|
#define GLUT_KEY_F6 6
|
||||||
|
#define GLUT_KEY_F7 7
|
||||||
|
#define GLUT_KEY_F8 8
|
||||||
|
#define GLUT_KEY_F9 9
|
||||||
|
#define GLUT_KEY_F10 10
|
||||||
|
#define GLUT_KEY_F11 11
|
||||||
|
#define GLUT_KEY_F12 12
|
||||||
|
/* directional keys */
|
||||||
|
#define GLUT_KEY_LEFT 100
|
||||||
|
#define GLUT_KEY_UP 101
|
||||||
|
#define GLUT_KEY_RIGHT 102
|
||||||
|
#define GLUT_KEY_DOWN 103
|
||||||
|
#define GLUT_KEY_PAGE_UP 104
|
||||||
|
#define GLUT_KEY_PAGE_DOWN 105
|
||||||
|
#define GLUT_KEY_HOME 106
|
||||||
|
#define GLUT_KEY_END 107
|
||||||
|
#define GLUT_KEY_INSERT 108
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Entry/exit state. */
|
||||||
|
#define GLUT_LEFT 0
|
||||||
|
#define GLUT_ENTERED 1
|
||||||
|
|
||||||
|
/* Menu usage state. */
|
||||||
|
#define GLUT_MENU_NOT_IN_USE 0
|
||||||
|
#define GLUT_MENU_IN_USE 1
|
||||||
|
|
||||||
|
/* Visibility state. */
|
||||||
|
#define GLUT_NOT_VISIBLE 0
|
||||||
|
#define GLUT_VISIBLE 1
|
||||||
|
|
||||||
|
/* Window status state. */
|
||||||
|
#define GLUT_HIDDEN 0
|
||||||
|
#define GLUT_FULLY_RETAINED 1
|
||||||
|
#define GLUT_PARTIALLY_RETAINED 2
|
||||||
|
#define GLUT_FULLY_COVERED 3
|
||||||
|
|
||||||
|
/* Color index component selection values. */
|
||||||
|
#define GLUT_RED 0
|
||||||
|
#define GLUT_GREEN 1
|
||||||
|
#define GLUT_BLUE 2
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* Stroke font constants (use these in GLUT program). */
|
||||||
|
#define GLUT_STROKE_ROMAN ((void*)0)
|
||||||
|
#define GLUT_STROKE_MONO_ROMAN ((void*)1)
|
||||||
|
|
||||||
|
/* Bitmap font constants (use these in GLUT program). */
|
||||||
|
#define GLUT_BITMAP_9_BY_15 ((void*)2)
|
||||||
|
#define GLUT_BITMAP_8_BY_13 ((void*)3)
|
||||||
|
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
|
||||||
|
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)
|
||||||
|
#if (GLUT_API_VERSION >= 3)
|
||||||
|
#define GLUT_BITMAP_HELVETICA_10 ((void*)6)
|
||||||
|
#define GLUT_BITMAP_HELVETICA_12 ((void*)7)
|
||||||
|
#define GLUT_BITMAP_HELVETICA_18 ((void*)8)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* Stroke font opaque addresses (use constants instead in source code). */
|
||||||
|
GLUTAPI void *glutStrokeRoman;
|
||||||
|
GLUTAPI void *glutStrokeMonoRoman;
|
||||||
|
|
||||||
|
/* Stroke font constants (use these in GLUT program). */
|
||||||
|
#define GLUT_STROKE_ROMAN (&glutStrokeRoman)
|
||||||
|
#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman)
|
||||||
|
|
||||||
|
/* Bitmap font opaque addresses (use constants instead in source code). */
|
||||||
|
GLUTAPI void *glutBitmap9By15;
|
||||||
|
GLUTAPI void *glutBitmap8By13;
|
||||||
|
GLUTAPI void *glutBitmapTimesRoman10;
|
||||||
|
GLUTAPI void *glutBitmapTimesRoman24;
|
||||||
|
GLUTAPI void *glutBitmapHelvetica10;
|
||||||
|
GLUTAPI void *glutBitmapHelvetica12;
|
||||||
|
GLUTAPI void *glutBitmapHelvetica18;
|
||||||
|
|
||||||
|
/* Bitmap font constants (use these in GLUT program). */
|
||||||
|
#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15)
|
||||||
|
#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13)
|
||||||
|
#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10)
|
||||||
|
#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24)
|
||||||
|
#if (GLUT_API_VERSION >= 3)
|
||||||
|
#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10)
|
||||||
|
#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12)
|
||||||
|
#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* glutGet parameters. */
|
||||||
|
#define GLUT_WINDOW_X ((GLenum) 100)
|
||||||
|
#define GLUT_WINDOW_Y ((GLenum) 101)
|
||||||
|
#define GLUT_WINDOW_WIDTH ((GLenum) 102)
|
||||||
|
#define GLUT_WINDOW_HEIGHT ((GLenum) 103)
|
||||||
|
#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104)
|
||||||
|
#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105)
|
||||||
|
#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106)
|
||||||
|
#define GLUT_WINDOW_RED_SIZE ((GLenum) 107)
|
||||||
|
#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108)
|
||||||
|
#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109)
|
||||||
|
#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110)
|
||||||
|
#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111)
|
||||||
|
#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112)
|
||||||
|
#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113)
|
||||||
|
#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114)
|
||||||
|
#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115)
|
||||||
|
#define GLUT_WINDOW_RGBA ((GLenum) 116)
|
||||||
|
#define GLUT_WINDOW_PARENT ((GLenum) 117)
|
||||||
|
#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118)
|
||||||
|
#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119)
|
||||||
|
#if (GLUT_API_VERSION >= 2)
|
||||||
|
#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120)
|
||||||
|
#define GLUT_WINDOW_STEREO ((GLenum) 121)
|
||||||
|
#endif
|
||||||
|
#if (GLUT_API_VERSION >= 3)
|
||||||
|
#define GLUT_WINDOW_CURSOR ((GLenum) 122)
|
||||||
|
#endif
|
||||||
|
#define GLUT_SCREEN_WIDTH ((GLenum) 200)
|
||||||
|
#define GLUT_SCREEN_HEIGHT ((GLenum) 201)
|
||||||
|
#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202)
|
||||||
|
#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203)
|
||||||
|
#define GLUT_MENU_NUM_ITEMS ((GLenum) 300)
|
||||||
|
#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400)
|
||||||
|
#define GLUT_INIT_WINDOW_X ((GLenum) 500)
|
||||||
|
#define GLUT_INIT_WINDOW_Y ((GLenum) 501)
|
||||||
|
#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502)
|
||||||
|
#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503)
|
||||||
|
#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504)
|
||||||
|
#if (GLUT_API_VERSION >= 2)
|
||||||
|
#define GLUT_ELAPSED_TIME ((GLenum) 700)
|
||||||
|
#endif
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
|
||||||
|
#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (GLUT_API_VERSION >= 2)
|
||||||
|
/* glutDeviceGet parameters. */
|
||||||
|
#define GLUT_HAS_KEYBOARD ((GLenum) 600)
|
||||||
|
#define GLUT_HAS_MOUSE ((GLenum) 601)
|
||||||
|
#define GLUT_HAS_SPACEBALL ((GLenum) 602)
|
||||||
|
#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603)
|
||||||
|
#define GLUT_HAS_TABLET ((GLenum) 604)
|
||||||
|
#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605)
|
||||||
|
#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606)
|
||||||
|
#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607)
|
||||||
|
#define GLUT_NUM_DIALS ((GLenum) 608)
|
||||||
|
#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609)
|
||||||
|
#endif
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
|
||||||
|
#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610)
|
||||||
|
#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611)
|
||||||
|
#define GLUT_HAS_JOYSTICK ((GLenum) 612)
|
||||||
|
#define GLUT_OWNS_JOYSTICK ((GLenum) 613)
|
||||||
|
#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614)
|
||||||
|
#define GLUT_JOYSTICK_AXES ((GLenum) 615)
|
||||||
|
#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (GLUT_API_VERSION >= 3)
|
||||||
|
/* glutLayerGet parameters. */
|
||||||
|
#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800)
|
||||||
|
#define GLUT_LAYER_IN_USE ((GLenum) 801)
|
||||||
|
#define GLUT_HAS_OVERLAY ((GLenum) 802)
|
||||||
|
#define GLUT_TRANSPARENT_INDEX ((GLenum) 803)
|
||||||
|
#define GLUT_NORMAL_DAMAGED ((GLenum) 804)
|
||||||
|
#define GLUT_OVERLAY_DAMAGED ((GLenum) 805)
|
||||||
|
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||||
|
/* glutVideoResizeGet parameters. */
|
||||||
|
#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900)
|
||||||
|
#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901)
|
||||||
|
#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902)
|
||||||
|
#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903)
|
||||||
|
#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904)
|
||||||
|
#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905)
|
||||||
|
#define GLUT_VIDEO_RESIZE_X ((GLenum) 906)
|
||||||
|
#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907)
|
||||||
|
#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908)
|
||||||
|
#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* glutUseLayer parameters. */
|
||||||
|
#define GLUT_NORMAL ((GLenum) 0)
|
||||||
|
#define GLUT_OVERLAY ((GLenum) 1)
|
||||||
|
|
||||||
|
/* glutGetModifiers return mask. */
|
||||||
|
#define GLUT_ACTIVE_SHIFT 1
|
||||||
|
#define GLUT_ACTIVE_CTRL 2
|
||||||
|
#define GLUT_ACTIVE_ALT 4
|
||||||
|
|
||||||
|
/* glutSetCursor parameters. */
|
||||||
|
/* Basic arrows. */
|
||||||
|
#define GLUT_CURSOR_RIGHT_ARROW 0
|
||||||
|
#define GLUT_CURSOR_LEFT_ARROW 1
|
||||||
|
/* Symbolic cursor shapes. */
|
||||||
|
#define GLUT_CURSOR_INFO 2
|
||||||
|
#define GLUT_CURSOR_DESTROY 3
|
||||||
|
#define GLUT_CURSOR_HELP 4
|
||||||
|
#define GLUT_CURSOR_CYCLE 5
|
||||||
|
#define GLUT_CURSOR_SPRAY 6
|
||||||
|
#define GLUT_CURSOR_WAIT 7
|
||||||
|
#define GLUT_CURSOR_TEXT 8
|
||||||
|
#define GLUT_CURSOR_CROSSHAIR 9
|
||||||
|
/* Directional cursors. */
|
||||||
|
#define GLUT_CURSOR_UP_DOWN 10
|
||||||
|
#define GLUT_CURSOR_LEFT_RIGHT 11
|
||||||
|
/* Sizing cursors. */
|
||||||
|
#define GLUT_CURSOR_TOP_SIDE 12
|
||||||
|
#define GLUT_CURSOR_BOTTOM_SIDE 13
|
||||||
|
#define GLUT_CURSOR_LEFT_SIDE 14
|
||||||
|
#define GLUT_CURSOR_RIGHT_SIDE 15
|
||||||
|
#define GLUT_CURSOR_TOP_LEFT_CORNER 16
|
||||||
|
#define GLUT_CURSOR_TOP_RIGHT_CORNER 17
|
||||||
|
#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18
|
||||||
|
#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19
|
||||||
|
/* Inherit from parent window. */
|
||||||
|
#define GLUT_CURSOR_INHERIT 100
|
||||||
|
/* Blank cursor. */
|
||||||
|
#define GLUT_CURSOR_NONE 101
|
||||||
|
/* Fullscreen crosshair (if available). */
|
||||||
|
#define GLUT_CURSOR_FULL_CROSSHAIR 102
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GLUT initialization sub-API. */
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutInit(int *argcp, char **argv);
|
||||||
|
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
|
||||||
|
GLUTAPI void GLUTAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
|
||||||
|
#ifndef GLUT_BUILDING_LIB
|
||||||
|
static void GLUTAPIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
|
||||||
|
#define glutInit glutInit_ATEXIT_HACK
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutInitDisplayMode(unsigned int mode);
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutInitDisplayString(const char *string);
|
||||||
|
#endif
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutInitWindowPosition(int x, int y);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutInitWindowSize(int width, int height);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutMainLoop(void);
|
||||||
|
|
||||||
|
/* GLUT window sub-API. */
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutCreateWindow(const char *title);
|
||||||
|
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
|
||||||
|
GLUTAPI int GLUTAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
|
||||||
|
#ifndef GLUT_BUILDING_LIB
|
||||||
|
static int GLUTAPIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
|
||||||
|
#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutDestroyWindow(int win);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutPostRedisplay(void);
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutPostWindowRedisplay(int win);
|
||||||
|
#endif
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSwapBuffers(void);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutGetWindow(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSetWindow(int win);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSetWindowTitle(const char *title);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSetIconTitle(const char *title);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutPositionWindow(int x, int y);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutReshapeWindow(int width, int height);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutPopWindow(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutPushWindow(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutIconifyWindow(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutShowWindow(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutHideWindow(void);
|
||||||
|
#if (GLUT_API_VERSION >= 3)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutFullScreen(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSetCursor(int cursor);
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWarpPointer(int x, int y);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GLUT overlay sub-API. */
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutEstablishOverlay(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutRemoveOverlay(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutUseLayer(GLenum layer);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutPostOverlayRedisplay(void);
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutPostWindowOverlayRedisplay(int win);
|
||||||
|
#endif
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutShowOverlay(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutHideOverlay(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GLUT menu sub-API. */
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int));
|
||||||
|
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
|
||||||
|
GLUTAPI int GLUTAPIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int));
|
||||||
|
#ifndef GLUT_BUILDING_LIB
|
||||||
|
static int GLUTAPIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); }
|
||||||
|
#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutDestroyMenu(int menu);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutGetMenu(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSetMenu(int menu);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutAddMenuEntry(const char *label, int value);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutAddSubMenu(const char *label, int submenu);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutChangeToMenuEntry(int item, const char *label, int value);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutChangeToSubMenu(int item, const char *label, int submenu);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutRemoveMenuItem(int item);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutAttachMenu(int button);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutDetachMenu(int button);
|
||||||
|
|
||||||
|
/* GLUT window callback sub-API. */
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state));
|
||||||
|
#if (GLUT_API_VERSION >= 2)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
|
||||||
|
#if (GLUT_API_VERSION >= 3)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void));
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state));
|
||||||
|
#endif
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GLUT color index sub-API. */
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
|
||||||
|
GLUTAPI GLfloat GLUTAPIENTRY glutGetColor(int ndx, int component);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutCopyColormap(int win);
|
||||||
|
|
||||||
|
/* GLUT state retrieval sub-API. */
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutGet(GLenum type);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutDeviceGet(GLenum type);
|
||||||
|
#if (GLUT_API_VERSION >= 2)
|
||||||
|
/* GLUT extension support sub-API */
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutExtensionSupported(const char *name);
|
||||||
|
#endif
|
||||||
|
#if (GLUT_API_VERSION >= 3)
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutGetModifiers(void);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutLayerGet(GLenum type);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GLUT font sub-API */
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutBitmapCharacter(void *font, int character);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutBitmapWidth(void *font, int character);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutStrokeCharacter(void *font, int character);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutStrokeWidth(void *font, int character);
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutBitmapLength(void *font, const unsigned char *string);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutStrokeLength(void *font, const unsigned char *string);
|
||||||
|
#endif
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 17)
|
||||||
|
GLUTAPI float GLUTAPIENTRY glutStrokeWidthf(void *font, int character);
|
||||||
|
GLUTAPI float GLUTAPIENTRY glutStrokeLengthf(void *font, const unsigned char *string);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GLUT pre-built models sub-API */
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireCube(GLdouble size);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidCube(GLdouble size);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireDodecahedron(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidDodecahedron(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireTeapot(GLdouble size);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidTeapot(GLdouble size);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireOctahedron(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidOctahedron(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireTetrahedron(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidTetrahedron(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutWireIcosahedron(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSolidIcosahedron(void);
|
||||||
|
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||||
|
/* GLUT video resize sub-API. */
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutVideoResizeGet(GLenum param);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSetupVideoResizing(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutStopVideoResizing(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutVideoResize(int x, int y, int width, int height);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutVideoPan(int x, int y, int width, int height);
|
||||||
|
|
||||||
|
/* GLUT debugging sub-API. */
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutReportErrors(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
|
||||||
|
/* GLUT device control sub-API. */
|
||||||
|
/* glutSetKeyRepeat modes. */
|
||||||
|
#define GLUT_KEY_REPEAT_OFF 0
|
||||||
|
#define GLUT_KEY_REPEAT_ON 1
|
||||||
|
#define GLUT_KEY_REPEAT_DEFAULT 2
|
||||||
|
|
||||||
|
/* Joystick button masks. */
|
||||||
|
#define GLUT_JOYSTICK_BUTTON_A 1
|
||||||
|
#define GLUT_JOYSTICK_BUTTON_B 2
|
||||||
|
#define GLUT_JOYSTICK_BUTTON_C 4
|
||||||
|
#define GLUT_JOYSTICK_BUTTON_D 8
|
||||||
|
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutIgnoreKeyRepeat(int ignore);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutSetKeyRepeat(int repeatMode);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutForceJoystickFunc(void);
|
||||||
|
|
||||||
|
/* GLUT game mode sub-API. */
|
||||||
|
/* glutGameModeGet. */
|
||||||
|
#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0)
|
||||||
|
#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1)
|
||||||
|
#define GLUT_GAME_MODE_WIDTH ((GLenum) 2)
|
||||||
|
#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3)
|
||||||
|
#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4)
|
||||||
|
#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5)
|
||||||
|
#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6)
|
||||||
|
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutGameModeString(const char *string);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutEnterGameMode(void);
|
||||||
|
GLUTAPI void GLUTAPIENTRY glutLeaveGameMode(void);
|
||||||
|
GLUTAPI int GLUTAPIENTRY glutGameModeGet(GLenum mode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GLUT_APIENTRY_DEFINED
|
||||||
|
# undef GLUT_APIENTRY_DEFINED
|
||||||
|
# undef APIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GLUT_WINGDIAPI_DEFINED
|
||||||
|
# undef GLUT_WINGDIAPI_DEFINED
|
||||||
|
# undef WINGDIAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GLUT_DEFINED___CDECL
|
||||||
|
# undef GLUT_DEFINED___CDECL
|
||||||
|
# undef __cdecl
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GLUT_DEFINED__CRTIMP
|
||||||
|
# undef GLUT_DEFINED__CRTIMP
|
||||||
|
# undef _CRTIMP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __glut_h__ */
|
||||||
1948
Extras/sph/common/image.cpp
Normal file
1948
Extras/sph/common/image.cpp
Normal file
File diff suppressed because it is too large
Load Diff
188
Extras/sph/common/image.h
Normal file
188
Extras/sph/common/image.h
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Image;
|
||||||
|
|
||||||
|
#ifndef IMAGE_H
|
||||||
|
#define IMAGE_H
|
||||||
|
|
||||||
|
#include "common_defs.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Image class code below...
|
||||||
|
#define IRED 0
|
||||||
|
#define IGREEN 1
|
||||||
|
#define IBLUE 2
|
||||||
|
#define IALPHA 3
|
||||||
|
|
||||||
|
class Pixel {
|
||||||
|
public:
|
||||||
|
Pixel () { r=0;g=0;b=0;a=1;}
|
||||||
|
Pixel ( double r_, double g_, double b_ ) {r = r_; g = g_; b = b_; a = 1.0; }
|
||||||
|
Pixel ( double r_, double g_, double b_, double a_ ) {r = r_; g = g_; b = b_; a = a_; }
|
||||||
|
double r;
|
||||||
|
double g;
|
||||||
|
double b;
|
||||||
|
double a;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(USE_JPEG)
|
||||||
|
#pragma comment(lib, "jpegd.lib" )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* generic multi channel 8-bit max image class. can read and write
|
||||||
|
* BMP, ascii PNM, and JPG file formats, and supports some useful OpenGL
|
||||||
|
* calls.
|
||||||
|
*
|
||||||
|
* get and set pixel methods use doubles from 0.0 to 1.0. these
|
||||||
|
* values are mapped to integer values from 0 to the maximum value
|
||||||
|
* allowed by the number of bits per channel in the image.
|
||||||
|
*/
|
||||||
|
class Image {
|
||||||
|
public:
|
||||||
|
Image ();
|
||||||
|
~Image ();
|
||||||
|
|
||||||
|
// create empty image with specified characteristics
|
||||||
|
Image (int width_, int height_);
|
||||||
|
Image (int width_, int height_, int channels_);
|
||||||
|
Image (int width_, int height_, int channels_,
|
||||||
|
int bits_);
|
||||||
|
|
||||||
|
// create image and read data from filename
|
||||||
|
// use good() or bad() to check success
|
||||||
|
Image (const char* filename);
|
||||||
|
|
||||||
|
// copy constructor and assignment operator
|
||||||
|
// _deep_ copy!
|
||||||
|
Image (const Image& image);
|
||||||
|
Image& operator= (const Image& image);
|
||||||
|
|
||||||
|
// accessors
|
||||||
|
int getWidth () { return width; }
|
||||||
|
int getHeight () { return height; }
|
||||||
|
int getChannels () { return channels; }
|
||||||
|
int getBits () { return bits; }
|
||||||
|
unsigned char* getPixels () { return pixels; }
|
||||||
|
|
||||||
|
void create ( int width_, int height_, int channels_ );
|
||||||
|
|
||||||
|
void refresh ();
|
||||||
|
|
||||||
|
void draw ();
|
||||||
|
void draw ( float x, float y );
|
||||||
|
|
||||||
|
|
||||||
|
// unsafe! use at your own risk!
|
||||||
|
void setPixels ( unsigned char *newPixels );
|
||||||
|
|
||||||
|
// check if the image is valid
|
||||||
|
bool good ();
|
||||||
|
bool bad ();
|
||||||
|
|
||||||
|
// set all the pixel data
|
||||||
|
void clear ();
|
||||||
|
void clear ( Pixel pixel );
|
||||||
|
|
||||||
|
// retrieve pixel data. methods with _ at the
|
||||||
|
// end of their name return 0.0 if the x and y
|
||||||
|
// are out of range. otherwise, an assertion
|
||||||
|
// failure occurs
|
||||||
|
double getPixel (int x, int y, int channel);
|
||||||
|
double getPixel_ (int x, int y, int channel);
|
||||||
|
Pixel getPixel (int x, int y);
|
||||||
|
Pixel getPixel_ (int x, int y);
|
||||||
|
Pixel& getPixel (int x, int y, Pixel& pixel);
|
||||||
|
Pixel& getPixel_ (int x, int y, Pixel& pixel);
|
||||||
|
|
||||||
|
// set pixel data. if x and y are out of range,
|
||||||
|
// an assertion failure occurs
|
||||||
|
void setPixel (int x, int y, int channel, double value);
|
||||||
|
void setPixel_ (int x, int y, int channel, double value);
|
||||||
|
void setPixel (int x, int y, Pixel pixel);
|
||||||
|
void setPixel_ (int x, int y, Pixel pixel);
|
||||||
|
void setPixel4 ( int x, int y, Pixel pixel );
|
||||||
|
|
||||||
|
void setAlpha (int x, int y, double value);
|
||||||
|
|
||||||
|
#ifndef DISABLE_OPENGL
|
||||||
|
// OpenGL call wrappers
|
||||||
|
void glReadPixelsWrapper ();
|
||||||
|
void glDrawPixelsWrapper ();
|
||||||
|
void glTexImage2DWrapper ();
|
||||||
|
void glTexImageCubeWrapper ( int i );
|
||||||
|
void glTexSubImage2DWrapper ( int x, int y);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// top-level file read and write calls,
|
||||||
|
// determines file type
|
||||||
|
int read (const char* filename);
|
||||||
|
int read (const char* filename, const char* alphaname );
|
||||||
|
int write (const char* filename);
|
||||||
|
|
||||||
|
int readPaletteBMP ( FILE* fp, RGBQUAD*& palette, int bit_count );
|
||||||
|
|
||||||
|
// BMP specific read and write calls
|
||||||
|
int readBMP (const char* filename);
|
||||||
|
int readBMP (FILE* file, FILE* file_a, bool bBaseImg );
|
||||||
|
int writeBMP (const char* filename);
|
||||||
|
int writeBMP (FILE* file);
|
||||||
|
|
||||||
|
// PNM specific read and write calls
|
||||||
|
int readPNM (const char* filename);
|
||||||
|
int readPNM (FILE* file);
|
||||||
|
int writePNM (const char* filename);
|
||||||
|
int writePNM (FILE* file);
|
||||||
|
|
||||||
|
#ifdef USE_JPEG
|
||||||
|
// JPG specific read and write calls
|
||||||
|
int readJPG (const char* filename);
|
||||||
|
int readJPG (FILE* file);
|
||||||
|
int writeJPG (const char* filename);
|
||||||
|
int writeJPG (FILE* file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int index(int x, int y, int c);
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int channels; // number of channels per pixel
|
||||||
|
int bits; // number of bits per channel
|
||||||
|
int maxValue; // max that can be stored in bits
|
||||||
|
|
||||||
|
unsigned char* pixels; // image data
|
||||||
|
|
||||||
|
bool owns; // if image owns pixels
|
||||||
|
|
||||||
|
unsigned int imgID;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // IMAGE_H
|
||||||
1879
Extras/sph/common/matrix-inline.h
Normal file
1879
Extras/sph/common/matrix-inline.h
Normal file
File diff suppressed because it is too large
Load Diff
2046
Extras/sph/common/matrix.cci
Normal file
2046
Extras/sph/common/matrix.cci
Normal file
File diff suppressed because it is too large
Load Diff
23
Extras/sph/common/matrix.cpp
Normal file
23
Extras/sph/common/matrix.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#include "matrix.h"
|
||||||
|
|
||||||
429
Extras/sph/common/matrix.h
Normal file
429
Extras/sph/common/matrix.h
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
//*********** NOTE
|
||||||
|
//
|
||||||
|
// LOOK AT MovieTrackPoint. IN ORDER FOR VECTORS AND MATRICIES TO BE USED IN OBJECTS
|
||||||
|
// THAT WILL BE USED IN stl::vectors, THEIR CONSTRUCTORS AND OPERATORS MUST TAKE ONLY
|
||||||
|
// const PARAMETERS. LOOK AT MatrixF and Vector2DF.. THIS WAS NOT YET DONE WITH
|
||||||
|
// THE OTHER MATRIX AND VECTOR CLASSES (Vector2DC, Vector2DI, MatrixC, MatrixI, ...)
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MATRIX_DEF
|
||||||
|
#define MATRIX_DEF
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
#include "mdebug.h"
|
||||||
|
|
||||||
|
//#define MATRIX_INITIALIZE // Initializes vectors
|
||||||
|
|
||||||
|
class MatrixC; // Forward Referencing
|
||||||
|
class MatrixI;
|
||||||
|
class MatrixF;
|
||||||
|
|
||||||
|
class Matrix {
|
||||||
|
public:
|
||||||
|
// Member Virtual Functions
|
||||||
|
virtual Matrix &operator= (unsigned char c)=0;
|
||||||
|
virtual Matrix &operator= (int c)=0;
|
||||||
|
virtual Matrix &operator= (double c)=0;
|
||||||
|
virtual Matrix &operator= (MatrixC &op)=0;
|
||||||
|
virtual Matrix &operator= (MatrixI &op)=0;
|
||||||
|
virtual Matrix &operator= (MatrixF &op)=0;
|
||||||
|
|
||||||
|
virtual Matrix &operator+= (unsigned char c)=0;
|
||||||
|
virtual Matrix &operator+= (int c)=0;
|
||||||
|
virtual Matrix &operator+= (double c)=0;
|
||||||
|
virtual Matrix &operator+= (MatrixC &op)=0;
|
||||||
|
virtual Matrix &operator+= (MatrixI &op)=0;
|
||||||
|
virtual Matrix &operator+= (MatrixF &op)=0;
|
||||||
|
|
||||||
|
virtual Matrix &operator-= (unsigned char c)=0;
|
||||||
|
virtual Matrix &operator-= (int c)=0;
|
||||||
|
virtual Matrix &operator-= (double c)=0;
|
||||||
|
virtual Matrix &operator-= (MatrixC &op)=0;
|
||||||
|
virtual Matrix &operator-= (MatrixI &op)=0;
|
||||||
|
virtual Matrix &operator-= (MatrixF &op)=0;
|
||||||
|
|
||||||
|
virtual Matrix &operator*= (unsigned char c)=0;
|
||||||
|
virtual Matrix &operator*= (int c)=0;
|
||||||
|
virtual Matrix &operator*= (double c)=0;
|
||||||
|
virtual Matrix &operator*= (MatrixC &op)=0;
|
||||||
|
virtual Matrix &operator*= (MatrixI &op)=0;
|
||||||
|
virtual Matrix &operator*= (MatrixF &op)=0;
|
||||||
|
|
||||||
|
virtual Matrix &operator/= (unsigned char c)=0;
|
||||||
|
virtual Matrix &operator/= (int c)=0;
|
||||||
|
virtual Matrix &operator/= (double c)=0;
|
||||||
|
virtual Matrix &operator/= (MatrixC &op)=0;
|
||||||
|
virtual Matrix &operator/= (MatrixI &op)=0;
|
||||||
|
virtual Matrix &operator/= (MatrixF &op)=0;
|
||||||
|
|
||||||
|
virtual Matrix &Multiply (MatrixF &op)=0;
|
||||||
|
virtual Matrix &Resize (int x, int y)=0;
|
||||||
|
virtual Matrix &ResizeSafe (int x, int y)=0;
|
||||||
|
virtual Matrix &InsertRow (int r)=0;
|
||||||
|
virtual Matrix &InsertCol (int c)=0;
|
||||||
|
virtual Matrix &Transpose (void)=0;
|
||||||
|
virtual Matrix &Identity (int order)=0;
|
||||||
|
/*inline Matrix &RotateX (double ang);
|
||||||
|
inline Matrix &RotateY (double ang);
|
||||||
|
inline Matrix &RotateZ (double ang); */
|
||||||
|
virtual Matrix &Basis (Vector3DF &c1, Vector3DF &c2, Vector3DF &c3)=0;
|
||||||
|
virtual Matrix &GaussJordan (MatrixF &b) { return *this; }
|
||||||
|
virtual Matrix &ConjugateGradient (MatrixF &b) { return *this; }
|
||||||
|
|
||||||
|
virtual int GetRows(void)=0;
|
||||||
|
virtual int GetCols(void)=0;
|
||||||
|
virtual int GetLength(void)=0;
|
||||||
|
|
||||||
|
virtual unsigned char *GetDataC (void)=0;
|
||||||
|
virtual int *GetDataI (void)=0;
|
||||||
|
virtual double *GetDataF (void)=0;
|
||||||
|
|
||||||
|
virtual double GetF (int r, int c);
|
||||||
|
};
|
||||||
|
|
||||||
|
// MatrixC Declaration
|
||||||
|
#define VNAME C
|
||||||
|
#define VTYPE unsigned char
|
||||||
|
|
||||||
|
class MatrixC {
|
||||||
|
public:
|
||||||
|
VTYPE *data;
|
||||||
|
int rows, cols, len;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline MatrixC ();
|
||||||
|
inline ~MatrixC ();
|
||||||
|
inline MatrixC (int r, int c);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline VTYPE &operator () (int c, int r);
|
||||||
|
inline MatrixC &operator= (unsigned char c);
|
||||||
|
inline MatrixC &operator= (int c);
|
||||||
|
inline MatrixC &operator= (double c);
|
||||||
|
inline MatrixC &operator= (MatrixC &op);
|
||||||
|
inline MatrixC &operator= (MatrixI &op);
|
||||||
|
inline MatrixC &operator= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixC &operator+= (unsigned char c);
|
||||||
|
inline MatrixC &operator+= (int c);
|
||||||
|
inline MatrixC &operator+= (double c);
|
||||||
|
inline MatrixC &operator+= (MatrixC &op);
|
||||||
|
inline MatrixC &operator+= (MatrixI &op);
|
||||||
|
inline MatrixC &operator+= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixC &operator-= (unsigned char c);
|
||||||
|
inline MatrixC &operator-= (int c);
|
||||||
|
inline MatrixC &operator-= (double c);
|
||||||
|
inline MatrixC &operator-= (MatrixC &op);
|
||||||
|
inline MatrixC &operator-= (MatrixI &op);
|
||||||
|
inline MatrixC &operator-= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixC &operator*= (unsigned char c);
|
||||||
|
inline MatrixC &operator*= (int c);
|
||||||
|
inline MatrixC &operator*= (double c);
|
||||||
|
inline MatrixC &operator*= (MatrixC &op);
|
||||||
|
inline MatrixC &operator*= (MatrixI &op);
|
||||||
|
inline MatrixC &operator*= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixC &operator/= (unsigned char c);
|
||||||
|
inline MatrixC &operator/= (int c);
|
||||||
|
inline MatrixC &operator/= (double c);
|
||||||
|
inline MatrixC &operator/= (MatrixC &op);
|
||||||
|
inline MatrixC &operator/= (MatrixI &op);
|
||||||
|
inline MatrixC &operator/= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixC &Multiply (MatrixF &op);
|
||||||
|
inline MatrixC &Resize (int x, int y);
|
||||||
|
inline MatrixC &ResizeSafe (int x, int y);
|
||||||
|
inline MatrixC &InsertRow (int r);
|
||||||
|
inline MatrixC &InsertCol (int c);
|
||||||
|
inline MatrixC &Transpose (void);
|
||||||
|
inline MatrixC &Identity (int order);
|
||||||
|
inline MatrixC &Basis (Vector3DF &c1, Vector3DF &c2, Vector3DF &c3);
|
||||||
|
inline MatrixC &GaussJordan (MatrixF &b);
|
||||||
|
|
||||||
|
inline int GetX();
|
||||||
|
inline int GetY();
|
||||||
|
inline int GetRows(void);
|
||||||
|
inline int GetCols(void);
|
||||||
|
inline int GetLength(void);
|
||||||
|
inline VTYPE *GetData(void);
|
||||||
|
|
||||||
|
inline unsigned char *GetDataC (void) {return data;}
|
||||||
|
inline int *GetDataI (void) {return NULL;}
|
||||||
|
inline double *GetDataF (void) {return NULL;}
|
||||||
|
|
||||||
|
inline double GetF (int r, int c);
|
||||||
|
};
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// MatrixI Declaration
|
||||||
|
#define VNAME I
|
||||||
|
#define VTYPE int
|
||||||
|
|
||||||
|
class MatrixI {
|
||||||
|
public:
|
||||||
|
VTYPE *data;
|
||||||
|
int rows, cols, len;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline MatrixI ();
|
||||||
|
inline ~MatrixI ();
|
||||||
|
inline MatrixI (int r, int c);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline VTYPE &operator () (int c, int r);
|
||||||
|
inline MatrixI &operator= (unsigned char c);
|
||||||
|
inline MatrixI &operator= (int c);
|
||||||
|
inline MatrixI &operator= (double c);
|
||||||
|
inline MatrixI &operator= (MatrixC &op);
|
||||||
|
inline MatrixI &operator= (MatrixI &op);
|
||||||
|
inline MatrixI &operator= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixI &operator+= (unsigned char c);
|
||||||
|
inline MatrixI &operator+= (int c);
|
||||||
|
inline MatrixI &operator+= (double c);
|
||||||
|
inline MatrixI &operator+= (MatrixC &op);
|
||||||
|
inline MatrixI &operator+= (MatrixI &op);
|
||||||
|
inline MatrixI &operator+= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixI &operator-= (unsigned char c);
|
||||||
|
inline MatrixI &operator-= (int c);
|
||||||
|
inline MatrixI &operator-= (double c);
|
||||||
|
inline MatrixI &operator-= (MatrixC &op);
|
||||||
|
inline MatrixI &operator-= (MatrixI &op);
|
||||||
|
inline MatrixI &operator-= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixI &operator*= (unsigned char c);
|
||||||
|
inline MatrixI &operator*= (int c);
|
||||||
|
inline MatrixI &operator*= (double c);
|
||||||
|
inline MatrixI &operator*= (MatrixC &op);
|
||||||
|
inline MatrixI &operator*= (MatrixI &op);
|
||||||
|
inline MatrixI &operator*= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixI &operator/= (unsigned char c);
|
||||||
|
inline MatrixI &operator/= (int c);
|
||||||
|
inline MatrixI &operator/= (double c);
|
||||||
|
inline MatrixI &operator/= (MatrixC &op);
|
||||||
|
inline MatrixI &operator/= (MatrixI &op);
|
||||||
|
inline MatrixI &operator/= (MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixI &Multiply (MatrixF &op);
|
||||||
|
inline MatrixI &Resize (int x, int y);
|
||||||
|
inline MatrixI &ResizeSafe (int x, int y);
|
||||||
|
inline MatrixI &InsertRow (int r);
|
||||||
|
inline MatrixI &InsertCol (int c);
|
||||||
|
inline MatrixI &Transpose (void);
|
||||||
|
inline MatrixI &Identity (int order);
|
||||||
|
inline MatrixI &Basis (Vector3DF &c1, Vector3DF &c2, Vector3DF &c3);
|
||||||
|
inline MatrixI &GaussJordan (MatrixF &b);
|
||||||
|
|
||||||
|
inline int GetX();
|
||||||
|
inline int GetY();
|
||||||
|
inline int GetRows(void);
|
||||||
|
inline int GetCols(void);
|
||||||
|
inline int GetLength(void);
|
||||||
|
inline VTYPE *GetData(void);
|
||||||
|
|
||||||
|
inline unsigned char *GetDataC (void) {return NULL;}
|
||||||
|
inline int *GetDataI (void) {return data;}
|
||||||
|
inline double *GetDataF (void) {return NULL;}
|
||||||
|
|
||||||
|
inline double GetF (int r, int c);
|
||||||
|
};
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// MatrixF Declaration
|
||||||
|
#define VNAME F
|
||||||
|
#define VTYPE double
|
||||||
|
|
||||||
|
class MatrixF {
|
||||||
|
public:
|
||||||
|
VTYPE *data;
|
||||||
|
int rows, cols, len;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline MatrixF ();
|
||||||
|
inline ~MatrixF ();
|
||||||
|
inline MatrixF (const int r, const int c);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline VTYPE GetVal ( int c, int r );
|
||||||
|
inline VTYPE &operator () (const int c, const int r);
|
||||||
|
inline MatrixF &operator= (const unsigned char c);
|
||||||
|
inline MatrixF &operator= (const int c);
|
||||||
|
inline MatrixF &operator= (const double c);
|
||||||
|
inline MatrixF &operator= (const MatrixC &op);
|
||||||
|
inline MatrixF &operator= (const MatrixI &op);
|
||||||
|
inline MatrixF &operator= (const MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixF &operator+= (const unsigned char c);
|
||||||
|
inline MatrixF &operator+= (const int c);
|
||||||
|
inline MatrixF &operator+= (const double c);
|
||||||
|
inline MatrixF &operator+= (const MatrixC &op);
|
||||||
|
inline MatrixF &operator+= (const MatrixI &op);
|
||||||
|
inline MatrixF &operator+= (const MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixF &operator-= (const unsigned char c);
|
||||||
|
inline MatrixF &operator-= (const int c);
|
||||||
|
inline MatrixF &operator-= (const double c);
|
||||||
|
inline MatrixF &operator-= (const MatrixC &op);
|
||||||
|
inline MatrixF &operator-= (const MatrixI &op);
|
||||||
|
inline MatrixF &operator-= (const MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixF &operator*= (const unsigned char c);
|
||||||
|
inline MatrixF &operator*= (const int c);
|
||||||
|
inline MatrixF &operator*= (const double c);
|
||||||
|
inline MatrixF &operator*= (const MatrixC &op);
|
||||||
|
inline MatrixF &operator*= (const MatrixI &op);
|
||||||
|
inline MatrixF &operator*= (const MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixF &operator/= (const unsigned char c);
|
||||||
|
inline MatrixF &operator/= (const int c);
|
||||||
|
inline MatrixF &operator/= (const double c);
|
||||||
|
inline MatrixF &operator/= (const MatrixC &op);
|
||||||
|
inline MatrixF &operator/= (const MatrixI &op);
|
||||||
|
inline MatrixF &operator/= (const MatrixF &op);
|
||||||
|
|
||||||
|
inline MatrixF &Multiply4x4 (const MatrixF &op);
|
||||||
|
inline MatrixF &Multiply (const MatrixF &op);
|
||||||
|
inline MatrixF &Resize (const int x, const int y);
|
||||||
|
inline MatrixF &ResizeSafe (const int x, const int y);
|
||||||
|
inline MatrixF &InsertRow (const int r);
|
||||||
|
inline MatrixF &InsertCol (const int c);
|
||||||
|
inline MatrixF &Transpose (void);
|
||||||
|
inline MatrixF &Identity (const int order);
|
||||||
|
inline MatrixF &RotateX (const double ang);
|
||||||
|
inline MatrixF &RotateY (const double ang);
|
||||||
|
inline MatrixF &RotateZ (const double ang);
|
||||||
|
inline MatrixF &Ortho (double sx, double sy, double n, double f);
|
||||||
|
inline MatrixF &Translate (double tx, double ty, double tz);
|
||||||
|
inline MatrixF &Basis (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3);
|
||||||
|
inline MatrixF &GaussJordan (MatrixF &b);
|
||||||
|
inline MatrixF &ConjugateGradient (MatrixF &b);
|
||||||
|
inline MatrixF &Submatrix ( MatrixF& b, int mx, int my);
|
||||||
|
inline MatrixF &MatrixVector5 (MatrixF& x, int mrows, MatrixF& b );
|
||||||
|
inline MatrixF &ConjugateGradient5 (MatrixF &b, int mrows );
|
||||||
|
inline double Dot ( MatrixF& b );
|
||||||
|
|
||||||
|
inline void Print ( char* fname );
|
||||||
|
|
||||||
|
inline int GetX();
|
||||||
|
inline int GetY();
|
||||||
|
inline int GetRows(void);
|
||||||
|
inline int GetCols(void);
|
||||||
|
inline int GetLength(void);
|
||||||
|
inline VTYPE *GetData(void);
|
||||||
|
inline void GetRowVec (int r, Vector3DF &v);
|
||||||
|
|
||||||
|
inline unsigned char *GetDataC (void) const {return NULL;}
|
||||||
|
inline int *GetDataI (void) const {return NULL;}
|
||||||
|
inline double *GetDataF (void) const {return data;}
|
||||||
|
|
||||||
|
inline double GetF (const int r, const int c);
|
||||||
|
};
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// MatrixF Declaration
|
||||||
|
#define VNAME F
|
||||||
|
#define VTYPE float
|
||||||
|
|
||||||
|
class Matrix4F {
|
||||||
|
public:
|
||||||
|
VTYPE data[16];
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Matrix4F ();
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline VTYPE &operator () (const int n) { return data[n]; }
|
||||||
|
inline VTYPE &operator () (const int c, const int r) { return data[ (r<<2)+c ]; }
|
||||||
|
inline Matrix4F &operator= (const unsigned char c);
|
||||||
|
inline Matrix4F &operator= (const int c);
|
||||||
|
inline Matrix4F &operator= (const double c);
|
||||||
|
inline Matrix4F &operator+= (const unsigned char c);
|
||||||
|
inline Matrix4F &operator+= (const int c);
|
||||||
|
inline Matrix4F &operator+= (const double c);
|
||||||
|
inline Matrix4F &operator-= (const unsigned char c);
|
||||||
|
inline Matrix4F &operator-= (const int c);
|
||||||
|
inline Matrix4F &operator-= (const double c);
|
||||||
|
inline Matrix4F &operator*= (const unsigned char c);
|
||||||
|
inline Matrix4F &operator*= (const int c);
|
||||||
|
inline Matrix4F &operator*= (const double c);
|
||||||
|
inline Matrix4F &operator/= (const unsigned char c);
|
||||||
|
inline Matrix4F &operator/= (const int c);
|
||||||
|
inline Matrix4F &operator/= (const double c);
|
||||||
|
|
||||||
|
inline Matrix4F &Multiply (const Matrix4F &op);
|
||||||
|
inline Matrix4F &Transpose (void);
|
||||||
|
inline Matrix4F &Identity (const int order);
|
||||||
|
inline Matrix4F &RotateX (const double ang);
|
||||||
|
inline Matrix4F &RotateY (const double ang);
|
||||||
|
inline Matrix4F &RotateZ (const double ang);
|
||||||
|
inline Matrix4F &Ortho (double sx, double sy, double n, double f);
|
||||||
|
inline Matrix4F &Translate (double tx, double ty, double tz);
|
||||||
|
inline Matrix4F &Basis (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3);
|
||||||
|
|
||||||
|
// Scale-Rotate-Translate (compound matrix)
|
||||||
|
inline Matrix4F &SRT (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const Vector3DF& s);
|
||||||
|
inline Matrix4F &SRT (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const float s);
|
||||||
|
|
||||||
|
// invTranslate-invRotate-invScale (compound matrix)
|
||||||
|
inline Matrix4F &InvTRS (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const Vector3DF& s);
|
||||||
|
inline Matrix4F &InvTRS (const Vector3DF &c1, const Vector3DF &c2, const Vector3DF &c3, const Vector3DF& t, const float s);
|
||||||
|
|
||||||
|
inline int GetX() { return 4; }
|
||||||
|
inline int GetY() { return 4; }
|
||||||
|
inline int GetRows(void) { return 4; }
|
||||||
|
inline int GetCols(void) { return 4; }
|
||||||
|
inline int GetLength(void) { return 16; }
|
||||||
|
inline VTYPE *GetData(void) { return data; }
|
||||||
|
inline void GetRowVec (int r, Vector3DF &v);
|
||||||
|
|
||||||
|
inline unsigned char *GetDataC (void) const {return NULL;}
|
||||||
|
inline int *GetDataI (void) const {return NULL;}
|
||||||
|
inline float *GetDataF (void) const {return (float*) data;}
|
||||||
|
|
||||||
|
inline float GetF (const int r, const int c);
|
||||||
|
};
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
|
||||||
|
// Matrix Code Definitions (Inlined)
|
||||||
|
|
||||||
|
#include "matrix.cci"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
583
Extras/sph/common/mdebug.cpp
Normal file
583
Extras/sph/common/mdebug.cpp
Normal file
@@ -0,0 +1,583 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#define MEMORY_DEBUG // Overloads the new and delete operators
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "mdebug.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <windows.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CDebug debug;
|
||||||
|
CError error;
|
||||||
|
|
||||||
|
//------------------------------------------------- DEBUG CLASS
|
||||||
|
CDebug::CDebug ()
|
||||||
|
{
|
||||||
|
m_OutName = "debug.txt";
|
||||||
|
m_bStarted = false;
|
||||||
|
m_bToFile = true;
|
||||||
|
m_bToSysbox = true;
|
||||||
|
m_bToCons = false;
|
||||||
|
m_OutFile = NULL;
|
||||||
|
m_OutCons = NULL;
|
||||||
|
Start ();
|
||||||
|
}
|
||||||
|
|
||||||
|
CDebug::~CDebug (void)
|
||||||
|
{
|
||||||
|
Stop ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::Start ()
|
||||||
|
{
|
||||||
|
if ( m_bStarted ) Stop ();
|
||||||
|
|
||||||
|
if ( m_bToFile ) {
|
||||||
|
char fn[200];
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
strcpy_s ( fn, 200, m_OutName.c_str () );
|
||||||
|
fopen_s ( &m_OutFile, fn, "w+t" );
|
||||||
|
#else
|
||||||
|
strncpy ( fn, m_OutName.c_str(), 200 );
|
||||||
|
m_OutFile = fopen( fn, "w+" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( m_OutFile == 0x0 ) {
|
||||||
|
exit ( EXIT_FAILURE ); // error: Cannot create debug file
|
||||||
|
}
|
||||||
|
m_bStarted = true;
|
||||||
|
Print ( "debug", "CDebug started to file.\n");
|
||||||
|
}
|
||||||
|
m_bStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::Exit ( int code )
|
||||||
|
{
|
||||||
|
if ( !m_bToSysbox ) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
_getch();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
exit ( code );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::Stop ()
|
||||||
|
{
|
||||||
|
if ( m_bStarted ) {
|
||||||
|
if ( m_bToFile ) {
|
||||||
|
Print ( "debug", "CDebug stopped.");
|
||||||
|
fclose ( m_OutFile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_bStarted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::SendToFile ( char* fname )
|
||||||
|
{
|
||||||
|
if (m_bStarted) Stop ();
|
||||||
|
m_bToFile = true;
|
||||||
|
m_OutName = fname;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::SendToConsole ( bool tf )
|
||||||
|
{
|
||||||
|
m_bToCons = tf;
|
||||||
|
if ( tf ) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
AllocConsole ();
|
||||||
|
long lStdHandle = (long) GetStdHandle( STD_OUTPUT_HANDLE );
|
||||||
|
int hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
|
||||||
|
m_OutCons = _fdopen( hConHandle, "w" );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::SendToSysbox ( bool tf )
|
||||||
|
{
|
||||||
|
m_bToSysbox = tf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::Print ( std::string subsys, std::string msg )
|
||||||
|
{
|
||||||
|
if ( m_bStarted ) {
|
||||||
|
if ( m_bToFile ) {
|
||||||
|
fprintf ( m_OutFile, "%s: %s\n", subsys.c_str(), msg.c_str() );
|
||||||
|
fflush ( m_OutFile);
|
||||||
|
}
|
||||||
|
if ( m_bToCons ) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
fprintf ( m_OutCons, "%s: %s\n", subsys.c_str(), msg.c_str() );
|
||||||
|
fflush ( m_OutCons );
|
||||||
|
#else
|
||||||
|
printf ( "%s: %s\n", subsys.c_str(), msg.c_str() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::Print (char* msg)
|
||||||
|
{
|
||||||
|
if ( m_bStarted ) {
|
||||||
|
if ( m_bToFile ) {
|
||||||
|
fprintf ( m_OutFile, "%s", msg );
|
||||||
|
fflush ( m_OutFile );
|
||||||
|
}
|
||||||
|
if ( m_bToCons ) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
fprintf ( m_OutCons, "%s", msg );
|
||||||
|
fflush ( m_OutCons );
|
||||||
|
#else
|
||||||
|
printf ( "%s", msg );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::Print ( std::string msg )
|
||||||
|
{
|
||||||
|
if ( m_bStarted ) {
|
||||||
|
if ( m_bToFile ) {
|
||||||
|
fprintf ( m_OutFile, "%s", msg.c_str() );
|
||||||
|
fflush ( m_OutFile );
|
||||||
|
}
|
||||||
|
if ( m_bToCons ) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
fprintf ( m_OutCons, "%s", msg.c_str() );
|
||||||
|
fflush ( m_OutCons );
|
||||||
|
#else
|
||||||
|
printf ( "%s", msg.c_str() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::PrintF ( std::string substr, char* format, ... )
|
||||||
|
{
|
||||||
|
// Note: This is the >only< way to do this. There is no general way to
|
||||||
|
// pass on all the arguments from one ellipsis function to another.
|
||||||
|
// The function vfprintf was specially designed to allow this.
|
||||||
|
|
||||||
|
if ( m_bStarted ) {
|
||||||
|
if ( m_bToFile ) {
|
||||||
|
va_list argptr;
|
||||||
|
va_start (argptr, format);
|
||||||
|
fprintf ( m_OutFile, "%s: ", substr.c_str() );
|
||||||
|
vfprintf ( m_OutFile, format, argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
fflush ( m_OutFile );
|
||||||
|
}
|
||||||
|
if ( m_bToCons ) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
va_list argptr;
|
||||||
|
va_start (argptr, format);
|
||||||
|
fprintf ( m_OutCons, "%s: ", substr.c_str() );
|
||||||
|
vfprintf ( m_OutCons, format, argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
fflush ( m_OutCons );
|
||||||
|
#else
|
||||||
|
va_list argptr;
|
||||||
|
va_start (argptr, format);
|
||||||
|
printf ( "%s: ", substr.c_str() );
|
||||||
|
vprintf ( format, argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CDebug::Printf ( char* format, ... )
|
||||||
|
{
|
||||||
|
// Note: This is the >only< way to do this. There is no general way to
|
||||||
|
// pass on all the arguments from one ellipsis function to another.
|
||||||
|
// The function vfprintf was specially designed to allow this.
|
||||||
|
|
||||||
|
if ( m_bStarted ) {
|
||||||
|
if ( m_bToFile ) {
|
||||||
|
va_list argptr;
|
||||||
|
va_start (argptr, format);
|
||||||
|
vfprintf ( m_OutFile, format, argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
fflush ( m_OutFile );
|
||||||
|
}
|
||||||
|
if ( m_bToCons ) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
va_list argptr;
|
||||||
|
va_start (argptr, format);
|
||||||
|
vfprintf ( m_OutCons, format, argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
fflush ( m_OutCons );
|
||||||
|
#else
|
||||||
|
va_list argptr;
|
||||||
|
va_start (argptr, format);
|
||||||
|
vprintf ( format, argptr);
|
||||||
|
va_end (argptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDebug::PrintErr ( std::string errid, std::string subsys, std::string msg, std::string sysbox )
|
||||||
|
{
|
||||||
|
if ( m_bStarted ) {
|
||||||
|
if ( m_bToFile ) {
|
||||||
|
fprintf ( m_OutFile, "%s: ERROR: %s\n", subsys.c_str(), msg.c_str() );
|
||||||
|
fflush ( m_OutFile );
|
||||||
|
}
|
||||||
|
if ( m_bToCons ) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
fprintf ( m_OutCons, "%s: ERROR: %s\n", subsys.c_str(), msg.c_str() );
|
||||||
|
fflush ( m_OutCons );
|
||||||
|
#else
|
||||||
|
printf ( "%s: ERROR[%s] %s\n", subsys.c_str(), errid.c_str(), msg.c_str() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if ( m_bToSysbox ) {
|
||||||
|
char disp[4000];
|
||||||
|
char caption[200];
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// Message boxes for Windows
|
||||||
|
strcpy_s ( caption, 200, "Mint - Error" );
|
||||||
|
strcpy_s ( disp, 4000, sysbox.c_str());
|
||||||
|
#include <windows.h>
|
||||||
|
int hr = MessageBoxA ( 0x0, disp, caption, MB_OK);
|
||||||
|
#else
|
||||||
|
strncpy ( caption, m_ErrorSubsys.c_str(), 200 );
|
||||||
|
strncpy ( disp, msg.c_str(), 4000 );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------- Error Class Code
|
||||||
|
//
|
||||||
|
// This software is released under the LGPL Open Source Liscense.
|
||||||
|
// See the documentation included with this source code for terms of modification,
|
||||||
|
// distribution and re-release.
|
||||||
|
//
|
||||||
|
// Original Copyright (C) 2002 Rama C. Hoetzlein, GameX R4
|
||||||
|
//
|
||||||
|
|
||||||
|
CError::CError ()
|
||||||
|
{
|
||||||
|
m_Errors.clear ();
|
||||||
|
m_ErrorID = "";
|
||||||
|
m_ErrorSubsys = "";
|
||||||
|
m_ErrorMsg = "";
|
||||||
|
m_ErrorFunc = "";
|
||||||
|
m_ErrorFix = "";
|
||||||
|
m_ErrorExtra = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::Start ()
|
||||||
|
{
|
||||||
|
Start ( "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::Start ( char* fname )
|
||||||
|
{
|
||||||
|
if ( fname != 0x0 && strlen(fname) > 0 ) {
|
||||||
|
// Read error message file. NOT YET IMPLEMENTED
|
||||||
|
} else {
|
||||||
|
debug.Print ( "error", "No error file loaded." );
|
||||||
|
}
|
||||||
|
debug.Print ( "error", "Error handler started." );
|
||||||
|
m_bStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::OutputMessage ()
|
||||||
|
{
|
||||||
|
// Create sysbox message
|
||||||
|
std::string box_msg;
|
||||||
|
box_msg = "Subsystem: " + m_ErrorSubsys + "\n\n";
|
||||||
|
box_msg += "Error: " + m_ErrorMsg + "\n";
|
||||||
|
if ( m_ErrorExtra.length() > 0) box_msg += "Info: " + m_ErrorExtra + "\n";
|
||||||
|
if ( m_ErrorFix.length() > 0) box_msg += "\nFix: " + m_ErrorFix + "\n";
|
||||||
|
if ( m_ErrorID.length() > 0 ) box_msg += "Error ID: " + m_ErrorID + "\n";
|
||||||
|
if ( m_ErrorFunc.length() > 0 ) box_msg += "Function: " + m_ErrorFunc + "\n";
|
||||||
|
|
||||||
|
// Error output to debug file
|
||||||
|
debug.PrintErr ( m_ErrorID, m_ErrorSubsys, m_ErrorMsg, box_msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::Exit ( int code )
|
||||||
|
{
|
||||||
|
debug.Exit ( code );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::Print ( char* msg)
|
||||||
|
{
|
||||||
|
// User-level error (no additional info)
|
||||||
|
m_ErrorID = "";
|
||||||
|
m_ErrorSubsys = "undef";
|
||||||
|
m_ErrorMsg = msg;
|
||||||
|
m_ErrorFunc = "";
|
||||||
|
m_ErrorFix = "";
|
||||||
|
m_ErrorExtra = "";
|
||||||
|
OutputMessage ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::Print ( std::string msg )
|
||||||
|
{
|
||||||
|
// User-level error (no additional info)
|
||||||
|
m_ErrorID = "";
|
||||||
|
m_ErrorSubsys = "undef";
|
||||||
|
m_ErrorMsg = msg;
|
||||||
|
m_ErrorFunc = "";
|
||||||
|
m_ErrorFix = "";
|
||||||
|
m_ErrorExtra = "";
|
||||||
|
OutputMessage ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::Print ( std::string subsys, std::string msg ){
|
||||||
|
// Unregistered error
|
||||||
|
m_ErrorID = "";
|
||||||
|
m_ErrorSubsys = subsys;
|
||||||
|
m_ErrorMsg = msg;
|
||||||
|
m_ErrorFunc = "";
|
||||||
|
m_ErrorFix = "";
|
||||||
|
m_ErrorExtra = "";
|
||||||
|
OutputMessage ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::PrintF ( std::string subsys, char* msg, ... )
|
||||||
|
{
|
||||||
|
char buf[2000];
|
||||||
|
va_list argptr;
|
||||||
|
m_ErrorID = "";
|
||||||
|
m_ErrorSubsys = subsys;
|
||||||
|
va_start(argptr, msg);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
vsprintf_s (buf, 2000, msg, argptr);
|
||||||
|
#else
|
||||||
|
vsnprintf(buf, 2000, msg, argptr);
|
||||||
|
#endif
|
||||||
|
va_end (argptr);
|
||||||
|
m_ErrorMsg = buf;
|
||||||
|
m_ErrorFunc = "";
|
||||||
|
m_ErrorFix = "";
|
||||||
|
m_ErrorExtra = "";
|
||||||
|
OutputMessage ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CError::PrintErr ( std::string err )
|
||||||
|
{
|
||||||
|
// Registered error - NOT YET IMPLEMENTED
|
||||||
|
// CErrorMsg* msg = m_
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::PrintErrDX ( std::string err, int result )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// #ifdef BUILD_DX
|
||||||
|
// m_ErrorExtra = DXGetErrorString9 ( result );
|
||||||
|
// #endif
|
||||||
|
OutputMessage ();
|
||||||
|
m_ErrorExtra = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::PrintErrGL ( std::string err, int result )
|
||||||
|
{
|
||||||
|
OutputMessage ();
|
||||||
|
m_ErrorExtra = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CError::PrintErrW ( std::string err, int result )
|
||||||
|
{
|
||||||
|
|
||||||
|
OutputMessage ();
|
||||||
|
m_ErrorExtra = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
void CError::GetErrorMessage ( ErrorDef::Errors err )
|
||||||
|
{
|
||||||
|
switch (err) {
|
||||||
|
//----------------------------------------------------- MATRIX Errors
|
||||||
|
case ErrorDef::MatrixIsNull:
|
||||||
|
m_strDescription = "Matrix data is null\n";
|
||||||
|
m_strFunction = "Matrix::op()";
|
||||||
|
m_strFix = "";
|
||||||
|
break;
|
||||||
|
case ErrorDef::ColOutOfBounds:
|
||||||
|
m_strDescription = "Column index out of bounds\n";
|
||||||
|
m_strFunction = "Matrix::op()";
|
||||||
|
m_strFix = "";
|
||||||
|
break;
|
||||||
|
case ErrorDef::RowOutOfBounds:
|
||||||
|
m_strDescription = "Row index out of bounds\n";
|
||||||
|
m_strFunction = "Matrix::op()";
|
||||||
|
m_strFix = "";
|
||||||
|
break;
|
||||||
|
//----------------------------------------------------- WinDX Errors
|
||||||
|
case ErrorDef::DXInitFail:
|
||||||
|
m_strDescription = "Initialization of DirectX failed.";
|
||||||
|
m_strFunction = "GameX::InitDirect3D";
|
||||||
|
m_strFix = "Reinstall DirectX 9.0. Confirm DirectX hardware support.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::DXCannotGetMode:
|
||||||
|
m_strDescription = "Cannot get current display mode.";
|
||||||
|
m_strFunction = "GameX::SysGetCurrentMode";
|
||||||
|
m_strFix = "";
|
||||||
|
break;
|
||||||
|
case ErrorDef::DXCannotSetMode:
|
||||||
|
m_strDescription = "Cannot select display mode.";
|
||||||
|
m_strFunction = "GameX::SysSelectMode";
|
||||||
|
m_strFix = "Try requesting a different display mode and options.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::WinCannotCreateClass:
|
||||||
|
m_strDescription = "Cannot create Windows class.";
|
||||||
|
m_strFunction = "GameX::SysCreateWindowsClass";
|
||||||
|
m_strFix = "Close other applications. Restart system.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::WinCannotCreateWindow:
|
||||||
|
m_strDescription = "Cannot create Window.";
|
||||||
|
m_strFunction = "GameX::SysCreateWindow";
|
||||||
|
m_strFix = "Try requesting a different display mode and options.\nClose other applications. Restart system. Possibly unsupported display hardware.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::DXCannotCreateDevice:
|
||||||
|
m_strDescription = "Cannot create DirectX Device.";
|
||||||
|
m_strFunction = "GameX::SysCreateDevice3D";
|
||||||
|
m_strFix = "Try requesting a different display mode and options.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::DXCannotCreateDepthStencils:
|
||||||
|
m_strDescription = "Cannot create DirectX Depth Stencils.";
|
||||||
|
m_strFunction = "GameX::SysCreateDepthStencils";
|
||||||
|
m_strFix = "Try requesting a different display mode and options.";
|
||||||
|
break;
|
||||||
|
//---------------------------------------------------------------- File Errors
|
||||||
|
case ErrorDef::CannotAppendAndRead:
|
||||||
|
m_strDescription = "Cannot open a file in both APPEND and READ mode.";
|
||||||
|
m_strFunction = "File::Open";
|
||||||
|
m_strFix = "Use either APPEND, READ or WRITE when opening file.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::CannotAppendAndWrite:
|
||||||
|
m_strDescription = "Cannot open a file in both APPEND and WRITE mode.";
|
||||||
|
m_strFunction = "File::Open";
|
||||||
|
m_strFix = "Use either APPEND, READ or WRITE when opening file.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::FileNotFound:
|
||||||
|
m_strDescription = "File not found.";
|
||||||
|
m_strFunction = "File::Open";
|
||||||
|
m_strFix = "Use AUTOCREATE if you would like to create a new file.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::LeaveEofOnlyOnAppend:
|
||||||
|
m_strDescription = "Warning:LEAVEEOF flag can only be used in APPEND mode.";
|
||||||
|
m_strFunction = "File::Open";
|
||||||
|
m_strFix = "Remove the LEAVEEOF flag or open file in APPEND mode.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::NoModeSpecified:
|
||||||
|
m_strDescription = "No open mode specified.";
|
||||||
|
m_strFunction = "File::Open";
|
||||||
|
m_strFix = "You must specify READ, WRITE or APPEND to open a file.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::NoNotOpenCmd:
|
||||||
|
m_strDescription = "NOTOPEN cannot be used as an open file flag.";
|
||||||
|
m_strFunction = "File::Open";
|
||||||
|
m_strFix = "Remove the NOTOPEN flag.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::NoSeqAndRandom:
|
||||||
|
m_strDescription = "Cannot open file in both SEQUENTIAL and RANDOM access modes.";
|
||||||
|
m_strFunction = "File::Open";
|
||||||
|
m_strFix = "Choose either SEQUENTIAL or RANDOM mode to open file in.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::CannotCreateFont:
|
||||||
|
m_strDescription = "Cannot create default font.";
|
||||||
|
m_strFunction = "RenderDX::Initialize";
|
||||||
|
m_strFix = "DirectX fonts are not supported for some reason.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::CannotCreateSprite:
|
||||||
|
m_strDescription = "Cannot create default sprite.";
|
||||||
|
m_strFunction = "RenderDX::Initialize";
|
||||||
|
m_strFix = "DirectX sprites are not supported for some reason.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::CannotAddImage:
|
||||||
|
m_strDescription = "Cannot create image on video memory.";
|
||||||
|
m_strFunction = "RenderDX::AddImage";
|
||||||
|
m_strFix = "DirectX was unable to create hardware texture for the image.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::CannotUpdateImage:
|
||||||
|
m_strDescription = "Cannot update image data on video memory.";
|
||||||
|
m_strFunction = "RenderDX::UpdateImage";
|
||||||
|
m_strFix = "DirectX was unable to modify hardware texture for the image.";
|
||||||
|
break;
|
||||||
|
case ErrorDef::CannotOpenFile:
|
||||||
|
#if defined(BUILD_VSNET)
|
||||||
|
m_strDescription = strerror( errno );
|
||||||
|
#else
|
||||||
|
m_strDescription = ""; // should replace with Mac general error code
|
||||||
|
#endif
|
||||||
|
m_strFunction = "File::Open";
|
||||||
|
m_strFix = "";
|
||||||
|
break;
|
||||||
|
case ErrorDef::ImageLoadError:
|
||||||
|
m_strDescription = "Unable to load image.";
|
||||||
|
m_strFunction = "ImageX::Load";
|
||||||
|
m_strFix = "";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
char msg[500];
|
||||||
|
sprintf (msg, "%d", (int) err );
|
||||||
|
m_strDescription = "Undefined error: ";
|
||||||
|
m_strDescription += msg;
|
||||||
|
m_strSubsystem = "Undefined error.";
|
||||||
|
m_strFix = "Error must be given a description and fix message.";
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MEMORY_DEBUG
|
||||||
|
|
||||||
|
// User-defined operator new.
|
||||||
|
void *operator new( size_t stSize )
|
||||||
|
{
|
||||||
|
void* pvMem = malloc( stSize );
|
||||||
|
debug.Printf ( "NEW %p (%d bytes)\n", pvMem, stSize );
|
||||||
|
return pvMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User-defined operator delete.
|
||||||
|
void operator delete( void *pvMem )
|
||||||
|
{
|
||||||
|
debug.Printf ( "DELETE %p\n", pvMem );
|
||||||
|
free ( pvMem );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
138
Extras/sph/common/mdebug.h
Normal file
138
Extras/sph/common/mdebug.h
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 INC_MINT_DEBUG_H
|
||||||
|
#define INC_MINT_DEBUG_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BUILD_VS2005
|
||||||
|
// #pragma warning( disable : 4101) // removes warning 4101 - unreferenced local
|
||||||
|
// #pragma warning( disable : 4244) // removes warning 4244 - conversion loss of data
|
||||||
|
#pragma warning( disable : 4995) // removes warning 4995 - depricated function
|
||||||
|
#pragma warning( disable : 4996) // removes warning 4996 - depricated function
|
||||||
|
// #pragma warning( disable : 4018) // removes warning 4018 - unsigned/signed
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class CDebug {
|
||||||
|
public:
|
||||||
|
CDebug ();
|
||||||
|
~CDebug ();
|
||||||
|
|
||||||
|
// Control functions
|
||||||
|
void Start ();
|
||||||
|
void Stop ();
|
||||||
|
void SendToConsole ( bool tf );
|
||||||
|
void SendToSysbox ( bool tf );
|
||||||
|
void SendToFile ( bool tf );
|
||||||
|
void SendToFile ( char *filename );
|
||||||
|
|
||||||
|
// Output functions
|
||||||
|
void Exit ( int code );
|
||||||
|
void Print ( std::string subsys, std::string msg );
|
||||||
|
void Print ( std::string msg );
|
||||||
|
void Print ( char* msg);
|
||||||
|
void PrintF ( std::string subsys, char *msg, ... );
|
||||||
|
void Printf ( char *msg, ... );
|
||||||
|
void PrintErr ( std::string errid, std::string subsys, std::string msg, std::string sysbox ); // Used by Error class
|
||||||
|
|
||||||
|
// Filtering functions
|
||||||
|
void AddFilter ( std::string subsys );
|
||||||
|
void ClearFilters ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_bStarted;
|
||||||
|
bool m_bToFile;
|
||||||
|
bool m_bToCons;
|
||||||
|
bool m_bToSysbox;
|
||||||
|
std::string m_OutName;
|
||||||
|
FILE* m_OutFile;
|
||||||
|
FILE* m_OutCons;
|
||||||
|
|
||||||
|
std::map< std::string, bool > m_Filters;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CErrorMsg {
|
||||||
|
std::string m_strSubsys;
|
||||||
|
std::string m_strFunction;
|
||||||
|
std::string m_strMessage;
|
||||||
|
std::string m_strFix;
|
||||||
|
std::string m_strExtraInfo;
|
||||||
|
bool m_bFatal;
|
||||||
|
bool m_bFilter;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CError {
|
||||||
|
public:
|
||||||
|
CError ();
|
||||||
|
|
||||||
|
void Start ();
|
||||||
|
void Start ( char* fname );
|
||||||
|
void LoadErrors ();
|
||||||
|
void OutputMessage ();
|
||||||
|
void Exit () { Exit (EXIT_SUCCESS); }
|
||||||
|
void Exit ( int code );
|
||||||
|
|
||||||
|
// Unregistered errors
|
||||||
|
void Print ( std::string subsys, std::string msg );
|
||||||
|
void Print ( std::string msg );
|
||||||
|
void Print ( char* msg);
|
||||||
|
void PrintF ( std::string subsys, char *msg, ... );
|
||||||
|
|
||||||
|
// Registered errors
|
||||||
|
void PrintErr ( std::string err );
|
||||||
|
void PrintErrDX ( std::string err, int result ); // for DirectX errors
|
||||||
|
void PrintErrGL ( std::string err, int result ); // for OpenGL errors
|
||||||
|
void PrintErrW ( std::string err, int result ); // for Windows errors
|
||||||
|
|
||||||
|
std::string GetErrorSubsys () { return m_ErrorID; }
|
||||||
|
std::string GetErrorMessage () { return m_ErrorMsg; }
|
||||||
|
std::string GetErrorFunction () { return m_ErrorFunc; }
|
||||||
|
std::string GetErrorFix () { return m_ErrorFix; }
|
||||||
|
std::string GetErrorExtra () { return m_ErrorExtra; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_bStarted;
|
||||||
|
|
||||||
|
std::string m_ErrorID; // Current error
|
||||||
|
std::string m_ErrorSubsys;
|
||||||
|
std::string m_ErrorMsg;
|
||||||
|
std::string m_ErrorFunc;
|
||||||
|
std::string m_ErrorFix;
|
||||||
|
std::string m_ErrorExtra;
|
||||||
|
bool m_bFatal;
|
||||||
|
|
||||||
|
std::map < std::string, CErrorMsg* > m_Errors; // List of registered errors
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern CError error;
|
||||||
|
extern CDebug debug;
|
||||||
|
#endif
|
||||||
|
|
||||||
955
Extras/sph/common/mesh.cpp
Normal file
955
Extras/sph/common/mesh.cpp
Normal file
@@ -0,0 +1,955 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <conio.h>
|
||||||
|
#include <vector.h>
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "mdebug.h"
|
||||||
|
//#include "mfile.h"
|
||||||
|
|
||||||
|
//#include "event.h"
|
||||||
|
|
||||||
|
#include <gl/glut.h>
|
||||||
|
|
||||||
|
#define DEGtoRAD (3.141592/180.0)
|
||||||
|
|
||||||
|
bool Mesh::mbInitStatic = false;
|
||||||
|
int Mesh::miBufSize[MAX_MFORMAT][MAX_BFORMAT];
|
||||||
|
|
||||||
|
Mesh::Mesh ()
|
||||||
|
{
|
||||||
|
debug.SendToConsole ( true );
|
||||||
|
|
||||||
|
m_Mform = MFormat::UDef;
|
||||||
|
m_CurrF = 0;
|
||||||
|
m_Vbuf = BUF_UNDEF;
|
||||||
|
m_Ebuf = BUF_UNDEF;
|
||||||
|
m_Fbuf = BUF_UNDEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh& Mesh::operator= ( Mesh& src )
|
||||||
|
{
|
||||||
|
CopyBuffers ( src );
|
||||||
|
CopyAttributes ( src );
|
||||||
|
m_Mform = src.GetMeshBufs ( m_Vbuf, m_Ebuf, m_Fbuf );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::InitStatic ()
|
||||||
|
{
|
||||||
|
mbInitStatic = true;
|
||||||
|
miBufSize[ (int) FVF ][ (int) BVert ] = sizeof ( VertFVF );
|
||||||
|
miBufSize[ (int) FVF ][ (int) BFace ] = sizeof ( FaceFVF );
|
||||||
|
miBufSize[ (int) FVF ][ (int) BEdge ] = 0;
|
||||||
|
miBufSize[ (int) CM ][ (int) BVert ] = sizeof ( VertCM );
|
||||||
|
miBufSize[ (int) CM ][ (int) BEdge ] = sizeof ( EdgeCM );
|
||||||
|
miBufSize[ (int) CM ][ (int) BFace ] = sizeof ( FaceCM );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*void Mesh::onUpdate ( objData dat, mint::Event* e )
|
||||||
|
{
|
||||||
|
uchar dtype;
|
||||||
|
hval num;
|
||||||
|
hval max;
|
||||||
|
long size;
|
||||||
|
ushort stride;
|
||||||
|
int num_buf;
|
||||||
|
|
||||||
|
switch ( dat ) {
|
||||||
|
case 'full':
|
||||||
|
ClearBuffers ();
|
||||||
|
ClearAttributes ();
|
||||||
|
|
||||||
|
m_Mform = (MFormat) e->getUChar ();
|
||||||
|
m_Vbuf = e->getUChar ();
|
||||||
|
m_Ebuf = e->getUChar ();
|
||||||
|
m_Fbuf = e->getUChar ();
|
||||||
|
num_buf = e->getInt ();
|
||||||
|
for (int b=0; b < num_buf; b++) {
|
||||||
|
dtype = e->getUChar ();
|
||||||
|
stride = e->getUShort ();
|
||||||
|
num = e->getInt ();
|
||||||
|
max = e->getInt ();
|
||||||
|
AddBuffer ( dtype, stride, max );
|
||||||
|
e->getMem ( mBuf[b].data, num * mBuf[b].stride );
|
||||||
|
mBuf[b].num = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHeapNum = e->getInt ();
|
||||||
|
mHeapMax = e->getInt ();
|
||||||
|
mHeapFree = e->getInt ();
|
||||||
|
mHeap = new hval[mHeapMax];
|
||||||
|
e->getMem ( (char*) mHeap, mHeapNum * sizeof(hval) );
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::UpdateMesh ()
|
||||||
|
{
|
||||||
|
int s = GetSize () + (mBuf.size()+1)*4*sizeof(int);
|
||||||
|
mint::Event* e = updateStart ( 'full', s );
|
||||||
|
|
||||||
|
e->attachUChar ( (char) m_Mform ) ;
|
||||||
|
e->attachUChar ( (char) m_Vbuf );
|
||||||
|
e->attachUChar ( (char) m_Ebuf );
|
||||||
|
e->attachUChar ( (char) m_Fbuf );
|
||||||
|
e->attachInt ( mBuf.size() );
|
||||||
|
for (int b=0; b < mBuf.size(); b++) {
|
||||||
|
e->attachUChar ( mBuf[b].dtype );
|
||||||
|
e->attachUShort ( mBuf[b].stride );
|
||||||
|
e->attachInt ( mBuf[b].num );
|
||||||
|
e->attachInt ( mBuf[b].max );
|
||||||
|
e->attachMem ( mBuf[b].data, mBuf[b].num * mBuf[b].stride );
|
||||||
|
}
|
||||||
|
e->attachInt ( mHeapNum );
|
||||||
|
e->attachInt ( mHeapMax );
|
||||||
|
e->attachInt ( mHeapFree );
|
||||||
|
e->attachMem ( (char*) mHeap, mHeapNum * sizeof(hval) );
|
||||||
|
|
||||||
|
updateEnd ( e );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------ FVF - Face-vertex-face Mesh
|
||||||
|
void Mesh::CreateFVF ()
|
||||||
|
{
|
||||||
|
if ( !mbInitStatic ) InitStatic ();
|
||||||
|
SetFuncFVF ();
|
||||||
|
|
||||||
|
m_Mform = FVF;
|
||||||
|
m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( FVF, BVert ), 64 );
|
||||||
|
m_Fbuf = AddBuffer ( (uchar) BFace, BufSize( FVF, BFace ), 64 );
|
||||||
|
AddAttribute ( m_Vbuf, "pos", sizeof ( AttrPos ), false );
|
||||||
|
AddAttribute ( m_Vbuf, "norm", sizeof ( AttrNorm ) );
|
||||||
|
|
||||||
|
AddHeap ( 128 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::ClearFVF ()
|
||||||
|
{
|
||||||
|
ResetBuffer ( 0, mBuf[0].max );
|
||||||
|
ResetBuffer ( 1, mBuf[0].max );
|
||||||
|
|
||||||
|
ResetHeap ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::SmoothFVF ( int iter )
|
||||||
|
{
|
||||||
|
Vector3DF norm, side;
|
||||||
|
int cnt;
|
||||||
|
FaceFVF* f;
|
||||||
|
VertFVF *v1, *v2, *v3;
|
||||||
|
AttrPos* face_pos;
|
||||||
|
face_pos = new AttrPos[ NumFace() ];
|
||||||
|
|
||||||
|
for (int j=0; j < iter; j++) {
|
||||||
|
// Compute centroid of all faces
|
||||||
|
for (int n=0; n < NumFace(); n++) {
|
||||||
|
f = GetFaceFVF ( n );
|
||||||
|
v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3);
|
||||||
|
face_pos[n].x = ( v1->x + v2->x + v3->x ) / 3.0;
|
||||||
|
face_pos[n].y = ( v1->y + v2->y + v3->y ) / 3.0;
|
||||||
|
face_pos[n].z = ( v1->z + v2->z + v3->z ) / 3.0;
|
||||||
|
}
|
||||||
|
// Compute new vertex positions
|
||||||
|
int cnt;
|
||||||
|
Vector3DF vec;
|
||||||
|
for (int n=0; n < NumVert(); n++) {
|
||||||
|
v1 = GetVertFVF ( n );
|
||||||
|
vec.Set (0,0,0);
|
||||||
|
hval* fptr = mHeap + v1->flist.pos;
|
||||||
|
for (int j=0; j < v1->flist.cnt; j++) {
|
||||||
|
vec.x += face_pos[ (*fptr) ].x;
|
||||||
|
vec.y += face_pos[ (*fptr) ].y;
|
||||||
|
vec.z += face_pos[ (*fptr) ].z;
|
||||||
|
fptr++;
|
||||||
|
}
|
||||||
|
v1->x = vec.x / (float) v1->flist.cnt;
|
||||||
|
v1->y = vec.y / (float) v1->flist.cnt;
|
||||||
|
v1->z = vec.z / (float) v1->flist.cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete face_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::SetNormalFVF ( int n, Vector3DF norm )
|
||||||
|
{
|
||||||
|
VertFVF* v1;
|
||||||
|
AttrNorm* vn;
|
||||||
|
int noff = GetAttrOffset ( "norm" );
|
||||||
|
v1 = GetVertFVF ( n );
|
||||||
|
vn = (AttrNorm* ) ((char*) v1 + noff );
|
||||||
|
vn->nx = norm.x;
|
||||||
|
vn->ny = norm.y;
|
||||||
|
vn->nz = norm.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Mesh::SetColorFVF ( int n, DWORD clr )
|
||||||
|
{
|
||||||
|
VertFVF* v1;
|
||||||
|
AttrClr* vc;
|
||||||
|
int coff = GetAttrOffset ( "color" );
|
||||||
|
if ( coff == -1 ) return;
|
||||||
|
v1 = GetVertFVF ( n );
|
||||||
|
vc = (AttrClr* ) ((char*) v1 + coff );
|
||||||
|
vc->clr = clr;
|
||||||
|
}
|
||||||
|
void Mesh::ComputeNormalsFVF ()
|
||||||
|
{
|
||||||
|
Vector3DF norm, side;
|
||||||
|
FaceFVF* f;
|
||||||
|
VertFVF *v1, *v2, *v3, *v4;
|
||||||
|
AttrNorm* vn;
|
||||||
|
AttrNorm* face_norms;
|
||||||
|
face_norms = new AttrNorm[ NumFace() ];
|
||||||
|
|
||||||
|
// Clear vertex normals
|
||||||
|
int noff = GetAttrOffset ( "norm" );
|
||||||
|
for (int n=0; n < NumVert(); n++) {
|
||||||
|
v1 = GetVertFVF ( n );
|
||||||
|
vn = (AttrNorm*) ((char*) v1 + noff);
|
||||||
|
vn->nx = 0;
|
||||||
|
vn->ny = 0;
|
||||||
|
vn->nz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute normals of all faces
|
||||||
|
for (int n=0; n < NumFace(); n++) {
|
||||||
|
f = GetFaceFVF ( n );
|
||||||
|
v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3);
|
||||||
|
side = Vector3DF ( v2->x, v2->y, v2->z );
|
||||||
|
side -= Vector3DF ( v1->x, v1->y, v1->z );
|
||||||
|
side.Normalize ();
|
||||||
|
norm = Vector3DF ( v3->x, v3->y, v3->z );
|
||||||
|
norm -= Vector3DF ( v1->x, v1->y, v1->z );
|
||||||
|
norm.Normalize ();
|
||||||
|
norm.Cross ( side );
|
||||||
|
face_norms[n].nx = norm.x;
|
||||||
|
face_norms[n].ny = norm.y;
|
||||||
|
face_norms[n].nz = norm.z;
|
||||||
|
vn = (AttrNorm*) ((char*) v1 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
|
||||||
|
vn = (AttrNorm*) ((char*) v2 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
|
||||||
|
vn = (AttrNorm*) ((char*) v3 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
|
||||||
|
if ( f->v4 != -1 ) {
|
||||||
|
v4 = GetVertFVF(f->v4);
|
||||||
|
vn = (AttrNorm*) ((char*) v4 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize vertex normals
|
||||||
|
Vector3DF vec;
|
||||||
|
for (int n=0; n < NumVert(); n++) {
|
||||||
|
v1 = GetVertFVF ( n );
|
||||||
|
vn = (AttrNorm*) ((char*) v1 + noff);
|
||||||
|
vec.Set ( vn->nx, vn->ny, vn->nz );
|
||||||
|
vec.Normalize ();
|
||||||
|
vn->nx = vec.x;
|
||||||
|
vn->ny = vec.y;
|
||||||
|
vn->nz = vec.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute normal of a vertex from surrounding faces (slow method)
|
||||||
|
/*int cnt;
|
||||||
|
for (int n=0; n < NumVert(); n++) {
|
||||||
|
v1 = GetVertFVF ( n );
|
||||||
|
vn = (VertNorm*) GetExtraFVF ( v1 );
|
||||||
|
cnt = 0;
|
||||||
|
vn->nx = 0; vn->ny = 0; vn->nz = 0;
|
||||||
|
hval* fptr = mHeap + v1->flist.pos;
|
||||||
|
for (int j=0; j < v1->flist.cnt; j++) {
|
||||||
|
vn->nx += face_norms[ (*fptr) ].nx;
|
||||||
|
vn->ny += face_norms[ (*fptr) ].ny;
|
||||||
|
vn->nz += face_norms[ (*fptr) ].nz;
|
||||||
|
cnt++;
|
||||||
|
fptr++;
|
||||||
|
}
|
||||||
|
vn->nx /= (float) cnt;
|
||||||
|
vn->ny /= (float) cnt;
|
||||||
|
vn->nz /= (float) cnt;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
delete face_norms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::SetFuncFVF ()
|
||||||
|
{
|
||||||
|
m_AddVertFunc = &Mesh::AddVertFVF;
|
||||||
|
m_AddFaceFast3Func = &Mesh::AddFaceFast3FVF;
|
||||||
|
m_AddFaceFast4Func = &Mesh::AddFaceFast4FVF;
|
||||||
|
}
|
||||||
|
|
||||||
|
xref Mesh::AddFaceFast3FVF ( xref v1, xref v2, xref v3 )
|
||||||
|
{
|
||||||
|
xref fNdx;
|
||||||
|
FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx );
|
||||||
|
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1;
|
||||||
|
AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA );
|
||||||
|
return fNdx;
|
||||||
|
}
|
||||||
|
xref Mesh::AddFaceFast4FVF ( xref v1, xref v2, xref v3, xref v4 )
|
||||||
|
{
|
||||||
|
xref fNdx;
|
||||||
|
FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx );
|
||||||
|
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4;
|
||||||
|
AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertFVF(v4)->flist, FACE_DELTA );
|
||||||
|
return fNdx;
|
||||||
|
}
|
||||||
|
xref Mesh::AddVertFVF ( float x, float y, float z )
|
||||||
|
{
|
||||||
|
xref ndx;
|
||||||
|
VertFVF* v = (VertFVF*) AddElem ( m_Vbuf, ndx );
|
||||||
|
v->x = x; v->y = y; v->z = z;
|
||||||
|
ClearRefs ( v->flist );
|
||||||
|
return ndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DebugFVF ()
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
int j;
|
||||||
|
VertFVF* v;
|
||||||
|
FaceFVF* f;
|
||||||
|
debug.Printf ( "-- MESH --\n");
|
||||||
|
|
||||||
|
debug.Printf ( "-- verts\n" );
|
||||||
|
for (n=0; n < NumVert(); n++) {
|
||||||
|
v = GetVertFVF(n);
|
||||||
|
debug.Printf ( "%d: (%2.1f,%2.1f,%2.1f) f:%d %d{", n, v->x, v->y, v->z, v->flist.cnt, v->flist.pos);
|
||||||
|
if ( v->flist.cnt > 0 ) {
|
||||||
|
for (j=0; j < v->flist.cnt; j++)
|
||||||
|
debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA );
|
||||||
|
}
|
||||||
|
debug.Printf ( "}\n" );
|
||||||
|
}
|
||||||
|
debug.Printf ( "-- faces\n" );
|
||||||
|
for (n=0; n < NumFace(); n++) {
|
||||||
|
f = GetFaceFVF(n);
|
||||||
|
debug.Printf ( "%d: v:%d %d %d\n", n, f->v1, f->v2, f->v3);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugHeap ();
|
||||||
|
|
||||||
|
debug.Printf ("\n\n");
|
||||||
|
//_getch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------ CM - Connected Mesh
|
||||||
|
// Create Connected Mesh (CM)
|
||||||
|
void Mesh::CreateCM ()
|
||||||
|
{
|
||||||
|
if ( !mbInitStatic ) InitStatic ();
|
||||||
|
SetFuncCM ();
|
||||||
|
|
||||||
|
m_Mform = CM;
|
||||||
|
m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( CM, BVert ), 64 );
|
||||||
|
m_Ebuf = AddBuffer ( (uchar) BEdge, BufSize ( CM, BEdge), 64 );
|
||||||
|
m_Fbuf = AddBuffer ( (uchar) BFace, BufSize ( CM, BFace), 64 );
|
||||||
|
AddAttribute ( m_Vbuf, "pos", sizeof(AttrPos), false );
|
||||||
|
AddAttribute ( m_Vbuf, "norm", sizeof(AttrNorm) );
|
||||||
|
|
||||||
|
AddHeap ( 128 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::SetFuncCM ()
|
||||||
|
{
|
||||||
|
m_AddVertFunc = &Mesh::AddVertCM;
|
||||||
|
m_AddFaceFast3Func = &Mesh::AddFaceFast3CM;
|
||||||
|
m_AddFaceFast4Func = &Mesh::AddFaceFast4CM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xref Mesh::AddVertCM ( float x, float y, float z )
|
||||||
|
{
|
||||||
|
xref ndx;
|
||||||
|
VertCM* v = (VertCM*) AddElem ( m_Vbuf, ndx );
|
||||||
|
v->x = x; v->y = y; v->z = z;
|
||||||
|
ClearRefs ( v->elist );
|
||||||
|
ClearRefs ( v->flist );
|
||||||
|
return ndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
xref Mesh::AddFaceFast3CM ( xref v1, xref v2, xref v3 )
|
||||||
|
{
|
||||||
|
xref fNdx;
|
||||||
|
FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx );
|
||||||
|
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1;
|
||||||
|
xref eNdx;
|
||||||
|
eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx;
|
||||||
|
eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx;
|
||||||
|
eNdx = AddEdgeCM ( f->v3, f->v1 ); f->e3 = eNdx;
|
||||||
|
AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA );
|
||||||
|
return fNdx;
|
||||||
|
}
|
||||||
|
xref Mesh::AddFaceFast4CM ( xref v1, xref v2, xref v3, xref v4 )
|
||||||
|
{
|
||||||
|
xref fNdx;
|
||||||
|
FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx );
|
||||||
|
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4;
|
||||||
|
xref eNdx;
|
||||||
|
eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx;
|
||||||
|
eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx;
|
||||||
|
eNdx = AddEdgeCM ( f->v3, f->v4 ); f->e3 = eNdx;
|
||||||
|
eNdx = AddEdgeCM ( f->v4, f->v1 ); f->e4 = eNdx;
|
||||||
|
AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA );
|
||||||
|
AddRef ( fNdx, GetVertCM(v4)->flist, FACE_DELTA );
|
||||||
|
return fNdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
xref Mesh::FindEdgeCM ( xref v1, xref v2 )
|
||||||
|
{
|
||||||
|
EdgeCM *pE;
|
||||||
|
VertCM *pV1;
|
||||||
|
pV1 = GetVertCM(v1);
|
||||||
|
if ( pV1->elist.cnt == 0 ) return -1;
|
||||||
|
hval* e = mHeap + pV1->elist.pos;
|
||||||
|
#ifdef MESH_DEBUG
|
||||||
|
for (int n=0; n < pV1->elist.cnt; n++) {
|
||||||
|
pE = GetEdgeCM( (*e)-EDGE_DELTA );
|
||||||
|
if ( pE->v1 == v2 || pE->v2 == v2 ) return (*e)-EDGE_DELTA;
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (int n=0; n < pV1->elist.cnt; n++) {
|
||||||
|
pE = GetEdgeCM( *e );
|
||||||
|
if ( pE->v1 == v2 || pE->v2 == v2 ) return *e;
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xref Mesh::AddEdgeCM ( xref v1, xref v2 )
|
||||||
|
{
|
||||||
|
xref eNdx = FindEdgeCM ( v1, v2 );
|
||||||
|
EdgeCM* e = GetEdgeCM(eNdx);
|
||||||
|
if ( eNdx == -1 ) {
|
||||||
|
e = (EdgeCM*) AddElem ( m_Ebuf, eNdx );
|
||||||
|
e->f1 = 0;
|
||||||
|
e->f2 = 0;
|
||||||
|
e->v1 = v1;
|
||||||
|
e->v2 = v2;
|
||||||
|
AddRef ( eNdx, GetVertCM(v1)->elist, EDGE_DELTA );
|
||||||
|
AddRef ( eNdx, GetVertCM(v2)->elist, EDGE_DELTA );
|
||||||
|
}
|
||||||
|
return eNdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DebugCM ()
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
int j;
|
||||||
|
VertCM* v;
|
||||||
|
EdgeCM* e;
|
||||||
|
FaceCM* f;
|
||||||
|
debug.Printf ( "-- MESH --\n");
|
||||||
|
|
||||||
|
debug.Printf ( "-- verts\n" );
|
||||||
|
for (n=0; n < NumVert(); n++) {
|
||||||
|
v = GetVertCM(n);
|
||||||
|
debug.Printf ( "%d: (%2.1f,%2.1f,%2.1f) e:%d %d{", n, v->x, v->y, v->z, v->elist.cnt, v->elist.pos);
|
||||||
|
if ( v->elist.cnt > 0 ) {
|
||||||
|
for (j=0; j < v->elist.cnt; j++)
|
||||||
|
debug.Printf ( "%d ", *(mHeap+v->elist.pos+j) - EDGE_DELTA );
|
||||||
|
}
|
||||||
|
debug.Printf ( "}, f:%d %d{", v->flist.cnt, v->flist.pos);
|
||||||
|
if ( v->flist.cnt > 0 ) {
|
||||||
|
for (j=0; j < v->flist.cnt; j++)
|
||||||
|
debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA );
|
||||||
|
}
|
||||||
|
debug.Printf ( "}\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.Printf ( "-- edges\n" );
|
||||||
|
for (n=0; n < NumEdge(); n++) {
|
||||||
|
e = GetEdgeCM (n);
|
||||||
|
debug.Printf ( "%d: v:%d %d, f:%d %d\n", n, e->v1, e->v2, e->f1, e->f2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.Printf ( "-- faces\n" );
|
||||||
|
for (n=0; n < NumFace(); n++) {
|
||||||
|
f = GetFaceCM(n);
|
||||||
|
debug.Printf ( "%d: v:%d %d %d, e:%d %d %d\n", n, f->v1, f->v2, f->v3, f->e1, f->e2, f->e3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hval* pVal = mHeap;
|
||||||
|
debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree );
|
||||||
|
for (n=0; n < mHeapNum; n++) {
|
||||||
|
if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n );
|
||||||
|
#ifdef MESH_DEBUG
|
||||||
|
if ( *pVal == 0 ) {
|
||||||
|
debug.Printf ( "00000 ");
|
||||||
|
} else if ( *pVal == (hval) 0xFFFF ) {
|
||||||
|
debug.Printf ( "----- ");
|
||||||
|
} else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) {
|
||||||
|
debug.Printf ( "v%04d ", *pVal - VERT_DELTA );
|
||||||
|
} else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) {
|
||||||
|
debug.Printf ( "e%04d ", *pVal - EDGE_DELTA );
|
||||||
|
} else if ( *pVal >= FACE_DELTA ) {
|
||||||
|
debug.Printf ( "f%04d ", *pVal - FACE_DELTA );
|
||||||
|
} else {
|
||||||
|
debug.Printf ( "H%04d ", (int) *pVal );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
debug.Printf ( "%05d ", (int) *pVal );
|
||||||
|
#endif
|
||||||
|
pVal++;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.Printf ("\n\n");
|
||||||
|
//_getch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DebugHeap ()
|
||||||
|
{
|
||||||
|
hval* pVal = mHeap;
|
||||||
|
debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree );
|
||||||
|
for (int n=0; n < mHeapNum; n++) {
|
||||||
|
if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n );
|
||||||
|
#ifdef MESH_DEBUG
|
||||||
|
if ( *pVal == 0 ) {
|
||||||
|
debug.Printf ( "00000 ");
|
||||||
|
} else if ( *pVal == (hval) 0xFFFF ) {
|
||||||
|
debug.Printf ( "----- ");
|
||||||
|
} else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) {
|
||||||
|
debug.Printf ( "v%04d ", *pVal - VERT_DELTA );
|
||||||
|
} else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) {
|
||||||
|
debug.Printf ( "e%04d ", *pVal - EDGE_DELTA );
|
||||||
|
} else if ( *pVal >= FACE_DELTA ) {
|
||||||
|
debug.Printf ( "f%04d ", *pVal - FACE_DELTA );
|
||||||
|
} else {
|
||||||
|
debug.Printf ( "H%04d ", (int) *pVal );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
debug.Printf ( "%05d ", (int) *pVal );
|
||||||
|
#endif
|
||||||
|
pVal++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DrawVertsCM ( float* viewmat, int a, int b )
|
||||||
|
{
|
||||||
|
VertCM* v;
|
||||||
|
|
||||||
|
glColor3f (1,0,0);
|
||||||
|
glLoadMatrixf ( viewmat );
|
||||||
|
glTranslatef ( mT.x, mT.y, mT.z );
|
||||||
|
glBegin ( GL_POINTS );
|
||||||
|
for (int n = a; n <= b; n++) {
|
||||||
|
v = GetVertCM (n);
|
||||||
|
glVertex3f ( v->x, v->y, v->z );
|
||||||
|
//glCallList ( m_GLObj );
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DrawVertsFVF ( float* viewmat, int a, int b )
|
||||||
|
{
|
||||||
|
VertFVF* v;
|
||||||
|
glColor3f (1,0,0);
|
||||||
|
glLoadMatrixf ( viewmat );
|
||||||
|
glTranslatef ( mT.x, mT.y, mT.z );
|
||||||
|
glBegin ( GL_POINTS );
|
||||||
|
for (int n = a; n <= b; n++) {
|
||||||
|
v = GetVertFVF (n);
|
||||||
|
glVertex3f ( v->x, v->y, v->z );
|
||||||
|
//glCallList ( m_GLObj );
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DrawFacesCM ( float* viewmat, int a, int b )
|
||||||
|
{
|
||||||
|
FaceCM* f;
|
||||||
|
VertCM* v;
|
||||||
|
AttrNorm* vn;
|
||||||
|
int noff = GetAttrOffset ( "norm" );
|
||||||
|
glLoadMatrixf ( viewmat );
|
||||||
|
glTranslatef ( mT.x, mT.y, mT.z );
|
||||||
|
GLenum dm = GL_TRIANGLES;
|
||||||
|
glBegin ( dm );
|
||||||
|
f = GetFaceCM ( a );
|
||||||
|
for (int n = a; n <= b; n++) {
|
||||||
|
if ( f->v4 == -1 ) {
|
||||||
|
if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; }
|
||||||
|
v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff);
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff);
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff);
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
} else {
|
||||||
|
if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; }
|
||||||
|
v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff);
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff);
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff);
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
v = GetVertCM(f->v4); vn = (AttrNorm*) ((char*) v + noff);
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
}
|
||||||
|
f++;
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DrawFacesFVF ( float* viewmat, int a, int b )
|
||||||
|
{
|
||||||
|
FaceFVF* f;
|
||||||
|
VertFVF* v;
|
||||||
|
AttrNorm* vn;
|
||||||
|
AttrClr* vc;
|
||||||
|
int noff = GetAttrOffset ( "norm" );
|
||||||
|
int coff = GetAttrOffset ( "color" );
|
||||||
|
coff = -1;
|
||||||
|
|
||||||
|
//glLoadMatrixf ( viewmat );
|
||||||
|
//glTranslatef ( mT.x, mT.y, mT.z );
|
||||||
|
GLenum dm = GL_TRIANGLES;
|
||||||
|
glBegin ( dm );
|
||||||
|
f = GetFaceFVF ( a );
|
||||||
|
for (int n = a; n <= b; n++) {
|
||||||
|
if ( f->v4 == -1 ) {
|
||||||
|
if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; }
|
||||||
|
v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||||||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
|
||||||
|
v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||||||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
|
||||||
|
v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||||||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
} else {
|
||||||
|
if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; }
|
||||||
|
v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||||||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
|
||||||
|
v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||||||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
|
||||||
|
v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||||||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
|
||||||
|
v = GetVertFVF(f->v4); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||||||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||||||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||||||
|
}
|
||||||
|
f++;
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DrawEdgesCM ( float* viewmat, int a, int b )
|
||||||
|
{
|
||||||
|
EdgeCM* e;
|
||||||
|
|
||||||
|
glLoadMatrixf ( viewmat );
|
||||||
|
glTranslatef ( mT.x, mT.y, mT.z );
|
||||||
|
glBegin ( GL_LINES );
|
||||||
|
e = GetEdgeCM ( a );
|
||||||
|
for (int n = a; n <= b; n++) {
|
||||||
|
glVertex3f ( GetVertCM(e->v1)->x, GetVertCM(e->v1)->y, GetVertCM(e->v1)->z );
|
||||||
|
glVertex3f ( GetVertCM(e->v2)->x, GetVertCM(e->v2)->y, GetVertCM(e->v2)->z );
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DrawGL ( float* viewmat )
|
||||||
|
{
|
||||||
|
mT.Set(0,0,0);
|
||||||
|
|
||||||
|
switch ( m_Mform ) {
|
||||||
|
case CM: {
|
||||||
|
glDepthRange (0.001, 1.001);
|
||||||
|
//glColor3f ( 1, 0, 0 ); DrawVertsCM ( viewmat, 0, NumVert()-1 );
|
||||||
|
glColor3f ( .6, .6, .6 ); DrawFacesCM ( viewmat, 0, NumFace()-1 );
|
||||||
|
//glDepthRange (0.0005, 1.0005);
|
||||||
|
//glColor3f ( 1, 1, 1); DrawEdgesCM ( viewmat, 0, NumEdge()-1 );
|
||||||
|
} break;
|
||||||
|
case FVF: {
|
||||||
|
//glColor3f (1,0,0); DrawVertsFVF ( viewmat, 0, NumVert()-1 );
|
||||||
|
//glEnable (GL_LIGHTING);
|
||||||
|
|
||||||
|
glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );
|
||||||
|
glColor4f ( .9, .9, .9, 0.75 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 );
|
||||||
|
|
||||||
|
/*glDisable (GL_LIGHTING );
|
||||||
|
glDepthRange (0.000, 1.00);
|
||||||
|
glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
|
||||||
|
glLineWidth ( 3 );
|
||||||
|
glColor4f ( 0, 0, 0, 1.0 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 );
|
||||||
|
glEnable ( GL_LIGHTING );
|
||||||
|
|
||||||
|
glLineWidth ( 1);
|
||||||
|
|
||||||
|
glDepthRange (0.0, 1.0);
|
||||||
|
glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );*/
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::DrawFaceGL ( float* viewmat )
|
||||||
|
{
|
||||||
|
mT.Set (0,0,0);
|
||||||
|
if ( m_CurrF < 0 ) m_CurrF = NumFace()-1;
|
||||||
|
if ( m_CurrF >= NumFace() ) m_CurrF = 0;
|
||||||
|
|
||||||
|
switch ( m_Mform ) {
|
||||||
|
case FVF:
|
||||||
|
glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 );
|
||||||
|
DrawFacesFVF ( viewmat, m_CurrF, m_CurrF );
|
||||||
|
break;
|
||||||
|
case CM:
|
||||||
|
glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 );
|
||||||
|
DrawFacesCM ( viewmat, m_CurrF, m_CurrF );
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::Measure ()
|
||||||
|
{
|
||||||
|
hval* pCurr = mHeap + mHeapFree;
|
||||||
|
int vs, es, fs, hs, hm, as, frees = 0;
|
||||||
|
vs = NumVert(); if ( vs !=0 ) vs *= GetStride(m_Vbuf);
|
||||||
|
es = NumEdge(); if ( es !=0 ) es *= GetStride(m_Ebuf);
|
||||||
|
fs = NumFace(); if ( fs !=0 ) fs *= GetStride(m_Fbuf);
|
||||||
|
hs = mHeapNum*sizeof(hval);
|
||||||
|
hm = mHeapMax*sizeof(hval);
|
||||||
|
|
||||||
|
while ( pCurr != mHeap-1 ) {
|
||||||
|
frees += *(pCurr);
|
||||||
|
pCurr = mHeap + * (hpos*) (pCurr + FPOS);
|
||||||
|
}
|
||||||
|
frees *= sizeof(hval);
|
||||||
|
as = 0;
|
||||||
|
if ( m_Vbuf!=-1 ) as += mBuf[m_Vbuf].max * GetStride(m_Vbuf);
|
||||||
|
if ( m_Fbuf!=-1 ) as += mBuf[m_Fbuf].max * GetStride(m_Fbuf);
|
||||||
|
if ( m_Ebuf!=-1 ) as += mBuf[m_Ebuf].max * GetStride(m_Ebuf);
|
||||||
|
as += hm;
|
||||||
|
|
||||||
|
debug.Printf ( "NumVert: %07.1fk (%d)\n", vs/1000.0, NumVert() );
|
||||||
|
debug.Printf ( "NumFace: %07.1fk (%d)\n", fs/1000.0, NumFace() );
|
||||||
|
debug.Printf ( "NumEdge: %07.1fk (%d)\n", es/1000.0, NumEdge() );
|
||||||
|
debug.Printf ( "Heap Size: %07.1fk (%d)\n", hs/1000.0, mHeapNum );
|
||||||
|
debug.Printf ( "Free Size: %07.1fk\n", frees/1000.0 );
|
||||||
|
debug.Printf ( "Heap Used: %07.1fk (%5.1f%%)\n", (hs-frees)/1000.0, (hs-frees)*100.0/(vs+es+fs+hs-frees) );
|
||||||
|
debug.Printf ( "Heap Max: %07.1fk\n", hm/1000.0 );
|
||||||
|
debug.Printf ( "Total Used: %07.1fk\n", (vs+es+fs+hs-frees)/1000.0 );
|
||||||
|
debug.Printf ( "Total Alloc: %07.1fk\n", as/1000.0 );
|
||||||
|
debug.Printf ( "Fragmentation: %f%%\n", (hm-(hs-frees))*100.0 / hm );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*int Mesh::GetIndex ( int b, void* v )
|
||||||
|
{
|
||||||
|
if ( v == 0x0 ) return -1;
|
||||||
|
return ((char*) v - (char*) mBuf[b].data) / mBuf[b].stride;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
int Mesh::FindPlyElem ( char typ )
|
||||||
|
{
|
||||||
|
for (int n=0; n < m_Ply.size(); n++) {
|
||||||
|
if ( m_Ply[n]->type == typ ) return n;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Mesh::FindPlyProp ( int elem, std::string name )
|
||||||
|
{
|
||||||
|
for (int n=0; n < m_Ply[elem]->prop_list.size(); n++) {
|
||||||
|
if ( m_Ply[elem]->prop_list[n].name.compare ( name)==0 )
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::LoadPly ( char* fname, float s )
|
||||||
|
{
|
||||||
|
/* int m_PlyCnt;
|
||||||
|
float m_PlyData[40];
|
||||||
|
char buf[1000];
|
||||||
|
char bword[1000];
|
||||||
|
std::string word;
|
||||||
|
Buffer b(1000);
|
||||||
|
int vnum, fnum, elem, cnt;
|
||||||
|
char typ;
|
||||||
|
|
||||||
|
if ( m_Mform == MFormat::UDef )
|
||||||
|
CreateFVF ();
|
||||||
|
|
||||||
|
m_File.Open ( fname, FILE_READ | FILE_SEQUENTIAL );
|
||||||
|
if ( !m_File.Valid() ) {
|
||||||
|
error.PrintF ( "mesh", "Could not find file: %s\n", fname );
|
||||||
|
error.Exit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read header
|
||||||
|
m_File.ReadLine ( buf, 1000 );
|
||||||
|
b.ReadWord ( buf, bword ); word = bword;
|
||||||
|
if ( word.compare("ply" )!=0 ) {
|
||||||
|
error.PrintF ( "Not a ply file. %s\n", fname );
|
||||||
|
error.Exit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.Printf ( "Reading PLY.\n" );
|
||||||
|
while ( m_File.ReadLine ( buf, 1000 ) == FILE_STATUS_OK ) {
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
word = bword;
|
||||||
|
if ( word.compare("comment" )!=0 ) {
|
||||||
|
if ( word.compare("end_header")==0 ) break;
|
||||||
|
if ( word.compare("property")==0 ) {
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
word = bword;
|
||||||
|
if ( word.compare("float")==0 ) typ = PLY_FLOAT;
|
||||||
|
if ( word.compare("float16")==0 ) typ = PLY_FLOAT;
|
||||||
|
if ( word.compare("float32")==0 ) typ = PLY_FLOAT;
|
||||||
|
if ( word.compare("int8")==0 ) typ = PLY_INT;
|
||||||
|
if ( word.compare("uint8")==0 ) typ = PLY_UINT;
|
||||||
|
if ( word.compare("list")==0) {
|
||||||
|
typ = PLY_LIST;
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
}
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
word = bword;
|
||||||
|
AddPlyProperty ( typ, word );
|
||||||
|
}
|
||||||
|
if ( word.compare("element" )==0 ) {
|
||||||
|
b.ReadWord ( buf, bword); word = bword;
|
||||||
|
if ( word.compare("vertex")==0 ) {
|
||||||
|
b.ReadWord ( buf, bword);
|
||||||
|
vnum = atoi ( bword );
|
||||||
|
debug.Printf ( " Verts: %d\n", vnum );
|
||||||
|
AddPlyElement ( PLY_VERTS, vnum );
|
||||||
|
}
|
||||||
|
if ( word.compare("face")==0 ) {
|
||||||
|
b.ReadWord ( buf, bword);
|
||||||
|
fnum = atoi ( bword );
|
||||||
|
debug.Printf ( " Faces: %d\n", fnum );
|
||||||
|
AddPlyElement ( PLY_FACES, fnum );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read data
|
||||||
|
int xi, yi, zi;
|
||||||
|
debug.Printf ( " Reading verts..\n" );
|
||||||
|
elem = FindPlyElem ( PLY_VERTS );
|
||||||
|
xi = FindPlyProp ( elem, "x" );
|
||||||
|
yi = FindPlyProp ( elem, "y" );
|
||||||
|
zi = FindPlyProp ( elem, "z" );
|
||||||
|
if ( elem == -1 || xi == -1 || yi == -1 || zi == -1 ) {
|
||||||
|
debug.Printf ( "ERROR: Vertex data not found.\n" );
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
for (int n=0; n < m_Ply[elem]->num; n++) {
|
||||||
|
m_File.ReadLine ( buf, 1000 );
|
||||||
|
for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) {
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
m_PlyData[ j ] = atof ( bword );
|
||||||
|
}
|
||||||
|
AddVert ( m_PlyData[xi]*s, m_PlyData[zi]*s, m_PlyData[yi]*s );
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.Printf ( " Reading faces..\n" );
|
||||||
|
elem = FindPlyElem ( PLY_FACES );
|
||||||
|
xi = FindPlyProp ( elem, "vertex_indices" );
|
||||||
|
if ( elem == -1 || xi == -1 ) {
|
||||||
|
debug.Printf ( "ERROR: Face data not found.\n" );
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
for (int n=0; n < m_Ply[elem]->num; n++) {
|
||||||
|
m_File.ReadLine ( buf, 1000 );
|
||||||
|
m_PlyCnt = 0;
|
||||||
|
for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) {
|
||||||
|
if ( m_Ply[elem]->prop_list[j].type == PLY_LIST ) {
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
cnt = atoi ( bword );
|
||||||
|
m_PlyData[ m_PlyCnt++ ] = cnt;
|
||||||
|
for (int c =0; c < cnt; c++) {
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
m_PlyData[ m_PlyCnt++ ] = atof ( bword );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b.ReadWord ( buf, bword );
|
||||||
|
m_PlyData[ m_PlyCnt++ ] = atof ( bword );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( m_PlyData[xi] == 3 ) {
|
||||||
|
//debug.Printf ( " Face: %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] );
|
||||||
|
AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_PlyData[xi] == 4 ) {
|
||||||
|
//debug.Printf ( " Face: %d, %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4]);
|
||||||
|
AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Measure ();
|
||||||
|
ComputeNormalsFVF (); // !-- should be abstracted
|
||||||
|
*/
|
||||||
|
|
||||||
|
// UpdateMesh ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::AddPlyElement ( char typ, int n )
|
||||||
|
{
|
||||||
|
debug.Printf ( " Element: %d, %d\n", typ, n );
|
||||||
|
PlyElement* p = new PlyElement;
|
||||||
|
p->num = n;
|
||||||
|
p->type = typ;
|
||||||
|
p->prop_list.clear ();
|
||||||
|
m_PlyCurrElem = m_Ply.size();
|
||||||
|
m_Ply.push_back ( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::AddPlyProperty ( char typ, std::string name )
|
||||||
|
{
|
||||||
|
debug.Printf ( " Property: %d, %s\n", typ, name.c_str() );
|
||||||
|
PlyProperty p;
|
||||||
|
p.name = name;
|
||||||
|
p.type = typ;
|
||||||
|
m_Ply [ m_PlyCurrElem ]->prop_list.push_back ( p );
|
||||||
|
}
|
||||||
160
Extras/sph/common/mesh.h
Normal file
160
Extras/sph/common/mesh.h
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 DEF_MESH
|
||||||
|
#define DEF_MESH
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <gl/glut.h>
|
||||||
|
|
||||||
|
#include "geomx.h"
|
||||||
|
#include "mesh_info.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
//#include "mfile.h"
|
||||||
|
|
||||||
|
//#define MESH_DEBUG
|
||||||
|
|
||||||
|
#ifdef MESH_DEBUG
|
||||||
|
#define VERT_DELTA 10000
|
||||||
|
#define EDGE_DELTA 20000
|
||||||
|
#define FACE_DELTA 30000
|
||||||
|
#else
|
||||||
|
#define VERT_DELTA 0
|
||||||
|
#define EDGE_DELTA 0
|
||||||
|
#define FACE_DELTA 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PLY_UINT 0
|
||||||
|
#define PLY_INT 1
|
||||||
|
#define PLY_FLOAT 2
|
||||||
|
#define PLY_LIST 3
|
||||||
|
#define PLY_VERTS 4
|
||||||
|
#define PLY_FACES 5
|
||||||
|
|
||||||
|
struct PlyProperty {
|
||||||
|
char type;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
struct PlyElement {
|
||||||
|
int num;
|
||||||
|
char type; // 0 = vert, 1 = face
|
||||||
|
std::vector<PlyProperty> prop_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Mesh : public GeomX, public MeshInfo {
|
||||||
|
public:
|
||||||
|
Mesh ();
|
||||||
|
|
||||||
|
//virtual objType GetType () { return 'mesh'; }
|
||||||
|
|
||||||
|
// Distributed functions
|
||||||
|
//virtual void onUpdate ( objData dat, mint::Event* e );
|
||||||
|
//void UpdateMesh ();
|
||||||
|
|
||||||
|
// Generic functions
|
||||||
|
void InitStatic ();
|
||||||
|
void DrawGL ( float* viewmat );
|
||||||
|
void DrawFaceGL ( float* viewmat );
|
||||||
|
void Measure ();
|
||||||
|
Mesh& operator= ( Mesh& op2 );
|
||||||
|
|
||||||
|
// Load PLY mesh
|
||||||
|
void LoadPly ( char* fname, float s );
|
||||||
|
void AddPlyElement ( char typ, int n );
|
||||||
|
void AddPlyProperty ( char typ, std::string name );
|
||||||
|
void LoadPlyVerts ();
|
||||||
|
void LoadPlyFaces ();
|
||||||
|
int FindPlyElem ( char typ );
|
||||||
|
int FindPlyProp ( int elem, std::string name );
|
||||||
|
|
||||||
|
// Vertex, Face, Edge functions
|
||||||
|
xref AddVert (float x, float y, float z ) { return (this->*m_AddVertFunc) (x, y, z); }
|
||||||
|
xref AddFaceFast (xref v1, xref v2, xref v3 ) { return (this->*m_AddFaceFast3Func) (v1, v2, v3); }
|
||||||
|
xref AddFaceFast (xref v1, xref v2, xref v3, xref v4 ) { return (this->*m_AddFaceFast4Func) (v1, v2, v3, v4); }
|
||||||
|
xref (Mesh::*m_AddVertFunc) (float x, float y, float z);
|
||||||
|
xref (Mesh::*m_AddFaceFast3Func) (xref v1, xref v2, xref v3);
|
||||||
|
xref (Mesh::*m_AddFaceFast4Func) (xref v1, xref v2, xref v3, xref v4);
|
||||||
|
|
||||||
|
int NumVert () { return NumElem ( m_Vbuf ); }
|
||||||
|
int NumEdge () { return NumElem ( m_Ebuf ); }
|
||||||
|
int NumFace () { return NumElem ( m_Fbuf ); }
|
||||||
|
|
||||||
|
void IncFace ( int n ) { m_CurrF += n; }
|
||||||
|
void DebugHeap ();
|
||||||
|
|
||||||
|
// FVF - Face-Vertex-Face Mesh
|
||||||
|
void CreateFVF ();
|
||||||
|
void ClearFVF ();
|
||||||
|
void SetFuncFVF ();
|
||||||
|
xref AddVertFVF ( float x, float y, float z );
|
||||||
|
xref AddFaceFast3FVF ( xref v1, xref v2, xref v3 );
|
||||||
|
xref AddFaceFast4FVF ( xref v1, xref v2, xref v3, xref v4 );
|
||||||
|
VertFVF* GetVertFVF ( int n ) { return (VertFVF*) (mBuf[m_Vbuf].data + n*mBuf[m_Vbuf].stride); }
|
||||||
|
FaceFVF* GetFaceFVF ( int n ) { return (FaceFVF*) (mBuf[m_Fbuf].data + n*mBuf[m_Fbuf].stride); }
|
||||||
|
void* GetExtraFVF ( VertFVF* v ) { return ((char*) v + miBufSize[(int) FVF][BVert]); }
|
||||||
|
void ComputeNormalsFVF ();
|
||||||
|
void SetNormalFVF ( int n, Vector3DF norm );
|
||||||
|
void SetColorFVF ( int n, DWORD clr );
|
||||||
|
void SmoothFVF ( int iter );
|
||||||
|
void DebugFVF ();
|
||||||
|
void DrawVertsFVF ( float* viewmat, int a, int b );
|
||||||
|
void DrawFacesFVF ( float* viewmat, int a, int b );
|
||||||
|
|
||||||
|
// CM - Connected Mesh
|
||||||
|
void CreateCM ();
|
||||||
|
void SetFuncCM ();
|
||||||
|
xref AddVertCM ( float x, float y, float z );
|
||||||
|
xref AddFaceFast3CM ( xref v1, xref v2, xref v3 );
|
||||||
|
xref AddFaceFast4CM ( xref v1, xref v2, xref v3, xref v4 );
|
||||||
|
xref AddEdgeCM ( xref v1, xref v2 );
|
||||||
|
xref FindEdgeCM ( xref v1, xref v2 );
|
||||||
|
VertCM* GetVertCM ( int n ) { return (VertCM*) (mBuf[m_Vbuf].data + n*mBuf[m_Vbuf].stride); }
|
||||||
|
EdgeCM* GetEdgeCM ( int n ) { return (EdgeCM*) (mBuf[m_Ebuf].data + n*mBuf[m_Ebuf].stride); }
|
||||||
|
FaceCM* GetFaceCM ( int n ) { return (FaceCM*) (mBuf[m_Fbuf].data + n*mBuf[m_Fbuf].stride); }
|
||||||
|
void* GetExtraCM ( VertCM* v ) { return ((char*) v + miBufSize[(int) CM][BVert] ); }
|
||||||
|
void DebugCM ();
|
||||||
|
void DrawVertsCM ( float* viewmat, int a, int b );
|
||||||
|
void DrawFacesCM ( float* viewmat, int a, int b );
|
||||||
|
void DrawEdgesCM ( float* viewmat, int a, int b );
|
||||||
|
|
||||||
|
MFormat GetMeshBufs ( char& v, char& e, char& f ) { v = m_Vbuf; e = m_Ebuf; f = m_Fbuf; return m_Mform; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MFormat m_Mform; // Mesh format
|
||||||
|
char m_Vbuf;
|
||||||
|
char m_Ebuf;
|
||||||
|
char m_Fbuf;
|
||||||
|
|
||||||
|
int m_CurrF;
|
||||||
|
|
||||||
|
std::vector< PlyElement* > m_Ply;
|
||||||
|
//File m_File;
|
||||||
|
int m_PlyCurrElem;
|
||||||
|
|
||||||
|
static bool mbInitStatic;
|
||||||
|
|
||||||
|
Vector3DF mT;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
97
Extras/sph/common/mesh_info.h
Normal file
97
Extras/sph/common/mesh_info.h
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 DEF_MESH_INFO
|
||||||
|
#define DEF_MESH_INFO
|
||||||
|
|
||||||
|
#include "common_defs.h"
|
||||||
|
//#include "mint_config.h"
|
||||||
|
typedef signed int xref;
|
||||||
|
|
||||||
|
#define MAX_MFORMAT 10
|
||||||
|
#define MAX_BFORMAT 5
|
||||||
|
|
||||||
|
// CM - Connected mesh
|
||||||
|
struct FaceCM {
|
||||||
|
xref e1, e2, e3, e4;
|
||||||
|
xref v1, v2, v3, v4;
|
||||||
|
};
|
||||||
|
struct EdgeCM {
|
||||||
|
xref v1, v2;
|
||||||
|
xref f1, f2;
|
||||||
|
};
|
||||||
|
struct VertCM {
|
||||||
|
hList elist;
|
||||||
|
hList flist;
|
||||||
|
float x, y, z;
|
||||||
|
};
|
||||||
|
// FVF - Face-vertex-face mesh
|
||||||
|
struct FaceFVF {
|
||||||
|
xref v1, v2, v3, v4;
|
||||||
|
};
|
||||||
|
struct VertFVF {
|
||||||
|
hList flist;
|
||||||
|
float x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extra attributes
|
||||||
|
struct AttrPos {
|
||||||
|
float x, y, z;
|
||||||
|
};
|
||||||
|
struct AttrClr {
|
||||||
|
DWORD clr;
|
||||||
|
};
|
||||||
|
struct AttrNorm {
|
||||||
|
float nx, ny, nz;
|
||||||
|
};
|
||||||
|
struct AttrTex {
|
||||||
|
float tu, tv;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MeshInfo {
|
||||||
|
public:
|
||||||
|
enum MFormat { // Mesh format
|
||||||
|
UDef = 0,
|
||||||
|
VV = 1, // Vertex-Vertex
|
||||||
|
FV = 2, // Face-Vertex
|
||||||
|
FVF = 3,
|
||||||
|
WE = 4, // Winged-Edge
|
||||||
|
CM = 5 // Connected-Mesh
|
||||||
|
};
|
||||||
|
enum BFormat { // Buffer format
|
||||||
|
BVert = 0,
|
||||||
|
BEdge = 1,
|
||||||
|
BFace = 2,
|
||||||
|
};
|
||||||
|
enum AFormat { // Extra Attribute formats
|
||||||
|
APos = 0,
|
||||||
|
AClr = 1,
|
||||||
|
ANorm = 2,
|
||||||
|
ATex = 3
|
||||||
|
};
|
||||||
|
static int BufSize ( MFormat m, BFormat b ) { return miBufSize[(int) m][(int) b]; }
|
||||||
|
static int miBufSize [MAX_MFORMAT][MAX_BFORMAT];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
612
Extras/sph/common/mtime.cpp
Normal file
612
Extras/sph/common/mtime.cpp
Normal file
@@ -0,0 +1,612 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "mtime.h"
|
||||||
|
#include "mdebug.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define VS2005
|
||||||
|
#pragma comment ( lib, "winmm.lib" )
|
||||||
|
LARGE_INTEGER m_BaseCount;
|
||||||
|
LARGE_INTEGER m_BaseFreq;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace mint;
|
||||||
|
|
||||||
|
const int Time::m_DaysInMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
|
bool Time::m_Started = false;
|
||||||
|
sjtime m_BaseTime;
|
||||||
|
sjtime m_BaseTicks;
|
||||||
|
|
||||||
|
void mint::start_timing ( sjtime base )
|
||||||
|
{
|
||||||
|
m_BaseTime = base;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
m_BaseTicks = timeGetTime();
|
||||||
|
QueryPerformanceCounter ( &m_BaseCount );
|
||||||
|
QueryPerformanceFrequency ( &m_BaseFreq );
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
m_BaseTicks = ((sjtime) tv.tv_sec * 1000000LL) + (sjtime) tv.tv_usec;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::SetSystemTime ( int accuracy )
|
||||||
|
{
|
||||||
|
switch ( accuracy ) {
|
||||||
|
case ACC_SEC: // 1 second accuracy
|
||||||
|
SetSystemTime ();
|
||||||
|
break;
|
||||||
|
case ACC_MSEC: { // 1 millisecond accuracy
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
m_CurrTime = m_BaseTime + sjtime(timeGetTime() - m_BaseTicks)*MSEC_SCALAR;
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
sjtime t = ((sjtime) tv.tv_sec * 1000000LL) + (sjtime) tv.tv_usec;
|
||||||
|
m_CurrTime = m_BaseTime + ( t - m_BaseTicks) * 1000LL; // 1000LL - converts microseconds to milliseconds
|
||||||
|
#endif
|
||||||
|
} break;
|
||||||
|
case ACC_NSEC: { // 1 nanosecond accuracy
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
LARGE_INTEGER currCount;
|
||||||
|
QueryPerformanceCounter ( &currCount );
|
||||||
|
m_CurrTime = m_BaseTime + sjtime( (double(currCount.QuadPart-m_BaseCount.QuadPart) / m_BaseFreq.QuadPart) * SEC_SCALAR);
|
||||||
|
#else
|
||||||
|
debug.Printf ( "mtime", "ERROR: ACC_NSEC NOT IMPLEMENTED for Time::SetSystemTime\n" );
|
||||||
|
#endif
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Time::Time ()
|
||||||
|
{
|
||||||
|
if ( !m_Started ) {
|
||||||
|
m_Started = true;
|
||||||
|
SetSystemTime (); // Get base time from wall clock
|
||||||
|
start_timing ( m_CurrTime ); // Start timing from base time
|
||||||
|
}
|
||||||
|
m_CurrTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note regarding hours:
|
||||||
|
// 0 <= hr <= 23
|
||||||
|
// hr = 0 is midnight (12 am)
|
||||||
|
// hr = 1 is 1 am
|
||||||
|
// hr = 12 is noon
|
||||||
|
// hr = 13 is 1 pm (subtract 12)
|
||||||
|
// hr = 23 is 11 pm (subtact 12)
|
||||||
|
|
||||||
|
// GetScaledJulianTime
|
||||||
|
// Returns -1.0 if the time specified is invalid.
|
||||||
|
sjtime Time::GetScaledJulianTime ( int hr, int min, int m, int d, int y, int s, int ms, int ns )
|
||||||
|
{
|
||||||
|
double MJD; // Modified Julian Date (JD - 2400000.5)
|
||||||
|
sjtime SJT; // Scaled Julian Time SJT = MJD * 86400000 + UT
|
||||||
|
|
||||||
|
// Check if date/time is valid
|
||||||
|
if (m <=0 || m > 12) return (sjtime) -1;
|
||||||
|
if ( y % 4 == 0 && m == 2) { // leap year in february
|
||||||
|
if (d <=0 || d > m_DaysInMonth[m]+1) return (sjtime) -1;
|
||||||
|
} else {
|
||||||
|
if (d <=0 || d > m_DaysInMonth[m]) return (sjtime) -1;
|
||||||
|
}
|
||||||
|
if (hr < 0 || hr > 23) return (sjtime) -1;
|
||||||
|
if (min < 0 || min > 59) return (sjtime) -1;
|
||||||
|
|
||||||
|
// Compute Modified Julian Date
|
||||||
|
MJD = 367 * y - int ( 7 * (y + int (( m + 9)/12)) / 4 );
|
||||||
|
MJD -= int ( 3 * (int((y + (m - 9)/7)/100) + 1) / 4);
|
||||||
|
MJD += int ( 275 * m / 9 ) + d + 1721028.5 - 1.0;
|
||||||
|
MJD -= 2400000.5;
|
||||||
|
// Compute Scaled Julian Time
|
||||||
|
SJT = sjtime(MJD) * sjtime( DAY_SCALAR );
|
||||||
|
SJT += hr * HR_SCALAR + min * MIN_SCALAR + s * SEC_SCALAR + ms * MSEC_SCALAR + ns * NSEC_SCALAR;
|
||||||
|
return SJT;
|
||||||
|
}
|
||||||
|
|
||||||
|
sjtime Time::GetScaledJulianTime ( int hr, int min, int m, int d, int y )
|
||||||
|
{
|
||||||
|
return GetScaledJulianTime ( hr, min, m, d, y, 0, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::GetTime ( sjtime SJT, int& hr, int& min, int& m, int& d, int& y)
|
||||||
|
{
|
||||||
|
int s = 0, ms = 0, ns = 0;
|
||||||
|
GetTime ( SJT, hr, min, m, d, y, s, ms, ns );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::GetTime ( sjtime SJT, int& hr, int& min, int& m, int& d, int& y, int& s, int &ms, int& ns)
|
||||||
|
{
|
||||||
|
// Compute Universal Time from SJT
|
||||||
|
sjtime UT = sjtime( SJT % sjtime( DAY_SCALAR ) );
|
||||||
|
|
||||||
|
// Compute Modified Julian Date from SJT
|
||||||
|
double MJD = double(SJT / DAY_SCALAR);
|
||||||
|
|
||||||
|
// Use MJD to get Month, Day, Year
|
||||||
|
double z = floor ( MJD + 1 + 2400000.5 - 1721118.5);
|
||||||
|
double g = z - 0.25;
|
||||||
|
double a = floor ( g / 36524.25 );
|
||||||
|
double b = a - floor ( a / 4.0 );
|
||||||
|
y = int( floor (( b + g ) / 365.25 ) );
|
||||||
|
double c = b + z - floor ( 365.25 * y );
|
||||||
|
m = int (( 5 * c + 456) / 153 );
|
||||||
|
d = int( c - int (( 153 * m - 457) / 5) );
|
||||||
|
if (m > 12) {
|
||||||
|
y++;
|
||||||
|
m -= 12;
|
||||||
|
}
|
||||||
|
// Use UT to get Hrs, Mins, Secs, Msecs
|
||||||
|
hr = int( UT / HR_SCALAR );
|
||||||
|
UT -= hr * HR_SCALAR;
|
||||||
|
min = int( UT / MIN_SCALAR );
|
||||||
|
UT -= min * MIN_SCALAR;
|
||||||
|
s = int ( UT / SEC_SCALAR );
|
||||||
|
UT -= s * SEC_SCALAR;
|
||||||
|
ms = int ( UT / MSEC_SCALAR );
|
||||||
|
UT -= ms * MSEC_SCALAR;
|
||||||
|
ns = int ( UT / NSEC_SCALAR );
|
||||||
|
|
||||||
|
// UT Example:
|
||||||
|
// MSEC_SCALAR = 1
|
||||||
|
// SEC_SCALAR = 1,000
|
||||||
|
// MIN_SCALAR = 60,000
|
||||||
|
// HR_SCALAR = 3,600,000
|
||||||
|
// DAY_SCALAR = 86,400,000
|
||||||
|
//
|
||||||
|
// 7:14:03, 32 msec
|
||||||
|
// UT = 7*3,600,000 + 14*60,000 + 3*1,000 + 32 = 26,043,032
|
||||||
|
//
|
||||||
|
// 26,043,032 / 3,600,000 = 7 26,043,032 - (7 * 3,600,000) = 843,032
|
||||||
|
// 843,032 / 60,000 = 14 843,032 - (14 * 60,000) = 3,032
|
||||||
|
// 3,032 / 1,000 = 3 3,032 - (3 * 1,000) = 32
|
||||||
|
// 32 / 1 = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::GetTime (int& s, int& ms, int& ns )
|
||||||
|
{
|
||||||
|
int hr, min, m, d, y;
|
||||||
|
GetTime ( m_CurrTime, hr, min, m, d, y, s, ms, ns );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Time::GetTime (int& hr, int& min, int& m, int& d, int& y)
|
||||||
|
{
|
||||||
|
GetTime ( m_CurrTime, hr, min, m, d, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::GetTime (int& hr, int& min, int& m, int& d, int& y, int& s, int& ms, int& ns)
|
||||||
|
{
|
||||||
|
GetTime ( m_CurrTime, hr, min, m, d, y, s, ms, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::SetTime ( int sec )
|
||||||
|
{
|
||||||
|
int hr, min, m, d, y;
|
||||||
|
GetTime ( m_CurrTime, hr, min, m, d, y );
|
||||||
|
m_CurrTime = GetScaledJulianTime ( hr, min, m, d, y, sec, 0, 0 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::SetTime ( int sec, int msec )
|
||||||
|
{
|
||||||
|
int hr, min, m, d, y;
|
||||||
|
GetTime ( m_CurrTime, hr, min, m, d, y );
|
||||||
|
m_CurrTime = GetScaledJulianTime ( hr, min, m, d, y, sec, msec, 0 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::SetTime (int hr, int min, int m, int d, int y)
|
||||||
|
{
|
||||||
|
int s, ms, ns;
|
||||||
|
GetTime ( s, ms, ns );
|
||||||
|
m_CurrTime = GetScaledJulianTime ( hr, min, m, d, y, s, ms, ns );
|
||||||
|
if (m_CurrTime == -1.0) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::SetTime (int hr, int min, int m, int d, int y, int s, int ms, int ns)
|
||||||
|
{
|
||||||
|
m_CurrTime = GetScaledJulianTime ( hr, min, m, d, y, s, ms, ns );
|
||||||
|
if (m_CurrTime == -1.0) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::SetTime ( std::string line )
|
||||||
|
{
|
||||||
|
int hr, min, m, d, y;
|
||||||
|
std::string dat;
|
||||||
|
if ( line.substr ( 0, 1 ) == " " )
|
||||||
|
dat = line.substr ( 1, line.length()-1 ).c_str();
|
||||||
|
else
|
||||||
|
dat = line;
|
||||||
|
|
||||||
|
hr = atoi ( dat.substr ( 0, 2).c_str() );
|
||||||
|
min = atoi ( dat.substr ( 3, 2).c_str() );
|
||||||
|
m = atoi ( dat.substr ( 6, 2).c_str () );
|
||||||
|
d = atoi ( dat.substr ( 9, 2).c_str () );
|
||||||
|
y = atoi ( dat.substr ( 12, 4).c_str () );
|
||||||
|
return SetTime ( hr, min, m, d, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::SetDate ( std::string line )
|
||||||
|
{
|
||||||
|
int hr, min, m, d, y;
|
||||||
|
std::string dat;
|
||||||
|
if ( line.substr ( 0, 1 ) == " " )
|
||||||
|
dat = line.substr ( 1, line.length()-1 ).c_str();
|
||||||
|
else
|
||||||
|
dat = line;
|
||||||
|
|
||||||
|
hr = 0;
|
||||||
|
min = 0;
|
||||||
|
m = atoi ( dat.substr ( 0, 2).c_str () );
|
||||||
|
d = atoi ( dat.substr ( 3, 2).c_str () );
|
||||||
|
y = atoi ( dat.substr ( 6, 4).c_str () );
|
||||||
|
return SetTime ( hr, min, m, d, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Time::GetDayOfWeekName ()
|
||||||
|
{
|
||||||
|
switch (GetDayOfWeek()) {
|
||||||
|
case 1: return "Sunday"; break;
|
||||||
|
case 2: return "Monday"; break;
|
||||||
|
case 3: return "Tuesday"; break;
|
||||||
|
case 4: return "Wednesday"; break;
|
||||||
|
case 5: return "Thursday"; break;
|
||||||
|
case 6: return "Friday"; break;
|
||||||
|
case 7: return "Saturday"; break;
|
||||||
|
}
|
||||||
|
return "day error";
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetDayOfWeek ()
|
||||||
|
{
|
||||||
|
// Compute Modified Julian Date
|
||||||
|
double MJD = (double) m_CurrTime / sjtime( DAY_SCALAR );
|
||||||
|
|
||||||
|
// Compute Julian Date
|
||||||
|
double JD = floor ( MJD + 1 + 2400000.5 );
|
||||||
|
int dow = (int(JD - 0.5) % 7) + 4;
|
||||||
|
if (dow > 7) dow -= 7;
|
||||||
|
|
||||||
|
// day of week (1 = sunday, 7 = saturday)
|
||||||
|
return dow ;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetWeekOfYear ()
|
||||||
|
{
|
||||||
|
int hr, min, m, d, y;
|
||||||
|
GetTime ( hr, min, m, d, y );
|
||||||
|
double mjd_start = (double) GetScaledJulianTime ( 0, 0, 1, 1, y ) / DAY_SCALAR; // mjt for jan 1st of year
|
||||||
|
double mjd_curr = (double) GetScaledJulianTime ( 0, 0, m, d, y ) / DAY_SCALAR; // mjt for specified day in year
|
||||||
|
double JD = floor ( mjd_start + 1 + 2400000.5 );
|
||||||
|
int dow = (int ( JD - 0.5 ) % 7) + 4; // day of week for jan 1st of year.
|
||||||
|
if (dow > 7) dow -= 7;
|
||||||
|
|
||||||
|
// week of year (first week in january = week 0)
|
||||||
|
return int((mjd_curr - mjd_start + dow -1 ) / 7 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetElapsedDays ( Time& base )
|
||||||
|
{
|
||||||
|
return int( sjtime(m_CurrTime - base.GetSJT() ) / sjtime( DAY_SCALAR ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetElapsedWeeks ( Time& base )
|
||||||
|
{
|
||||||
|
return GetElapsedDays(base) / 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetElapsedMonths ( Time& base)
|
||||||
|
{
|
||||||
|
return int ( double(GetElapsedDays(base)) / 30.416 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetElapsedYears ( Time& base )
|
||||||
|
{
|
||||||
|
// It is much easier to compute this in m/d/y format rather
|
||||||
|
// than using julian dates.
|
||||||
|
int bhr, bmin, bm, bd, by;
|
||||||
|
int ehr, emin, em, ed, ey;
|
||||||
|
GetTime ( base.GetSJT(), bhr, bmin, bm, bd, by );
|
||||||
|
GetTime ( m_CurrTime, ehr, emin, em, ed, ey );
|
||||||
|
if ( em < bm) {
|
||||||
|
// earlier month
|
||||||
|
return ey - by - 1;
|
||||||
|
} else if ( em > bm) {
|
||||||
|
// later month
|
||||||
|
return ey - by;
|
||||||
|
} else {
|
||||||
|
// same month
|
||||||
|
if ( ed < bd ) {
|
||||||
|
// earlier day
|
||||||
|
return ey - by - 1;
|
||||||
|
} else if ( ed >= bd ) {
|
||||||
|
// later or same day
|
||||||
|
return ey - by;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetFracDay ( Time& base )
|
||||||
|
{
|
||||||
|
// Resolution = 5-mins
|
||||||
|
return int( sjtime(m_CurrTime - base.GetSJT() ) % sjtime(DAY_SCALAR) ) / (MIN_SCALAR*5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetFracWeek ( Time& base )
|
||||||
|
{
|
||||||
|
// Resolution = 1 hr
|
||||||
|
int day = GetElapsedDays(base) % 7; // day in week
|
||||||
|
int hrs = int( sjtime(m_CurrTime - base.GetSJT() ) % sjtime(DAY_SCALAR) ) / (HR_SCALAR);
|
||||||
|
return day * 24 + hrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetFracMonth ( Time& base )
|
||||||
|
{
|
||||||
|
// Resolution = 4 hrs
|
||||||
|
int day = (int) fmod ( double(GetElapsedDays(base)), 30.416 ); // day in month
|
||||||
|
int hrs = int( sjtime(m_CurrTime - base.GetSJT() ) % sjtime(DAY_SCALAR) ) / (HR_SCALAR*4);
|
||||||
|
return day * (24 / 4) + hrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetFracYear ( Time& base )
|
||||||
|
{
|
||||||
|
// It is much easier to compute this in m/d/y format rather
|
||||||
|
// than using julian dates.
|
||||||
|
int bhr, bmin, bm, bd, by;
|
||||||
|
int ehr, emin, em, ed, ey;
|
||||||
|
sjtime LastFullYear;
|
||||||
|
GetTime ( base.GetSJT() , bhr, bmin, bm, bd, by );
|
||||||
|
GetTime ( m_CurrTime, ehr, emin, em, ed, ey );
|
||||||
|
if ( em < bm) {
|
||||||
|
// earlier month
|
||||||
|
LastFullYear = GetScaledJulianTime ( ehr, emin, bm, bd, ey - 1);
|
||||||
|
return int( sjtime(m_CurrTime - LastFullYear) / sjtime(DAY_SCALAR) );
|
||||||
|
} else if ( em > bm) {
|
||||||
|
// later month
|
||||||
|
LastFullYear = GetScaledJulianTime ( ehr, emin, bm, bd, ey);
|
||||||
|
return int( sjtime(m_CurrTime - LastFullYear) / sjtime(DAY_SCALAR) );
|
||||||
|
} else {
|
||||||
|
// same month
|
||||||
|
if ( ed < bd ) {
|
||||||
|
// earlier day
|
||||||
|
LastFullYear = GetScaledJulianTime ( ehr, emin, bm, bd, ey - 1);
|
||||||
|
return int( sjtime(m_CurrTime - LastFullYear) / sjtime(DAY_SCALAR) );
|
||||||
|
} else if ( ed > bd ) {
|
||||||
|
// later day
|
||||||
|
LastFullYear = GetScaledJulianTime ( ehr, emin, bm, bd, ey);
|
||||||
|
return int( sjtime(m_CurrTime - LastFullYear) / sjtime(DAY_SCALAR) );
|
||||||
|
} else {
|
||||||
|
return 0; // same day
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Time::GetReadableDate ()
|
||||||
|
{
|
||||||
|
char buf[200];
|
||||||
|
std::string line;
|
||||||
|
int hr, min, m, d, y;
|
||||||
|
|
||||||
|
GetTime ( hr, min, m, d, y );
|
||||||
|
sprintf ( buf, "%02d:%02d %02d-%02d-%04d", hr, min, m, d, y);
|
||||||
|
return std::string ( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Time::GetReadableTime ()
|
||||||
|
{
|
||||||
|
char buf[200];
|
||||||
|
std::string line;
|
||||||
|
int hr, min, m, d, y, s, ms, ns;
|
||||||
|
|
||||||
|
GetTime ( hr, min, m, d, y, s, ms, ns );
|
||||||
|
sprintf ( buf, "%02d:%02d:%02d %03d.%06d %02d-%02d-%04d", hr, min, s, ms, ns, m, d, y);
|
||||||
|
return std::string ( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Time::GetReadableSJT ()
|
||||||
|
{
|
||||||
|
char buf[200];
|
||||||
|
sprintf ( buf, "%I64d", m_CurrTime );
|
||||||
|
return std::string ( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Time::GetReadableTime ( int fmt )
|
||||||
|
{
|
||||||
|
char buf[200];
|
||||||
|
int hr, min, m, d, y, s, ms, ns;
|
||||||
|
GetTime ( hr, min, m, d, y, s, ms, ns );
|
||||||
|
|
||||||
|
switch (fmt) {
|
||||||
|
case 0: sprintf ( buf, "%02d %03d.%06d", s, ms, ns);
|
||||||
|
}
|
||||||
|
return std::string ( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::SetSystemTime ()
|
||||||
|
{
|
||||||
|
int hr, mn, sec, m, d, y;
|
||||||
|
char timebuf[100];
|
||||||
|
char datebuf[100];
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#ifdef VS2005
|
||||||
|
_strtime_s ( timebuf, 100 );
|
||||||
|
_strdate_s ( datebuf, 100 );
|
||||||
|
#else
|
||||||
|
_strtime ( timebuf );
|
||||||
|
_strdate ( datebuf );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if (defined(__linux__) || defined(__CYGWIN__))
|
||||||
|
time_t tt;
|
||||||
|
struct tm tim;
|
||||||
|
tt = time(NULL);
|
||||||
|
localtime_r(&tt, &tim);
|
||||||
|
sprintf( timebuf, "%02i:%02i:%02i", tim.tm_hour, tim.tm_min, tim.tm_sec);
|
||||||
|
sprintf( datebuf, "%02i:%02i:%02i", tim.tm_mon, tim.tm_mday, tim.tm_year % 100);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
line = timebuf;
|
||||||
|
hr = atoi ( line.substr ( 0, 2).c_str() );
|
||||||
|
mn = atoi ( line.substr ( 3, 2).c_str() );
|
||||||
|
sec = atoi ( line.substr ( 6, 2).c_str() );
|
||||||
|
line = datebuf;
|
||||||
|
m = atoi ( line.substr ( 0, 2).c_str() );
|
||||||
|
d = atoi ( line.substr ( 3, 2).c_str() );
|
||||||
|
y = atoi ( line.substr ( 6, 2).c_str() );
|
||||||
|
|
||||||
|
// NOTE: This only works from 1930 to 2030
|
||||||
|
if ( y > 30) y += 1900;
|
||||||
|
else y += 2000;
|
||||||
|
|
||||||
|
SetTime ( hr, mn, m, d, y, sec, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double Time::GetSec ()
|
||||||
|
{
|
||||||
|
return ((double) m_CurrTime / (double) SEC_SCALAR );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Time::GetMSec ()
|
||||||
|
{
|
||||||
|
return ((double) m_CurrTime / (double) MSEC_SCALAR );
|
||||||
|
|
||||||
|
/*int s, ms, ns;
|
||||||
|
GetTime ( s, ms, ns );
|
||||||
|
return ms;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::Advance ( Time& t )
|
||||||
|
{
|
||||||
|
m_CurrTime += t.GetSJT ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::AdvanceMinutes ( int n)
|
||||||
|
{
|
||||||
|
m_CurrTime += (sjtime) MIN_SCALAR * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::AdvanceHours ( int n )
|
||||||
|
{
|
||||||
|
m_CurrTime += (sjtime) HR_SCALAR * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::AdvanceDays ( int n )
|
||||||
|
{
|
||||||
|
m_CurrTime += (sjtime) DAY_SCALAR * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::AdvanceSec ( int n )
|
||||||
|
{
|
||||||
|
m_CurrTime += (sjtime) SEC_SCALAR * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::AdvanceMins ( int n)
|
||||||
|
{
|
||||||
|
m_CurrTime += (sjtime) MIN_SCALAR * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::AdvanceMSec ( int n )
|
||||||
|
{
|
||||||
|
m_CurrTime += (sjtime) MSEC_SCALAR * n;
|
||||||
|
}
|
||||||
|
|
||||||
|
Time& Time::operator= ( const Time& op ) { m_CurrTime = op.m_CurrTime; return *this; }
|
||||||
|
Time& Time::operator= ( Time& op ) { m_CurrTime = op.m_CurrTime; return *this; }
|
||||||
|
bool Time::operator< ( const Time& op ) { return (m_CurrTime < op.m_CurrTime); }
|
||||||
|
bool Time::operator> ( const Time& op ) { return (m_CurrTime > op.m_CurrTime); }
|
||||||
|
bool Time::operator< ( Time& op ) { return (m_CurrTime < op.m_CurrTime); }
|
||||||
|
bool Time::operator> ( Time& op ) { return (m_CurrTime > op.m_CurrTime); }
|
||||||
|
|
||||||
|
bool Time::operator<= ( const Time& op ) { return (m_CurrTime <= op.m_CurrTime); }
|
||||||
|
bool Time::operator>= ( const Time& op ) { return (m_CurrTime >= op.m_CurrTime); }
|
||||||
|
bool Time::operator<= ( Time& op ) { return (m_CurrTime <= op.m_CurrTime); }
|
||||||
|
bool Time::operator>= ( Time& op ) { return (m_CurrTime >= op.m_CurrTime); }
|
||||||
|
|
||||||
|
Time Time::operator- ( Time& op )
|
||||||
|
{
|
||||||
|
return Time( m_CurrTime - op.GetSJT() );
|
||||||
|
}
|
||||||
|
Time Time::operator+ ( Time& op )
|
||||||
|
{
|
||||||
|
return Time( m_CurrTime + op.GetSJT() );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Time::operator== ( const Time& op )
|
||||||
|
{
|
||||||
|
return (m_CurrTime == op.m_CurrTime);
|
||||||
|
}
|
||||||
|
bool Time::operator!= ( Time& op )
|
||||||
|
{
|
||||||
|
return (m_CurrTime != op.m_CurrTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Time::RegressionTest ()
|
||||||
|
{
|
||||||
|
// This code verifies the Julian Date calculations are correct for all
|
||||||
|
// minutes over a range of years. Useful to debug type issues when
|
||||||
|
// compiling on different platforms.
|
||||||
|
//
|
||||||
|
int m, d, y, hr, min;
|
||||||
|
int cm, cd, cy, chr, cmin;
|
||||||
|
|
||||||
|
for (y=2000; y < 2080; y++) {
|
||||||
|
for (m=1; m <= 12; m++) {
|
||||||
|
for (d=1; d <= 31; d++) {
|
||||||
|
for (hr=0; hr<=23; hr++) {
|
||||||
|
for (min=0; min<=59; min++) {
|
||||||
|
if ( SetTime ( hr, min, m, d, y, 0, 0, 0 ) ) {
|
||||||
|
GetTime ( chr, cmin, cm, cd, cy );
|
||||||
|
if ( hr!=chr || min!=cmin || m!=cm || d!=cd || y!=cy) {
|
||||||
|
// debug.Printf (" time", "Error: %d, %d, %d, %d, %d = %I64d\n", hr, min, m, d, y, GetSJT());
|
||||||
|
// debug.Printf (" time", "-----: %d, %d, %d, %d, %d\n", chr, cmin, cm, cd, cy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// debug.Printf (" time", "Verified: %d\n", y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
234
Extras/sph/common/mtime.h
Normal file
234
Extras/sph/common/mtime.h
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 TIME_HPP
|
||||||
|
#define TIME_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <windows.h>
|
||||||
|
typedef __int64 mstime; // microsecond time = 8 byte integer
|
||||||
|
typedef __int64 sjtime; // scaled julian times = 8 byte integer
|
||||||
|
|
||||||
|
#define MSEC_SCALAR 1000000i64
|
||||||
|
#define SEC_SCALAR 1000000000i64
|
||||||
|
#define MIN_SCALAR 60000000000i64
|
||||||
|
#define HR_SCALAR 3600000000000i64
|
||||||
|
#define DAY_SCALAR 86400000000000i64
|
||||||
|
|
||||||
|
#pragma warning ( disable : 4522 )
|
||||||
|
#pragma warning ( disable : 4996 ) // sprintf warning
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <linux/types.h>
|
||||||
|
typedef __s64 mstime;
|
||||||
|
typedef __s64 sjtime;
|
||||||
|
|
||||||
|
#define MSEC_SCALAR 1000000LL
|
||||||
|
#define SEC_SCALAR 1000000000LL
|
||||||
|
#define MIN_SCALAR 60000000000LL
|
||||||
|
#define HR_SCALAR 3600000000000LL
|
||||||
|
#define DAY_SCALAR 86400000000000LL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#include <largeint.h> // found in \cygwin\usr\include\w32api
|
||||||
|
typedef __int64 mstime;
|
||||||
|
typedef __int64 sjtime;
|
||||||
|
|
||||||
|
#define MSEC_SCALAR 1000000LL
|
||||||
|
#define SEC_SCALAR 1000000000LL
|
||||||
|
#define MIN_SCALAR 60000000000LL
|
||||||
|
#define HR_SCALAR 3600000000000LL
|
||||||
|
#define DAY_SCALAR 86400000000000LL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ACC_SEC 0
|
||||||
|
#define ACC_MSEC 1
|
||||||
|
#define ACC_NSEC 2
|
||||||
|
|
||||||
|
#define NSEC_SCALAR 1
|
||||||
|
|
||||||
|
// Time Class
|
||||||
|
// R. Hoetzlein
|
||||||
|
//
|
||||||
|
// Overview:
|
||||||
|
// There is a need in many systems to represent both very small (nanoseconds) and
|
||||||
|
// very large (millenia) timescales accurately. Modified Julian Date accurate represents
|
||||||
|
// individual days over +/- about 30,000 yrs. However, MJD represents fractions of a day
|
||||||
|
// as a floating point fraction. This is inaccurate for any timing-critical applications.
|
||||||
|
// The Time class here uses an 8-byte (64 bit) integer called SJT, Scaled Julian Time.
|
||||||
|
// SJT = MJD * DAY_SCALAR + UT (nanoseconds).
|
||||||
|
// SJT is the Modified Julian Date scaled by a integer factor, and added to Universal Time
|
||||||
|
// represented in nanoseconds.
|
||||||
|
//
|
||||||
|
// Features:
|
||||||
|
// - Accurately represents individual nanoseconds over +/- 30,000 yrs.
|
||||||
|
// - Correct rollover of tiny time scales on month, day, year boundaries.
|
||||||
|
// e.g. Set date/time to 11:59:59.9999, on Feb 28th,
|
||||||
|
// - Accurately gives day of the week for any date
|
||||||
|
// - Accurately compares two dates (days elapsed) even across leap-years.
|
||||||
|
// - Adjust sec/nsec independently from month/day/year (work at scale you desire)
|
||||||
|
//
|
||||||
|
// Implementation Notes:
|
||||||
|
// JD = Julian Day is the number of days elapsed since Jan 1, 4713 BC in the proleptic Julian calendar.
|
||||||
|
// http://en.wikipedia.org/wiki/Julian_day
|
||||||
|
// MJD = Modified Julian Date. Most modern dates, after 19th c., have Julian Date which are greater
|
||||||
|
// than 2400000.5. MJD is an offset. MJD = JD - 2400000.5
|
||||||
|
// It shifts the epoch date (start date) to Nov 17, 1858.
|
||||||
|
// UT = Universal Time. This is the time of day in hours as measured from Greenwich England.
|
||||||
|
// For non-astronomic uses, this is: UT = Local Time + Time Zone.
|
||||||
|
// SJT = Scaled Julian Time = MJD * DAY_SCALAR + UT (in nanoseconds).
|
||||||
|
//
|
||||||
|
// Julian Dates (and their MJD and SJT equivalents)
|
||||||
|
// ------------
|
||||||
|
// Jan 1, 4713 BC = JD 0 = MJD -2400000 = SJT
|
||||||
|
// Jan 1, 1500 AD = JD 2268933.5 = MJD -131067 = SJT
|
||||||
|
// Nov 16, 1858 AD = JD 2400000.5 = MJD 0 = SJT 0
|
||||||
|
// Jan 1, 1960 AD = JD 2436935.5 = MJD 36935 = SJT 3,191,184,000,000
|
||||||
|
// Jan 1, 2005 AD = JD 2453372.5 = MJD 53372 = SJT 4,611,340,800,000
|
||||||
|
// Jan 1, 2100 AD = JD 2488070.5 = MJD 88070 = SJT 7,609,248,000,000
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 32/64-Bit Integer Ranges
|
||||||
|
// 32-bit Integer Min: <20>2,147,483,648 ( 4 bytes )
|
||||||
|
// 32-bit Integer Max: 2,147,483,647
|
||||||
|
// SJT 2005: 4,611,340,800,000
|
||||||
|
// 64-bit Integer Min: <20>9,223,372,036,854,775,808
|
||||||
|
// 64-bit Integer Max: 9,223,372,036,854,775,807 ( 8 bytes )
|
||||||
|
//
|
||||||
|
// SJT Range
|
||||||
|
// ---------
|
||||||
|
// * USING DAY_SCALAR = 86,400,000 (millisec accuracy)
|
||||||
|
// SJT Range = (+/-9,223,372,036,854,775,807 SJT / 86,400,000 DAY_SCALAR)
|
||||||
|
// SJT Range (in Julian Days) = +2400000.5 + (+/-106,751,991,167 MJD)
|
||||||
|
// SJT Range (in Julian Days) = +/- 292278883 years, with 1 millisecond accuracy.
|
||||||
|
//
|
||||||
|
// * USING DAY_SCALAR = 86,400,000,000,000 (nanosec accuracy)
|
||||||
|
// SJT Range = (+/-9,223,372,036,854,775,807 SJT / 86,400,000,000,000 DAY_SCALAR)
|
||||||
|
// SJT Range (in Julian Days) = +2400000.5 + (+/-106,751 MJD)
|
||||||
|
// SJT Range (in Julian Days) = 1566 AD to 2151 AD, with 1 nanosecond accuracy.
|
||||||
|
|
||||||
|
namespace mint {
|
||||||
|
|
||||||
|
class Time {
|
||||||
|
public:
|
||||||
|
Time ();
|
||||||
|
Time ( sjtime t ) { m_CurrTime = t; }
|
||||||
|
Time ( int sec, int msec ) { m_CurrTime = 0; SetTime ( sec, msec ); }
|
||||||
|
|
||||||
|
// Set time
|
||||||
|
bool SetTime ( int sec ); // Set seconds
|
||||||
|
bool SetTime ( int sec, int msec ); // Set seconds, msecs
|
||||||
|
bool SetTime ( int hr, int min, int m, int d, int y); // Set hr/min, month, day, year
|
||||||
|
bool SetTime ( int hr, int min, int m, int d, int y, int s, int ms, int ns); // Set hr/min, month, day, year, sec, ms, ns
|
||||||
|
bool SetTime ( Time& t ) { m_CurrTime = t.GetSJT(); return true;} // Set to another Time object
|
||||||
|
bool SetTime ( std::string line ); // Set time from string (hr,min,sec)
|
||||||
|
bool SetDate ( std::string line ); // Set date from string (mo,day,yr)
|
||||||
|
void SetSystemTime (); // Set date/time to system clock
|
||||||
|
void SetSystemTime ( int accuracy ); // Set date/time to system clock
|
||||||
|
void SetSJT ( sjtime t ) { m_CurrTime = t ;} // Set Scaled Julian Time directly
|
||||||
|
|
||||||
|
// Get time
|
||||||
|
void GetTime (int& sec, int& msec, int& nsec );
|
||||||
|
void GetTime (int& hr, int& min, int& m, int& d, int& y);
|
||||||
|
void GetTime (int& hr, int& min, int& m, int& d, int& y, int& s, int& ms, int& ns);
|
||||||
|
double GetSec ();
|
||||||
|
int GetMSec ();
|
||||||
|
std::string GetReadableDate ();
|
||||||
|
std::string GetReadableTime ();
|
||||||
|
std::string GetReadableTime ( int fmt );
|
||||||
|
std::string GetReadableSJT ();
|
||||||
|
std::string GetDayOfWeekName ();
|
||||||
|
sjtime GetSJT () { return m_CurrTime; }
|
||||||
|
|
||||||
|
// Advance Time
|
||||||
|
void Advance ( Time& t );
|
||||||
|
void AdvanceMinutes ( int n);
|
||||||
|
void AdvanceHours ( int n );
|
||||||
|
void AdvanceDays ( int n );
|
||||||
|
void AdvanceSec ( int n );
|
||||||
|
void AdvanceMins ( int n);
|
||||||
|
void AdvanceMSec ( int n );
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
// (these do the actual work, but should not be private as they may be useful to user)
|
||||||
|
sjtime GetScaledJulianTime ( int hr, int min, int m, int d, int y );
|
||||||
|
sjtime GetScaledJulianTime ( int hr, int min, int m, int d, int y, int s, int ms, int ns );
|
||||||
|
void GetTime ( sjtime t, int& hr, int& min, int& m, int& d, int& y);
|
||||||
|
void GetTime ( sjtime t, int& hr, int& min, int& m, int& d, int& y, int& s, int& ms, int& ns);
|
||||||
|
|
||||||
|
// Get/Set Julian Date and Modified Julain Date
|
||||||
|
void SetJD ( double jd );
|
||||||
|
void SetMJD ( int jd );
|
||||||
|
double GetJD ();
|
||||||
|
int GetMJD ();
|
||||||
|
|
||||||
|
// Time operators
|
||||||
|
Time& operator= ( const Time& op );
|
||||||
|
Time& operator= ( Time& op );
|
||||||
|
bool operator< ( const Time& op );
|
||||||
|
bool operator< ( Time& op );
|
||||||
|
bool operator> ( const Time& op );
|
||||||
|
bool operator> ( Time& op );
|
||||||
|
bool operator<= ( const Time& op );
|
||||||
|
bool operator<= ( Time& op );
|
||||||
|
bool operator>= ( const Time& op );
|
||||||
|
bool operator>= ( Time& op );
|
||||||
|
bool operator== ( const Time& op );
|
||||||
|
bool operator!= ( Time& op );
|
||||||
|
Time operator- ( Time& op );
|
||||||
|
Time operator+ ( Time& op );
|
||||||
|
|
||||||
|
// Elapsed Times
|
||||||
|
int GetElapsedDays ( Time& base );
|
||||||
|
int GetElapsedWeeks ( Time& base );
|
||||||
|
int GetElapsedMonths ( Time& base );
|
||||||
|
int GetElapsedYears ( Time& base );
|
||||||
|
int GetFracDay ( Time& base ); // Return Unit = 5 mins
|
||||||
|
int GetFracWeek ( Time& base ); // Return Unit = 1 hr
|
||||||
|
int GetFracMonth ( Time& base ); // Return Unit = 4 hrs
|
||||||
|
int GetFracYear ( Time& base ); // Return Unit = 1 day
|
||||||
|
int GetDayOfWeek ();
|
||||||
|
int GetWeekOfYear ();
|
||||||
|
|
||||||
|
void RegressionTest ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int m_DaysInMonth[13];
|
||||||
|
static bool m_Started;
|
||||||
|
|
||||||
|
sjtime m_CurrTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used for precise system time (Win32)
|
||||||
|
void start_timing ( sjtime base );
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
23
Extras/sph/common/particle.cpp
Normal file
23
Extras/sph/common/particle.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "particle.h"
|
||||||
29
Extras/sph/common/particle.h
Normal file
29
Extras/sph/common/particle.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 DEF_PARTICLE
|
||||||
|
#define DEF_PARTICLE
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
539
Extras/sph/common/point_set.cpp
Normal file
539
Extras/sph/common/point_set.cpp
Normal file
@@ -0,0 +1,539 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gl_helper.h"
|
||||||
|
|
||||||
|
#include "point_set.h"
|
||||||
|
|
||||||
|
int PointSet::m_pcurr = -1;
|
||||||
|
|
||||||
|
PointSet::PointSet ()
|
||||||
|
{
|
||||||
|
m_GridRes.Set ( 0, 0, 0 );
|
||||||
|
m_pcurr = -1;
|
||||||
|
Reset ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int PointSet::GetGridCell ( int x, int y, int z )
|
||||||
|
{
|
||||||
|
return (int) ( (z*m_GridRes.y + y)*m_GridRes.x + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point* PointSet::firstGridParticle ( int gc, int& p )
|
||||||
|
{
|
||||||
|
m_pcurr = m_Grid [ gc ];
|
||||||
|
if ( m_pcurr == -1 ) return 0x0;
|
||||||
|
p = m_pcurr;
|
||||||
|
return (Point*) (mBuf[0].data + m_pcurr * mBuf[0].stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point* PointSet::nextGridParticle ( int& p )
|
||||||
|
{
|
||||||
|
Point* pnt = 0x0;
|
||||||
|
if ( m_pcurr != -1 ) {
|
||||||
|
pnt = (Point*) (mBuf[0].data + m_pcurr * mBuf[0].stride);
|
||||||
|
p = m_pcurr;
|
||||||
|
m_pcurr = pnt->next;
|
||||||
|
}
|
||||||
|
return pnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short* PointSet::getNeighborTable ( int n, int& cnt )
|
||||||
|
{
|
||||||
|
cnt = m_NC[n];
|
||||||
|
if ( cnt == 0 ) return 0x0;
|
||||||
|
return &m_Neighbor[n][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
float PointSet::GetValue ( float x, float y, float z )
|
||||||
|
{
|
||||||
|
float dx, dy, dz, dsq;
|
||||||
|
float sum;
|
||||||
|
int pndx;
|
||||||
|
Point* pcurr;
|
||||||
|
float R2 = 1.8*1.8;
|
||||||
|
|
||||||
|
Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 );
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
sum = 0.0;
|
||||||
|
for (int cell=0; cell < 8; cell++ ) {
|
||||||
|
if ( m_GridCell[cell] != -1 ) {
|
||||||
|
pndx = m_Grid [ m_GridCell[cell] ];
|
||||||
|
while ( pndx != -1 ) {
|
||||||
|
pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride);
|
||||||
|
dx = x - pcurr->pos.x;
|
||||||
|
dy = y - pcurr->pos.y;
|
||||||
|
dz = z - pcurr->pos.z;
|
||||||
|
dsq = dx*dx+dy*dy+dz*dz;
|
||||||
|
if ( dsq < R2 ) sum += R2 / dsq;
|
||||||
|
pndx = pcurr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
Vector3DF PointSet::GetGradient ( float x, float y, float z )
|
||||||
|
{
|
||||||
|
Vector3DF norm;
|
||||||
|
float dx, dy, dz, dsq;
|
||||||
|
float sum;
|
||||||
|
int pndx;
|
||||||
|
Point* pcurr;
|
||||||
|
float R2 = (m_GridCellsize/2.0)*(m_GridCellsize/2.0);
|
||||||
|
|
||||||
|
Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 );
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
sum = 0.0;
|
||||||
|
norm.Set (0,0,0);
|
||||||
|
for (int cell=0; cell < 8; cell++ ) {
|
||||||
|
if ( m_GridCell[cell] != -1 ) {
|
||||||
|
pndx = m_Grid [ m_GridCell[cell] ];
|
||||||
|
while ( pndx != -1 ) {
|
||||||
|
pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride);
|
||||||
|
dx = x - pcurr->pos.x;
|
||||||
|
dy = y - pcurr->pos.y;
|
||||||
|
dz = z - pcurr->pos.z;
|
||||||
|
dsq = dx*dx+dy*dy+dz*dz;
|
||||||
|
if ( dsq > 0 && dsq < R2 ) {
|
||||||
|
dsq = 2.0*R2 / (dsq*dsq);
|
||||||
|
norm.x += dx * dsq;
|
||||||
|
norm.y += dy * dsq;
|
||||||
|
norm.z += dz * dsq;
|
||||||
|
}
|
||||||
|
pndx = pcurr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
norm.Normalize ();
|
||||||
|
return norm;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD PointSet::GetColor ( float x, float y, float z )
|
||||||
|
{
|
||||||
|
Vector3DF clr;
|
||||||
|
float dx, dy, dz, dsq;
|
||||||
|
float sum;
|
||||||
|
int pndx;
|
||||||
|
Point* pcurr;
|
||||||
|
float R2 = (m_GridCellsize/2.0)*(m_GridCellsize/2.0);
|
||||||
|
|
||||||
|
Grid_FindCells ( Vector3DF(x,y,z), m_GridCellsize/2.0 );
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
sum = 0.0;
|
||||||
|
clr.Set (0,0,0);
|
||||||
|
for (int cell=0; cell < 8; cell++ ) {
|
||||||
|
if ( m_GridCell[cell] != -1 ) {
|
||||||
|
pndx = m_Grid [ m_GridCell[cell] ];
|
||||||
|
while ( pndx != -1 ) {
|
||||||
|
pcurr = (Point*) (mBuf[0].data + pndx*mBuf[0].stride);
|
||||||
|
dx = x - pcurr->pos.x;
|
||||||
|
dy = y - pcurr->pos.y;
|
||||||
|
dz = z - pcurr->pos.z;
|
||||||
|
dsq = dx*dx+dy*dy+dz*dz;
|
||||||
|
if ( dsq < R2 ) {
|
||||||
|
dsq = 2.0*R2 / (dsq*dsq);
|
||||||
|
clr.x += RED(pcurr->clr) * dsq;
|
||||||
|
clr.y += GRN(pcurr->clr) * dsq;
|
||||||
|
clr.z += BLUE(pcurr->clr) * dsq;
|
||||||
|
}
|
||||||
|
pndx = pcurr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clr.Normalize ();
|
||||||
|
return COLORA(clr.x, clr.y, clr.z, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::Reset ()
|
||||||
|
{
|
||||||
|
// Reset number of particles
|
||||||
|
// ResetBuffer ( 0 );
|
||||||
|
|
||||||
|
m_Time = 0;
|
||||||
|
m_DT = 0.1;
|
||||||
|
m_Param[POINT_GRAV] = 100.0;
|
||||||
|
m_Param[PLANE_GRAV] = 0.0;
|
||||||
|
|
||||||
|
m_Vec[ POINT_GRAV_POS].Set(0,0,50.0);
|
||||||
|
m_Vec[ PLANE_GRAV_DIR].Set(0,0,-9.8);
|
||||||
|
m_Vec[ EMIT_RATE ].Set ( 1, 10, 0 );
|
||||||
|
m_Vec[ EMIT_POS ].Set ( 50, 0, 35 );
|
||||||
|
m_Vec[ EMIT_ANG ].Set ( 90, 45, 50.0 );
|
||||||
|
m_Vec[ EMIT_DANG ].Set ( 0, 0, 0 );
|
||||||
|
m_Vec[ EMIT_SPREAD ].Set ( 4, 4, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::Initialize ( int mode, int total )
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case BPOINT: {
|
||||||
|
FreeBuffers ();
|
||||||
|
AddBuffer ( BPOINT, sizeof ( Point ), total );
|
||||||
|
AddAttribute ( 0, "pos", sizeof ( Vector3DF ), false );
|
||||||
|
AddAttribute ( 0, "color", sizeof ( DWORD ), false );
|
||||||
|
Reset ();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case BPARTICLE: {
|
||||||
|
FreeBuffers ();
|
||||||
|
AddBuffer ( BPARTICLE, sizeof ( Particle ), total );
|
||||||
|
AddAttribute ( 0, "pos", sizeof ( Vector3DF ), false );
|
||||||
|
AddAttribute ( 0, "color", sizeof ( DWORD ), false );
|
||||||
|
AddAttribute ( 0, "vel", sizeof ( Vector3DF ), false );
|
||||||
|
AddAttribute ( 0, "ndx", sizeof ( unsigned short ), false );
|
||||||
|
AddAttribute ( 0, "age", sizeof ( unsigned short ), false );
|
||||||
|
Reset ();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int PointSet::AddPoint ()
|
||||||
|
{
|
||||||
|
xref ndx;
|
||||||
|
AddElem ( 0, ndx );
|
||||||
|
return ndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PointSet::AddPointReuse ()
|
||||||
|
{
|
||||||
|
xref ndx;
|
||||||
|
if ( NumPoints() < mBuf[0].max-1 )
|
||||||
|
AddElem ( 0, ndx );
|
||||||
|
else
|
||||||
|
RandomElem ( 0, ndx );
|
||||||
|
return ndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::AddVolume ( Vector3DF min, Vector3DF max, float spacing )
|
||||||
|
{
|
||||||
|
Vector3DF pos;
|
||||||
|
Point* p;
|
||||||
|
float dx, dy, dz;
|
||||||
|
dx = max.x-min.x;
|
||||||
|
dy = max.y-min.y;
|
||||||
|
dz = max.z-min.z;
|
||||||
|
for (float z = max.z; z >= min.z; z -= spacing ) {
|
||||||
|
for (float y = min.y; y <= max.y; y += spacing ) {
|
||||||
|
for (float x = min.x; x <= max.x; x += spacing ) {
|
||||||
|
p = GetPoint ( AddPointReuse () );
|
||||||
|
pos.Set ( x, y, z);
|
||||||
|
//pos.x += -0.05 + float( rand() * 0.1 ) / RAND_MAX;
|
||||||
|
//pos.y += -0.05 + float( rand() * 0.1 ) / RAND_MAX;
|
||||||
|
//pos.z += -0.05 + float( rand() * 0.1 ) / RAND_MAX;
|
||||||
|
p->pos = pos;
|
||||||
|
p->clr = COLORA( (x-min.x)/dx, (y-min.y)/dy, (z-min.z)/dz, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::Draw ( float* view_mat, float rad )
|
||||||
|
{
|
||||||
|
char* dat;
|
||||||
|
Point* p;
|
||||||
|
glEnable ( GL_NORMALIZE );
|
||||||
|
|
||||||
|
if ( m_Param[PNT_DRAWMODE] == 0 ) {
|
||||||
|
glLoadMatrixf ( view_mat );
|
||||||
|
dat = mBuf[0].data;
|
||||||
|
for (int n = 0; n < NumPoints(); n++) {
|
||||||
|
p = (Point*) dat;
|
||||||
|
glPushMatrix ();
|
||||||
|
glTranslatef ( p->pos.x, p->pos.y, p->pos.z );
|
||||||
|
glScalef ( 0.2, 0.2, 0.2 );
|
||||||
|
glColor4f ( RED(p->clr), GRN(p->clr), BLUE(p->clr), ALPH(p->clr) );
|
||||||
|
drawSphere ();
|
||||||
|
glPopMatrix ();
|
||||||
|
dat += mBuf[0].stride;
|
||||||
|
}
|
||||||
|
} else if ( m_Param[PNT_DRAWMODE] == 1 ) {
|
||||||
|
glLoadMatrixf ( view_mat );
|
||||||
|
dat = mBuf[0].data;
|
||||||
|
glBegin ( GL_POINTS );
|
||||||
|
for (int n=0; n < NumPoints(); n++) {
|
||||||
|
p = (Point*) dat;
|
||||||
|
glColor3f ( RED(p->clr), GRN(p->clr), BLUE(p->clr) );
|
||||||
|
glVertex3f ( p->pos.x, p->pos.y, p->pos.z );
|
||||||
|
dat += mBuf[0].stride;
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::Emit ( float spacing )
|
||||||
|
{
|
||||||
|
Particle* p;
|
||||||
|
Vector3DF dir;
|
||||||
|
Vector3DF pos;
|
||||||
|
float ang_rand, tilt_rand;
|
||||||
|
float rnd = m_Vec[EMIT_RATE].y * 0.15;
|
||||||
|
int x = (int) sqrt(m_Vec[EMIT_RATE].y);
|
||||||
|
|
||||||
|
for ( int n = 0; n < m_Vec[EMIT_RATE].y; n++ ) {
|
||||||
|
ang_rand = (float(rand()*2.0/RAND_MAX) - 1.0) * m_Vec[EMIT_SPREAD].x;
|
||||||
|
tilt_rand = (float(rand()*2.0/RAND_MAX) - 1.0) * m_Vec[EMIT_SPREAD].y;
|
||||||
|
dir.x = cos ( ( m_Vec[EMIT_ANG].x + ang_rand) * DEGtoRAD ) * sin( ( m_Vec[EMIT_ANG].y + tilt_rand) * DEGtoRAD ) * m_Vec[EMIT_ANG].z;
|
||||||
|
dir.y = sin ( ( m_Vec[EMIT_ANG].x + ang_rand) * DEGtoRAD ) * sin( ( m_Vec[EMIT_ANG].y + tilt_rand) * DEGtoRAD ) * m_Vec[EMIT_ANG].z;
|
||||||
|
dir.z = cos ( ( m_Vec[EMIT_ANG].y + tilt_rand) * DEGtoRAD ) * m_Vec[EMIT_ANG].z;
|
||||||
|
pos = m_Vec[EMIT_POS];
|
||||||
|
pos.x += spacing * (n/x);
|
||||||
|
pos.y += spacing * (n%x);
|
||||||
|
|
||||||
|
p = (Particle*) GetElem( 0, AddPointReuse () );
|
||||||
|
p->pos = pos;
|
||||||
|
p->vel = dir;
|
||||||
|
p->vel_eval = dir;
|
||||||
|
p->age = 0;
|
||||||
|
p->clr = COLORA ( m_Time/10.0, m_Time/5.0, m_Time /4.0, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PointSet::Run ()
|
||||||
|
{
|
||||||
|
if ( m_Vec[EMIT_RATE].x > 0 && ++m_Frame >= (int) m_Vec[EMIT_RATE].x ) {
|
||||||
|
m_Frame = 0;
|
||||||
|
Emit ( 1.0 );
|
||||||
|
}
|
||||||
|
Advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::Advance ()
|
||||||
|
{
|
||||||
|
char* dat;
|
||||||
|
Particle* p;
|
||||||
|
Vector3DF vnext, accel, norm;
|
||||||
|
|
||||||
|
vnext = m_Vec[EMIT_DANG];
|
||||||
|
vnext *= m_DT;
|
||||||
|
m_Vec[EMIT_ANG] += vnext;
|
||||||
|
|
||||||
|
dat = mBuf[0].data;
|
||||||
|
for ( int c = 0; c < NumPoints(); c++ ) {
|
||||||
|
p = (Particle*) dat;
|
||||||
|
|
||||||
|
accel.Set (0, 0, 0);
|
||||||
|
|
||||||
|
// Plane gravity
|
||||||
|
if ( m_Param[PLANE_GRAV] > 0)
|
||||||
|
accel += m_Vec[PLANE_GRAV_DIR];
|
||||||
|
|
||||||
|
// Point gravity
|
||||||
|
if ( m_Param[POINT_GRAV] > 0 ) {
|
||||||
|
norm.x = ( p->pos.x - m_Vec[POINT_GRAV_POS].x );
|
||||||
|
norm.y = ( p->pos.y - m_Vec[POINT_GRAV_POS].y );
|
||||||
|
norm.z = ( p->pos.z - m_Vec[POINT_GRAV_POS].z );
|
||||||
|
norm.Normalize ();
|
||||||
|
norm *= m_Param[POINT_GRAV];
|
||||||
|
accel -= norm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leapfrog Integration ----------------------------
|
||||||
|
vnext = accel;
|
||||||
|
vnext *= m_DT;
|
||||||
|
vnext += p->vel; // v(t+1/2) = v(t-1/2) + a(t) dt
|
||||||
|
p->vel_eval = p->vel;
|
||||||
|
p->vel_eval += vnext;
|
||||||
|
p->vel_eval *= 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later
|
||||||
|
p->vel = vnext;
|
||||||
|
vnext *= m_DT;
|
||||||
|
p->pos += vnext; // p(t+1) = p(t) + v(t+1/2) dt
|
||||||
|
|
||||||
|
// Euler integration -------------------------------
|
||||||
|
// accel += m_Gravity;
|
||||||
|
// accel *= m_DT;
|
||||||
|
// mParticles[c].vel += accel; // v(t+1) = v(t) + a(t) dt
|
||||||
|
// mParticles[c].vel_eval += accel;
|
||||||
|
// mParticles[c].vel_eval *= m_DT/d;
|
||||||
|
// mParticles[c].pos += mParticles[c].vel_eval;
|
||||||
|
// mParticles[c].vel_eval = mParticles[c].vel;
|
||||||
|
|
||||||
|
dat += mBuf[0].stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Time += m_DT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ideal grid cell size (gs) = 2 * smoothing radius = 0.02*2 = 0.04
|
||||||
|
// Ideal domain size = k*gs/d = k*0.02*2/0.005 = k*8 = {8, 16, 24, 32, 40, 48, ..}
|
||||||
|
// (k = number of cells, gs = cell size, d = simulation scale)
|
||||||
|
void PointSet::Grid_Setup ( Vector3DF min, Vector3DF max, float sim_scale, float cell_size, float border )
|
||||||
|
{
|
||||||
|
float world_cellsize = cell_size / sim_scale;
|
||||||
|
m_Grid.clear ();
|
||||||
|
m_GridMin = min; m_GridMin -= border;
|
||||||
|
m_GridMax = max; m_GridMax += border;
|
||||||
|
m_GridSize = m_GridMax;
|
||||||
|
m_GridSize -= m_GridMin;
|
||||||
|
m_GridCellsize = world_cellsize;
|
||||||
|
m_GridRes.x = ceil ( m_GridSize.x / world_cellsize ); // Determine grid resolution
|
||||||
|
m_GridRes.y = ceil ( m_GridSize.y / world_cellsize );
|
||||||
|
m_GridRes.z = ceil ( m_GridSize.z / world_cellsize );
|
||||||
|
m_GridSize.x = m_GridRes.x * cell_size / sim_scale; // Adjust grid size to multiple of cell size
|
||||||
|
m_GridSize.y = m_GridRes.y * cell_size / sim_scale;
|
||||||
|
m_GridSize.z = m_GridRes.z * cell_size / sim_scale;
|
||||||
|
m_GridDelta = m_GridRes; // delta = translate from world space to cell #
|
||||||
|
m_GridDelta /= m_GridSize;
|
||||||
|
m_GridTotal = (int)(m_GridSize.x * m_GridSize.y * m_GridSize.z);
|
||||||
|
|
||||||
|
m_Grid.clear ();
|
||||||
|
m_GridCnt.clear ();
|
||||||
|
|
||||||
|
m_Grid.reserve ( m_GridTotal );
|
||||||
|
m_GridCnt.reserve ( m_GridTotal );
|
||||||
|
for (int n=0; n < m_GridTotal; n++) {
|
||||||
|
m_Grid.push_back ( -1 );
|
||||||
|
m_GridCnt.push_back ( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::Grid_Draw ( float* view_mat )
|
||||||
|
{
|
||||||
|
float clr;
|
||||||
|
int cx, cy, cz;
|
||||||
|
float x1, y1, z1;
|
||||||
|
float x2, y2, z2;
|
||||||
|
int g = 0;
|
||||||
|
|
||||||
|
glLoadMatrixf ( view_mat );
|
||||||
|
glColor3f ( 0.7, 0.7, 0.7 );
|
||||||
|
|
||||||
|
glBegin ( GL_LINES );
|
||||||
|
|
||||||
|
cz = 0;
|
||||||
|
//for ( cz = 0; cz < m_GridRes.z; cz++ ) {
|
||||||
|
for ( cy = 0; cy < m_GridRes.y; cy++ ) {
|
||||||
|
for ( cx = 0; cx < m_GridRes.x; cx++ ) {
|
||||||
|
// Cell is not empty. Process it.
|
||||||
|
//if ( m_Grid[g] != 0x0 ) {
|
||||||
|
// clr = m_GridCnt[g]/30.0;
|
||||||
|
clr = 0.25;
|
||||||
|
if ( clr <0.25) clr =0.25;
|
||||||
|
if ( clr >1) clr =1 ;
|
||||||
|
glColor3f ( clr, clr, clr );
|
||||||
|
x1 = (cx * m_GridDelta.x) + m_GridMin.x; x2 = ((cx+1) * m_GridDelta.x) + m_GridMin.x;
|
||||||
|
y1 = (cy * m_GridDelta.y) + m_GridMin.y; y2 = ((cy+1) * m_GridDelta.y) + m_GridMin.y;
|
||||||
|
z1 = (cz * m_GridDelta.z) + m_GridMin.z; z2 = ((cz+1) * m_GridDelta.z) + m_GridMin.z;
|
||||||
|
glVertex3f ( x1, y1, z1 ); glVertex3f ( x2, y1, z1 );
|
||||||
|
glVertex3f ( x2, y1, z1 ); glVertex3f ( x2, y2, z1 );
|
||||||
|
glVertex3f ( x2, y2, z1 ); glVertex3f ( x1, y2, z1 );
|
||||||
|
glVertex3f ( x1, y2, z1 ); glVertex3f ( x1, y1, z1 );
|
||||||
|
glVertex3f ( x1, y1, z2 ); glVertex3f ( x2, y1, z2 );
|
||||||
|
glVertex3f ( x2, y1, z2 ); glVertex3f ( x2, y2, z2 );
|
||||||
|
glVertex3f ( x2, y2, z2 ); glVertex3f ( x1, y2, z2 );
|
||||||
|
glVertex3f ( x1, y2, z2 ); glVertex3f ( x1, y1, z2 );
|
||||||
|
glVertex3f ( x1, y1, z1 ); glVertex3f ( x1, y1, z2 );
|
||||||
|
glVertex3f ( x1, y2, z1 ); glVertex3f ( x1, y2, z2 );
|
||||||
|
glVertex3f ( x2, y2, z1 ); glVertex3f ( x2, y2, z2 );
|
||||||
|
glVertex3f ( x2, y1, z1 ); glVertex3f ( x2, y1, z2 );
|
||||||
|
//}
|
||||||
|
g++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::Grid_InsertParticles ()
|
||||||
|
{
|
||||||
|
char *dat1, *dat1_end;
|
||||||
|
Point *p;
|
||||||
|
int gs;
|
||||||
|
int gx, gy, gz;
|
||||||
|
|
||||||
|
dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride )
|
||||||
|
((Point*) dat1)->next = -1;
|
||||||
|
|
||||||
|
for (int n=0; n < m_GridTotal; n++) {
|
||||||
|
m_Grid[n] = -1;
|
||||||
|
m_GridCnt[n] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
int n = 0;
|
||||||
|
for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
|
||||||
|
p = (Point*) dat1;
|
||||||
|
gx = (int)( (p->pos.x - m_GridMin.x) * m_GridDelta.x); // Determine grid cell
|
||||||
|
gy = (int)( (p->pos.y - m_GridMin.y) * m_GridDelta.y);
|
||||||
|
gz = (int)( (p->pos.z - m_GridMin.z) * m_GridDelta.z);
|
||||||
|
gs = (int)( (gz*m_GridRes.y + gy)*m_GridRes.x + gx);
|
||||||
|
if ( gs >= 0 && gs < m_GridTotal ) {
|
||||||
|
p->next = m_Grid[gs];
|
||||||
|
m_Grid[gs] = n;
|
||||||
|
m_GridCnt[gs]++;
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PointSet::Grid_FindCell ( Vector3DF p )
|
||||||
|
{
|
||||||
|
int gc;
|
||||||
|
Vector3DI cell;
|
||||||
|
cell.x = (int) (p.x - m_GridMin.x) * m_GridDelta.x;
|
||||||
|
cell.y = (int) (p.y - m_GridMin.y) * m_GridDelta.y;
|
||||||
|
cell.z = (int) (p.z - m_GridMin.z) * m_GridDelta.z;
|
||||||
|
gc = (int)( (cell.z*m_GridRes.y + cell.y)*m_GridRes.x + cell.x);
|
||||||
|
if ( gc < 0 || gc > m_GridTotal ) return -1;
|
||||||
|
return gc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointSet::Grid_FindCells ( Vector3DF p, float radius )
|
||||||
|
{
|
||||||
|
Vector3DI sph_min;
|
||||||
|
|
||||||
|
// Compute sphere range
|
||||||
|
sph_min.x = (int)((-radius + p.x - m_GridMin.x) * m_GridDelta.x);
|
||||||
|
sph_min.y = (int)((-radius + p.y - m_GridMin.y) * m_GridDelta.y);
|
||||||
|
sph_min.z = (int)((-radius + p.z - m_GridMin.z) * m_GridDelta.z);
|
||||||
|
if ( sph_min.x < 0 ) sph_min.x = 0;
|
||||||
|
if ( sph_min.y < 0 ) sph_min.y = 0;
|
||||||
|
if ( sph_min.z < 0 ) sph_min.z = 0;
|
||||||
|
|
||||||
|
m_GridCell[0] = (int)((sph_min.z * m_GridRes.y + sph_min.y) * m_GridRes.x + sph_min.x);
|
||||||
|
m_GridCell[1] = m_GridCell[0] + 1;
|
||||||
|
m_GridCell[2] = (int)(m_GridCell[0] + m_GridRes.x);
|
||||||
|
m_GridCell[3] = m_GridCell[2] + 1;
|
||||||
|
|
||||||
|
if ( sph_min.z+1 < m_GridRes.z ) {
|
||||||
|
m_GridCell[4] = (int)(m_GridCell[0] + m_GridRes.y*m_GridRes.x);
|
||||||
|
m_GridCell[5] = m_GridCell[4] + 1;
|
||||||
|
m_GridCell[6] = (int)(m_GridCell[4] + m_GridRes.x);
|
||||||
|
m_GridCell[7] = m_GridCell[6] + 1;
|
||||||
|
}
|
||||||
|
if ( sph_min.x+1 >= m_GridRes.x ) {
|
||||||
|
m_GridCell[1] = -1; m_GridCell[3] = -1;
|
||||||
|
m_GridCell[5] = -1; m_GridCell[7] = -1;
|
||||||
|
}
|
||||||
|
if ( sph_min.y+1 >= m_GridRes.y ) {
|
||||||
|
m_GridCell[2] = -1; m_GridCell[3] = -1;
|
||||||
|
m_GridCell[6] = -1; m_GridCell[7] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
165
Extras/sph/common/point_set.h
Normal file
165
Extras/sph/common/point_set.h
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 DEF_POINT_SET
|
||||||
|
#define DEF_POINT_SET
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "common_defs.h"
|
||||||
|
#include "geomx.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
typedef signed int xref;
|
||||||
|
|
||||||
|
#define MAX_NEIGHBOR 80
|
||||||
|
|
||||||
|
#define MAX_PARAM 21
|
||||||
|
|
||||||
|
// Scalar params
|
||||||
|
#define PNT_DRAWMODE 0
|
||||||
|
#define PNT_SPHERE 0
|
||||||
|
#define PNT_POINT 1
|
||||||
|
#define PNT_DRAWSIZE 1
|
||||||
|
#define POINT_GRAV 2
|
||||||
|
#define PLANE_GRAV 3
|
||||||
|
|
||||||
|
// Vector params
|
||||||
|
#define EMIT_POS 0
|
||||||
|
#define EMIT_ANG 1
|
||||||
|
#define EMIT_DANG 2
|
||||||
|
#define EMIT_SPREAD 3
|
||||||
|
#define EMIT_RATE 4
|
||||||
|
#define POINT_GRAV_POS 5
|
||||||
|
#define PLANE_GRAV_DIR 6
|
||||||
|
|
||||||
|
|
||||||
|
#define BPOINT 0
|
||||||
|
#define BPARTICLE 1
|
||||||
|
|
||||||
|
struct Point {
|
||||||
|
Vector3DF pos;
|
||||||
|
DWORD clr;
|
||||||
|
int next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Particle {
|
||||||
|
Vector3DF pos;
|
||||||
|
DWORD clr;
|
||||||
|
int next;
|
||||||
|
Vector3DF vel;
|
||||||
|
Vector3DF vel_eval;
|
||||||
|
unsigned short age;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PointSet : public GeomX {
|
||||||
|
public:
|
||||||
|
PointSet ();
|
||||||
|
|
||||||
|
// Point Sets
|
||||||
|
|
||||||
|
virtual void Initialize ( int mode, int max );
|
||||||
|
virtual void Draw ( float* view_mat, float rad );
|
||||||
|
virtual void Reset ();
|
||||||
|
virtual int AddPoint ();
|
||||||
|
virtual int AddPointReuse ();
|
||||||
|
Point* GetPoint ( int n ) { return (Point*) GetElem(0, n); }
|
||||||
|
int NumPoints () { return NumElem(0); }
|
||||||
|
|
||||||
|
// Metablobs
|
||||||
|
virtual float GetValue ( float x, float y, float z );
|
||||||
|
virtual Vector3DF GetGradient ( float x, float y, float z );
|
||||||
|
// virtual float GetValue ( float x, float y, float z, Vector3DF& dir );
|
||||||
|
virtual DWORD GetColor ( float x, float y, float z );
|
||||||
|
|
||||||
|
// Particle system
|
||||||
|
virtual void Run ();
|
||||||
|
virtual void Advance ();
|
||||||
|
virtual void Emit ( float spacing );
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
virtual void AddVolume ( Vector3DF min, Vector3DF max, float spacing );
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
void SetParam (int p, float v ) { m_Param[p] = v; }
|
||||||
|
void SetParam (int p, int v ) { m_Param[p] = (float) v; }
|
||||||
|
float GetParam ( int p ) { return (float) m_Param[p]; }
|
||||||
|
Vector3DF GetVec ( int p ) { return m_Vec[p]; }
|
||||||
|
void SetVec ( int p, Vector3DF v ) { m_Vec[p] = v; }
|
||||||
|
void Toggle ( int p ) { m_Toggle[p] = !m_Toggle[p]; }
|
||||||
|
bool GetToggle ( int p ) { return m_Toggle[p]; }
|
||||||
|
|
||||||
|
float GetDT() { return (float) m_DT; }
|
||||||
|
|
||||||
|
// Spatial Subdivision
|
||||||
|
void Grid_Setup ( Vector3DF min, Vector3DF max, float sim_scale, float cell_size, float border );
|
||||||
|
void Grid_Create ();
|
||||||
|
void Grid_InsertParticles ();
|
||||||
|
void Grid_Draw ( float* view_mat );
|
||||||
|
void Grid_FindCells ( Vector3DF p, float radius );
|
||||||
|
int Grid_FindCell ( Vector3DF p );
|
||||||
|
Vector3DF GetGridRes () { return m_GridRes; }
|
||||||
|
Vector3DF GetGridMin () { return m_GridMin; }
|
||||||
|
Vector3DF GetGridMax () { return m_GridMax; }
|
||||||
|
Vector3DF GetGridDelta () { return m_GridDelta; }
|
||||||
|
int GetGridCell ( int x, int y, int z );
|
||||||
|
Point* firstGridParticle ( int gc, int& p );
|
||||||
|
Point* nextGridParticle ( int& p );
|
||||||
|
unsigned short* getNeighborTable ( int n, int& cnt );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_Frame;
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
double m_Param [ MAX_PARAM ]; // see defines above
|
||||||
|
Vector3DF m_Vec [ MAX_PARAM ];
|
||||||
|
bool m_Toggle [ MAX_PARAM ];
|
||||||
|
|
||||||
|
// Particle System
|
||||||
|
double m_DT;
|
||||||
|
double m_Time;
|
||||||
|
|
||||||
|
// Spatial Grid
|
||||||
|
std::vector< int > m_Grid;
|
||||||
|
std::vector< int > m_GridCnt;
|
||||||
|
int m_GridTotal; // total # cells
|
||||||
|
Vector3DF m_GridMin; // volume of grid (may not match domain volume exactly)
|
||||||
|
Vector3DF m_GridMax;
|
||||||
|
Vector3DF m_GridRes; // resolution in each axis
|
||||||
|
Vector3DF m_GridSize; // physical size in each axis
|
||||||
|
Vector3DF m_GridDelta;
|
||||||
|
float m_GridCellsize;
|
||||||
|
int m_GridCell[27];
|
||||||
|
|
||||||
|
// Neighbor Table
|
||||||
|
unsigned short m_NC[65536]; // neighbor table (600k)
|
||||||
|
unsigned short m_Neighbor[65536][MAX_NEIGHBOR];
|
||||||
|
float m_NDist[65536][MAX_NEIGHBOR];
|
||||||
|
|
||||||
|
static int m_pcurr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
782
Extras/sph/common/vector-inline.h
Normal file
782
Extras/sph/common/vector-inline.h
Normal file
@@ -0,0 +1,782 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
// Vector Operations Implemented:
|
||||||
|
// =, +, -, *, / (on vectors and scalars)
|
||||||
|
// Cross Cross product vector with op
|
||||||
|
// Dot Dot product vector with op
|
||||||
|
// Dist (op) Distance from vector to op
|
||||||
|
// DistSq Distance^2 from vector to op
|
||||||
|
// Length () Length of vector
|
||||||
|
// Normalize () Normalizes vector
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
// Vector2DC Code Definition
|
||||||
|
|
||||||
|
#define VTYPE unsigned char
|
||||||
|
#define VNAME 2DC
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector2DC::Vector2DC() {x=0; y=0;}
|
||||||
|
inline Vector2DC::~Vector2DC() {}
|
||||||
|
inline Vector2DC::Vector2DC (VTYPE xa, VTYPE ya) {x=xa; y=ya;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
inline double Vector2DC::Dot(Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DC::Dot(Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DC::Dot(Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
|
||||||
|
inline double Vector2DC::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::DistSq (Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x = (VTYPE) (((double) x*255)/n);
|
||||||
|
y = (VTYPE) (((double) y*255)/n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector2DC::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector2DC::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector2DC::Y(void) {return y;}
|
||||||
|
inline VTYPE Vector2DC::Z(void) {return 0;}
|
||||||
|
inline VTYPE Vector2DC::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector2DC::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector2DC::Y(void) const {return y;}
|
||||||
|
inline const VTYPE Vector2DC::Z(void) const {return 0;}
|
||||||
|
inline const VTYPE Vector2DC::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector2DC::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector2DI Code Definition
|
||||||
|
|
||||||
|
#define VNAME 2DI
|
||||||
|
#define VTYPE int
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector2DI::Vector2DI() {x=0; y=0;}
|
||||||
|
inline Vector2DI::~Vector2DI() {}
|
||||||
|
inline Vector2DI::Vector2DI (VTYPE xa, VTYPE ya) {x=xa; y=ya;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
inline double Vector2DI::Dot(Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DI::Dot(Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DI::Dot(Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
|
||||||
|
inline double Vector2DI::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::DistSq (Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x = (VTYPE) (((double) x*255)/n);
|
||||||
|
y = (VTYPE) (((double) y*255)/n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector2DI::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector2DI::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector2DI::Y(void) {return y;}
|
||||||
|
inline VTYPE Vector2DI::Z(void) {return 0;}
|
||||||
|
inline VTYPE Vector2DI::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector2DI::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector2DI::Y(void) const {return y;}
|
||||||
|
inline const VTYPE Vector2DI::Z(void) const {return 0;}
|
||||||
|
inline const VTYPE Vector2DI::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector2DI::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector2DF Code Definition
|
||||||
|
|
||||||
|
#define VNAME 2DF
|
||||||
|
#define VTYPE double
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector2DF::Vector2DF() {x=0; y=0;}
|
||||||
|
inline Vector2DF::~Vector2DF() {}
|
||||||
|
inline Vector2DF::Vector2DF (const VTYPE xa, const VTYPE ya) {x=xa; y=ya;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
inline double Vector2DF::Dot(const Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DF::Dot(const Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DF::Dot(const Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
|
||||||
|
inline double Vector2DF::Dist (const Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::DistSq (const Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x /= n;
|
||||||
|
y /= n;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector2DF::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector2DF::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector2DF::Y(void) {return y;}
|
||||||
|
inline VTYPE Vector2DF::Z(void) {return 0;}
|
||||||
|
inline VTYPE Vector2DF::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector2DF::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector2DF::Y(void) const {return y;}
|
||||||
|
inline const VTYPE Vector2DF::Z(void) const {return 0;}
|
||||||
|
inline const VTYPE Vector2DF::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector2DF::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector3DC Code Definition
|
||||||
|
|
||||||
|
#define VNAME 3DC
|
||||||
|
#define VTYPE unsigned char
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DC::Vector3DC() {x=0; y=0; z=0;}
|
||||||
|
inline Vector3DC::~Vector3DC() {}
|
||||||
|
inline Vector3DC::Vector3DC (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DC &Vector3DC::Set (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::Cross (Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::Cross (Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::Cross (Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
|
||||||
|
inline double Vector3DC::Dot(Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DC::Dot(Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DC::Dot(Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
|
||||||
|
inline double Vector3DC::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::DistSq (Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y + (double) z*z;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x = (VTYPE) (((double) x*255)/n);
|
||||||
|
y = (VTYPE) (((double) y*255)/n);
|
||||||
|
z = (VTYPE) (((double) z*255)/n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector3DC::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector3DC::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector3DC::Y(void) {return y;}
|
||||||
|
inline VTYPE &Vector3DC::Z(void) {return z;}
|
||||||
|
inline VTYPE Vector3DC::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector3DC::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector3DC::Y(void) const {return y;}
|
||||||
|
inline const VTYPE &Vector3DC::Z(void) const {return z;}
|
||||||
|
inline const VTYPE Vector3DC::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector3DC::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector3DI Code Definition
|
||||||
|
|
||||||
|
#define VNAME 3DI
|
||||||
|
#define VTYPE int
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DI::Vector3DI() {x=0; y=0; z=0;}
|
||||||
|
inline Vector3DI::~Vector3DI() {}
|
||||||
|
inline Vector3DI::Vector3DI (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
|
||||||
|
// Set Functions
|
||||||
|
inline Vector3DI &Vector3DI::Set (const int xa, const int ya, const int za)
|
||||||
|
{
|
||||||
|
x = xa; y = ya; z = za;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::Cross (Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::Cross (Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::Cross (Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
|
||||||
|
inline double Vector3DI::Dot(Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DI::Dot(Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DI::Dot(Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
|
||||||
|
inline double Vector3DI::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::DistSq (Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y + (double) z*z;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x = (VTYPE) (((double) x*255)/n);
|
||||||
|
y = (VTYPE) (((double) y*255)/n);
|
||||||
|
z = (VTYPE) (((double) z*255)/n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector3DI::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector3DI::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector3DI::Y(void) {return y;}
|
||||||
|
inline VTYPE &Vector3DI::Z(void) {return z;}
|
||||||
|
inline VTYPE Vector3DI::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector3DI::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector3DI::Y(void) const {return y;}
|
||||||
|
inline const VTYPE &Vector3DI::Z(void) const {return z;}
|
||||||
|
inline const VTYPE Vector3DI::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector3DI::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector3DF Code Definition
|
||||||
|
|
||||||
|
#define VNAME 3DF
|
||||||
|
#define VTYPE double
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DF::Vector3DF() {x=0; y=0; z=0;}
|
||||||
|
inline Vector3DF::~Vector3DF() {}
|
||||||
|
inline Vector3DF::Vector3DF (const VTYPE xa, const VTYPE ya, const VTYPE za) {x=xa; y=ya; z=za;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
|
||||||
|
// Set Functions
|
||||||
|
inline Vector3DF &Vector3DF::Set (const double xa, const double ya, const double za)
|
||||||
|
{
|
||||||
|
x = xa; y = ya; z = za;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const int op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const double op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const int op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const double op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const int op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const double op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const int op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const double op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const int op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const double op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::Cross (const Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::Cross (const Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::Cross (const Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
|
||||||
|
inline double Vector3DF::Dot(const Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DF::Dot(const Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DF::Dot(const Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
|
||||||
|
inline double Vector3DF::Dist (const Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::DistSq (const Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y + (double) z*z;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x /= n; y /= n; z /= n;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector3DF::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector3DF::X() {return x;}
|
||||||
|
inline VTYPE &Vector3DF::Y() {return y;}
|
||||||
|
inline VTYPE &Vector3DF::Z() {return z;}
|
||||||
|
inline VTYPE Vector3DF::W() {return 0;}
|
||||||
|
inline const VTYPE &Vector3DF::X() const {return x;}
|
||||||
|
inline const VTYPE &Vector3DF::Y() const {return y;}
|
||||||
|
inline const VTYPE &Vector3DF::Z() const {return z;}
|
||||||
|
inline const VTYPE Vector3DF::W() const {return 0;}
|
||||||
|
inline VTYPE *Vector3DF::Data () {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector4DF Code Definition
|
||||||
|
|
||||||
|
#define VNAME 4DF
|
||||||
|
#define VTYPE double
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector4DF::Vector4DF() {x=0; y=0; z=0; w=0;}
|
||||||
|
inline Vector4DF::~Vector4DF() {}
|
||||||
|
inline Vector4DF::Vector4DF (VTYPE xa, VTYPE ya, VTYPE za, VTYPE wa) {x=xa; y=ya; z=za; w=wa;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) op.w;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector4DF &Vector4DF::operator= (int op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; w = (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (double op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; w = (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (int op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; w += (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (double op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; w += (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; w+=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (int op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; w -= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (double op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; w -= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; w-=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (int op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; w *= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (double op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; w *= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; w*=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (int op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; w /= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (double op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; w /= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; w/=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::Cross (Vector4DF &v) {double ax = x, ay = y, az = z, aw = w; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); w = (VTYPE) 0; return *this;}
|
||||||
|
|
||||||
|
inline double Vector4DF::Dot(Vector4DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z + (double) w*v.w; return dot;}
|
||||||
|
|
||||||
|
inline double Vector4DF::Dist (Vector4DF &v) {double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
|
||||||
|
inline double Vector4DF::DistSq (Vector4DF &v) {double a,b,c,d; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; d = (double) w - (double) v.w; return (a*a + b*b + c*c + d*d);}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y + (double) z*z + (double) w*w;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x /= n; y /= n; z /= n; w /= n;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector4DF::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z + (double) w*w; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector4DF::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector4DF::Y(void) {return y;}
|
||||||
|
inline VTYPE &Vector4DF::Z(void) {return z;}
|
||||||
|
inline VTYPE &Vector4DF::W(void) {return w;}
|
||||||
|
inline const VTYPE &Vector4DF::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector4DF::Y(void) const {return y;}
|
||||||
|
inline const VTYPE &Vector4DF::Z(void) const {return z;}
|
||||||
|
inline const VTYPE &Vector4DF::W(void) const {return w;}
|
||||||
|
inline VTYPE *Vector4DF::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
761
Extras/sph/common/vector.cci
Normal file
761
Extras/sph/common/vector.cci
Normal file
@@ -0,0 +1,761 @@
|
|||||||
|
// Vector Operations Implemented:
|
||||||
|
// =, +, -, *, / (on vectors and scalars)
|
||||||
|
// Cross Cross product vector with op
|
||||||
|
// Dot Dot product vector with op
|
||||||
|
// Dist (op) Distance from vector to op
|
||||||
|
// DistSq Distance^2 from vector to op
|
||||||
|
// Length () Length of vector
|
||||||
|
// Normalize () Normalizes vector
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// Vector2DC Code Definition
|
||||||
|
|
||||||
|
#define VTYPE unsigned char
|
||||||
|
#define VNAME 2DC
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector2DC::Vector2DC() {x=0; y=0;}
|
||||||
|
inline Vector2DC::~Vector2DC() {}
|
||||||
|
inline Vector2DC::Vector2DC (VTYPE xa, VTYPE ya) {x=xa; y=ya;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DC::Vector2DC (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DC &Vector2DC::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
inline double Vector2DC::Dot(Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DC::Dot(Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DC::Dot(Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
|
||||||
|
inline double Vector2DC::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DC::DistSq (Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DC::DistSq (Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
|
||||||
|
inline Vector2DC &Vector2DC::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x = (VTYPE) (((double) x*255)/n);
|
||||||
|
y = (VTYPE) (((double) y*255)/n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector2DC::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector2DC::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector2DC::Y(void) {return y;}
|
||||||
|
inline VTYPE Vector2DC::Z(void) {return 0;}
|
||||||
|
inline VTYPE Vector2DC::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector2DC::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector2DC::Y(void) const {return y;}
|
||||||
|
inline const VTYPE Vector2DC::Z(void) const {return 0;}
|
||||||
|
inline const VTYPE Vector2DC::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector2DC::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector2DI Code Definition
|
||||||
|
|
||||||
|
#define VNAME 2DI
|
||||||
|
#define VTYPE int
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector2DI::Vector2DI() {x=0; y=0;}
|
||||||
|
inline Vector2DI::~Vector2DI() {}
|
||||||
|
inline Vector2DI::Vector2DI (VTYPE xa, VTYPE ya) {x=xa; y=ya;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DI::Vector2DI (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DI &Vector2DI::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
inline double Vector2DI::Dot(Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DI::Dot(Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DI::Dot(Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
|
||||||
|
inline double Vector2DI::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DI::DistSq (Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DI::DistSq (Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
|
||||||
|
inline Vector2DI &Vector2DI::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x = (VTYPE) (((double) x*255)/n);
|
||||||
|
y = (VTYPE) (((double) y*255)/n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector2DI::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector2DI::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector2DI::Y(void) {return y;}
|
||||||
|
inline VTYPE Vector2DI::Z(void) {return 0;}
|
||||||
|
inline VTYPE Vector2DI::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector2DI::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector2DI::Y(void) const {return y;}
|
||||||
|
inline const VTYPE Vector2DI::Z(void) const {return 0;}
|
||||||
|
inline const VTYPE Vector2DI::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector2DI::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector2DF Code Definition
|
||||||
|
|
||||||
|
#define VNAME 2DF
|
||||||
|
#define VTYPE double
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector2DF::Vector2DF() {x=0; y=0;}
|
||||||
|
inline Vector2DF::~Vector2DF() {}
|
||||||
|
inline Vector2DF::Vector2DF (const VTYPE xa, const VTYPE ya) {x=xa; y=ya;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
inline Vector2DF::Vector2DF (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator= (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator+= (const Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator-= (const Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator*= (const Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector2DF &Vector2DF::operator/= (const Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
inline double Vector2DF::Dot(const Vector2DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DF::Dot(const Vector2DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
inline double Vector2DF::Dot(const Vector2DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y; return dot;}
|
||||||
|
|
||||||
|
inline double Vector2DF::Dist (const Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::Dist (const Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector2DF::DistSq (const Vector2DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector2DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector2DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector3DC &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector3DI &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector3DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
inline double Vector2DF::DistSq (const Vector4DF &v) { double a,b; a = (double) x - (double) v.x; b = (double) y - (double) v.y; return (a*a + b*b);}
|
||||||
|
|
||||||
|
inline Vector2DF &Vector2DF::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x /= n;
|
||||||
|
y /= n;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector2DF::Length (void) { double n; n = (double) x*x + (double) y*y; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector2DF::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector2DF::Y(void) {return y;}
|
||||||
|
inline VTYPE Vector2DF::Z(void) {return 0;}
|
||||||
|
inline VTYPE Vector2DF::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector2DF::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector2DF::Y(void) const {return y;}
|
||||||
|
inline const VTYPE Vector2DF::Z(void) const {return 0;}
|
||||||
|
inline const VTYPE Vector2DF::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector2DF::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector3DC Code Definition
|
||||||
|
|
||||||
|
#define VNAME 3DC
|
||||||
|
#define VTYPE unsigned char
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DC::Vector3DC() {x=0; y=0; z=0;}
|
||||||
|
inline Vector3DC::~Vector3DC() {}
|
||||||
|
inline Vector3DC::Vector3DC (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DC::Vector3DC (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DC &Vector3DC::Set (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::Cross (Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::Cross (Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DC &Vector3DC::Cross (Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
|
||||||
|
inline double Vector3DC::Dot(Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DC::Dot(Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DC::Dot(Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
|
||||||
|
inline double Vector3DC::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DC::DistSq (Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DC::DistSq (Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
|
||||||
|
inline Vector3DC &Vector3DC::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y + (double) z*z;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x = (VTYPE) (((double) x*255)/n);
|
||||||
|
y = (VTYPE) (((double) y*255)/n);
|
||||||
|
z = (VTYPE) (((double) z*255)/n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector3DC::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector3DC::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector3DC::Y(void) {return y;}
|
||||||
|
inline VTYPE &Vector3DC::Z(void) {return z;}
|
||||||
|
inline VTYPE Vector3DC::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector3DC::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector3DC::Y(void) const {return y;}
|
||||||
|
inline const VTYPE &Vector3DC::Z(void) const {return z;}
|
||||||
|
inline const VTYPE Vector3DC::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector3DC::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector3DI Code Definition
|
||||||
|
|
||||||
|
#define VNAME 3DI
|
||||||
|
#define VTYPE int
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DI::Vector3DI() {x=0; y=0; z=0;}
|
||||||
|
inline Vector3DI::~Vector3DI() {}
|
||||||
|
inline Vector3DI::Vector3DI (VTYPE xa, VTYPE ya, VTYPE za) {x=xa; y=ya; z=za;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DI::Vector3DI (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
|
||||||
|
// Set Functions
|
||||||
|
inline Vector3DI &Vector3DI::Set (const int xa, const int ya, const int za)
|
||||||
|
{
|
||||||
|
x = xa; y = ya; z = za;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::Cross (Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::Cross (Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DI &Vector3DI::Cross (Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
|
||||||
|
inline double Vector3DI::Dot(Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DI::Dot(Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DI::Dot(Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
|
||||||
|
inline double Vector3DI::Dist (Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::Dist (Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DI::DistSq (Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DI::DistSq (Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
|
||||||
|
inline Vector3DI &Vector3DI::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y + (double) z*z;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x = (VTYPE) (((double) x*255)/n);
|
||||||
|
y = (VTYPE) (((double) y*255)/n);
|
||||||
|
z = (VTYPE) (((double) z*255)/n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector3DI::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector3DI::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector3DI::Y(void) {return y;}
|
||||||
|
inline VTYPE &Vector3DI::Z(void) {return z;}
|
||||||
|
inline VTYPE Vector3DI::W(void) {return 0;}
|
||||||
|
inline const VTYPE &Vector3DI::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector3DI::Y(void) const {return y;}
|
||||||
|
inline const VTYPE &Vector3DI::Z(void) const {return z;}
|
||||||
|
inline const VTYPE Vector3DI::W(void) const {return 0;}
|
||||||
|
inline VTYPE *Vector3DI::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector3DF Code Definition
|
||||||
|
|
||||||
|
#define VNAME 3DF
|
||||||
|
#define VTYPE float
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DF::Vector3DF() {x=0; y=0; z=0;}
|
||||||
|
inline Vector3DF::~Vector3DF() {}
|
||||||
|
inline Vector3DF::Vector3DF (const VTYPE xa, const VTYPE ya, const VTYPE za) {x=xa; y=ya; z=za;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
inline Vector3DF::Vector3DF (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z;}
|
||||||
|
|
||||||
|
// Set Functions
|
||||||
|
inline Vector3DF &Vector3DF::Set (const double xa, const double ya, const double za)
|
||||||
|
{
|
||||||
|
x = (float) xa; y = (float) ya; z = (float) za;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const int op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const double op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator= (const Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const int op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const double op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator+= (const Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const int op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const double op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator-= (const Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const int op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const double op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator*= (const Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const int op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const double op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::operator/= (const Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::Cross (const Vector3DC &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::Cross (const Vector3DI &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
inline Vector3DF &Vector3DF::Cross (const Vector3DF &v) {double ax = x, ay = y, az = z; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); return *this;}
|
||||||
|
|
||||||
|
inline double Vector3DF::Dot(const Vector3DC &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DF::Dot(const Vector3DI &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
inline double Vector3DF::Dot(const Vector3DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z; return dot;}
|
||||||
|
|
||||||
|
inline double Vector3DF::Dist (const Vector2DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector2DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector2DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector3DC &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector3DI &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector3DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::Dist (const Vector4DF &v) { double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
inline double Vector3DF::DistSq (const Vector2DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector2DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector2DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector3DC &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector3DI &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector3DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
inline double Vector3DF::DistSq (const Vector4DF &v) { double a,b,c; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; return (a*a + b*b + c*c);}
|
||||||
|
|
||||||
|
inline Vector3DF &Vector3DF::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y + (double) z*z;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x /= (float) n; y /= (float) n; z /= (float) n;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector3DF::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector3DF::X() {return x;}
|
||||||
|
inline VTYPE &Vector3DF::Y() {return y;}
|
||||||
|
inline VTYPE &Vector3DF::Z() {return z;}
|
||||||
|
inline VTYPE Vector3DF::W() {return 0;}
|
||||||
|
inline const VTYPE &Vector3DF::X() const {return x;}
|
||||||
|
inline const VTYPE &Vector3DF::Y() const {return y;}
|
||||||
|
inline const VTYPE &Vector3DF::Z() const {return z;}
|
||||||
|
inline const VTYPE Vector3DF::W() const {return 0;}
|
||||||
|
inline VTYPE *Vector3DF::Data () {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
|
|
||||||
|
// Vector4DF Code Definition
|
||||||
|
|
||||||
|
#define VNAME 4DF
|
||||||
|
#define VTYPE double
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector4DF::Vector4DF() {x=0; y=0; z=0; w=0;}
|
||||||
|
inline Vector4DF::~Vector4DF() {}
|
||||||
|
inline Vector4DF::Vector4DF (VTYPE xa, VTYPE ya, VTYPE za, VTYPE wa) {x=xa; y=ya; z=za; w=wa;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0;}
|
||||||
|
inline Vector4DF::Vector4DF (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) op.w;}
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector4DF &Vector4DF::operator= (int op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; w = (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (double op) {x= (VTYPE) op; y= (VTYPE) op; z= (VTYPE) op; w = (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector2DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector2DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector2DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) 0; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector3DC &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector3DI &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector3DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) 0; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator= (Vector4DF &op) {x=(VTYPE) op.x; y=(VTYPE) op.y; z=(VTYPE) op.z; w=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (int op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; w += (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (double op) {x+= (VTYPE) op; y+= (VTYPE) op; z+= (VTYPE) op; w += (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector2DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector2DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector2DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector3DC &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector3DI &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector3DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator+= (Vector4DF &op) {x+=(VTYPE) op.x; y+=(VTYPE) op.y; z+=(VTYPE) op.z; w+=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (int op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; w -= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (double op) {x-= (VTYPE) op; y-= (VTYPE) op; z-= (VTYPE) op; w -= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector2DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector2DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector2DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector3DC &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector3DI &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector3DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator-= (Vector4DF &op) {x-=(VTYPE) op.x; y-=(VTYPE) op.y; z-=(VTYPE) op.z; w-=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (int op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; w *= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (double op) {x*= (VTYPE) op; y*= (VTYPE) op; z*= (VTYPE) op; w *= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector2DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector2DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector2DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector3DC &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector3DI &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector3DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator*= (Vector4DF &op) {x*=(VTYPE) op.x; y*=(VTYPE) op.y; z*=(VTYPE) op.z; w*=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (int op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; w /= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (double op) {x/= (VTYPE) op; y/= (VTYPE) op; z/= (VTYPE) op; w /= (VTYPE) op; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector2DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector2DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector2DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector3DC &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector3DI &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector3DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; return *this;}
|
||||||
|
inline Vector4DF &Vector4DF::operator/= (Vector4DF &op) {x/=(VTYPE) op.x; y/=(VTYPE) op.y; z/=(VTYPE) op.z; w/=(VTYPE) op.w; return *this;}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::Cross (Vector4DF &v) {double ax = x, ay = y, az = z, aw = w; x = (VTYPE) (ay * (double) v.z - az * (double) v.y); y = (VTYPE) (-ax * (double) v.z + az * (double) v.x); z = (VTYPE) (ax * (double) v.y - ay * (double) v.x); w = (VTYPE) 0; return *this;}
|
||||||
|
|
||||||
|
inline double Vector4DF::Dot(Vector4DF &v) {double dot; dot = (double) x*v.x + (double) y*v.y + (double) z*v.z + (double) w*v.w; return dot;}
|
||||||
|
|
||||||
|
inline double Vector4DF::Dist (Vector4DF &v) {double distsq = DistSq (v); if (distsq!=0) return sqrt(distsq); return 0.0;}
|
||||||
|
|
||||||
|
inline double Vector4DF::DistSq (Vector4DF &v) {double a,b,c,d; a = (double) x - (double) v.x; b = (double) y - (double) v.y; c = (double) z - (double) v.z; d = (double) w - (double) v.w; return (a*a + b*b + c*c + d*d);}
|
||||||
|
|
||||||
|
inline Vector4DF &Vector4DF::Normalize (void) {
|
||||||
|
double n = (double) x*x + (double) y*y + (double) z*z + (double) w*w;
|
||||||
|
if (n!=0.0) {
|
||||||
|
n = sqrt(n);
|
||||||
|
x /= n; y /= n; z /= n; w /= n;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline double Vector4DF::Length (void) { double n; n = (double) x*x + (double) y*y + (double) z*z + (double) w*w; if (n != 0.0) return sqrt(n); return 0.0; }
|
||||||
|
|
||||||
|
inline VTYPE &Vector4DF::X(void) {return x;}
|
||||||
|
inline VTYPE &Vector4DF::Y(void) {return y;}
|
||||||
|
inline VTYPE &Vector4DF::Z(void) {return z;}
|
||||||
|
inline VTYPE &Vector4DF::W(void) {return w;}
|
||||||
|
inline const VTYPE &Vector4DF::X(void) const {return x;}
|
||||||
|
inline const VTYPE &Vector4DF::Y(void) const {return y;}
|
||||||
|
inline const VTYPE &Vector4DF::Z(void) const {return z;}
|
||||||
|
inline const VTYPE &Vector4DF::W(void) const {return w;}
|
||||||
|
inline VTYPE *Vector4DF::Data (void) {return &x;}
|
||||||
|
|
||||||
|
#undef VTYPE
|
||||||
|
#undef VNAME
|
||||||
70
Extras/sph/common/vector.cpp
Normal file
70
Extras/sph/common/vector.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
|
||||||
|
Vector3DF &Vector3DF::operator*= (const MatrixF &op)
|
||||||
|
{
|
||||||
|
double *m = op.GetDataF ();
|
||||||
|
double xa, ya, za;
|
||||||
|
xa = x * (*m++); ya = x * (*m++); za = x * (*m++); m++;
|
||||||
|
xa += y * (*m++); ya += y * (*m++); za += y * (*m++); m++;
|
||||||
|
xa += z * (*m++); ya += z * (*m++); za += z * (*m++); m++;
|
||||||
|
xa += (*m++); ya += (*m++); za += (*m++);
|
||||||
|
x = (float) xa; y = (float) ya; z = (float) za;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3DF &Vector3DF::operator*= (const Matrix4F &op)
|
||||||
|
{
|
||||||
|
float xa, ya, za;
|
||||||
|
xa = x * op.data[0] + y * op.data[4] + z * op.data[8] + op.data[12];
|
||||||
|
ya = x * op.data[1] + y * op.data[5] + z * op.data[9] + op.data[13];
|
||||||
|
za = x * op.data[2] + y * op.data[6] + z * op.data[10] + op.data[14];
|
||||||
|
x = xa; y = ya; z = za;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector4DF &Vector4DF::operator*= (const MatrixF &op)
|
||||||
|
{
|
||||||
|
double *m = op.GetDataF ();
|
||||||
|
double xa, ya, za, wa;
|
||||||
|
xa = x * (*m++); ya = x * (*m++); za = x * (*m++); wa = x * (*m++);
|
||||||
|
xa += y * (*m++); ya += y * (*m++); za += y * (*m++); wa += y * (*m++);
|
||||||
|
xa += z * (*m++); ya += z * (*m++); za += z * (*m++); wa += z * (*m++);
|
||||||
|
xa += w * (*m++); ya += w * (*m++); za += w * (*m++); wa += w * (*m++);
|
||||||
|
x = xa; y = ya; z = za; w = wa;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector4DF &Vector4DF::operator*= (const Matrix4F &op)
|
||||||
|
{
|
||||||
|
double xa, ya, za, wa;
|
||||||
|
xa = x * op.data[0] + y * op.data[4] + z * op.data[8] + w * op.data[12];
|
||||||
|
ya = x * op.data[1] + y * op.data[5] + z * op.data[9] + w * op.data[13];
|
||||||
|
za = x * op.data[2] + y * op.data[6] + z * op.data[10] + w * op.data[14];
|
||||||
|
wa = x * op.data[3] + y * op.data[7] + z * op.data[11] + w * op.data[15];
|
||||||
|
x = xa; y = ya; z = za; w = wa;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
785
Extras/sph/common/vector.h
Normal file
785
Extras/sph/common/vector.h
Normal file
@@ -0,0 +1,785 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
// ** NOTES **
|
||||||
|
// Vector code CANNOT be inlined in header file because of dependencies
|
||||||
|
// across vector classes (error generated: "Use of undeclared class..")
|
||||||
|
//
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifndef VECTOR_DEF
|
||||||
|
#define VECTOR_DEF
|
||||||
|
|
||||||
|
//#define VECTOR_INITIALIZE // Initializes vectors
|
||||||
|
|
||||||
|
class Vector2DC; // Forward Referencing
|
||||||
|
class Vector2DI;
|
||||||
|
class Vector2DF;
|
||||||
|
class Vector3DC;
|
||||||
|
class Vector3DI;
|
||||||
|
class Vector3DF;
|
||||||
|
class Vector4DF;
|
||||||
|
class MatrixF;
|
||||||
|
class Matrix4F;
|
||||||
|
|
||||||
|
// Vector2DC Declaration
|
||||||
|
|
||||||
|
#define VNAME 2DC
|
||||||
|
#define VTYPE unsigned char
|
||||||
|
|
||||||
|
class Vector2DC {
|
||||||
|
public:
|
||||||
|
VTYPE x, y;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector2DC();
|
||||||
|
inline ~Vector2DC();
|
||||||
|
inline Vector2DC (VTYPE xa, VTYPE ya);
|
||||||
|
inline Vector2DC (Vector2DC &op);
|
||||||
|
inline Vector2DC (Vector2DI &op);
|
||||||
|
inline Vector2DC (Vector2DF &op);
|
||||||
|
inline Vector2DC (Vector3DC &op);
|
||||||
|
inline Vector2DC (Vector3DI &op);
|
||||||
|
inline Vector2DC (Vector3DF &op);
|
||||||
|
inline Vector2DC (Vector4DF &op);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector2DC &operator= (Vector2DC &op);
|
||||||
|
inline Vector2DC &operator= (Vector2DI &op);
|
||||||
|
inline Vector2DC &operator= (Vector2DF &op);
|
||||||
|
inline Vector2DC &operator= (Vector3DC &op);
|
||||||
|
inline Vector2DC &operator= (Vector3DI &op);
|
||||||
|
inline Vector2DC &operator= (Vector3DF &op);
|
||||||
|
inline Vector2DC &operator= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector2DC &operator+= (Vector2DC &op);
|
||||||
|
inline Vector2DC &operator+= (Vector2DI &op);
|
||||||
|
inline Vector2DC &operator+= (Vector2DF &op);
|
||||||
|
inline Vector2DC &operator+= (Vector3DC &op);
|
||||||
|
inline Vector2DC &operator+= (Vector3DI &op);
|
||||||
|
inline Vector2DC &operator+= (Vector3DF &op);
|
||||||
|
inline Vector2DC &operator+= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector2DC &operator-= (Vector2DC &op);
|
||||||
|
inline Vector2DC &operator-= (Vector2DI &op);
|
||||||
|
inline Vector2DC &operator-= (Vector2DF &op);
|
||||||
|
inline Vector2DC &operator-= (Vector3DC &op);
|
||||||
|
inline Vector2DC &operator-= (Vector3DI &op);
|
||||||
|
inline Vector2DC &operator-= (Vector3DF &op);
|
||||||
|
inline Vector2DC &operator-= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector2DC &operator*= (Vector2DC &op);
|
||||||
|
inline Vector2DC &operator*= (Vector2DI &op);
|
||||||
|
inline Vector2DC &operator*= (Vector2DF &op);
|
||||||
|
inline Vector2DC &operator*= (Vector3DC &op);
|
||||||
|
inline Vector2DC &operator*= (Vector3DI &op);
|
||||||
|
inline Vector2DC &operator*= (Vector3DF &op);
|
||||||
|
inline Vector2DC &operator*= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector2DC &operator/= (Vector2DC &op);
|
||||||
|
inline Vector2DC &operator/= (Vector2DI &op);
|
||||||
|
inline Vector2DC &operator/= (Vector2DF &op);
|
||||||
|
inline Vector2DC &operator/= (Vector3DC &op);
|
||||||
|
inline Vector2DC &operator/= (Vector3DI &op);
|
||||||
|
inline Vector2DC &operator/= (Vector3DF &op);
|
||||||
|
inline Vector2DC &operator/= (Vector4DF &op);
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
inline double Dot(Vector2DC &v);
|
||||||
|
inline double Dot(Vector2DI &v);
|
||||||
|
inline double Dot(Vector2DF &v);
|
||||||
|
|
||||||
|
inline double Dist (Vector2DC &v);
|
||||||
|
inline double Dist (Vector2DI &v);
|
||||||
|
inline double Dist (Vector2DF &v);
|
||||||
|
inline double Dist (Vector3DC &v);
|
||||||
|
inline double Dist (Vector3DI &v);
|
||||||
|
inline double Dist (Vector3DF &v);
|
||||||
|
inline double Dist (Vector4DF &v);
|
||||||
|
|
||||||
|
inline double DistSq (Vector2DC &v);
|
||||||
|
inline double DistSq (Vector2DI &v);
|
||||||
|
inline double DistSq (Vector2DF &v);
|
||||||
|
inline double DistSq (Vector3DC &v);
|
||||||
|
inline double DistSq (Vector3DI &v);
|
||||||
|
inline double DistSq (Vector3DF &v);
|
||||||
|
inline double DistSq (Vector4DF &v);
|
||||||
|
|
||||||
|
inline Vector2DC &Normalize (void);
|
||||||
|
inline double Length (void);
|
||||||
|
|
||||||
|
inline VTYPE &X(void);
|
||||||
|
inline VTYPE &Y(void);
|
||||||
|
inline VTYPE Z(void);
|
||||||
|
inline VTYPE W(void);
|
||||||
|
inline const VTYPE &X(void) const;
|
||||||
|
inline const VTYPE &Y(void) const;
|
||||||
|
inline const VTYPE Z(void) const;
|
||||||
|
inline const VTYPE W(void) const;
|
||||||
|
inline VTYPE *Data (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// Vector2DI Declaration
|
||||||
|
|
||||||
|
#define VNAME 2DI
|
||||||
|
#define VTYPE int
|
||||||
|
|
||||||
|
class Vector2DI {
|
||||||
|
public:
|
||||||
|
VTYPE x, y;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector2DI();
|
||||||
|
inline ~Vector2DI();
|
||||||
|
inline Vector2DI (VTYPE xa, VTYPE ya);
|
||||||
|
inline Vector2DI (Vector2DC &op);
|
||||||
|
inline Vector2DI (Vector2DI &op);
|
||||||
|
inline Vector2DI (Vector2DF &op);
|
||||||
|
inline Vector2DI (Vector3DC &op);
|
||||||
|
inline Vector2DI (Vector3DI &op);
|
||||||
|
inline Vector2DI (Vector3DF &op);
|
||||||
|
inline Vector2DI (Vector4DF &op);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector2DI &operator= (Vector2DC &op);
|
||||||
|
inline Vector2DI &operator= (Vector2DI &op);
|
||||||
|
inline Vector2DI &operator= (Vector2DF &op);
|
||||||
|
inline Vector2DI &operator= (Vector3DC &op);
|
||||||
|
inline Vector2DI &operator= (Vector3DI &op);
|
||||||
|
inline Vector2DI &operator= (Vector3DF &op);
|
||||||
|
inline Vector2DI &operator= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector2DI &operator+= (Vector2DC &op);
|
||||||
|
inline Vector2DI &operator+= (Vector2DI &op);
|
||||||
|
inline Vector2DI &operator+= (Vector2DF &op);
|
||||||
|
inline Vector2DI &operator+= (Vector3DC &op);
|
||||||
|
inline Vector2DI &operator+= (Vector3DI &op);
|
||||||
|
inline Vector2DI &operator+= (Vector3DF &op);
|
||||||
|
inline Vector2DI &operator+= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector2DI &operator-= (Vector2DC &op);
|
||||||
|
inline Vector2DI &operator-= (Vector2DI &op);
|
||||||
|
inline Vector2DI &operator-= (Vector2DF &op);
|
||||||
|
inline Vector2DI &operator-= (Vector3DC &op);
|
||||||
|
inline Vector2DI &operator-= (Vector3DI &op);
|
||||||
|
inline Vector2DI &operator-= (Vector3DF &op);
|
||||||
|
inline Vector2DI &operator-= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector2DI &operator*= (Vector2DC &op);
|
||||||
|
inline Vector2DI &operator*= (Vector2DI &op);
|
||||||
|
inline Vector2DI &operator*= (Vector2DF &op);
|
||||||
|
inline Vector2DI &operator*= (Vector3DC &op);
|
||||||
|
inline Vector2DI &operator*= (Vector3DI &op);
|
||||||
|
inline Vector2DI &operator*= (Vector3DF &op);
|
||||||
|
inline Vector2DI &operator*= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector2DI &operator/= (Vector2DC &op);
|
||||||
|
inline Vector2DI &operator/= (Vector2DI &op);
|
||||||
|
inline Vector2DI &operator/= (Vector2DF &op);
|
||||||
|
inline Vector2DI &operator/= (Vector3DC &op);
|
||||||
|
inline Vector2DI &operator/= (Vector3DI &op);
|
||||||
|
inline Vector2DI &operator/= (Vector3DF &op);
|
||||||
|
inline Vector2DI &operator/= (Vector4DF &op);
|
||||||
|
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
inline double Dot(Vector2DC &v);
|
||||||
|
inline double Dot(Vector2DI &v);
|
||||||
|
inline double Dot(Vector2DF &v);
|
||||||
|
|
||||||
|
inline double Dist (Vector2DC &v);
|
||||||
|
inline double Dist (Vector2DI &v);
|
||||||
|
inline double Dist (Vector2DF &v);
|
||||||
|
inline double Dist (Vector3DC &v);
|
||||||
|
inline double Dist (Vector3DI &v);
|
||||||
|
inline double Dist (Vector3DF &v);
|
||||||
|
inline double Dist (Vector4DF &v);
|
||||||
|
|
||||||
|
inline double DistSq (Vector2DC &v);
|
||||||
|
inline double DistSq (Vector2DI &v);
|
||||||
|
inline double DistSq (Vector2DF &v);
|
||||||
|
inline double DistSq (Vector3DC &v);
|
||||||
|
inline double DistSq (Vector3DI &v);
|
||||||
|
inline double DistSq (Vector3DF &v);
|
||||||
|
inline double DistSq (Vector4DF &v);
|
||||||
|
|
||||||
|
inline Vector2DI &Normalize (void);
|
||||||
|
inline double Length (void);
|
||||||
|
|
||||||
|
inline VTYPE &X(void);
|
||||||
|
inline VTYPE &Y(void);
|
||||||
|
inline VTYPE Z(void);
|
||||||
|
inline VTYPE W(void);
|
||||||
|
inline const VTYPE &X(void) const;
|
||||||
|
inline const VTYPE &Y(void) const;
|
||||||
|
inline const VTYPE Z(void) const;
|
||||||
|
inline const VTYPE W(void) const;
|
||||||
|
inline VTYPE *Data (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// Vector2DF Declarations
|
||||||
|
|
||||||
|
#define VNAME 2DF
|
||||||
|
#define VTYPE double
|
||||||
|
|
||||||
|
class Vector2DF {
|
||||||
|
public:
|
||||||
|
VTYPE x, y;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
Vector2DF ();
|
||||||
|
~Vector2DF ();
|
||||||
|
Vector2DF (const VTYPE xa, const VTYPE ya);
|
||||||
|
Vector2DF (const Vector2DC &op);
|
||||||
|
Vector2DF (const Vector2DI &op);
|
||||||
|
Vector2DF (const Vector2DF &op);
|
||||||
|
Vector2DF (const Vector3DC &op);
|
||||||
|
Vector2DF (const Vector3DI &op);
|
||||||
|
Vector2DF (const Vector3DF &op);
|
||||||
|
Vector2DF (const Vector4DF &op);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
Vector2DF &operator= (const Vector2DC &op);
|
||||||
|
Vector2DF &operator= (const Vector2DI &op);
|
||||||
|
Vector2DF &operator= (const Vector2DF &op);
|
||||||
|
Vector2DF &operator= (const Vector3DC &op);
|
||||||
|
Vector2DF &operator= (const Vector3DI &op);
|
||||||
|
Vector2DF &operator= (const Vector3DF &op);
|
||||||
|
Vector2DF &operator= (const Vector4DF &op);
|
||||||
|
|
||||||
|
Vector2DF &operator+= (const Vector2DC &op);
|
||||||
|
Vector2DF &operator+= (const Vector2DI &op);
|
||||||
|
Vector2DF &operator+= (const Vector2DF &op);
|
||||||
|
Vector2DF &operator+= (const Vector3DC &op);
|
||||||
|
Vector2DF &operator+= (const Vector3DI &op);
|
||||||
|
Vector2DF &operator+= (const Vector3DF &op);
|
||||||
|
Vector2DF &operator+= (const Vector4DF &op);
|
||||||
|
|
||||||
|
Vector2DF &operator-= (const Vector2DC &op);
|
||||||
|
Vector2DF &operator-= (const Vector2DI &op);
|
||||||
|
Vector2DF &operator-= (const Vector2DF &op);
|
||||||
|
Vector2DF &operator-= (const Vector3DC &op);
|
||||||
|
Vector2DF &operator-= (const Vector3DI &op);
|
||||||
|
Vector2DF &operator-= (const Vector3DF &op);
|
||||||
|
Vector2DF &operator-= (const Vector4DF &op);
|
||||||
|
|
||||||
|
Vector2DF &operator*= (const Vector2DC &op);
|
||||||
|
Vector2DF &operator*= (const Vector2DI &op);
|
||||||
|
Vector2DF &operator*= (const Vector2DF &op);
|
||||||
|
Vector2DF &operator*= (const Vector3DC &op);
|
||||||
|
Vector2DF &operator*= (const Vector3DI &op);
|
||||||
|
Vector2DF &operator*= (const Vector3DF &op);
|
||||||
|
Vector2DF &operator*= (const Vector4DF &op);
|
||||||
|
|
||||||
|
Vector2DF &operator/= (const Vector2DC &op);
|
||||||
|
Vector2DF &operator/= (const Vector2DI &op);
|
||||||
|
Vector2DF &operator/= (const Vector2DF &op);
|
||||||
|
Vector2DF &operator/= (const Vector3DC &op);
|
||||||
|
Vector2DF &operator/= (const Vector3DI &op);
|
||||||
|
Vector2DF &operator/= (const Vector3DF &op);
|
||||||
|
Vector2DF &operator/= (const Vector4DF &op);
|
||||||
|
|
||||||
|
Vector2DF &operator/= (const double v) {x /= v; y /= v; return *this;}
|
||||||
|
|
||||||
|
// Note: Cross product does not exist for 2D vectors (only 3D)
|
||||||
|
|
||||||
|
double Dot(const Vector2DC &v);
|
||||||
|
double Dot(const Vector2DI &v);
|
||||||
|
double Dot(const Vector2DF &v);
|
||||||
|
|
||||||
|
double Dist (const Vector2DC &v);
|
||||||
|
double Dist (const Vector2DI &v);
|
||||||
|
double Dist (const Vector2DF &v);
|
||||||
|
double Dist (const Vector3DC &v);
|
||||||
|
double Dist (const Vector3DI &v);
|
||||||
|
double Dist (const Vector3DF &v);
|
||||||
|
double Dist (const Vector4DF &v);
|
||||||
|
|
||||||
|
double DistSq (const Vector2DC &v);
|
||||||
|
double DistSq (const Vector2DI &v);
|
||||||
|
double DistSq (const Vector2DF &v);
|
||||||
|
double DistSq (const Vector3DC &v);
|
||||||
|
double DistSq (const Vector3DI &v);
|
||||||
|
double DistSq (const Vector3DF &v);
|
||||||
|
double DistSq (const Vector4DF &v);
|
||||||
|
|
||||||
|
Vector2DF &Normalize (void);
|
||||||
|
double Length (void);
|
||||||
|
|
||||||
|
VTYPE &X(void);
|
||||||
|
VTYPE &Y(void);
|
||||||
|
VTYPE Z(void);
|
||||||
|
VTYPE W(void);
|
||||||
|
const VTYPE &X(void) const;
|
||||||
|
const VTYPE &Y(void) const;
|
||||||
|
const VTYPE Z(void) const;
|
||||||
|
const VTYPE W(void) const;
|
||||||
|
VTYPE *Data (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// Vector3DC Declaration
|
||||||
|
|
||||||
|
#define VNAME 3DC
|
||||||
|
#define VTYPE unsigned char
|
||||||
|
|
||||||
|
class Vector3DC {
|
||||||
|
public:
|
||||||
|
VTYPE x, y, z;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DC();
|
||||||
|
inline ~Vector3DC();
|
||||||
|
inline Vector3DC (VTYPE xa, VTYPE ya, VTYPE za);
|
||||||
|
inline Vector3DC (Vector2DC &op);
|
||||||
|
inline Vector3DC (Vector2DI &op);
|
||||||
|
inline Vector3DC (Vector2DF &op);
|
||||||
|
inline Vector3DC (Vector3DC &op);
|
||||||
|
inline Vector3DC (Vector3DI &op);
|
||||||
|
inline Vector3DC (Vector3DF &op);
|
||||||
|
inline Vector3DC (Vector4DF &op);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DC &Set (VTYPE xa, VTYPE ya, VTYPE za);
|
||||||
|
|
||||||
|
inline Vector3DC &operator= (Vector2DC &op);
|
||||||
|
inline Vector3DC &operator= (Vector2DI &op);
|
||||||
|
inline Vector3DC &operator= (Vector2DF &op);
|
||||||
|
inline Vector3DC &operator= (Vector3DC &op);
|
||||||
|
inline Vector3DC &operator= (Vector3DI &op);
|
||||||
|
inline Vector3DC &operator= (Vector3DF &op);
|
||||||
|
inline Vector3DC &operator= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DC &operator+= (Vector2DC &op);
|
||||||
|
inline Vector3DC &operator+= (Vector2DI &op);
|
||||||
|
inline Vector3DC &operator+= (Vector2DF &op);
|
||||||
|
inline Vector3DC &operator+= (Vector3DC &op);
|
||||||
|
inline Vector3DC &operator+= (Vector3DI &op);
|
||||||
|
inline Vector3DC &operator+= (Vector3DF &op);
|
||||||
|
inline Vector3DC &operator+= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DC &operator-= (Vector2DC &op);
|
||||||
|
inline Vector3DC &operator-= (Vector2DI &op);
|
||||||
|
inline Vector3DC &operator-= (Vector2DF &op);
|
||||||
|
inline Vector3DC &operator-= (Vector3DC &op);
|
||||||
|
inline Vector3DC &operator-= (Vector3DI &op);
|
||||||
|
inline Vector3DC &operator-= (Vector3DF &op);
|
||||||
|
inline Vector3DC &operator-= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DC &operator*= (Vector2DC &op);
|
||||||
|
inline Vector3DC &operator*= (Vector2DI &op);
|
||||||
|
inline Vector3DC &operator*= (Vector2DF &op);
|
||||||
|
inline Vector3DC &operator*= (Vector3DC &op);
|
||||||
|
inline Vector3DC &operator*= (Vector3DI &op);
|
||||||
|
inline Vector3DC &operator*= (Vector3DF &op);
|
||||||
|
inline Vector3DC &operator*= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DC &operator/= (Vector2DC &op);
|
||||||
|
inline Vector3DC &operator/= (Vector2DI &op);
|
||||||
|
inline Vector3DC &operator/= (Vector2DF &op);
|
||||||
|
inline Vector3DC &operator/= (Vector3DC &op);
|
||||||
|
inline Vector3DC &operator/= (Vector3DI &op);
|
||||||
|
inline Vector3DC &operator/= (Vector3DF &op);
|
||||||
|
inline Vector3DC &operator/= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DC &Cross (Vector3DC &v);
|
||||||
|
inline Vector3DC &Cross (Vector3DI &v);
|
||||||
|
inline Vector3DC &Cross (Vector3DF &v);
|
||||||
|
|
||||||
|
inline double Dot(Vector3DC &v);
|
||||||
|
inline double Dot(Vector3DI &v);
|
||||||
|
inline double Dot(Vector3DF &v);
|
||||||
|
|
||||||
|
inline double Dist (Vector2DC &v);
|
||||||
|
inline double Dist (Vector2DI &v);
|
||||||
|
inline double Dist (Vector2DF &v);
|
||||||
|
inline double Dist (Vector3DC &v);
|
||||||
|
inline double Dist (Vector3DI &v);
|
||||||
|
inline double Dist (Vector3DF &v);
|
||||||
|
inline double Dist (Vector4DF &v);
|
||||||
|
|
||||||
|
inline double DistSq (Vector2DC &v);
|
||||||
|
inline double DistSq (Vector2DI &v);
|
||||||
|
inline double DistSq (Vector2DF &v);
|
||||||
|
inline double DistSq (Vector3DC &v);
|
||||||
|
inline double DistSq (Vector3DI &v);
|
||||||
|
inline double DistSq (Vector3DF &v);
|
||||||
|
inline double DistSq (Vector4DF &v);
|
||||||
|
|
||||||
|
inline Vector3DC &Normalize (void);
|
||||||
|
inline double Length (void);
|
||||||
|
|
||||||
|
inline VTYPE &X(void);
|
||||||
|
inline VTYPE &Y(void);
|
||||||
|
inline VTYPE &Z(void);
|
||||||
|
inline VTYPE W(void);
|
||||||
|
inline const VTYPE &X(void) const;
|
||||||
|
inline const VTYPE &Y(void) const;
|
||||||
|
inline const VTYPE &Z(void) const;
|
||||||
|
inline const VTYPE W(void) const;
|
||||||
|
inline VTYPE *Data (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// Vector3DI Declaration
|
||||||
|
|
||||||
|
#define VNAME 3DI
|
||||||
|
#define VTYPE int
|
||||||
|
|
||||||
|
class Vector3DI {
|
||||||
|
public:
|
||||||
|
VTYPE x, y, z;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DI();
|
||||||
|
inline ~Vector3DI();
|
||||||
|
inline Vector3DI (VTYPE xa, VTYPE ya, VTYPE za);
|
||||||
|
inline Vector3DI (Vector2DC &op);
|
||||||
|
inline Vector3DI (Vector2DI &op);
|
||||||
|
inline Vector3DI (Vector2DF &op);
|
||||||
|
inline Vector3DI (Vector3DC &op);
|
||||||
|
inline Vector3DI (Vector3DI &op);
|
||||||
|
inline Vector3DI (Vector3DF &op);
|
||||||
|
inline Vector3DI (Vector4DF &op);
|
||||||
|
|
||||||
|
// Set Functions
|
||||||
|
inline Vector3DI &Set (const int xa, const int ya, const int za);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DI &operator= (Vector2DC &op);
|
||||||
|
inline Vector3DI &operator= (Vector2DI &op);
|
||||||
|
inline Vector3DI &operator= (Vector2DF &op);
|
||||||
|
inline Vector3DI &operator= (Vector3DC &op);
|
||||||
|
inline Vector3DI &operator= (Vector3DI &op);
|
||||||
|
inline Vector3DI &operator= (Vector3DF &op);
|
||||||
|
inline Vector3DI &operator= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DI &operator+= (Vector2DC &op);
|
||||||
|
inline Vector3DI &operator+= (Vector2DI &op);
|
||||||
|
inline Vector3DI &operator+= (Vector2DF &op);
|
||||||
|
inline Vector3DI &operator+= (Vector3DC &op);
|
||||||
|
inline Vector3DI &operator+= (Vector3DI &op);
|
||||||
|
inline Vector3DI &operator+= (Vector3DF &op);
|
||||||
|
inline Vector3DI &operator+= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DI &operator-= (Vector2DC &op);
|
||||||
|
inline Vector3DI &operator-= (Vector2DI &op);
|
||||||
|
inline Vector3DI &operator-= (Vector2DF &op);
|
||||||
|
inline Vector3DI &operator-= (Vector3DC &op);
|
||||||
|
inline Vector3DI &operator-= (Vector3DI &op);
|
||||||
|
inline Vector3DI &operator-= (Vector3DF &op);
|
||||||
|
inline Vector3DI &operator-= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DI &operator*= (Vector2DC &op);
|
||||||
|
inline Vector3DI &operator*= (Vector2DI &op);
|
||||||
|
inline Vector3DI &operator*= (Vector2DF &op);
|
||||||
|
inline Vector3DI &operator*= (Vector3DC &op);
|
||||||
|
inline Vector3DI &operator*= (Vector3DI &op);
|
||||||
|
inline Vector3DI &operator*= (Vector3DF &op);
|
||||||
|
inline Vector3DI &operator*= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DI &operator/= (Vector2DC &op);
|
||||||
|
inline Vector3DI &operator/= (Vector2DI &op);
|
||||||
|
inline Vector3DI &operator/= (Vector2DF &op);
|
||||||
|
inline Vector3DI &operator/= (Vector3DC &op);
|
||||||
|
inline Vector3DI &operator/= (Vector3DI &op);
|
||||||
|
inline Vector3DI &operator/= (Vector3DF &op);
|
||||||
|
inline Vector3DI &operator/= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DI &Cross (Vector3DC &v);
|
||||||
|
inline Vector3DI &Cross (Vector3DI &v);
|
||||||
|
inline Vector3DI &Cross (Vector3DF &v);
|
||||||
|
|
||||||
|
inline double Dot(Vector3DC &v);
|
||||||
|
inline double Dot(Vector3DI &v);
|
||||||
|
inline double Dot(Vector3DF &v);
|
||||||
|
|
||||||
|
inline double Dist (Vector2DC &v);
|
||||||
|
inline double Dist (Vector2DI &v);
|
||||||
|
inline double Dist (Vector2DF &v);
|
||||||
|
inline double Dist (Vector3DC &v);
|
||||||
|
inline double Dist (Vector3DI &v);
|
||||||
|
inline double Dist (Vector3DF &v);
|
||||||
|
inline double Dist (Vector4DF &v);
|
||||||
|
|
||||||
|
inline double DistSq (Vector2DC &v);
|
||||||
|
inline double DistSq (Vector2DI &v);
|
||||||
|
inline double DistSq (Vector2DF &v);
|
||||||
|
inline double DistSq (Vector3DC &v);
|
||||||
|
inline double DistSq (Vector3DI &v);
|
||||||
|
inline double DistSq (Vector3DF &v);
|
||||||
|
inline double DistSq (Vector4DF &v);
|
||||||
|
|
||||||
|
inline Vector3DI &Normalize (void);
|
||||||
|
inline double Length (void);
|
||||||
|
|
||||||
|
inline VTYPE &X(void);
|
||||||
|
inline VTYPE &Y(void);
|
||||||
|
inline VTYPE &Z(void);
|
||||||
|
inline VTYPE W(void);
|
||||||
|
inline const VTYPE &X(void) const;
|
||||||
|
inline const VTYPE &Y(void) const;
|
||||||
|
inline const VTYPE &Z(void) const;
|
||||||
|
inline const VTYPE W(void) const;
|
||||||
|
inline VTYPE *Data (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// Vector3DF Declarations
|
||||||
|
|
||||||
|
#define VNAME 3DF
|
||||||
|
#define VTYPE float
|
||||||
|
|
||||||
|
class Vector3DF {
|
||||||
|
public:
|
||||||
|
VTYPE x, y, z;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector3DF();
|
||||||
|
inline ~Vector3DF();
|
||||||
|
inline Vector3DF (const VTYPE xa, const VTYPE ya, const VTYPE za);
|
||||||
|
inline Vector3DF (const Vector2DC &op);
|
||||||
|
inline Vector3DF (const Vector2DI &op);
|
||||||
|
inline Vector3DF (const Vector2DF &op);
|
||||||
|
inline Vector3DF (const Vector3DC &op);
|
||||||
|
inline Vector3DF (const Vector3DI &op);
|
||||||
|
inline Vector3DF (const Vector3DF &op);
|
||||||
|
inline Vector3DF (const Vector4DF &op);
|
||||||
|
|
||||||
|
// Set Functions
|
||||||
|
inline Vector3DF &Set (const double xa, const double ya, const double za);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector3DF &operator= (const int op);
|
||||||
|
inline Vector3DF &operator= (const double op);
|
||||||
|
inline Vector3DF &operator= (const Vector2DC &op);
|
||||||
|
inline Vector3DF &operator= (const Vector2DI &op);
|
||||||
|
inline Vector3DF &operator= (const Vector2DF &op);
|
||||||
|
inline Vector3DF &operator= (const Vector3DC &op);
|
||||||
|
inline Vector3DF &operator= (const Vector3DI &op);
|
||||||
|
inline Vector3DF &operator= (const Vector3DF &op);
|
||||||
|
inline Vector3DF &operator= (const Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DF &operator+= (const int op);
|
||||||
|
inline Vector3DF &operator+= (const double op);
|
||||||
|
inline Vector3DF &operator+= (const Vector2DC &op);
|
||||||
|
inline Vector3DF &operator+= (const Vector2DI &op);
|
||||||
|
inline Vector3DF &operator+= (const Vector2DF &op);
|
||||||
|
inline Vector3DF &operator+= (const Vector3DC &op);
|
||||||
|
inline Vector3DF &operator+= (const Vector3DI &op);
|
||||||
|
inline Vector3DF &operator+= (const Vector3DF &op);
|
||||||
|
inline Vector3DF &operator+= (const Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DF &operator-= (const int op);
|
||||||
|
inline Vector3DF &operator-= (const double op);
|
||||||
|
inline Vector3DF &operator-= (const Vector2DC &op);
|
||||||
|
inline Vector3DF &operator-= (const Vector2DI &op);
|
||||||
|
inline Vector3DF &operator-= (const Vector2DF &op);
|
||||||
|
inline Vector3DF &operator-= (const Vector3DC &op);
|
||||||
|
inline Vector3DF &operator-= (const Vector3DI &op);
|
||||||
|
inline Vector3DF &operator-= (const Vector3DF &op);
|
||||||
|
inline Vector3DF &operator-= (const Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DF &operator*= (const int op);
|
||||||
|
inline Vector3DF &operator*= (const double op);
|
||||||
|
inline Vector3DF &operator*= (const Vector2DC &op);
|
||||||
|
inline Vector3DF &operator*= (const Vector2DI &op);
|
||||||
|
inline Vector3DF &operator*= (const Vector2DF &op);
|
||||||
|
inline Vector3DF &operator*= (const Vector3DC &op);
|
||||||
|
inline Vector3DF &operator*= (const Vector3DI &op);
|
||||||
|
inline Vector3DF &operator*= (const Vector3DF &op);
|
||||||
|
inline Vector3DF &operator*= (const Vector4DF &op);
|
||||||
|
Vector3DF &operator*= (const Matrix4F &op);
|
||||||
|
Vector3DF &operator*= (const MatrixF &op); // see vector.cpp
|
||||||
|
|
||||||
|
inline Vector3DF &operator/= (const int op);
|
||||||
|
inline Vector3DF &operator/= (const double op);
|
||||||
|
inline Vector3DF &operator/= (const Vector2DC &op);
|
||||||
|
inline Vector3DF &operator/= (const Vector2DI &op);
|
||||||
|
inline Vector3DF &operator/= (const Vector2DF &op);
|
||||||
|
inline Vector3DF &operator/= (const Vector3DC &op);
|
||||||
|
inline Vector3DF &operator/= (const Vector3DI &op);
|
||||||
|
inline Vector3DF &operator/= (const Vector3DF &op);
|
||||||
|
inline Vector3DF &operator/= (const Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector3DF &Cross (const Vector3DC &v);
|
||||||
|
inline Vector3DF &Cross (const Vector3DI &v);
|
||||||
|
inline Vector3DF &Cross (const Vector3DF &v);
|
||||||
|
|
||||||
|
inline double Dot(const Vector3DC &v);
|
||||||
|
inline double Dot(const Vector3DI &v);
|
||||||
|
inline double Dot(const Vector3DF &v);
|
||||||
|
|
||||||
|
inline double Dist (const Vector2DC &v);
|
||||||
|
inline double Dist (const Vector2DI &v);
|
||||||
|
inline double Dist (const Vector2DF &v);
|
||||||
|
inline double Dist (const Vector3DC &v);
|
||||||
|
inline double Dist (const Vector3DI &v);
|
||||||
|
inline double Dist (const Vector3DF &v);
|
||||||
|
inline double Dist (const Vector4DF &v);
|
||||||
|
|
||||||
|
inline double DistSq (const Vector2DC &v);
|
||||||
|
inline double DistSq (const Vector2DI &v);
|
||||||
|
inline double DistSq (const Vector2DF &v);
|
||||||
|
inline double DistSq (const Vector3DC &v);
|
||||||
|
inline double DistSq (const Vector3DI &v);
|
||||||
|
inline double DistSq (const Vector3DF &v);
|
||||||
|
inline double DistSq (const Vector4DF &v);
|
||||||
|
|
||||||
|
inline Vector3DF &Normalize (void);
|
||||||
|
inline double Length (void);
|
||||||
|
|
||||||
|
inline VTYPE &X();
|
||||||
|
inline VTYPE &Y();
|
||||||
|
inline VTYPE &Z();
|
||||||
|
inline VTYPE W();
|
||||||
|
inline const VTYPE &X() const;
|
||||||
|
inline const VTYPE &Y() const;
|
||||||
|
inline const VTYPE &Z() const;
|
||||||
|
inline const VTYPE W() const;
|
||||||
|
inline VTYPE *Data ();
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// Vector4DF Declarations
|
||||||
|
|
||||||
|
#define VNAME 4DF
|
||||||
|
#define VTYPE double
|
||||||
|
|
||||||
|
class Vector4DF {
|
||||||
|
public:
|
||||||
|
VTYPE x, y, z, w;
|
||||||
|
|
||||||
|
// Constructors/Destructors
|
||||||
|
inline Vector4DF();
|
||||||
|
inline ~Vector4DF();
|
||||||
|
inline Vector4DF (VTYPE xa, VTYPE ya, VTYPE za, VTYPE wa);
|
||||||
|
inline Vector4DF (Vector2DC &op);
|
||||||
|
inline Vector4DF (Vector2DI &op);
|
||||||
|
inline Vector4DF (Vector2DF &op);
|
||||||
|
inline Vector4DF (Vector3DC &op);
|
||||||
|
inline Vector4DF (Vector3DI &op);
|
||||||
|
inline Vector4DF (Vector3DF &op);
|
||||||
|
inline Vector4DF (Vector4DF &op);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
inline Vector4DF &operator= (int op);
|
||||||
|
inline Vector4DF &operator= (double op);
|
||||||
|
inline Vector4DF &operator= (Vector2DC &op);
|
||||||
|
inline Vector4DF &operator= (Vector2DI &op);
|
||||||
|
inline Vector4DF &operator= (Vector2DF &op);
|
||||||
|
inline Vector4DF &operator= (Vector3DC &op);
|
||||||
|
inline Vector4DF &operator= (Vector3DI &op);
|
||||||
|
inline Vector4DF &operator= (Vector3DF &op);
|
||||||
|
inline Vector4DF &operator= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector4DF &operator+= (int op);
|
||||||
|
inline Vector4DF &operator+= (double op);
|
||||||
|
inline Vector4DF &operator+= (Vector2DC &op);
|
||||||
|
inline Vector4DF &operator+= (Vector2DI &op);
|
||||||
|
inline Vector4DF &operator+= (Vector2DF &op);
|
||||||
|
inline Vector4DF &operator+= (Vector3DC &op);
|
||||||
|
inline Vector4DF &operator+= (Vector3DI &op);
|
||||||
|
inline Vector4DF &operator+= (Vector3DF &op);
|
||||||
|
inline Vector4DF &operator+= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector4DF &operator-= (int op);
|
||||||
|
inline Vector4DF &operator-= (double op);
|
||||||
|
inline Vector4DF &operator-= (Vector2DC &op);
|
||||||
|
inline Vector4DF &operator-= (Vector2DI &op);
|
||||||
|
inline Vector4DF &operator-= (Vector2DF &op);
|
||||||
|
inline Vector4DF &operator-= (Vector3DC &op);
|
||||||
|
inline Vector4DF &operator-= (Vector3DI &op);
|
||||||
|
inline Vector4DF &operator-= (Vector3DF &op);
|
||||||
|
inline Vector4DF &operator-= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector4DF &operator*= (int op);
|
||||||
|
inline Vector4DF &operator*= (double op);
|
||||||
|
inline Vector4DF &operator*= (Vector2DC &op);
|
||||||
|
inline Vector4DF &operator*= (Vector2DI &op);
|
||||||
|
inline Vector4DF &operator*= (Vector2DF &op);
|
||||||
|
inline Vector4DF &operator*= (Vector3DC &op);
|
||||||
|
inline Vector4DF &operator*= (Vector3DI &op);
|
||||||
|
inline Vector4DF &operator*= (Vector3DF &op);
|
||||||
|
inline Vector4DF &operator*= (Vector4DF &op);
|
||||||
|
Vector4DF &operator*= (const Matrix4F &op);
|
||||||
|
Vector4DF &operator*= (const MatrixF &op); // see vector.cpp
|
||||||
|
|
||||||
|
inline Vector4DF &operator/= (int op);
|
||||||
|
inline Vector4DF &operator/= (double op);
|
||||||
|
inline Vector4DF &operator/= (Vector2DC &op);
|
||||||
|
inline Vector4DF &operator/= (Vector2DI &op);
|
||||||
|
inline Vector4DF &operator/= (Vector2DF &op);
|
||||||
|
inline Vector4DF &operator/= (Vector3DC &op);
|
||||||
|
inline Vector4DF &operator/= (Vector3DI &op);
|
||||||
|
inline Vector4DF &operator/= (Vector3DF &op);
|
||||||
|
inline Vector4DF &operator/= (Vector4DF &op);
|
||||||
|
|
||||||
|
inline Vector4DF &Cross (Vector4DF &v);
|
||||||
|
|
||||||
|
inline double Dot(Vector4DF &v);
|
||||||
|
|
||||||
|
inline double Dist (Vector4DF &v);
|
||||||
|
|
||||||
|
inline double DistSq (Vector4DF &v);
|
||||||
|
|
||||||
|
inline Vector4DF &Normalize (void);
|
||||||
|
inline double Length (void);
|
||||||
|
|
||||||
|
inline VTYPE &X(void);
|
||||||
|
inline VTYPE &Y(void);
|
||||||
|
inline VTYPE &Z(void);
|
||||||
|
inline VTYPE &W(void);
|
||||||
|
inline const VTYPE &X(void) const;
|
||||||
|
inline const VTYPE &Y(void) const;
|
||||||
|
inline const VTYPE &Z(void) const;
|
||||||
|
inline const VTYPE &W(void) const;
|
||||||
|
inline VTYPE *Data (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef VNAME
|
||||||
|
#undef VTYPE
|
||||||
|
|
||||||
|
// Vector Code Definitions (Inlined)
|
||||||
|
#include "vector.cci"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
1
Extras/sph/fluid_system_host.linkinfo
Normal file
1
Extras/sph/fluid_system_host.linkinfo
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--import sRadixSum,%laneid,%ctaid,%nctaid,%smid,A7,%pm3,%pm2,%pm1,__CC-temp__0__,%pm0,%tid,%clock,%warpid,%ntid,%gridid --export _Z8RadixSumP12KeyValuePairjjj,_Z13hashParticlesPcP5uint2i,_Z15insertParticlesPcP5uint2Piii,_Z15computePressurePcPiP5uint2i,_Z25RadixAddOffsetsAndShuffleP12KeyValuePairS0_jji,_Z20insertParticlesRadixPcP5uint2PiS_ii,_Z12computeForcePcPiP5uint2i,_Z15computeForceNbrPci,_Z16advanceParticlesPciff,_Z14RadixPrefixSumv
|
||||||
302
Extras/sph/fluids.vcproj
Normal file
302
Extras/sph/fluids.vcproj
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="fluids"
|
||||||
|
ProjectGUID="{F9F0795D-4C39-41F4-9381-25C616D69FB2}"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="131072"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="common;fluids;marching;sphere_scan;marching_tris"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="glee_2008d.lib"
|
||||||
|
OutputFile="$(OutDir)/fluids_debug.exe"
|
||||||
|
LinkIncremental="2"
|
||||||
|
AdditionalLibraryDirectories=""C:\Program Files\NVIDIA Corporation\Cg\lib""
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/cgdemo.pdb"
|
||||||
|
SubSystem="1"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="Release"
|
||||||
|
IntermediateDirectory="Release"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="3"
|
||||||
|
InlineFunctionExpansion="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
FavorSizeOrSpeed="1"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
AdditionalIncludeDirectories="fluids;common;marching;sphere_scan;marching_tris"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="glee_2008.lib"
|
||||||
|
OutputFile="$(OutDir)/fluids.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
IgnoreDefaultLibraryNames="libcmtd.lib"
|
||||||
|
GenerateDebugInformation="false"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="0"
|
||||||
|
EnableCOMDATFolding="0"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="fluids"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid_system.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid_system.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="common"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\common_defs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\geomx.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\geomx.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\gl_helper.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\gl_helper.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\image.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\image.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\matrix-inline.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\matrix.cci"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\matrix.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\matrix.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mdebug.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mdebug.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mtime.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mtime.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\point_set.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\point_set.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\vector-inline.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\vector.cci"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\vector.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\vector.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<File
|
||||||
|
RelativePath=".\main.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
22
Extras/sph/fluids/fluid.cpp
Normal file
22
Extras/sph/fluids/fluid.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#include "fluid.h"
|
||||||
44
Extras/sph/fluids/fluid.h
Normal file
44
Extras/sph/fluids/fluid.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 DEF_FLUID
|
||||||
|
#define DEF_FLUID
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
|
#include "common_defs.h"
|
||||||
|
|
||||||
|
struct Fluid {
|
||||||
|
public:
|
||||||
|
Vector3DF pos; // Basic particle (must match Particle class)
|
||||||
|
DWORD clr;
|
||||||
|
int next;
|
||||||
|
Vector3DF vel;
|
||||||
|
Vector3DF vel_eval;
|
||||||
|
unsigned short age;
|
||||||
|
|
||||||
|
float pressure; // Smoothed Particle Hydrodynamics
|
||||||
|
float density;
|
||||||
|
Vector3DF sph_force;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*PARTICLE_H_*/
|
||||||
869
Extras/sph/fluids/fluid_system.cpp
Normal file
869
Extras/sph/fluids/fluid_system.cpp
Normal file
@@ -0,0 +1,869 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <conio.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <gl/glut.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common_defs.h"
|
||||||
|
#include "mtime.h"
|
||||||
|
#include "fluid_system.h"
|
||||||
|
|
||||||
|
#ifdef BUILD_CUDA
|
||||||
|
#include "fluid_system_host.cuh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EPSILON 0.00001f //for collision detection
|
||||||
|
|
||||||
|
FluidSystem::FluidSystem ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidSystem::Initialize ( int mode, int total )
|
||||||
|
{
|
||||||
|
if ( mode != BFLUID ) {
|
||||||
|
printf ( "ERROR: FluidSystem not initialized as BFLUID.\n");
|
||||||
|
}
|
||||||
|
PointSet::Initialize ( mode, total );
|
||||||
|
|
||||||
|
FreeBuffers ();
|
||||||
|
AddBuffer ( BFLUID, sizeof ( Fluid ), total );
|
||||||
|
AddAttribute ( 0, "pos", sizeof ( Vector3DF ), false );
|
||||||
|
AddAttribute ( 0, "color", sizeof ( DWORD ), false );
|
||||||
|
AddAttribute ( 0, "vel", sizeof ( Vector3DF ), false );
|
||||||
|
AddAttribute ( 0, "ndx", sizeof ( unsigned short ), false );
|
||||||
|
AddAttribute ( 0, "age", sizeof ( unsigned short ), false );
|
||||||
|
|
||||||
|
AddAttribute ( 0, "pressure", sizeof ( double ), false );
|
||||||
|
AddAttribute ( 0, "density", sizeof ( double ), false );
|
||||||
|
AddAttribute ( 0, "sph_force", sizeof ( Vector3DF ), false );
|
||||||
|
AddAttribute ( 0, "next", sizeof ( Fluid* ), false );
|
||||||
|
AddAttribute ( 0, "tag", sizeof ( bool ), false );
|
||||||
|
|
||||||
|
SPH_Setup ();
|
||||||
|
Reset ( total );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidSystem::Reset ( int nmax )
|
||||||
|
{
|
||||||
|
ResetBuffer ( 0, nmax );
|
||||||
|
|
||||||
|
m_DT = 0.003; // 0.001; // .001 = for point grav
|
||||||
|
|
||||||
|
// Reset parameters
|
||||||
|
m_Param [ MAX_FRAC ] = 1.0;
|
||||||
|
m_Param [ POINT_GRAV ] = 0.0;
|
||||||
|
m_Param [ PLANE_GRAV ] = 1.0;
|
||||||
|
|
||||||
|
m_Param [ BOUND_ZMIN_SLOPE ] = 0.0;
|
||||||
|
m_Param [ FORCE_XMAX_SIN ] = 0.0;
|
||||||
|
m_Param [ FORCE_XMIN_SIN ] = 0.0;
|
||||||
|
m_Toggle [ WRAP_X ] = false;
|
||||||
|
m_Toggle [ WALL_BARRIER ] = false;
|
||||||
|
m_Toggle [ LEVY_BARRIER ] = false;
|
||||||
|
m_Toggle [ DRAIN_BARRIER ] = false;
|
||||||
|
m_Param [ SPH_INTSTIFF ] = 1.00;
|
||||||
|
m_Param [ SPH_VISC ] = 0.2;
|
||||||
|
m_Param [ SPH_INTSTIFF ] = 0.50;
|
||||||
|
m_Param [ SPH_EXTSTIFF ] = 20000;
|
||||||
|
m_Param [ SPH_SMOOTHRADIUS ] = 0.01;
|
||||||
|
|
||||||
|
m_Vec [ POINT_GRAV_POS ].Set ( 0, 0, 50 );
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, -9.8 );
|
||||||
|
m_Vec [ EMIT_POS ].Set ( 0, 0, 0 );
|
||||||
|
m_Vec [ EMIT_RATE ].Set ( 0, 0, 0 );
|
||||||
|
m_Vec [ EMIT_ANG ].Set ( 0, 90, 1.0 );
|
||||||
|
m_Vec [ EMIT_DANG ].Set ( 0, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int FluidSystem::AddPoint ()
|
||||||
|
{
|
||||||
|
xref ndx;
|
||||||
|
Fluid* f = (Fluid*) AddElem ( 0, ndx );
|
||||||
|
f->sph_force.Set(0,0,0);
|
||||||
|
f->vel.Set(0,0,0);
|
||||||
|
f->vel_eval.Set(0,0,0);
|
||||||
|
f->next = 0x0;
|
||||||
|
f->pressure = 0;
|
||||||
|
f->density = 0;
|
||||||
|
return ndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FluidSystem::AddPointReuse ()
|
||||||
|
{
|
||||||
|
xref ndx;
|
||||||
|
Fluid* f;
|
||||||
|
if ( NumPoints() <= mBuf[0].max-2 )
|
||||||
|
f = (Fluid*) AddElem ( 0, ndx );
|
||||||
|
else
|
||||||
|
f = (Fluid*) RandomElem ( 0, ndx );
|
||||||
|
|
||||||
|
f->sph_force.Set(0,0,0);
|
||||||
|
f->vel.Set(0,0,0);
|
||||||
|
f->vel_eval.Set(0,0,0);
|
||||||
|
f->next = 0x0;
|
||||||
|
f->pressure = 0;
|
||||||
|
f->density = 0;
|
||||||
|
return ndx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidSystem::Run ()
|
||||||
|
{
|
||||||
|
bool bTiming = true;
|
||||||
|
|
||||||
|
mint::Time start, stop;
|
||||||
|
|
||||||
|
float ss = m_Param [ SPH_PDIST ] / m_Param[ SPH_SIMSCALE ]; // simulation scale (not Schutzstaffel)
|
||||||
|
|
||||||
|
if ( m_Vec[EMIT_RATE].x > 0 && (++m_Frame) % (int) m_Vec[EMIT_RATE].x == 0 ) {
|
||||||
|
//m_Frame = 0;
|
||||||
|
Emit ( ss );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NOGRID
|
||||||
|
// Slow method - O(n^2)
|
||||||
|
SPH_ComputePressureSlow ();
|
||||||
|
SPH_ComputeForceSlow ();
|
||||||
|
#else
|
||||||
|
|
||||||
|
if ( m_Toggle[USE_CUDA] ) {
|
||||||
|
|
||||||
|
#ifdef BUILD_CUDA
|
||||||
|
// -- GPU --
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
TransferToCUDA ( mBuf[0].data, (int*) &m_Grid[0], NumPoints() );
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "TO: %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
Grid_InsertParticlesCUDA ();
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "INSERT (CUDA): %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
SPH_ComputePressureCUDA ();
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "PRESS (CUDA): %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
SPH_ComputeForceCUDA ();
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FORCE (CUDA): %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
//** CUDA integrator is incomplete..
|
||||||
|
// Once integrator is done, we can remove TransferTo/From steps
|
||||||
|
/*start.SetSystemTime ( ACC_NSEC );
|
||||||
|
SPH_AdvanceCUDA( m_DT, m_DT/m_Param[SPH_SIMSCALE] );
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "ADV (CUDA): %s\n", stop.GetReadableTime().c_str() ); }*/
|
||||||
|
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
TransferFromCUDA ( mBuf[0].data, (int*) &m_Grid[0], NumPoints() );
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FROM: %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
// .. Do advance on CPU
|
||||||
|
Advance();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// -- CPU only --
|
||||||
|
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
Grid_InsertParticles ();
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "INSERT: %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
SPH_ComputePressureGrid ();
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "PRESS: %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
SPH_ComputeForceGridNC ();
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "FORCE: %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
Advance();
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "ADV: %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FluidSystem::SPH_DrawDomain ()
|
||||||
|
{
|
||||||
|
Vector3DF min, max;
|
||||||
|
min = m_Vec[SPH_VOLMIN];
|
||||||
|
max = m_Vec[SPH_VOLMAX];
|
||||||
|
min.z += 0.5;
|
||||||
|
|
||||||
|
glColor3f ( 0.0, 0.0, 1.0 );
|
||||||
|
glBegin ( GL_LINES );
|
||||||
|
glVertex3f ( min.x, min.y, min.z ); glVertex3f ( max.x, min.y, min.z );
|
||||||
|
glVertex3f ( min.x, max.y, min.z ); glVertex3f ( max.x, max.y, min.z );
|
||||||
|
glVertex3f ( min.x, min.y, min.z ); glVertex3f ( min.x, max.y, min.z );
|
||||||
|
glVertex3f ( max.x, min.y, min.z ); glVertex3f ( max.x, max.y, min.z );
|
||||||
|
glEnd ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidSystem::Advance ()
|
||||||
|
{
|
||||||
|
char *dat1, *dat1_end;
|
||||||
|
Fluid* p;
|
||||||
|
Vector3DF norm, z;
|
||||||
|
Vector3DF dir, accel;
|
||||||
|
Vector3DF vnext;
|
||||||
|
Vector3DF min, max;
|
||||||
|
double adj;
|
||||||
|
float SL, SL2, ss, radius;
|
||||||
|
float stiff, damp, speed, diff;
|
||||||
|
SL = m_Param[SPH_LIMIT];
|
||||||
|
SL2 = SL*SL;
|
||||||
|
|
||||||
|
stiff = m_Param[SPH_EXTSTIFF];
|
||||||
|
damp = m_Param[SPH_EXTDAMP];
|
||||||
|
radius = m_Param[SPH_PRADIUS];
|
||||||
|
min = m_Vec[SPH_VOLMIN];
|
||||||
|
max = m_Vec[SPH_VOLMAX];
|
||||||
|
ss = m_Param[SPH_SIMSCALE];
|
||||||
|
|
||||||
|
dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
|
||||||
|
p = (Fluid*) dat1;
|
||||||
|
|
||||||
|
// Compute Acceleration
|
||||||
|
accel = p->sph_force;
|
||||||
|
accel *= m_Param[SPH_PMASS];
|
||||||
|
|
||||||
|
// Velocity limiting
|
||||||
|
speed = accel.x*accel.x + accel.y*accel.y + accel.z*accel.z;
|
||||||
|
if ( speed > SL2 ) {
|
||||||
|
accel *= SL / sqrt(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boundary Conditions
|
||||||
|
|
||||||
|
// Z-axis walls
|
||||||
|
diff = 2 * radius - ( p->pos.z - min.z - (p->pos.x - m_Vec[SPH_VOLMIN].x) * m_Param[BOUND_ZMIN_SLOPE] )*ss;
|
||||||
|
if (diff > EPSILON ) {
|
||||||
|
norm.Set ( -m_Param[BOUND_ZMIN_SLOPE], 0, 1.0 - m_Param[BOUND_ZMIN_SLOPE] );
|
||||||
|
adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff = 2 * radius - ( max.z - p->pos.z )*ss;
|
||||||
|
if (diff > EPSILON) {
|
||||||
|
norm.Set ( 0, 0, -1 );
|
||||||
|
adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// X-axis walls
|
||||||
|
if ( !m_Toggle[WRAP_X] ) {
|
||||||
|
diff = 2 * radius - ( p->pos.x - min.x + (sin(m_Time*10.0)-1+(p->pos.y*0.025)*0.25) * m_Param[FORCE_XMIN_SIN] )*ss;
|
||||||
|
//diff = 2 * radius - ( p->pos.x - min.x + (sin(m_Time*10.0)-1) * m_Param[FORCE_XMIN_SIN] )*ss;
|
||||||
|
if (diff > EPSILON ) {
|
||||||
|
norm.Set ( 1.0, 0, 0 );
|
||||||
|
adj = (m_Param[ FORCE_XMIN_SIN ] + 1) * stiff * diff - damp * norm.Dot ( p->vel_eval ) ;
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff = 2 * radius - ( max.x - p->pos.x + (sin(m_Time*10.0)-1) * m_Param[FORCE_XMAX_SIN] )*ss;
|
||||||
|
if (diff > EPSILON) {
|
||||||
|
norm.Set ( -1, 0, 0 );
|
||||||
|
adj = (m_Param[ FORCE_XMAX_SIN ]+1) * stiff * diff - damp * norm.Dot ( p->vel_eval );
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Y-axis walls
|
||||||
|
diff = 2 * radius - ( p->pos.y - min.y )*ss;
|
||||||
|
if (diff > EPSILON) {
|
||||||
|
norm.Set ( 0, 1, 0 );
|
||||||
|
adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
diff = 2 * radius - ( max.y - p->pos.y )*ss;
|
||||||
|
if (diff > EPSILON) {
|
||||||
|
norm.Set ( 0, -1, 0 );
|
||||||
|
adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wall barrier
|
||||||
|
if ( m_Toggle[WALL_BARRIER] ) {
|
||||||
|
diff = 2 * radius - ( p->pos.x - 0 )*ss;
|
||||||
|
if (diff < 2*radius && diff > EPSILON && fabs(p->pos.y) < 3 && p->pos.z < 10) {
|
||||||
|
norm.Set ( 1.0, 0, 0 );
|
||||||
|
adj = 2*stiff * diff - damp * norm.Dot ( p->vel_eval ) ;
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Levy barrier
|
||||||
|
if ( m_Toggle[LEVY_BARRIER] ) {
|
||||||
|
diff = 2 * radius - ( p->pos.x - 0 )*ss;
|
||||||
|
if (diff < 2*radius && diff > EPSILON && fabs(p->pos.y) > 5 && p->pos.z < 10) {
|
||||||
|
norm.Set ( 1.0, 0, 0 );
|
||||||
|
adj = 2*stiff * diff - damp * norm.Dot ( p->vel_eval ) ;
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Drain barrier
|
||||||
|
if ( m_Toggle[DRAIN_BARRIER] ) {
|
||||||
|
diff = 2 * radius - ( p->pos.z - min.z-15 )*ss;
|
||||||
|
if (diff < 2*radius && diff > EPSILON && (fabs(p->pos.x)>3 || fabs(p->pos.y)>3) ) {
|
||||||
|
norm.Set ( 0, 0, 1);
|
||||||
|
adj = stiff * diff - damp * norm.Dot ( p->vel_eval );
|
||||||
|
accel.x += adj * norm.x; accel.y += adj * norm.y; accel.z += adj * norm.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plane gravity
|
||||||
|
if ( m_Param[PLANE_GRAV] > 0)
|
||||||
|
accel += m_Vec[PLANE_GRAV_DIR];
|
||||||
|
|
||||||
|
// Point gravity
|
||||||
|
if ( m_Param[POINT_GRAV] > 0 ) {
|
||||||
|
norm.x = ( p->pos.x - m_Vec[POINT_GRAV_POS].x );
|
||||||
|
norm.y = ( p->pos.y - m_Vec[POINT_GRAV_POS].y );
|
||||||
|
norm.z = ( p->pos.z - m_Vec[POINT_GRAV_POS].z );
|
||||||
|
norm.Normalize ();
|
||||||
|
norm *= m_Param[POINT_GRAV];
|
||||||
|
accel -= norm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leapfrog Integration ----------------------------
|
||||||
|
vnext = accel;
|
||||||
|
vnext *= m_DT;
|
||||||
|
vnext += p->vel; // v(t+1/2) = v(t-1/2) + a(t) dt
|
||||||
|
p->vel_eval = p->vel;
|
||||||
|
p->vel_eval += vnext;
|
||||||
|
p->vel_eval *= 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later
|
||||||
|
p->vel = vnext;
|
||||||
|
vnext *= m_DT/ss;
|
||||||
|
p->pos += vnext; // p(t+1) = p(t) + v(t+1/2) dt
|
||||||
|
|
||||||
|
if ( m_Param[CLR_MODE]==1.0 ) {
|
||||||
|
adj = fabs(vnext.x)+fabs(vnext.y)+fabs(vnext.z) / 7000.0;
|
||||||
|
adj = (adj > 1.0) ? 1.0 : adj;
|
||||||
|
p->clr = COLORA( 0, adj, adj, 1 );
|
||||||
|
}
|
||||||
|
if ( m_Param[CLR_MODE]==2.0 ) {
|
||||||
|
float v = 0.5 + ( p->pressure / 1500.0);
|
||||||
|
if ( v < 0.1 ) v = 0.1;
|
||||||
|
if ( v > 1.0 ) v = 1.0;
|
||||||
|
p->clr = COLORA ( v, 1-v, 0, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Euler integration -------------------------------
|
||||||
|
/* accel += m_Gravity;
|
||||||
|
accel *= m_DT;
|
||||||
|
p->vel += accel; // v(t+1) = v(t) + a(t) dt
|
||||||
|
p->vel_eval += accel;
|
||||||
|
p->vel_eval *= m_DT/d;
|
||||||
|
p->pos += p->vel_eval;
|
||||||
|
p->vel_eval = p->vel; */
|
||||||
|
|
||||||
|
|
||||||
|
if ( m_Toggle[WRAP_X] ) {
|
||||||
|
diff = p->pos.x - (m_Vec[SPH_VOLMIN].x + 2); // -- Simulates object in center of flow
|
||||||
|
if ( diff <= 0 ) {
|
||||||
|
p->pos.x = (m_Vec[SPH_VOLMAX].x - 2) + diff*2;
|
||||||
|
p->pos.z = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Time += m_DT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------ SPH Setup
|
||||||
|
//
|
||||||
|
// Range = +/- 10.0 * 0.006 (r) = 0.12 m (= 120 mm = 4.7 inch)
|
||||||
|
// Container Volume (Vc) = 0.001728 m^3
|
||||||
|
// Rest Density (D) = 1000.0 kg / m^3
|
||||||
|
// Particle Mass (Pm) = 0.00020543 kg (mass = vol * density)
|
||||||
|
// Number of Particles (N) = 4000.0
|
||||||
|
// Water Mass (M) = 0.821 kg (= 821 grams)
|
||||||
|
// Water Volume (V) = 0.000821 m^3 (= 3.4 cups, .21 gals)
|
||||||
|
// Smoothing Radius (R) = 0.02 m (= 20 mm = ~3/4 inch)
|
||||||
|
// Particle Radius (Pr) = 0.00366 m (= 4 mm = ~1/8 inch)
|
||||||
|
// Particle Volume (Pv) = 2.054e-7 m^3 (= .268 milliliters)
|
||||||
|
// Rest Distance (Pd) = 0.0059 m
|
||||||
|
//
|
||||||
|
// Given: D, Pm, N
|
||||||
|
// Pv = Pm / D 0.00020543 kg / 1000 kg/m^3 = 2.054e-7 m^3
|
||||||
|
// Pv = 4/3*pi*Pr^3 cuberoot( 2.054e-7 m^3 * 3/(4pi) ) = 0.00366 m
|
||||||
|
// M = Pm * N 0.00020543 kg * 4000.0 = 0.821 kg
|
||||||
|
// V = M / D 0.821 kg / 1000 kg/m^3 = 0.000821 m^3
|
||||||
|
// V = Pv * N 2.054e-7 m^3 * 4000 = 0.000821 m^3
|
||||||
|
// Pd = cuberoot(Pm/D) cuberoot(0.00020543/1000) = 0.0059 m
|
||||||
|
//
|
||||||
|
// Ideal grid cell size (gs) = 2 * smoothing radius = 0.02*2 = 0.04
|
||||||
|
// Ideal domain size = k*gs/d = k*0.02*2/0.005 = k*8 = {8, 16, 24, 32, 40, 48, ..}
|
||||||
|
// (k = number of cells, gs = cell size, d = simulation scale)
|
||||||
|
|
||||||
|
void FluidSystem::SPH_Setup ()
|
||||||
|
{
|
||||||
|
m_Param [ SPH_SIMSCALE ] = 0.004; // unit size
|
||||||
|
m_Param [ SPH_VISC ] = 0.2; // pascal-second (Pa.s) = 1 kg m^-1 s^-1 (see wikipedia page on viscosity)
|
||||||
|
m_Param [ SPH_RESTDENSITY ] = 600.0; // kg / m^3
|
||||||
|
m_Param [ SPH_PMASS ] = 0.00020543; // kg
|
||||||
|
m_Param [ SPH_PRADIUS ] = 0.004; // m
|
||||||
|
m_Param [ SPH_PDIST ] = 0.0059; // m
|
||||||
|
m_Param [ SPH_SMOOTHRADIUS ] = 0.01; // m
|
||||||
|
m_Param [ SPH_INTSTIFF ] = 1.00;
|
||||||
|
m_Param [ SPH_EXTSTIFF ] = 10000.0;
|
||||||
|
m_Param [ SPH_EXTDAMP ] = 256.0;
|
||||||
|
m_Param [ SPH_LIMIT ] = 200.0; // m / s
|
||||||
|
|
||||||
|
m_Toggle [ SPH_GRID ] = false;
|
||||||
|
m_Toggle [ SPH_DEBUG ] = false;
|
||||||
|
|
||||||
|
SPH_ComputeKernels ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidSystem::SPH_ComputeKernels ()
|
||||||
|
{
|
||||||
|
m_Param [ SPH_PDIST ] = pow ( m_Param[SPH_PMASS] / m_Param[SPH_RESTDENSITY], 1/3.0 );
|
||||||
|
m_R2 = m_Param [SPH_SMOOTHRADIUS] * m_Param[SPH_SMOOTHRADIUS];
|
||||||
|
m_Poly6Kern = 315.0f / (64.0f * 3.141592 * pow( m_Param[SPH_SMOOTHRADIUS], 9) ); // Wpoly6 kernel (denominator part) - 2003 Muller, p.4
|
||||||
|
m_SpikyKern = -45.0f / (3.141592 * pow( m_Param[SPH_SMOOTHRADIUS], 6) ); // Laplacian of viscocity (denominator): PI h^6
|
||||||
|
m_LapKern = 45.0f / (3.141592 * pow( m_Param[SPH_SMOOTHRADIUS], 6) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidSystem::SPH_CreateExample ( int n, int nmax )
|
||||||
|
{
|
||||||
|
Vector3DF pos;
|
||||||
|
Vector3DF min, max;
|
||||||
|
|
||||||
|
Reset ( nmax );
|
||||||
|
|
||||||
|
switch ( n ) {
|
||||||
|
case 0: // Wave pool
|
||||||
|
|
||||||
|
//-- TEST CASE: 2x2x2 grid, 32 particles. NOTE: Set PRADIUS to 0.0004 to reduce wall influence
|
||||||
|
// grid 0: 3*3*2 = 18 particles
|
||||||
|
// grid 1,2: 3*1*2 = 6 particles
|
||||||
|
// grid 3: 1*1*2 = 2 particles
|
||||||
|
// grid 4,5,6: 0 = 0 particles
|
||||||
|
/*m_Vec [ SPH_VOLMIN ].Set ( -2.5, -2.5, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 2.5, 2.5, 5.0 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -2.5, -2.5, 0 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 2.5, 2.5, 1.6 );*/
|
||||||
|
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 40 );
|
||||||
|
|
||||||
|
//m_Vec [ SPH_INITMIN ].Set ( -5, -5, 10 );
|
||||||
|
//m_Vec [ SPH_INITMAX ].Set ( 5, 5, 20 );
|
||||||
|
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -20, -26, 10 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 20, 26, 40 );
|
||||||
|
|
||||||
|
m_Param [ FORCE_XMIN_SIN ] = 12.0;
|
||||||
|
m_Param [ BOUND_ZMIN_SLOPE ] = 0.05;
|
||||||
|
break;
|
||||||
|
case 1: // Dam break
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -30, -14, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 30, 14, 60 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( 0, -13, 0 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 29, 13, 30 );
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
|
||||||
|
break;
|
||||||
|
case 2: // Dual-Wave pool
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -60, -5, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 60, 5, 50 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -46, -5, 0 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 46, 5, 15 );
|
||||||
|
m_Param [ FORCE_XMIN_SIN ] = 8.0;
|
||||||
|
m_Param [ FORCE_XMAX_SIN ] = 8.0;
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
|
||||||
|
break;
|
||||||
|
case 3: // Swirl Stream
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 50 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -30, -30, 0 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 30, 30, 40 );
|
||||||
|
m_Vec [ EMIT_POS ].Set ( -20, -20, 22 );
|
||||||
|
m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );
|
||||||
|
m_Vec [ EMIT_ANG ].Set ( 0, 120, 1.5 );
|
||||||
|
m_Vec [ EMIT_DANG ].Set ( 0, 0, 0 );
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
|
||||||
|
break;
|
||||||
|
case 4: // Shockwave
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -60, -15, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 60, 15, 50 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -59, -14, 0 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 59, 14, 30 );
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
|
||||||
|
m_Toggle [ WALL_BARRIER ] = true;
|
||||||
|
m_Toggle [ WRAP_X ] = true;
|
||||||
|
break;
|
||||||
|
case 5: // Zero gravity
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -20, -20, 20 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 20, 20, 40 );
|
||||||
|
m_Vec [ EMIT_POS ].Set ( -20, 0, 40 );
|
||||||
|
m_Vec [ EMIT_RATE ].Set ( 2, 1, 0 );
|
||||||
|
m_Vec [ EMIT_ANG ].Set ( 0, 120, 0.25 );
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, 0 );
|
||||||
|
m_Param [ SPH_INTSTIFF ] = 0.20;
|
||||||
|
break;
|
||||||
|
case 6: // Point gravity
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -20, -20, 20 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 20, 20, 40 );
|
||||||
|
m_Param [ SPH_INTSTIFF ] = 0.50;
|
||||||
|
m_Vec [ EMIT_POS ].Set ( -20, 20, 25 );
|
||||||
|
m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );
|
||||||
|
m_Vec [ EMIT_ANG ].Set ( -20, 100, 2.0 );
|
||||||
|
m_Vec [ POINT_GRAV_POS ].Set ( 0, 0, 25 );
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0, 0, 0 );
|
||||||
|
m_Param [ POINT_GRAV ] = 3.5;
|
||||||
|
break;
|
||||||
|
case 7: // Levy break
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -40, -40, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 40, 40, 50 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( 10, -40, 0 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 40, 40, 50 );
|
||||||
|
m_Vec [ EMIT_POS ].Set ( 34, 27, 16.6 );
|
||||||
|
m_Vec [ EMIT_RATE ].Set ( 2, 9, 0 );
|
||||||
|
m_Vec [ EMIT_ANG ].Set ( 118, 200, 1.0 );
|
||||||
|
m_Toggle [ LEVY_BARRIER ] = true;
|
||||||
|
m_Param [ BOUND_ZMIN_SLOPE ] = 0.1;
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
|
||||||
|
break;
|
||||||
|
case 8: // Drain
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -20, -20, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 20, 20, 50 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -15, -20, 20 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 20, 20, 50 );
|
||||||
|
m_Vec [ EMIT_POS ].Set ( -16, -16, 30 );
|
||||||
|
m_Vec [ EMIT_RATE ].Set ( 1, 4, 0 );
|
||||||
|
m_Vec [ EMIT_ANG ].Set ( -20, 140, 1.8 );
|
||||||
|
m_Toggle [ DRAIN_BARRIER ] = true;
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
|
||||||
|
break;
|
||||||
|
case 9: // Tumbler
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -30, -30, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 30, 30, 50 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( 24, -29, 20 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 29, 29, 40 );
|
||||||
|
m_Param [ SPH_VISC ] = 0.1;
|
||||||
|
m_Param [ SPH_INTSTIFF ] = 0.50;
|
||||||
|
m_Param [ SPH_EXTSTIFF ] = 8000;
|
||||||
|
//m_Param [ SPH_SMOOTHRADIUS ] = 0.01;
|
||||||
|
m_Param [ BOUND_ZMIN_SLOPE ] = 0.4;
|
||||||
|
m_Param [ FORCE_XMIN_SIN ] = 12.00;
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
|
||||||
|
break;
|
||||||
|
case 10: // Large sim
|
||||||
|
m_Vec [ SPH_VOLMIN ].Set ( -35, -35, 0 );
|
||||||
|
m_Vec [ SPH_VOLMAX ].Set ( 35, 35, 60 );
|
||||||
|
m_Vec [ SPH_INITMIN ].Set ( -5, -35, 0 );
|
||||||
|
m_Vec [ SPH_INITMAX ].Set ( 30, 0, 60 );
|
||||||
|
m_Vec [ PLANE_GRAV_DIR ].Set ( 0.0, 0, -9.8 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPH_ComputeKernels ();
|
||||||
|
|
||||||
|
m_Param [ SPH_SIMSIZE ] = m_Param [ SPH_SIMSCALE ] * (m_Vec[SPH_VOLMAX].z - m_Vec[SPH_VOLMIN].z);
|
||||||
|
m_Param [ SPH_PDIST ] = pow ( m_Param[SPH_PMASS] / m_Param[SPH_RESTDENSITY], 1/3.0 );
|
||||||
|
|
||||||
|
float ss = m_Param [ SPH_PDIST ]*0.87 / m_Param[ SPH_SIMSCALE ];
|
||||||
|
printf ( "Spacing: %f\n", ss);
|
||||||
|
AddVolume ( m_Vec[SPH_INITMIN], m_Vec[SPH_INITMAX], ss ); // Create the particles
|
||||||
|
|
||||||
|
float cell_size = m_Param[SPH_SMOOTHRADIUS]*2.0; // Grid cell size (2r)
|
||||||
|
Grid_Setup ( m_Vec[SPH_VOLMIN], m_Vec[SPH_VOLMAX], m_Param[SPH_SIMSCALE], cell_size, 1.0 ); // Setup grid
|
||||||
|
Grid_InsertParticles (); // Insert particles
|
||||||
|
|
||||||
|
Vector3DF vmin, vmax;
|
||||||
|
vmin = m_Vec[SPH_VOLMIN];
|
||||||
|
vmin -= Vector3DF(2,2,2);
|
||||||
|
vmax = m_Vec[SPH_VOLMAX];
|
||||||
|
vmax += Vector3DF(2,2,-2);
|
||||||
|
|
||||||
|
#ifdef BUILD_CUDA
|
||||||
|
FluidClearCUDA ();
|
||||||
|
Sleep ( 500 );
|
||||||
|
|
||||||
|
FluidSetupCUDA ( NumPoints(), sizeof(Fluid), *(float3*)& m_GridMin, *(float3*)& m_GridMax, *(float3*)& m_GridRes, *(float3*)& m_GridSize, (int) m_Vec[EMIT_RATE].x );
|
||||||
|
|
||||||
|
Sleep ( 500 );
|
||||||
|
|
||||||
|
FluidParamCUDA ( m_Param[SPH_SIMSCALE], m_Param[SPH_SMOOTHRADIUS], m_Param[SPH_PMASS], m_Param[SPH_RESTDENSITY], m_Param[SPH_INTSTIFF], m_Param[SPH_VISC] );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute Pressures - Very slow yet simple. O(n^2)
|
||||||
|
void FluidSystem::SPH_ComputePressureSlow ()
|
||||||
|
{
|
||||||
|
char *dat1, *dat1_end;
|
||||||
|
char *dat2, *dat2_end;
|
||||||
|
Fluid *p, *q;
|
||||||
|
int cnt = 0;
|
||||||
|
double dx, dy, dz, sum, dsq, c;
|
||||||
|
double d, d2, mR, mR2;
|
||||||
|
d = m_Param[SPH_SIMSCALE];
|
||||||
|
d2 = d*d;
|
||||||
|
mR = m_Param[SPH_SMOOTHRADIUS];
|
||||||
|
mR2 = mR*mR;
|
||||||
|
|
||||||
|
dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
|
||||||
|
p = (Fluid*) dat1;
|
||||||
|
|
||||||
|
sum = 0.0;
|
||||||
|
cnt = 0;
|
||||||
|
|
||||||
|
dat2_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
for ( dat2 = mBuf[0].data; dat2 < dat2_end; dat2 += mBuf[0].stride ) {
|
||||||
|
q = (Fluid*) dat2;
|
||||||
|
|
||||||
|
if ( p==q ) continue;
|
||||||
|
dx = ( p->pos.x - q->pos.x)*d; // dist in cm
|
||||||
|
dy = ( p->pos.y - q->pos.y)*d;
|
||||||
|
dz = ( p->pos.z - q->pos.z)*d;
|
||||||
|
dsq = (dx*dx + dy*dy + dz*dz);
|
||||||
|
if ( mR2 > dsq ) {
|
||||||
|
c = m_R2 - dsq;
|
||||||
|
sum += c * c * c;
|
||||||
|
cnt++;
|
||||||
|
//if ( p == m_CurrP ) q->tag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->density = sum * m_Param[SPH_PMASS] * m_Poly6Kern ;
|
||||||
|
p->pressure = ( p->density - m_Param[SPH_RESTDENSITY] ) * m_Param[SPH_INTSTIFF];
|
||||||
|
p->density = 1.0f / p->density;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute Pressures - Using spatial grid, and also create neighbor table
|
||||||
|
void FluidSystem::SPH_ComputePressureGrid ()
|
||||||
|
{
|
||||||
|
char *dat1, *dat1_end;
|
||||||
|
Fluid* p;
|
||||||
|
Fluid* pcurr;
|
||||||
|
int pndx;
|
||||||
|
int i, cnt = 0;
|
||||||
|
float dx, dy, dz, sum, dsq, c;
|
||||||
|
float d, d2, mR, mR2;
|
||||||
|
float radius = m_Param[SPH_SMOOTHRADIUS] / m_Param[SPH_SIMSCALE];
|
||||||
|
d = m_Param[SPH_SIMSCALE];
|
||||||
|
d2 = d*d;
|
||||||
|
mR = m_Param[SPH_SMOOTHRADIUS];
|
||||||
|
mR2 = mR*mR;
|
||||||
|
|
||||||
|
dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
i = 0;
|
||||||
|
for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride, i++ ) {
|
||||||
|
p = (Fluid*) dat1;
|
||||||
|
|
||||||
|
sum = 0.0;
|
||||||
|
m_NC[i] = 0;
|
||||||
|
|
||||||
|
Grid_FindCells ( p->pos, radius );
|
||||||
|
for (int cell=0; cell < 8; cell++) {
|
||||||
|
if ( m_GridCell[cell] != -1 ) {
|
||||||
|
pndx = m_Grid [ m_GridCell[cell] ];
|
||||||
|
while ( pndx != -1 ) {
|
||||||
|
pcurr = (Fluid*) (mBuf[0].data + pndx*mBuf[0].stride);
|
||||||
|
if ( pcurr == p ) {pndx = pcurr->next; continue; }
|
||||||
|
dx = ( p->pos.x - pcurr->pos.x)*d; // dist in cm
|
||||||
|
dy = ( p->pos.y - pcurr->pos.y)*d;
|
||||||
|
dz = ( p->pos.z - pcurr->pos.z)*d;
|
||||||
|
dsq = (dx*dx + dy*dy + dz*dz);
|
||||||
|
if ( mR2 > dsq ) {
|
||||||
|
c = m_R2 - dsq;
|
||||||
|
sum += c * c * c;
|
||||||
|
if ( m_NC[i] < MAX_NEIGHBOR ) {
|
||||||
|
m_Neighbor[i][ m_NC[i] ] = pndx;
|
||||||
|
m_NDist[i][ m_NC[i] ] = sqrt(dsq);
|
||||||
|
m_NC[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pndx = pcurr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_GridCell[cell] = -1;
|
||||||
|
}
|
||||||
|
p->density = sum * m_Param[SPH_PMASS] * m_Poly6Kern ;
|
||||||
|
p->pressure = ( p->density - m_Param[SPH_RESTDENSITY] ) * m_Param[SPH_INTSTIFF];
|
||||||
|
p->density = 1.0f / p->density;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute Forces - Very slow, but simple. O(n^2)
|
||||||
|
void FluidSystem::SPH_ComputeForceSlow ()
|
||||||
|
{
|
||||||
|
char *dat1, *dat1_end;
|
||||||
|
char *dat2, *dat2_end;
|
||||||
|
Fluid *p, *q;
|
||||||
|
Vector3DF force, fcurr;
|
||||||
|
register double pterm, vterm, dterm;
|
||||||
|
double c, r, d, sum, dsq;
|
||||||
|
double dx, dy, dz;
|
||||||
|
double mR, mR2, visc;
|
||||||
|
|
||||||
|
d = m_Param[SPH_SIMSCALE];
|
||||||
|
mR = m_Param[SPH_SMOOTHRADIUS];
|
||||||
|
mR2 = (mR*mR);
|
||||||
|
visc = m_Param[SPH_VISC];
|
||||||
|
vterm = m_LapKern * visc;
|
||||||
|
|
||||||
|
dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
|
||||||
|
p = (Fluid*) dat1;
|
||||||
|
|
||||||
|
sum = 0.0;
|
||||||
|
force.Set ( 0, 0, 0 );
|
||||||
|
|
||||||
|
dat2_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
for ( dat2 = mBuf[0].data; dat2 < dat2_end; dat2 += mBuf[0].stride ) {
|
||||||
|
q = (Fluid*) dat2;
|
||||||
|
|
||||||
|
if ( p == q ) continue;
|
||||||
|
dx = ( p->pos.x - q->pos.x )*d; // dist in cm
|
||||||
|
dy = ( p->pos.y - q->pos.y )*d;
|
||||||
|
dz = ( p->pos.z - q->pos.z )*d;
|
||||||
|
dsq = (dx*dx + dy*dy + dz*dz);
|
||||||
|
if ( mR2 > dsq ) {
|
||||||
|
r = sqrt ( dsq );
|
||||||
|
c = (mR - r);
|
||||||
|
pterm = -0.5f * c * m_SpikyKern * ( p->pressure + q->pressure) / r;
|
||||||
|
dterm = c * p->density * q->density;
|
||||||
|
force.x += ( pterm * dx + vterm * (q->vel_eval.x - p->vel_eval.x) ) * dterm;
|
||||||
|
force.y += ( pterm * dy + vterm * (q->vel_eval.y - p->vel_eval.y) ) * dterm;
|
||||||
|
force.z += ( pterm * dz + vterm * (q->vel_eval.z - p->vel_eval.z) ) * dterm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->sph_force = force;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute Forces - Using spatial grid. Faster.
|
||||||
|
void FluidSystem::SPH_ComputeForceGrid ()
|
||||||
|
{
|
||||||
|
char *dat1, *dat1_end;
|
||||||
|
Fluid *p;
|
||||||
|
Fluid *pcurr;
|
||||||
|
int pndx;
|
||||||
|
Vector3DF force, fcurr;
|
||||||
|
register double pterm, vterm, dterm;
|
||||||
|
double c, d, dsq, r;
|
||||||
|
double dx, dy, dz;
|
||||||
|
double mR, mR2, visc;
|
||||||
|
float radius = m_Param[SPH_SMOOTHRADIUS] / m_Param[SPH_SIMSCALE];
|
||||||
|
|
||||||
|
d = m_Param[SPH_SIMSCALE];
|
||||||
|
mR = m_Param[SPH_SMOOTHRADIUS];
|
||||||
|
mR2 = (mR*mR);
|
||||||
|
visc = m_Param[SPH_VISC];
|
||||||
|
|
||||||
|
dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride ) {
|
||||||
|
p = (Fluid*) dat1;
|
||||||
|
|
||||||
|
force.Set ( 0, 0, 0 );
|
||||||
|
|
||||||
|
Grid_FindCells ( p->pos, radius );
|
||||||
|
for (int cell=0; cell < 8; cell++) {
|
||||||
|
if ( m_GridCell[cell] != -1 ) {
|
||||||
|
pndx = m_Grid [ m_GridCell[cell] ];
|
||||||
|
while ( pndx != -1 ) {
|
||||||
|
pcurr = (Fluid*) (mBuf[0].data + pndx*mBuf[0].stride);
|
||||||
|
if ( pcurr == p ) {pndx = pcurr->next; continue; }
|
||||||
|
|
||||||
|
dx = ( p->pos.x - pcurr->pos.x)*d; // dist in cm
|
||||||
|
dy = ( p->pos.y - pcurr->pos.y)*d;
|
||||||
|
dz = ( p->pos.z - pcurr->pos.z)*d;
|
||||||
|
dsq = (dx*dx + dy*dy + dz*dz);
|
||||||
|
if ( mR2 > dsq ) {
|
||||||
|
r = sqrt ( dsq );
|
||||||
|
c = (mR - r);
|
||||||
|
pterm = -0.5f * c * m_SpikyKern * ( p->pressure + pcurr->pressure) / r;
|
||||||
|
dterm = c * p->density * pcurr->density;
|
||||||
|
vterm = m_LapKern * visc;
|
||||||
|
force.x += ( pterm * dx + vterm * (pcurr->vel_eval.x - p->vel_eval.x) ) * dterm;
|
||||||
|
force.y += ( pterm * dy + vterm * (pcurr->vel_eval.y - p->vel_eval.y) ) * dterm;
|
||||||
|
force.z += ( pterm * dz + vterm * (pcurr->vel_eval.z - p->vel_eval.z) ) * dterm;
|
||||||
|
}
|
||||||
|
pndx = pcurr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->sph_force = force;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute Forces - Using spatial grid with saved neighbor table. Fastest.
|
||||||
|
void FluidSystem::SPH_ComputeForceGridNC ()
|
||||||
|
{
|
||||||
|
char *dat1, *dat1_end;
|
||||||
|
Fluid *p;
|
||||||
|
Fluid *pcurr;
|
||||||
|
Vector3DF force, fcurr;
|
||||||
|
register float pterm, vterm, dterm;
|
||||||
|
int i;
|
||||||
|
float c, d;
|
||||||
|
float dx, dy, dz;
|
||||||
|
float mR, mR2, visc;
|
||||||
|
|
||||||
|
d = m_Param[SPH_SIMSCALE];
|
||||||
|
mR = m_Param[SPH_SMOOTHRADIUS];
|
||||||
|
mR2 = (mR*mR);
|
||||||
|
visc = m_Param[SPH_VISC];
|
||||||
|
|
||||||
|
dat1_end = mBuf[0].data + NumPoints()*mBuf[0].stride;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for ( dat1 = mBuf[0].data; dat1 < dat1_end; dat1 += mBuf[0].stride, i++ ) {
|
||||||
|
p = (Fluid*) dat1;
|
||||||
|
|
||||||
|
force.Set ( 0, 0, 0 );
|
||||||
|
for (int j=0; j < m_NC[i]; j++ ) {
|
||||||
|
pcurr = (Fluid*) (mBuf[0].data + m_Neighbor[i][j]*mBuf[0].stride);
|
||||||
|
dx = ( p->pos.x - pcurr->pos.x)*d; // dist in cm
|
||||||
|
dy = ( p->pos.y - pcurr->pos.y)*d;
|
||||||
|
dz = ( p->pos.z - pcurr->pos.z)*d;
|
||||||
|
c = ( mR - m_NDist[i][j] );
|
||||||
|
pterm = -0.5f * c * m_SpikyKern * ( p->pressure + pcurr->pressure) / m_NDist[i][j];
|
||||||
|
dterm = c * p->density * pcurr->density;
|
||||||
|
vterm = m_LapKern * visc;
|
||||||
|
force.x += ( pterm * dx + vterm * (pcurr->vel_eval.x - p->vel_eval.x) ) * dterm;
|
||||||
|
force.y += ( pterm * dy + vterm * (pcurr->vel_eval.y - p->vel_eval.y) ) * dterm;
|
||||||
|
force.z += ( pterm * dz + vterm * (pcurr->vel_eval.z - p->vel_eval.z) ) * dterm;
|
||||||
|
}
|
||||||
|
p->sph_force = force;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
71
Extras/sph/fluids/fluid_system.cu
Normal file
71
Extras/sph/fluids/fluid_system.cu
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cutil.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(__APPLE__) || defined(MACOSX)
|
||||||
|
#include <GLUT/glut.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
#include <cuda_gl_interop.h>
|
||||||
|
|
||||||
|
#include "fluid_system_kern.cu"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
// Compute number of blocks to create
|
||||||
|
int iDivUp (int a, int b) {
|
||||||
|
return (a % b != 0) ? (a / b + 1) : (a / b);
|
||||||
|
}
|
||||||
|
void computeNumBlocks (int numPnts, int minThreads, int &numBlocks, int &numThreads)
|
||||||
|
{
|
||||||
|
numThreads = min( minThreads, numPnts );
|
||||||
|
numBlocks = iDivUp ( numPnts, numThreads );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Grid_InsertParticlesCUDA ( uchar* data, uint stride, uint numPoints )
|
||||||
|
{
|
||||||
|
int numThreads, numBlocks;
|
||||||
|
computeNumBlocks (numPoints, 256, numBlocks, numThreads);
|
||||||
|
|
||||||
|
// transfer point data to device
|
||||||
|
char* pntData;
|
||||||
|
size = numPoints * stride;
|
||||||
|
cudaMalloc( (void**) &pntData, size);
|
||||||
|
cudaMemcpy( pntData, data, size, cudaMemcpyHostToDevice);
|
||||||
|
|
||||||
|
// execute the kernel
|
||||||
|
insertParticles<<< numBlocks, numThreads >>> ( pntData, stride );
|
||||||
|
|
||||||
|
// transfer data back to host
|
||||||
|
cudaMemcpy( data, pntData, cudaMemcpyDeviceToHost);
|
||||||
|
|
||||||
|
// check if kernel invocation generated an error
|
||||||
|
CUT_CHECK_ERROR("Kernel execution failed");
|
||||||
|
CUDA_SAFE_CALL(cudaGLUnmapBufferObject(vboPos));
|
||||||
|
}
|
||||||
106
Extras/sph/fluids/fluid_system.h
Normal file
106
Extras/sph/fluids/fluid_system.h
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 DEF_FLUID_SYS
|
||||||
|
#define DEF_FLUID_SYS
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "point_set.h"
|
||||||
|
#include "fluid.h"
|
||||||
|
|
||||||
|
// Scalar params
|
||||||
|
#define SPH_SIMSIZE 4
|
||||||
|
#define SPH_SIMSCALE 5
|
||||||
|
#define SPH_VISC 6
|
||||||
|
#define SPH_RESTDENSITY 7
|
||||||
|
#define SPH_PMASS 8
|
||||||
|
#define SPH_PRADIUS 9
|
||||||
|
#define SPH_PDIST 10
|
||||||
|
#define SPH_SMOOTHRADIUS 11
|
||||||
|
#define SPH_INTSTIFF 12
|
||||||
|
#define SPH_EXTSTIFF 13
|
||||||
|
#define SPH_EXTDAMP 14
|
||||||
|
#define SPH_LIMIT 15
|
||||||
|
#define BOUND_ZMIN_SLOPE 16
|
||||||
|
#define FORCE_XMAX_SIN 17
|
||||||
|
#define FORCE_XMIN_SIN 18
|
||||||
|
#define MAX_FRAC 19
|
||||||
|
#define CLR_MODE 20
|
||||||
|
|
||||||
|
// Vector params
|
||||||
|
#define SPH_VOLMIN 7
|
||||||
|
#define SPH_VOLMAX 8
|
||||||
|
#define SPH_INITMIN 9
|
||||||
|
#define SPH_INITMAX 10
|
||||||
|
|
||||||
|
// Toggles
|
||||||
|
#define SPH_GRID 0
|
||||||
|
#define SPH_DEBUG 1
|
||||||
|
#define WRAP_X 2
|
||||||
|
#define WALL_BARRIER 3
|
||||||
|
#define LEVY_BARRIER 4
|
||||||
|
#define DRAIN_BARRIER 5
|
||||||
|
#define USE_CUDA 6
|
||||||
|
|
||||||
|
#define MAX_PARAM 21
|
||||||
|
#define BFLUID 2
|
||||||
|
|
||||||
|
class FluidSystem : public PointSet {
|
||||||
|
public:
|
||||||
|
FluidSystem ();
|
||||||
|
|
||||||
|
// Basic Particle System
|
||||||
|
virtual void Initialize ( int mode, int nmax );
|
||||||
|
virtual void Reset ( int nmax );
|
||||||
|
virtual void Run ();
|
||||||
|
virtual void Advance ();
|
||||||
|
virtual int AddPoint ();
|
||||||
|
virtual int AddPointReuse ();
|
||||||
|
Fluid* AddFluid () { return (Fluid*) GetElem(0, AddPointReuse()); }
|
||||||
|
Fluid* GetFluid (int n) { return (Fluid*) GetElem(0, n); }
|
||||||
|
|
||||||
|
// Smoothed Particle Hydrodynamics
|
||||||
|
void SPH_Setup ();
|
||||||
|
void SPH_CreateExample ( int n, int nmax );
|
||||||
|
void SPH_DrawDomain ();
|
||||||
|
void SPH_ComputeKernels ();
|
||||||
|
|
||||||
|
void SPH_ComputePressureSlow (); // O(n^2)
|
||||||
|
void SPH_ComputePressureGrid (); // O(kn) - spatial grid
|
||||||
|
|
||||||
|
void SPH_ComputeForceSlow (); // O(n^2)
|
||||||
|
void SPH_ComputeForceGrid (); // O(kn) - spatial grid
|
||||||
|
void SPH_ComputeForceGridNC (); // O(cn) - neighbor table
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Smoothed Particle Hydrodynamics
|
||||||
|
double m_R2, m_Poly6Kern, m_LapKern, m_SpikyKern; // Kernel functions
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
247
Extras/sph/fluids/fluid_system_host.cu
Normal file
247
Extras/sph/fluids/fluid_system_host.cu
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "C:\CUDA\common\inc\cutil.h" // cutil32.lib
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__APPLE__) || defined(MACOSX)
|
||||||
|
#include <GLUT/glut.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
#include <cuda_gl_interop.h>
|
||||||
|
|
||||||
|
#include "radixsort.cu"
|
||||||
|
#include "fluid_system_kern.cu" // build kernel
|
||||||
|
|
||||||
|
FluidParams fcuda;
|
||||||
|
|
||||||
|
__device__ char* bufPnts; // point data (array of Fluid structs)
|
||||||
|
__device__ char* bufPntSort; // point data (array of Fluid structs)
|
||||||
|
__device__ uint* bufHash[2]; // point grid hash
|
||||||
|
__device__ int* bufGrid;
|
||||||
|
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
// Initialize CUDA
|
||||||
|
void cudaInit(int argc, char **argv)
|
||||||
|
{
|
||||||
|
CUT_DEVICE_INIT(argc, argv);
|
||||||
|
|
||||||
|
cudaDeviceProp p;
|
||||||
|
cudaGetDeviceProperties ( &p, 0);
|
||||||
|
|
||||||
|
printf ( "-- CUDA --\n" );
|
||||||
|
printf ( "Name: %s\n", p.name );
|
||||||
|
printf ( "Revision: %d.%d\n", p.major, p.minor );
|
||||||
|
printf ( "Global Mem: %d\n", p.totalGlobalMem );
|
||||||
|
printf ( "Shared/Blk: %d\n", p.sharedMemPerBlock );
|
||||||
|
printf ( "Regs/Blk: %d\n", p.regsPerBlock );
|
||||||
|
printf ( "Warp Size: %d\n", p.warpSize );
|
||||||
|
printf ( "Mem Pitch: %d\n", p.memPitch );
|
||||||
|
printf ( "Thrds/Blk: %d\n", p.maxThreadsPerBlock );
|
||||||
|
printf ( "Const Mem: %d\n", p.totalConstMem );
|
||||||
|
printf ( "Clock Rate: %d\n", p.clockRate );
|
||||||
|
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufPnts, 10 ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufPntSort, 10 ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufHash, 10 ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufGrid, 10 ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compute number of blocks to create
|
||||||
|
int iDivUp (int a, int b) {
|
||||||
|
return (a % b != 0) ? (a / b + 1) : (a / b);
|
||||||
|
}
|
||||||
|
void computeNumBlocks (int numPnts, int maxThreads, int &numBlocks, int &numThreads)
|
||||||
|
{
|
||||||
|
numThreads = min( maxThreads, numPnts );
|
||||||
|
numBlocks = iDivUp ( numPnts, numThreads );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidClearCUDA ()
|
||||||
|
{
|
||||||
|
CUDA_SAFE_CALL ( cudaFree ( bufPnts ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaFree ( bufPntSort ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaFree ( bufHash[0] ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaFree ( bufHash[1] ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaFree ( bufGrid ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FluidSetupCUDA ( int num, int stride, float3 min, float3 max, float3 res, float3 size, int chk )
|
||||||
|
{
|
||||||
|
fcuda.min = make_float3(min.x, min.y, min.z);
|
||||||
|
fcuda.max = make_float3(max.x, max.y, max.z);
|
||||||
|
fcuda.res = make_float3(res.x, res.y, res.z);
|
||||||
|
fcuda.size = make_float3(size.x, size.y, size.z);
|
||||||
|
fcuda.pnts = num;
|
||||||
|
fcuda.delta.x = res.x / size.x;
|
||||||
|
fcuda.delta.y = res.y / size.y;
|
||||||
|
fcuda.delta.z = res.z / size.z;
|
||||||
|
fcuda.cells = res.x*res.y*res.z;
|
||||||
|
fcuda.chk = chk;
|
||||||
|
|
||||||
|
computeNumBlocks ( fcuda.pnts, 256, fcuda.numBlocks, fcuda.numThreads); // particles
|
||||||
|
computeNumBlocks ( fcuda.cells, 256, fcuda.gridBlocks, fcuda.gridThreads); // grid cell
|
||||||
|
|
||||||
|
fcuda.szPnts = (fcuda.numBlocks * fcuda.numThreads) * stride;
|
||||||
|
fcuda.szHash = (fcuda.numBlocks * fcuda.numThreads) * sizeof(uint2); // <cell, particle> pairs
|
||||||
|
fcuda.szGrid = (fcuda.gridBlocks * fcuda.gridThreads) * sizeof(uint);
|
||||||
|
fcuda.stride = stride;
|
||||||
|
printf ( "pnts: %d, t:%dx%d=%d, bufPnts:%d, bufHash:%d\n", fcuda.pnts, fcuda.numBlocks, fcuda.numThreads, fcuda.numBlocks*fcuda.numThreads, fcuda.szPnts, fcuda.szHash );
|
||||||
|
printf ( "grds: %d, t:%dx%d=%d, bufGrid:%d, Res: %dx%dx%d\n", fcuda.cells, fcuda.gridBlocks, fcuda.gridThreads, fcuda.gridBlocks*fcuda.gridThreads, fcuda.szGrid, (int) fcuda.res.x, (int) fcuda.res.y, (int) fcuda.res.z );
|
||||||
|
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufPnts, fcuda.szPnts ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufPntSort, fcuda.szPnts ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufHash[0], fcuda.szHash ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufHash[1], fcuda.szHash ) );
|
||||||
|
CUDA_SAFE_CALL ( cudaMalloc ( (void**) &bufGrid, fcuda.szGrid ) );
|
||||||
|
|
||||||
|
printf ( "POINTERS\n");
|
||||||
|
printf ( "bufPnts: %p\n", bufPnts );
|
||||||
|
printf ( "bufPntSort: %p\n", bufPntSort );
|
||||||
|
printf ( "bufHash0: %p\n", bufHash[0] );
|
||||||
|
printf ( "bufHash1: %p\n", bufHash[1] );
|
||||||
|
printf ( "bufGrid: %p\n", bufGrid );
|
||||||
|
|
||||||
|
CUDA_SAFE_CALL ( cudaMemcpyToSymbol ( simData, &fcuda, sizeof(FluidParams) ) );
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidParamCUDA ( float sim_scale, float smooth_rad, float mass, float rest, float stiff, float visc )
|
||||||
|
{
|
||||||
|
fcuda.sim_scale = sim_scale;
|
||||||
|
fcuda.smooth_rad = smooth_rad;
|
||||||
|
fcuda.r2 = smooth_rad * smooth_rad;
|
||||||
|
fcuda.pmass = mass;
|
||||||
|
fcuda.rest_dens = rest;
|
||||||
|
fcuda.stiffness = stiff;
|
||||||
|
fcuda.visc = visc;
|
||||||
|
|
||||||
|
fcuda.pdist = pow ( fcuda.pmass / fcuda.rest_dens, 1/3.0f );
|
||||||
|
fcuda.poly6kern = 315.0f / (64.0f * 3.141592 * pow( smooth_rad, 9.0f) );
|
||||||
|
fcuda.spikykern = -45.0f / (3.141592 * pow( smooth_rad, 6.0f) );
|
||||||
|
fcuda.lapkern = 45.0f / (3.141592 * pow( smooth_rad, 6.0f) );
|
||||||
|
|
||||||
|
CUDA_SAFE_CALL( cudaMemcpyToSymbol ( simData, &fcuda, sizeof(FluidParams) ) );
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransferToCUDA ( char* data, int* grid, int numPoints )
|
||||||
|
{
|
||||||
|
CUDA_SAFE_CALL( cudaMemcpy ( bufPnts, data, numPoints * fcuda.stride, cudaMemcpyHostToDevice ) );
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransferFromCUDA ( char* data, int* grid, int numPoints )
|
||||||
|
{
|
||||||
|
CUDA_SAFE_CALL( cudaMemcpy ( data, bufPntSort, numPoints * fcuda.stride, cudaMemcpyDeviceToHost ) );
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
|
||||||
|
CUDA_SAFE_CALL( cudaMemcpy ( grid, bufGrid, fcuda.cells * sizeof(uint), cudaMemcpyDeviceToHost ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Grid_InsertParticlesCUDA ()
|
||||||
|
{
|
||||||
|
CUDA_SAFE_CALL( cudaMemset ( bufHash[0], 0, fcuda.szHash ) );
|
||||||
|
|
||||||
|
hashParticles<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPnts, (uint2*) bufHash[0], fcuda.pnts );
|
||||||
|
CUT_CHECK_ERROR( "Kernel execution failed");
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
|
||||||
|
//int buf[20000];
|
||||||
|
/*printf ( "HASH: %d (%d)\n", fcuda.pnts, fcuda.numBlocks*fcuda.numThreads );
|
||||||
|
CUDA_SAFE_CALL( cudaMemcpy ( buf, bufHash[0], fcuda.pnts * 2*sizeof(uint), cudaMemcpyDeviceToHost ) );
|
||||||
|
//for (int n=0; n < fcuda.numBlocks*fcuda.numThreads; n++) {
|
||||||
|
for (int n=0; n < 100; n++) {
|
||||||
|
printf ( "%d: <%d,%d>\n", n, buf[n*2], buf[n*2+1] );
|
||||||
|
}*/
|
||||||
|
|
||||||
|
RadixSort( (KeyValuePair *) bufHash[0], (KeyValuePair *) bufHash[1], fcuda.pnts, 32);
|
||||||
|
CUT_CHECK_ERROR( "Kernel execution failed");
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
|
||||||
|
/*printf ( "HASH: %d (%d)\n", fcuda.pnts, fcuda.numBlocks*fcuda.numThreads );
|
||||||
|
CUDA_SAFE_CALL( cudaMemcpy ( buf, bufHash[0], fcuda.pnts * 2*sizeof(uint), cudaMemcpyDeviceToHost ) );
|
||||||
|
//for (int n=0; n < fcuda.numBlocks*fcuda.numThreads; n++) {
|
||||||
|
for (int n=0; n < 100; n++) {
|
||||||
|
printf ( "%d: <%d,%d>\n", n, buf[n*2], buf[n*2+1] );
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// insertParticles<<< fcuda.gridBlocks, fcuda.gridThreads>>> ( bufPnts, (uint2*) bufHash[0], bufGrid, fcuda.pnts, fcuda.cells );
|
||||||
|
|
||||||
|
CUDA_SAFE_CALL( cudaMemset ( bufGrid, NULL_HASH, fcuda.cells * sizeof(uint) ) );
|
||||||
|
|
||||||
|
insertParticlesRadix<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPnts, (uint2*) bufHash[0], bufGrid, bufPntSort, fcuda.pnts, fcuda.cells );
|
||||||
|
CUT_CHECK_ERROR( "Kernel execution failed");
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
|
||||||
|
/*printf ( "GRID: %d\n", fcuda.cells );
|
||||||
|
CUDA_SAFE_CALL( cudaMemcpy ( buf, bufGrid, fcuda.cells * sizeof(uint), cudaMemcpyDeviceToHost ) );
|
||||||
|
*for (int n=0; n < 100; n++) {
|
||||||
|
printf ( "%d: %d\n", n, buf[n]);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPH_ComputePressureCUDA ()
|
||||||
|
{
|
||||||
|
computePressure<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPntSort, bufGrid, (uint2*) bufHash[0], fcuda.pnts );
|
||||||
|
CUT_CHECK_ERROR( "Kernel execution failed");
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPH_ComputeForceCUDA ()
|
||||||
|
{
|
||||||
|
//-- standard force
|
||||||
|
//computeForce<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPntSort, bufGrid, (uint2*) bufHash[0], fcuda.pnts );
|
||||||
|
|
||||||
|
// Force using neighbor table
|
||||||
|
computeForceNbr<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPntSort, fcuda.pnts );
|
||||||
|
CUT_CHECK_ERROR( "Kernel execution failed");
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPH_AdvanceCUDA ( float dt, float ss )
|
||||||
|
{
|
||||||
|
advanceParticles<<< fcuda.numBlocks, fcuda.numThreads>>> ( bufPntSort, fcuda.pnts, dt, ss );
|
||||||
|
CUT_CHECK_ERROR( "Kernel execution failed");
|
||||||
|
cudaThreadSynchronize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern C
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------- Per frame: Malloc/Free, Host<->Device
|
||||||
|
// transfer point data to device
|
||||||
|
/*char* pntData;
|
||||||
|
int size = (fcuda.numBlocks*fcuda.numThreads) * stride;
|
||||||
|
cudaMalloc( (void**) &pntData, size);
|
||||||
|
cudaMemcpy( pntData, data, numPoints*stride, cudaMemcpyHostToDevice);
|
||||||
|
insertParticles<<< fcuda.numBlocks, fcuda.numThreads >>> ( pntData, stride, numPoints );
|
||||||
|
cudaMemcpy( data, pntData, numPoints*stride, cudaMemcpyDeviceToHost);
|
||||||
|
cudaFree( pntData );*/
|
||||||
63
Extras/sph/fluids/fluid_system_host.cuh
Normal file
63
Extras/sph/fluids/fluid_system_host.cuh
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector_types.h>
|
||||||
|
#include <driver_types.h> // for cudaStream_t
|
||||||
|
|
||||||
|
typedef unsigned int uint; // should be 4-bytes on CUDA
|
||||||
|
typedef unsigned char uchar; // should be 1-bytes on CUDA
|
||||||
|
|
||||||
|
struct FluidParams {
|
||||||
|
int numThreads, numBlocks;
|
||||||
|
int gridThreads, gridBlocks;
|
||||||
|
int szPnts, szHash, szGrid;
|
||||||
|
int stride, pnts, cells;
|
||||||
|
int chk;
|
||||||
|
float smooth_rad, r2, sim_scale, visc;
|
||||||
|
float3 min, max, res, size, delta;
|
||||||
|
|
||||||
|
float pdist, pmass, rest_dens, stiffness;
|
||||||
|
float poly6kern, spikykern, lapkern;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
void cudaInit(int argc, char **argv);
|
||||||
|
|
||||||
|
void FluidClearCUDA ();
|
||||||
|
void FluidSetupCUDA ( int num, int stride, float3 min, float3 max, float3 res, float3 size, int chk );
|
||||||
|
void FluidParamCUDA ( float sim_scale, float smooth_rad, float mass, float rest, float stiff, float visc );
|
||||||
|
|
||||||
|
void TransferToCUDA ( char* data, int* grid, int numPoints );
|
||||||
|
void TransferFromCUDA ( char* data, int* grid, int numPoints );
|
||||||
|
|
||||||
|
void Grid_InsertParticlesCUDA ();
|
||||||
|
void SPH_ComputePressureCUDA ();
|
||||||
|
void SPH_ComputeForceCUDA ();
|
||||||
|
void SPH_AdvanceCUDA ( float dt, float ss );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
402
Extras/sph/fluids/fluid_system_kern.cu
Normal file
402
Extras/sph/fluids/fluid_system_kern.cu
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2008. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 _PARTICLES_KERNEL_H_
|
||||||
|
#define _PARTICLES_KERNEL_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "fluid_system_host.cuh"
|
||||||
|
|
||||||
|
#define TOTAL_THREADS 65536
|
||||||
|
#define BLOCK_THREADS 256
|
||||||
|
#define MAX_NBR 80
|
||||||
|
|
||||||
|
__constant__ FluidParams simData; // simulation data (on device)
|
||||||
|
|
||||||
|
__device__ int bufNeighbor[ TOTAL_THREADS*MAX_NBR ];
|
||||||
|
__device__ float bufNdist[ TOTAL_THREADS*MAX_NBR ];
|
||||||
|
|
||||||
|
#define COLOR(r,g,b) ( (uint((r)*255.0f)<<24) | (uint((g)*255.0f)<<16) | (uint((b)*255.0f)<<8) )
|
||||||
|
#define COLORA(r,g,b,a) ( (uint((r)*255.0f)<<24) | (uint((g)*255.0f)<<16) | (uint((b)*255.0f)<<8) | uint((a)*255.0f) )
|
||||||
|
|
||||||
|
#define NULL_HASH 333333
|
||||||
|
|
||||||
|
#define OFFSET_CLR 12
|
||||||
|
#define OFFSET_NEXT 16
|
||||||
|
#define OFFSET_VEL 20
|
||||||
|
#define OFFSET_VEVAL 32
|
||||||
|
#define OFFSET_PRESS 48
|
||||||
|
#define OFFSET_DENS 52
|
||||||
|
#define OFFSET_FORCE 56
|
||||||
|
|
||||||
|
|
||||||
|
__global__ void hashParticles ( char* bufPnts, uint2* bufHash, int numPnt )
|
||||||
|
{
|
||||||
|
uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index
|
||||||
|
float3* pos = (float3*) (bufPnts + __mul24(ndx, simData.stride) );
|
||||||
|
int gz = (pos->z - simData.min.z) * simData.delta.z ;
|
||||||
|
int gy = (pos->y - simData.min.y) * simData.delta.y ;
|
||||||
|
int gx = (pos->x - simData.min.x) * simData.delta.x ;
|
||||||
|
if ( ndx >= numPnt || gx < 0 || gz > simData.res.x-1 || gy < 0 || gy > simData.res.y-1 || gz < 0 || gz > simData.res.z-1 )
|
||||||
|
bufHash[ndx] = make_uint2( NULL_HASH, ndx );
|
||||||
|
else
|
||||||
|
bufHash[ndx] = make_uint2( __mul24(__mul24(gz, (int) simData.res.y)+gy, (int) simData.res.x) + gx, ndx );
|
||||||
|
|
||||||
|
__syncthreads ();
|
||||||
|
}
|
||||||
|
|
||||||
|
__global__ void insertParticles ( char* bufPnts, uint2* bufHash, int* bufGrid, int numPnt, int numGrid )
|
||||||
|
{
|
||||||
|
uint grid_ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // grid cell index
|
||||||
|
|
||||||
|
bufPnts += OFFSET_NEXT;
|
||||||
|
bufGrid[grid_ndx] = -1;
|
||||||
|
for (int n=0; n < numPnt; n++) {
|
||||||
|
if ( bufHash[n].x == grid_ndx ) {
|
||||||
|
*(int*) (bufPnts + __mul24(bufHash[n].y, simData.stride)) = bufGrid[grid_ndx];
|
||||||
|
bufGrid[grid_ndx] = bufHash[n].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__syncthreads ();
|
||||||
|
}
|
||||||
|
|
||||||
|
__global__ void insertParticlesRadix ( char* bufPnts, uint2* bufHash, int* bufGrid, char* bufPntSort, int numPnt, int numGrid )
|
||||||
|
{
|
||||||
|
uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index
|
||||||
|
|
||||||
|
uint2 bufHashSort = bufHash[ndx];
|
||||||
|
|
||||||
|
__shared__ uint sharedHash[257];
|
||||||
|
sharedHash[threadIdx.x+1] = bufHashSort.x;
|
||||||
|
if ( ndx > 0 && threadIdx.x == 0 ) {
|
||||||
|
volatile uint2 prevData = bufHash[ndx-1];
|
||||||
|
sharedHash[0] = prevData.x;
|
||||||
|
}
|
||||||
|
__syncthreads ();
|
||||||
|
|
||||||
|
if ( (ndx == 0 || bufHashSort.x != sharedHash[threadIdx.x]) && bufHashSort.x != NULL_HASH ) {
|
||||||
|
bufGrid [ bufHashSort.x ] = ndx;
|
||||||
|
}
|
||||||
|
if ( ndx < numPnt ) {
|
||||||
|
char* src = bufPnts + __mul24( bufHashSort.y, simData.stride );
|
||||||
|
char* dest = bufPntSort + __mul24( ndx, simData.stride );
|
||||||
|
|
||||||
|
*(float3*)(dest) = *(float3*)(src);
|
||||||
|
*(uint*) (dest + OFFSET_CLR) = *(uint*) (src + OFFSET_CLR);
|
||||||
|
*(float3*)(dest + OFFSET_VEL) = *(float3*)(src + OFFSET_VEL);
|
||||||
|
*(float3*)(dest + OFFSET_VEVAL) = *(float3*)(src + OFFSET_VEVAL);
|
||||||
|
|
||||||
|
*(float*) (dest + OFFSET_DENS) = 0.0;
|
||||||
|
*(float*) (dest + OFFSET_PRESS) = 0.0;
|
||||||
|
*(float3*) (dest + OFFSET_FORCE)= make_float3(0,0,0);
|
||||||
|
*(int*) (dest + OFFSET_NEXT) = bufHashSort.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
__syncthreads ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//__shared__ int ncount [ BLOCK_THREADS ];
|
||||||
|
|
||||||
|
__device__ float contributePressure ( int pndx, float3* p, int qndx, int grid_ndx, char* bufPnts, uint2* bufHash )
|
||||||
|
{
|
||||||
|
float3* qpos;
|
||||||
|
float3 dist;
|
||||||
|
float dsq, c, sum;
|
||||||
|
float d = simData.sim_scale;
|
||||||
|
int nbr = __mul24(pndx, MAX_NBR);
|
||||||
|
|
||||||
|
sum = 0.0;
|
||||||
|
for ( ; qndx < simData.pnts; qndx++ ) {
|
||||||
|
|
||||||
|
if ( bufHash[qndx].x != grid_ndx || qndx == NULL_HASH) break;
|
||||||
|
|
||||||
|
if ( qndx != pndx ) {
|
||||||
|
qpos = (float3*) ( bufPnts + __mul24(qndx, simData.stride ));
|
||||||
|
|
||||||
|
dist.x = ( p->x - qpos->x )*d; // dist in cm
|
||||||
|
dist.y = ( p->y - qpos->y )*d;
|
||||||
|
dist.z = ( p->z - qpos->z )*d;
|
||||||
|
dsq = (dist.x*dist.x + dist.y*dist.y + dist.z*dist.z);
|
||||||
|
if ( dsq < simData.r2 ) {
|
||||||
|
c = simData.r2 - dsq;
|
||||||
|
sum += c * c * c;
|
||||||
|
if ( bufNeighbor[nbr] < MAX_NBR ) {
|
||||||
|
bufNeighbor[ nbr+bufNeighbor[nbr] ] = qndx;
|
||||||
|
bufNdist[ nbr+bufNeighbor[nbr] ] = sqrt(dsq);
|
||||||
|
bufNeighbor[nbr]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//curr = *(int*) (bufPnts + __mul24(curr, simData.stride) + OFFSET_NEXT);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if ( ncount[threadIdx.x] < MAX_NBR ) {
|
||||||
|
bufNeighbor [ nbr + ncount[threadIdx.x] ] = curr;
|
||||||
|
bufNdist [ nbr + ncount[threadIdx.x] ] = sqrt(dsq);
|
||||||
|
ncount[threadIdx.x]++;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
__global__ void computePressure ( char* bufPntSort, int* bufGrid, uint2* bufHash, int numPnt )
|
||||||
|
{
|
||||||
|
uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index
|
||||||
|
|
||||||
|
//if ( ndx < 1024 ) {
|
||||||
|
|
||||||
|
float3* pos = (float3*) (bufPntSort + __mul24(ndx, simData.stride));
|
||||||
|
|
||||||
|
// Find 2x2x2 grid cells
|
||||||
|
// - Use registers only, no arrays (local-memory too slow)
|
||||||
|
int3 cell;
|
||||||
|
int gc0, gc1, gc2, gc3, gc4, gc5, gc6, gc7;
|
||||||
|
float gs = simData.smooth_rad / simData.sim_scale;
|
||||||
|
|
||||||
|
cell.x = max(0, (int)((-gs + pos->x - simData.min.x) * simData.delta.x));
|
||||||
|
cell.y = max(0, (int)((-gs + pos->y - simData.min.y) * simData.delta.y));
|
||||||
|
cell.z = max(0, (int)((-gs + pos->z - simData.min.z) * simData.delta.z));
|
||||||
|
gc0 = __mul24(__mul24(cell.z, simData.res.y) + cell.y, simData.res.x) + cell.x;
|
||||||
|
gc1 = gc0 + 1;
|
||||||
|
gc2 = gc0 + simData.res.x;
|
||||||
|
gc3 = gc2 + 1;
|
||||||
|
if ( cell.z+1 < simData.res.z ) {
|
||||||
|
gc4 = gc0 + __mul24(simData.res.x, simData.res.y);
|
||||||
|
gc5 = gc4 + 1;
|
||||||
|
gc6 = gc4 + simData.res.x;
|
||||||
|
gc7 = gc6 + 1;
|
||||||
|
}
|
||||||
|
if ( cell.x+1 >= simData.res.x ) {
|
||||||
|
gc1 = -1; gc3 = -1;
|
||||||
|
gc5 = -1; gc7 = -1;
|
||||||
|
}
|
||||||
|
if ( cell.y+1 >= simData.res.y ) {
|
||||||
|
gc2 = -1; gc3 = -1;
|
||||||
|
gc6 = -1; gc7 = -1;
|
||||||
|
}
|
||||||
|
// Sum Pressure
|
||||||
|
float sum = 0.0;
|
||||||
|
bufNeighbor[ __mul24(ndx, MAX_NBR) ] = 1;
|
||||||
|
if (gc0 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc0], gc0, bufPntSort, bufHash );
|
||||||
|
if (gc1 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc1], gc1, bufPntSort, bufHash );
|
||||||
|
if (gc2 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc2], gc2, bufPntSort, bufHash );
|
||||||
|
if (gc3 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc3], gc3, bufPntSort, bufHash );
|
||||||
|
if (gc4 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc4], gc4, bufPntSort, bufHash );
|
||||||
|
if (gc5 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc5], gc5, bufPntSort, bufHash );
|
||||||
|
if (gc6 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc6], gc6, bufPntSort, bufHash );
|
||||||
|
if (gc7 != -1 ) sum += contributePressure ( ndx, pos, bufGrid[gc7], gc7, bufPntSort, bufHash );
|
||||||
|
|
||||||
|
// Compute Density & Pressure
|
||||||
|
sum = sum * simData.pmass * simData.poly6kern;
|
||||||
|
if ( sum == 0.0 ) sum = 1.0;
|
||||||
|
*(float*) ((char*)pos + OFFSET_PRESS) = ( sum - simData.rest_dens ) * simData.stiffness;
|
||||||
|
*(float*) ((char*)pos + OFFSET_DENS) = 1.0f / sum;
|
||||||
|
|
||||||
|
//}
|
||||||
|
//__syncthreads ();
|
||||||
|
}
|
||||||
|
|
||||||
|
__device__ void contributeForce ( float3& force, int pndx, float3* p, int qndx, int grid_ndx, char* bufPnts, uint2* bufHash )
|
||||||
|
{
|
||||||
|
float press = *(float*) ((char*)p + OFFSET_PRESS);
|
||||||
|
float dens = *(float*) ((char*)p + OFFSET_DENS);
|
||||||
|
float3 veval = *(float3*) ((char*)p + OFFSET_VEVAL );
|
||||||
|
float3 qeval, dist;
|
||||||
|
float c, ndistj, dsq;
|
||||||
|
float pterm, dterm, vterm;
|
||||||
|
float3* qpos;
|
||||||
|
float d = simData.sim_scale;
|
||||||
|
|
||||||
|
vterm = simData.lapkern * simData.visc;
|
||||||
|
|
||||||
|
for ( ; qndx < simData.pnts; qndx++ ) {
|
||||||
|
|
||||||
|
if ( bufHash[qndx].x != grid_ndx || qndx == NULL_HASH) break;
|
||||||
|
|
||||||
|
if ( qndx != pndx ) {
|
||||||
|
qpos = (float3*) ( bufPnts + __mul24(qndx, simData.stride ));
|
||||||
|
|
||||||
|
dist.x = ( p->x - qpos->x )*d; // dist in cm
|
||||||
|
dist.y = ( p->y - qpos->y )*d;
|
||||||
|
dist.z = ( p->z - qpos->z )*d;
|
||||||
|
dsq = (dist.x*dist.x + dist.y*dist.y + dist.z*dist.z);
|
||||||
|
if ( dsq < simData.r2 ) {
|
||||||
|
ndistj = sqrt(dsq);
|
||||||
|
c = ( simData.smooth_rad - ndistj );
|
||||||
|
dist.x = ( p->x - qpos->x )*d; // dist in cm
|
||||||
|
dist.y = ( p->y - qpos->y )*d;
|
||||||
|
dist.z = ( p->z - qpos->z )*d;
|
||||||
|
pterm = -0.5f * c * simData.spikykern * ( press + *(float*)((char*)qpos+OFFSET_PRESS) ) / ndistj;
|
||||||
|
dterm = c * dens * *(float*)((char*)qpos+OFFSET_DENS);
|
||||||
|
qeval = *(float3*)((char*)qpos+OFFSET_VEVAL);
|
||||||
|
force.x += ( pterm * dist.x + vterm * ( qeval.x - veval.x )) * dterm;
|
||||||
|
force.y += ( pterm * dist.y + vterm * ( qeval.y - veval.y )) * dterm;
|
||||||
|
force.z += ( pterm * dist.z + vterm * ( qeval.z - veval.z )) * dterm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
__global__ void computeForce ( char* bufPntSort, int* bufGrid, uint2* bufHash, int numPnt )
|
||||||
|
{
|
||||||
|
uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index
|
||||||
|
|
||||||
|
//if ( ndx < numPnt ) {
|
||||||
|
|
||||||
|
float3* pos = (float3*) (bufPntSort + __mul24(ndx, simData.stride));
|
||||||
|
|
||||||
|
// Find 2x2x2 grid cells
|
||||||
|
// - Use registers only, no arrays (local-memory too slow)
|
||||||
|
int3 cell;
|
||||||
|
int gc0, gc1, gc2, gc3, gc4, gc5, gc6, gc7;
|
||||||
|
float gs = simData.smooth_rad / simData.sim_scale;
|
||||||
|
|
||||||
|
cell.x = max(0, (int)((-gs + pos->x - simData.min.x) * simData.delta.x));
|
||||||
|
cell.y = max(0, (int)((-gs + pos->y - simData.min.y) * simData.delta.y));
|
||||||
|
cell.z = max(0, (int)((-gs + pos->z - simData.min.z) * simData.delta.z));
|
||||||
|
gc0 = __mul24(__mul24(cell.z, simData.res.y) + cell.y, simData.res.x) + cell.x;
|
||||||
|
gc1 = gc0 + 1;
|
||||||
|
gc2 = gc0 + simData.res.x;
|
||||||
|
gc3 = gc2 + 1;
|
||||||
|
if ( cell.z+1 < simData.res.z ) {
|
||||||
|
gc4 = gc0 + __mul24(simData.res.x, simData.res.y);
|
||||||
|
gc5 = gc4 + 1;
|
||||||
|
gc6 = gc4 + simData.res.x;
|
||||||
|
gc7 = gc6 + 1;
|
||||||
|
}
|
||||||
|
if ( cell.x+1 >= simData.res.x ) {
|
||||||
|
gc1 = -1; gc3 = -1;
|
||||||
|
gc5 = -1; gc7 = -1;
|
||||||
|
}
|
||||||
|
if ( cell.y+1 >= simData.res.y ) {
|
||||||
|
gc2 = -1; gc3 = -1;
|
||||||
|
gc6 = -1; gc7 = -1;
|
||||||
|
}
|
||||||
|
// Sum Pressure
|
||||||
|
float3 force = make_float3(0,0,0);
|
||||||
|
if (gc0 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc0], gc0, bufPntSort, bufHash );
|
||||||
|
if (gc1 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc1], gc1, bufPntSort, bufHash );
|
||||||
|
if (gc2 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc2], gc2, bufPntSort, bufHash );
|
||||||
|
if (gc3 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc3], gc3, bufPntSort, bufHash );
|
||||||
|
if (gc4 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc4], gc4, bufPntSort, bufHash );
|
||||||
|
if (gc5 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc5], gc5, bufPntSort, bufHash );
|
||||||
|
if (gc6 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc6], gc6, bufPntSort, bufHash );
|
||||||
|
if (gc7 != -1 ) contributeForce ( force, ndx, pos, bufGrid[gc7], gc7, bufPntSort, bufHash );
|
||||||
|
|
||||||
|
// Update Force
|
||||||
|
*(float3*) ((char*)pos + OFFSET_FORCE ) = force;
|
||||||
|
|
||||||
|
//}
|
||||||
|
//__syncthreads ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__global__ void computeForceNbr ( char* bufPntSort, int numPnt )
|
||||||
|
{
|
||||||
|
uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index
|
||||||
|
|
||||||
|
if ( ndx < numPnt ) {
|
||||||
|
|
||||||
|
float3* pos = (float3*) (bufPntSort + __mul24(ndx, simData.stride));
|
||||||
|
|
||||||
|
float3* qpos;
|
||||||
|
float press = *(float*) ((char*)pos + OFFSET_PRESS);
|
||||||
|
float dens = *(float*) ((char*)pos + OFFSET_DENS);
|
||||||
|
float3 veval = *(float3*) ((char*)pos + OFFSET_VEVAL );
|
||||||
|
float3 qeval, dist, force;
|
||||||
|
float d = simData.sim_scale;
|
||||||
|
float c, ndistj;
|
||||||
|
float pterm, dterm, vterm;
|
||||||
|
vterm = simData.lapkern * simData.visc;
|
||||||
|
int nbr = __mul24(ndx, MAX_NBR);
|
||||||
|
|
||||||
|
int ncnt = bufNeighbor[ nbr ];
|
||||||
|
|
||||||
|
force = make_float3(0,0,0);
|
||||||
|
for (int j=1; j < ncnt; j++) { // base 1, n[0] = count
|
||||||
|
ndistj = bufNdist[ nbr+j ];
|
||||||
|
qpos = (float3*) (bufPntSort + __mul24( bufNeighbor[ nbr+j ], simData.stride) );
|
||||||
|
c = ( simData.smooth_rad - ndistj );
|
||||||
|
dist.x = ( pos->x - qpos->x )*d; // dist in cm
|
||||||
|
dist.y = ( pos->y - qpos->y )*d;
|
||||||
|
dist.z = ( pos->z - qpos->z )*d;
|
||||||
|
pterm = -0.5f * c * simData.spikykern * ( press + *(float*)((char*)qpos+OFFSET_PRESS) ) / ndistj;
|
||||||
|
dterm = c * dens * *(float*)((char*)qpos+OFFSET_DENS);
|
||||||
|
qeval = *(float3*)((char*)qpos+OFFSET_VEVAL);
|
||||||
|
force.x += ( pterm * dist.x + vterm * ( qeval.x - veval.x )) * dterm;
|
||||||
|
force.y += ( pterm * dist.y + vterm * ( qeval.y - veval.y )) * dterm;
|
||||||
|
force.z += ( pterm * dist.z + vterm * ( qeval.z - veval.z )) * dterm;
|
||||||
|
}
|
||||||
|
*(float3*) ((char*)pos + OFFSET_FORCE ) = force;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__global__ void advanceParticles ( char* bufPntSort, int numPnt, float dt, float ss )
|
||||||
|
{
|
||||||
|
uint ndx = __mul24(blockIdx.x, blockDim.x) + threadIdx.x; // particle index
|
||||||
|
|
||||||
|
if ( ndx < numPnt ) {
|
||||||
|
|
||||||
|
// Get particle vars
|
||||||
|
float3* pos = (float3*) (bufPntSort + __mul24(ndx, simData.stride));
|
||||||
|
float3* vel = (float3*) ((char*)pos + OFFSET_VEL );
|
||||||
|
float3* vel_eval = (float3*) ((char*)pos + OFFSET_VEVAL );
|
||||||
|
float3 accel = *(float3*) ((char*)pos + OFFSET_FORCE );
|
||||||
|
float3 vcurr, vnext;
|
||||||
|
|
||||||
|
// Leapfrog integration
|
||||||
|
accel.x *= 0.00020543; // NOTE - To do: SPH_PMASS should be passed in
|
||||||
|
accel.y *= 0.00020543;
|
||||||
|
accel.z *= 0.00020543;
|
||||||
|
accel.z -= 9.8;
|
||||||
|
|
||||||
|
vcurr = *vel;
|
||||||
|
vnext.x = accel.x*dt + vcurr.x;
|
||||||
|
vnext.y = accel.y*dt + vcurr.y;
|
||||||
|
vnext.z = accel.z*dt + vcurr.z; // v(t+1/2) = v(t-1/2) + a(t) dt
|
||||||
|
|
||||||
|
accel.x = (vcurr.x + vnext.x) * 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later
|
||||||
|
accel.y = (vcurr.y + vnext.y) * 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later
|
||||||
|
accel.z = (vcurr.z + vnext.z) * 0.5; // v(t+1) = [v(t-1/2) + v(t+1/2)] * 0.5 used to compute forces later
|
||||||
|
|
||||||
|
*vel_eval = accel;
|
||||||
|
*vel = vnext;
|
||||||
|
|
||||||
|
dt /= simData.sim_scale;
|
||||||
|
vnext.x = pos->x + vnext.x*dt;
|
||||||
|
vnext.y = pos->y + vnext.y*dt;
|
||||||
|
vnext.z = pos->z + vnext.z*dt;
|
||||||
|
*pos = vnext; // p(t+1) = p(t) + v(t+1/2) dt
|
||||||
|
}
|
||||||
|
|
||||||
|
__syncthreads ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
45
Extras/sph/fluids/fluid_system_kern.cuh
Normal file
45
Extras/sph/fluids/fluid_system_kern.cuh
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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 _PARTICLES_KERNEL_H_
|
||||||
|
#define _PARTICLES_KERNEL_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "cutil_math.h"
|
||||||
|
#include "math_constants.h"
|
||||||
|
|
||||||
|
// Insert particles in grid
|
||||||
|
|
||||||
|
__global__ void insertParticles ( char* pntData, uint pntStride )
|
||||||
|
{
|
||||||
|
int index = __mul24(blockIdx.x,blockDim.x) + threadIdx.x;
|
||||||
|
float4 p = *(float4*) (pntData + index*pntStride);
|
||||||
|
|
||||||
|
// get address in grid
|
||||||
|
int3 gridPos = calcGridPos(p);
|
||||||
|
|
||||||
|
addParticleToCell(gridPos, index, gridCounters, gridCells);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
79
Extras/sph/fluids/radixsort.cu
Normal file
79
Extras/sph/fluids/radixsort.cu
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1993-2006 NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* NOTICE TO USER:
|
||||||
|
*
|
||||||
|
* This source code is subject to NVIDIA ownership rights under U.S. and
|
||||||
|
* international Copyright laws.
|
||||||
|
*
|
||||||
|
* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
|
||||||
|
* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
|
||||||
|
* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
|
||||||
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||||
|
* OR PERFORMANCE OF THIS SOURCE CODE.
|
||||||
|
*
|
||||||
|
* U.S. Government End Users. This source code is a "commercial item" as
|
||||||
|
* that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
|
||||||
|
* "commercial computer software" and "commercial computer software
|
||||||
|
* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
|
||||||
|
* and is provided to the U.S. Government only as a commercial end item.
|
||||||
|
* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
|
||||||
|
* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
|
||||||
|
* source code with only those rights set forth herein.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Radixsort project with key/value and arbitrary datset size support
|
||||||
|
* which demonstrates the use of CUDA in a multi phase sorting
|
||||||
|
* computation.
|
||||||
|
* Host code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "radixsort.cuh"
|
||||||
|
#include "radixsort_kernel.cu"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//! Perform a radix sort
|
||||||
|
//! Sorting performed in place on passed arrays.
|
||||||
|
//!
|
||||||
|
//! @param pData0 input and output array - data will be sorted
|
||||||
|
//! @param pData1 additional array to allow ping pong computation
|
||||||
|
//! @param elements number of elements to sort
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void RadixSort(KeyValuePair *pData0, KeyValuePair *pData1, uint elements, uint bits)
|
||||||
|
{
|
||||||
|
// Round element count to total number of threads for efficiency
|
||||||
|
uint elements_rounded_to_3072;
|
||||||
|
int modval = elements % 3072;
|
||||||
|
if( modval == 0 )
|
||||||
|
elements_rounded_to_3072 = elements;
|
||||||
|
else
|
||||||
|
elements_rounded_to_3072 = elements + (3072 - (modval));
|
||||||
|
|
||||||
|
// Iterate over n bytes of y bit word, using each byte to sort the list in turn
|
||||||
|
for (uint shift = 0; shift < bits; shift += RADIX)
|
||||||
|
{
|
||||||
|
// Perform one round of radix sorting
|
||||||
|
|
||||||
|
// Generate per radix group sums radix counts across a radix group
|
||||||
|
RadixSum<<<NUM_BLOCKS, NUM_THREADS_PER_BLOCK, GRFSIZE>>>(pData0, elements, elements_rounded_to_3072, shift);
|
||||||
|
// Prefix sum in radix groups, and then between groups throughout a block
|
||||||
|
RadixPrefixSum<<<PREFIX_NUM_BLOCKS, PREFIX_NUM_THREADS_PER_BLOCK, PREFIX_GRFSIZE>>>();
|
||||||
|
// Sum the block offsets and then shuffle data into bins
|
||||||
|
RadixAddOffsetsAndShuffle<<<NUM_BLOCKS, NUM_THREADS_PER_BLOCK, SHUFFLE_GRFSIZE>>>(pData0, pData1, elements, elements_rounded_to_3072, shift);
|
||||||
|
|
||||||
|
// Exchange data pointers
|
||||||
|
KeyValuePair* pTemp = pData0;
|
||||||
|
pData0 = pData1;
|
||||||
|
pData1 = pTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
63
Extras/sph/fluids/radixsort.cuh
Normal file
63
Extras/sph/fluids/radixsort.cuh
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1993-2006 NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* NOTICE TO USER:
|
||||||
|
*
|
||||||
|
* This source code is subject to NVIDIA ownership rights under U.S. and
|
||||||
|
* international Copyright laws.
|
||||||
|
*
|
||||||
|
* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
|
||||||
|
* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
|
||||||
|
* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
|
||||||
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||||
|
* OR PERFORMANCE OF THIS SOURCE CODE.
|
||||||
|
*
|
||||||
|
* U.S. Government End Users. This source code is a "commercial item" as
|
||||||
|
* that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
|
||||||
|
* "commercial computer software" and "commercial computer software
|
||||||
|
* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
|
||||||
|
* and is provided to the U.S. Government only as a commercial end item.
|
||||||
|
* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
|
||||||
|
* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
|
||||||
|
* source code with only those rights set forth herein.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Radixsort project which demonstrates the use of CUDA in a multi phase
|
||||||
|
* sorting computation.
|
||||||
|
* Type definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RADIXSORT_H_
|
||||||
|
#define _RADIXSORT_H_
|
||||||
|
|
||||||
|
#include <host_defines.h>
|
||||||
|
|
||||||
|
#define SYNCIT __syncthreads()
|
||||||
|
|
||||||
|
// Use 16 bit keys/values
|
||||||
|
#define SIXTEEN 0
|
||||||
|
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
|
||||||
|
#if SIXTEEN
|
||||||
|
typedef struct __align__(4) {
|
||||||
|
ushort key;
|
||||||
|
ushort value;
|
||||||
|
#else
|
||||||
|
typedef struct __align__(8) {
|
||||||
|
uint key;
|
||||||
|
uint value;
|
||||||
|
#endif
|
||||||
|
} KeyValuePair;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void RadixSort(KeyValuePair *pData0, KeyValuePair *pData1, uint elements, uint bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef _RADIXSORT_H_
|
||||||
577
Extras/sph/fluids/radixsort_kernel.cu
Normal file
577
Extras/sph/fluids/radixsort_kernel.cu
Normal file
@@ -0,0 +1,577 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1993-2006 NVIDIA Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* NOTICE TO USER:
|
||||||
|
*
|
||||||
|
* This source code is subject to NVIDIA ownership rights under U.S. and
|
||||||
|
* international Copyright laws.
|
||||||
|
*
|
||||||
|
* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
|
||||||
|
* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
|
||||||
|
* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
|
||||||
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||||
|
* OR PERFORMANCE OF THIS SOURCE CODE.
|
||||||
|
*
|
||||||
|
* U.S. Government End Users. This source code is a "commercial item" as
|
||||||
|
* that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
|
||||||
|
* "commercial computer software" and "commercial computer software
|
||||||
|
* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
|
||||||
|
* and is provided to the U.S. Government only as a commercial end item.
|
||||||
|
* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
|
||||||
|
* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
|
||||||
|
* source code with only those rights set forth herein.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Radixsort project with key/value and arbitrary datset size support
|
||||||
|
* which demonstrates the use of CUDA in a multi phase sorting
|
||||||
|
* computation.
|
||||||
|
* Device code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RADIXSORT_KERNEL_H_
|
||||||
|
#define _RADIXSORT_KERNEL_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "radixsort.cuh"
|
||||||
|
|
||||||
|
#define SYNCIT __syncthreads()
|
||||||
|
|
||||||
|
static const int NUM_SMS = 16;
|
||||||
|
static const int NUM_THREADS_PER_SM = 192;
|
||||||
|
static const int NUM_THREADS_PER_BLOCK = 64;
|
||||||
|
//static const int NUM_THREADS = NUM_THREADS_PER_SM * NUM_SMS;
|
||||||
|
static const int NUM_BLOCKS = (NUM_THREADS_PER_SM / NUM_THREADS_PER_BLOCK) * NUM_SMS;
|
||||||
|
static const int RADIX = 8; // Number of bits per radix sort pass
|
||||||
|
static const int RADICES = 1 << RADIX; // Number of radices
|
||||||
|
static const int RADIXMASK = RADICES - 1; // Mask for each radix sort pass
|
||||||
|
#if SIXTEEN
|
||||||
|
static const int RADIXBITS = 16; // Number of bits to sort over
|
||||||
|
#else
|
||||||
|
static const int RADIXBITS = 32; // Number of bits to sort over
|
||||||
|
#endif
|
||||||
|
static const int RADIXTHREADS = 16; // Number of threads sharing each radix counter
|
||||||
|
static const int RADIXGROUPS = NUM_THREADS_PER_BLOCK / RADIXTHREADS; // Number of radix groups per CTA
|
||||||
|
static const int TOTALRADIXGROUPS = NUM_BLOCKS * RADIXGROUPS; // Number of radix groups for each radix
|
||||||
|
static const int SORTRADIXGROUPS = TOTALRADIXGROUPS * RADICES; // Total radix count
|
||||||
|
static const int GRFELEMENTS = (NUM_THREADS_PER_BLOCK / RADIXTHREADS) * RADICES;
|
||||||
|
static const int GRFSIZE = GRFELEMENTS * sizeof(uint);
|
||||||
|
|
||||||
|
// Prefix sum variables
|
||||||
|
static const int PREFIX_NUM_THREADS_PER_SM = NUM_THREADS_PER_SM;
|
||||||
|
static const int PREFIX_NUM_THREADS_PER_BLOCK = PREFIX_NUM_THREADS_PER_SM;
|
||||||
|
static const int PREFIX_NUM_BLOCKS = (PREFIX_NUM_THREADS_PER_SM / PREFIX_NUM_THREADS_PER_BLOCK) * NUM_SMS;
|
||||||
|
static const int PREFIX_BLOCKSIZE = SORTRADIXGROUPS / PREFIX_NUM_BLOCKS;
|
||||||
|
static const int PREFIX_GRFELEMENTS = PREFIX_BLOCKSIZE + 2 * PREFIX_NUM_THREADS_PER_BLOCK;
|
||||||
|
static const int PREFIX_GRFSIZE = PREFIX_GRFELEMENTS * sizeof(uint);
|
||||||
|
|
||||||
|
// Shuffle variables
|
||||||
|
static const int SHUFFLE_GRFOFFSET = RADIXGROUPS * RADICES;
|
||||||
|
static const int SHUFFLE_GRFELEMENTS = SHUFFLE_GRFOFFSET + PREFIX_NUM_BLOCKS;
|
||||||
|
static const int SHUFFLE_GRFSIZE = SHUFFLE_GRFELEMENTS * sizeof(uint);
|
||||||
|
|
||||||
|
|
||||||
|
#define SDATA( index) CUT_BANK_CHECKER(sdata, index)
|
||||||
|
|
||||||
|
// Prefix sum data
|
||||||
|
uint gRadixSum[TOTALRADIXGROUPS * RADICES];
|
||||||
|
__device__ uint dRadixSum[TOTALRADIXGROUPS * RADICES];
|
||||||
|
uint gRadixBlockSum[PREFIX_NUM_BLOCKS];
|
||||||
|
__device__ uint dRadixBlockSum[PREFIX_NUM_BLOCKS];
|
||||||
|
|
||||||
|
extern __shared__ uint sRadixSum[];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//! Perform a radix sum on the list to be sorted. Each SM holds a set of
|
||||||
|
//! radix counters for each group of RADIXGROUPS thread in the GRF.
|
||||||
|
//!
|
||||||
|
//! @param pData input data
|
||||||
|
//! @param elements total number of elements
|
||||||
|
//! @param elements_rounded_to_3072 total number of elements rounded up to the
|
||||||
|
//! nearest multiple of 3072
|
||||||
|
//! @param shift the shift (0 to 24) that we are using to obtain the correct
|
||||||
|
//! byte
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
__global__ void RadixSum(KeyValuePair *pData, uint elements, uint elements_rounded_to_3072, uint shift)
|
||||||
|
{
|
||||||
|
uint pos = threadIdx.x;
|
||||||
|
|
||||||
|
// Zero radix counts
|
||||||
|
while (pos < GRFELEMENTS)
|
||||||
|
{
|
||||||
|
sRadixSum[pos] = 0;
|
||||||
|
pos += NUM_THREADS_PER_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum up data
|
||||||
|
// Source addresses computed so that each thread is reading from a block of
|
||||||
|
// consecutive addresses so there are no conflicts between threads
|
||||||
|
// They then loop over their combined region and the next batch works elsewhere.
|
||||||
|
// So threads 0 to 16 work on memory 0 to 320.
|
||||||
|
// First reading 0,1,2,3...15 then 16,17,18,19...31 and so on
|
||||||
|
// optimising parallel access to shared memory by a thread accessing 16*threadID
|
||||||
|
// The next radix group runs from 320 to 640 and the same applies in that region
|
||||||
|
uint tmod = threadIdx.x % RADIXTHREADS;
|
||||||
|
uint tpos = threadIdx.x / RADIXTHREADS;
|
||||||
|
|
||||||
|
// Take the rounded element list size so that all threads have a certain size dataset to work with
|
||||||
|
// and no zero size datasets confusing the issue
|
||||||
|
// By using a multiple of 3072 we ensure that all threads have elements
|
||||||
|
// to work with until the last phase, at which point we individually test
|
||||||
|
uint element_fraction = elements_rounded_to_3072 / TOTALRADIXGROUPS;
|
||||||
|
|
||||||
|
// Generate range
|
||||||
|
// Note that it is possible for both pos and end to be past the end of the element set
|
||||||
|
// which will be caught later.
|
||||||
|
pos = (blockIdx.x * RADIXGROUPS + tpos) * element_fraction;
|
||||||
|
uint end = pos + element_fraction;
|
||||||
|
pos += tmod;
|
||||||
|
//printf("pos: %d\n", pos);
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
while (pos < end )
|
||||||
|
{
|
||||||
|
uint key = 0;
|
||||||
|
|
||||||
|
// Read first data element if we are in the set of elements
|
||||||
|
//if( pos < elements )
|
||||||
|
//key = pData[pos].key;
|
||||||
|
KeyValuePair kvp;
|
||||||
|
// Read first data element, both items at once as the memory will want to coalesce like that anyway
|
||||||
|
if (pos < elements)
|
||||||
|
kvp = pData[pos];
|
||||||
|
else
|
||||||
|
kvp.key = 0;
|
||||||
|
key = kvp.key;
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate position of radix counter to increment
|
||||||
|
// There are RADICES radices in each pass (256)
|
||||||
|
// and hence this many counters for bin grouping
|
||||||
|
// Multiply by RADIXGROUPS (4) to spread through memory
|
||||||
|
// and into 4 radix groups
|
||||||
|
uint p = ((key >> shift) & RADIXMASK) * RADIXGROUPS;
|
||||||
|
|
||||||
|
// Increment radix counters
|
||||||
|
// Each radix group has its own set of counters
|
||||||
|
// so we add the thread position [0-3], ie the group index.
|
||||||
|
// We slow down here and take at least 16 cycles to write to the summation boxes
|
||||||
|
// but other groups will only conflict with themselves and so can also be writing
|
||||||
|
// 16 cycles here at least avoids retries.
|
||||||
|
uint ppos = p + tpos;
|
||||||
|
|
||||||
|
// If we are past the last element we don't want to do anything
|
||||||
|
// We do have to check each time, however, to ensure that all
|
||||||
|
// threads sync on each sync here.
|
||||||
|
if (tmod == 0 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 1 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 2 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 3 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 4 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 5 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 6 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 7 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 8 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 9 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 10 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 11 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 12 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 13 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 14 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 15 && pos < elements)
|
||||||
|
sRadixSum[ppos]++;
|
||||||
|
SYNCIT;
|
||||||
|
|
||||||
|
pos += RADIXTHREADS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
// Output radix sums into separate memory regions for each radix group
|
||||||
|
// So this memory then is layed out:
|
||||||
|
// 0...... 192..... 384 ................ 192*256
|
||||||
|
// ie all 256 bins for each radix group
|
||||||
|
// in there:
|
||||||
|
// 0.............192
|
||||||
|
// 0 4 8 12... - block idx * 4
|
||||||
|
// And in the block boxes we see the 4 radix groups for that block
|
||||||
|
// So 0-192 should contain bin 0 for each radix group, and so on
|
||||||
|
uint offset = blockIdx.x * RADIXGROUPS;
|
||||||
|
uint row = threadIdx.x / RADIXGROUPS;
|
||||||
|
uint column = threadIdx.x % RADIXGROUPS;
|
||||||
|
while (row < RADICES)
|
||||||
|
{
|
||||||
|
dRadixSum[offset + row * TOTALRADIXGROUPS + column] = sRadixSum[row * RADIXGROUPS + column];
|
||||||
|
row += NUM_THREADS_PER_BLOCK / RADIXGROUPS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//! Performs first part of parallel prefix sum - individual sums of each radix
|
||||||
|
//! count. By the end of this we have prefix sums on a block level in dRadixSum
|
||||||
|
//! and totals for blocks in dRadixBlockSum.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
__global__ void RadixPrefixSum()
|
||||||
|
{
|
||||||
|
// Read radix groups in offset by one in the GRF so a zero can be inserted at the beginning
|
||||||
|
// and the final sum of all radix counts summed here is tacked onto the end for reading by
|
||||||
|
// the next stage
|
||||||
|
// Each block in this case is the full number of threads per SM (and hence the total number
|
||||||
|
// of radix groups), 192. We should then have the total set of offsets for an entire radix
|
||||||
|
// group by the end of this stage
|
||||||
|
// Device mem addressing
|
||||||
|
|
||||||
|
uint brow = blockIdx.x * (RADICES / PREFIX_NUM_BLOCKS);
|
||||||
|
uint drow = threadIdx.x / TOTALRADIXGROUPS; // In default parameterisation this is always 0
|
||||||
|
uint dcolumn = threadIdx.x % TOTALRADIXGROUPS; // And similarly this is always the same as threadIdx.x
|
||||||
|
uint dpos = (brow + drow) * TOTALRADIXGROUPS + dcolumn;
|
||||||
|
uint end = ((blockIdx.x + 1) * (RADICES / PREFIX_NUM_BLOCKS)) * TOTALRADIXGROUPS;
|
||||||
|
// Shared mem addressing
|
||||||
|
uint srow = threadIdx.x / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK);
|
||||||
|
uint scolumn = threadIdx.x % (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK);
|
||||||
|
uint spos = srow * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) + scolumn;
|
||||||
|
|
||||||
|
// Read (RADICES / PREFIX_NUM_BLOCKS) radix counts into the GRF alongside each other
|
||||||
|
while (dpos < end)
|
||||||
|
{
|
||||||
|
sRadixSum[spos] = dRadixSum[dpos];
|
||||||
|
spos += (PREFIX_NUM_THREADS_PER_BLOCK / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK)) *
|
||||||
|
(PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1);
|
||||||
|
dpos += (TOTALRADIXGROUPS / PREFIX_NUM_THREADS_PER_BLOCK) * TOTALRADIXGROUPS;
|
||||||
|
}
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
// Perform preliminary sum on each thread's stretch of data
|
||||||
|
// Each thread having a block of 16, with spacers between 0...16 18...33 and so on
|
||||||
|
int pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1);
|
||||||
|
end = pos + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK);
|
||||||
|
uint sum = 0;
|
||||||
|
while (pos < end)
|
||||||
|
{
|
||||||
|
sum += sRadixSum[pos];
|
||||||
|
sRadixSum[pos] = sum;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate internal offsets by performing a more traditional parallel
|
||||||
|
// prefix sum of the topmost member of each thread's work data. Right now,
|
||||||
|
// these are stored between the work data for each thread, allowing us to
|
||||||
|
// eliminate GRF conflicts as well as hold the offsets needed to complete the sum
|
||||||
|
// In other words we have:
|
||||||
|
// 0....15 16 17....32 33 34....
|
||||||
|
// Where this first stage updates the intermediate values (so 16=15, 33=32 etc)
|
||||||
|
int m = (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1);
|
||||||
|
pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) +
|
||||||
|
(PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK);
|
||||||
|
sRadixSum[pos] = sRadixSum[pos - 1];
|
||||||
|
__syncthreads();
|
||||||
|
// This stage then performs a parallel prefix sum (ie use powers of 2 to propagate in log n stages)
|
||||||
|
// to update 17, 34 etc with the totals to that point (so 34 becomes [34] + [17]) and so on.
|
||||||
|
while (m < PREFIX_NUM_THREADS_PER_BLOCK * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1))
|
||||||
|
{
|
||||||
|
int p = pos - m;
|
||||||
|
uint t = ((p > 0) ? sRadixSum[p] : 0);
|
||||||
|
__syncthreads();
|
||||||
|
sRadixSum[pos] += t;
|
||||||
|
__syncthreads();
|
||||||
|
m *= 2;
|
||||||
|
}
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add internal offsets to each thread's work data.
|
||||||
|
// So now we take 17 and add it to all values 18 to 33 so all offsets for that block
|
||||||
|
// are updated.
|
||||||
|
pos = threadIdx.x * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1);
|
||||||
|
end = pos + (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK);
|
||||||
|
int p = pos - 1;
|
||||||
|
sum = ((p > 0) ? sRadixSum[p] : 0);
|
||||||
|
while (pos < end)
|
||||||
|
{
|
||||||
|
sRadixSum[pos] += sum;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
// Write summed data back out to global memory in the same way as we read it in
|
||||||
|
// We now have prefix sum values internal to groups
|
||||||
|
brow = blockIdx.x * (RADICES / PREFIX_NUM_BLOCKS);
|
||||||
|
drow = threadIdx.x / TOTALRADIXGROUPS;
|
||||||
|
dcolumn = threadIdx.x % TOTALRADIXGROUPS;
|
||||||
|
srow = threadIdx.x / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK);
|
||||||
|
scolumn = threadIdx.x % (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK);
|
||||||
|
dpos = (brow + drow) * TOTALRADIXGROUPS + dcolumn + 1;
|
||||||
|
spos = srow * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) + scolumn;
|
||||||
|
end = ((blockIdx.x + 1) * RADICES / PREFIX_NUM_BLOCKS) * TOTALRADIXGROUPS;
|
||||||
|
while (dpos < end)
|
||||||
|
{
|
||||||
|
dRadixSum[dpos] = sRadixSum[spos];
|
||||||
|
dpos += (TOTALRADIXGROUPS / PREFIX_NUM_THREADS_PER_BLOCK) * TOTALRADIXGROUPS;
|
||||||
|
spos += (PREFIX_NUM_THREADS_PER_BLOCK / (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK)) *
|
||||||
|
(PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write last element to summation
|
||||||
|
// Storing block sums in a separate array
|
||||||
|
if (threadIdx.x == 0) {
|
||||||
|
dRadixBlockSum[blockIdx.x] = sRadixSum[PREFIX_NUM_THREADS_PER_BLOCK * (PREFIX_BLOCKSIZE / PREFIX_NUM_THREADS_PER_BLOCK + 1) - 1];
|
||||||
|
dRadixSum[blockIdx.x * PREFIX_BLOCKSIZE] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//! Initially perform prefix sum of block totals to obtain final set of offsets.
|
||||||
|
//! Then make use of radix sums to perform a shuffling of the data into the
|
||||||
|
//! correct bins.
|
||||||
|
//!
|
||||||
|
//! @param pSrc input data
|
||||||
|
//! @param pDst output data
|
||||||
|
//! @param elements total number of elements
|
||||||
|
//! @param shift the shift (0 to 24) that we are using to obtain the correct
|
||||||
|
//! byte
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
__global__ void RadixAddOffsetsAndShuffle(KeyValuePair* pSrc, KeyValuePair* pDst, uint elements, uint elements_rounded_to_3072, int shift)
|
||||||
|
{
|
||||||
|
// Read offsets from previous blocks
|
||||||
|
if (threadIdx.x == 0)
|
||||||
|
sRadixSum[SHUFFLE_GRFOFFSET] = 0;
|
||||||
|
|
||||||
|
if (threadIdx.x < PREFIX_NUM_BLOCKS - 1)
|
||||||
|
sRadixSum[SHUFFLE_GRFOFFSET + threadIdx.x + 1] = dRadixBlockSum[threadIdx.x];
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
// Parallel prefix sum over block sums
|
||||||
|
int pos = threadIdx.x;
|
||||||
|
int n = 1;
|
||||||
|
while (n < PREFIX_NUM_BLOCKS)
|
||||||
|
{
|
||||||
|
int ppos = pos - n;
|
||||||
|
uint t0 = ((pos < PREFIX_NUM_BLOCKS) && (ppos >= 0)) ? sRadixSum[SHUFFLE_GRFOFFSET + ppos] : 0;
|
||||||
|
__syncthreads();
|
||||||
|
if (pos < PREFIX_NUM_BLOCKS)
|
||||||
|
sRadixSum[SHUFFLE_GRFOFFSET + pos] += t0;
|
||||||
|
__syncthreads();
|
||||||
|
n *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read radix count data and add appropriate block offset
|
||||||
|
// for each radix at the memory location for this thread
|
||||||
|
// (where the other threads in the block will be reading
|
||||||
|
// as well, hence the large stride).
|
||||||
|
// There is one counter box per radix group per radix
|
||||||
|
// per block (4*256*3)
|
||||||
|
// We use 64 threads to read the 4 radix groups set of radices
|
||||||
|
// for the block.
|
||||||
|
int row = threadIdx.x / RADIXGROUPS;
|
||||||
|
int column = threadIdx.x % RADIXGROUPS;
|
||||||
|
int spos = row * RADIXGROUPS + column;
|
||||||
|
int dpos = row * TOTALRADIXGROUPS + column + blockIdx.x * RADIXGROUPS;
|
||||||
|
while (spos < SHUFFLE_GRFOFFSET)
|
||||||
|
{
|
||||||
|
sRadixSum[spos] = dRadixSum[dpos] + sRadixSum[SHUFFLE_GRFOFFSET + dpos / (TOTALRADIXGROUPS * RADICES / PREFIX_NUM_BLOCKS)];
|
||||||
|
spos += NUM_THREADS_PER_BLOCK;
|
||||||
|
dpos += (NUM_THREADS_PER_BLOCK / RADIXGROUPS) * TOTALRADIXGROUPS;
|
||||||
|
}
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
//int pos;
|
||||||
|
// Shuffle data
|
||||||
|
// Each of the subbins for a block should be filled via the counters, properly interleaved
|
||||||
|
// Then, as we now iterate over each data value, we increment the subbins (each thread in the
|
||||||
|
// radix group in turn to avoid miss writes due to conflicts) and set locations correctly.
|
||||||
|
uint element_fraction = elements_rounded_to_3072 / TOTALRADIXGROUPS;
|
||||||
|
int tmod = threadIdx.x % RADIXTHREADS;
|
||||||
|
int tpos = threadIdx.x / RADIXTHREADS;
|
||||||
|
|
||||||
|
pos = (blockIdx.x * RADIXGROUPS + tpos) * element_fraction;
|
||||||
|
uint end = pos + element_fraction; //(blockIdx.x * RADIXGROUPS + tpos + 1) * element_fraction;
|
||||||
|
pos += tmod;
|
||||||
|
|
||||||
|
__syncthreads();
|
||||||
|
|
||||||
|
while (pos < end )
|
||||||
|
{
|
||||||
|
KeyValuePair kvp;
|
||||||
|
#if 1 // old load
|
||||||
|
// Read first data element, both items at once as the memory will want to coalesce like that anyway
|
||||||
|
if (pos < elements)
|
||||||
|
{
|
||||||
|
kvp = pSrc[pos];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
kvp.key = 0;
|
||||||
|
|
||||||
|
#else // casting to float2 to get it to combine loads
|
||||||
|
int2 kvpf2;
|
||||||
|
|
||||||
|
// Read first data element, both items at once as the memory will want to coalesce like that anyway
|
||||||
|
if (pos < elements)
|
||||||
|
{
|
||||||
|
// kvp = pSrc[pos];
|
||||||
|
kvpf2 = ((int2*)pSrc)[pos];
|
||||||
|
// printf("kvp: %f %f kvpf2: %f %f\n", kvp.key, kvp.value, kvpf2.x, kvpf2.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
//kvp.key = 0;
|
||||||
|
kvpf2.x = 0;
|
||||||
|
|
||||||
|
kvp.key = kvpf2.x;
|
||||||
|
kvp.value = kvpf2.y;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint index;
|
||||||
|
|
||||||
|
// Calculate position of radix counter to increment
|
||||||
|
uint p = ((kvp.key >> shift) & RADIXMASK) * RADIXGROUPS;
|
||||||
|
|
||||||
|
// Move data, keeping counts updated.
|
||||||
|
// Increment radix counters, relying on hexadecathread
|
||||||
|
// warp to prevent this code from stepping all over itself.
|
||||||
|
uint ppos = p + tpos;
|
||||||
|
if (tmod == 0 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 1 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 2 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 3 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 4 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 5 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 6 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 7 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 8 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 9 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 10 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 11 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 12 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 13 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 14 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
if (tmod == 15 && pos < elements)
|
||||||
|
{
|
||||||
|
index = sRadixSum[ppos]++;
|
||||||
|
pDst[index] = kvp;
|
||||||
|
}
|
||||||
|
SYNCIT;
|
||||||
|
|
||||||
|
pos += RADIXTHREADS;
|
||||||
|
}
|
||||||
|
|
||||||
|
__syncthreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef _RADIXSORT_KERNEL_H_
|
||||||
23
Extras/sph/fluids_2005.sln
Normal file
23
Extras/sph/fluids_2005.sln
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||||
|
# Visual Studio 2005
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fluids_2005", "fluids_2005.vcproj", "{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
EmuDebug|Win32 = EmuDebug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.EmuDebug|Win32.ActiveCfg = EmuDebug|Win32
|
||||||
|
{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.EmuDebug|Win32.Build.0 = EmuDebug|Win32
|
||||||
|
{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
447
Extras/sph/fluids_2005.vcproj
Normal file
447
Extras/sph/fluids_2005.vcproj
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8.00"
|
||||||
|
Name="fluids_2005"
|
||||||
|
ProjectGUID="{644E4AC1-416D-4567-A68B-D66CA9FCFD9C}"
|
||||||
|
RootNamespace="fluids_2005"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="fluids;common;marching;marching_tris;C:\CUDA\common\inc"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="glee_2005.lib cudart.lib cutil32D.lib"
|
||||||
|
LinkIncremental="2"
|
||||||
|
IgnoreDefaultLibraryNames="libcmt.lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="C:\CUDA\common\inc;fluids;common;marching;marching_tris"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="cudart.lib cutil32.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="C:\CUDA\common\lib;."
|
||||||
|
IgnoreDefaultLibraryNames="libcmtd.lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="EmuDebug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="fluids;common;marching"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="glee_VS2005.lib cg.lib cgGL.lib cudart.lib cutil32D.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/fluids_2005.pdb"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="common"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\common_defs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\geomx.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\geomx.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\gl_helper.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\gl_helper.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\image.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\image.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\matrix-inline.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\matrix.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\matrix.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mdebug.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mdebug.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mesh.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mesh.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mesh_info.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mtime.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\mtime.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\particle.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\particle.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\point_set.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\point_set.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\vector-inline.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\vector.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\vector.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="fluids"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid_system.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid_system.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid_system_host.cu"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
CommandLine=""$(CUDA_BIN_PATH)\nvcc.exe" -arch=sm_10 -ccbin "$(VCInstallDir)\bin" -c -D_DEBUG -DWIN32 -D_CONSOLE -D_MBCS -Xcompiler /EHsc,/W3,/nologo,/Wp64,/Od,/Zi,/RTC1,/MTd -I "$(CUDA_INC_PATH)"; -I./ -o $(ConfigurationName)\fluid_system_cu.obj fluids\fluid_system_host.cu
"
|
||||||
|
AdditionalDependencies="fluid_system_host.cuh; fluid_system_kern.cu;"
|
||||||
|
Outputs="$(ConfigurationName)\fluid_system_cu.obj"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
CommandLine=""$(CUDA_BIN_PATH)\nvcc.exe" -arch=sm_10 -use_fast_math -ccbin "$(VCInstallDir)\bin" -c -I "$(CUDA_INC_PATH)"; -I./ -I../../common/inc -o $(ConfigurationName)\fluid_system_cu.obj fluids\fluid_system_host.cu
"
|
||||||
|
AdditionalDependencies="fluid_system_host.cuh; fluid_system_kern.cu; radixsort.cu"
|
||||||
|
Outputs="$(ConfigurationName)\fluid_system_cu.obj"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="EmuDebug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
CommandLine=""$(CUDA_BIN_PATH)\nvcc.exe" -arch=sm_10 -ccbin "$(VCInstallDir)\bin" -deviceemu -c -D_DEBUG -DWIN32 -D_CONSOLE -D_MBCS -Xcompiler /EHsc,/W3,/nologo,/Wp64,/Od,/Zi,/RTC1,/MTd -I "$(CUDA_INC_PATH)"; -I./ -o $(ConfigurationName)\fluid_system_cu.obj fluids\fluid_system_host.cu
"
|
||||||
|
AdditionalDependencies="fluid_system_host.cuh; fluid_system_kern.cu;"
|
||||||
|
Outputs="$(ConfigurationName)\fluid_system_cu.obj"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid_system_host.cuh"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\fluids\fluid_system_kern.cu"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="radix_sort"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\radixsort.cu"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\radixsort.cuh"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\radixsort_kernel.cu"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\GLee.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\common\GLee.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\main.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
19
Extras/sph/fluids_2008.sln
Normal file
19
Extras/sph/fluids_2008.sln
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fluids", "fluids.vcproj", "{F9F0795D-4C39-41F4-9381-25C616D69FB2}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{F9F0795D-4C39-41F4-9381-25C616D69FB2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{F9F0795D-4C39-41F4-9381-25C616D69FB2}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{F9F0795D-4C39-41F4-9381-25C616D69FB2}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{F9F0795D-4C39-41F4-9381-25C616D69FB2}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
585
Extras/sph/main.cpp
Normal file
585
Extras/sph/main.cpp
Normal file
@@ -0,0 +1,585 @@
|
|||||||
|
/*
|
||||||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||||||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||||||
|
|
||||||
|
ZLib license
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "common_defs.h"
|
||||||
|
|
||||||
|
#ifdef BUILD_CUDA
|
||||||
|
#include "fluid_system_host.cuh"
|
||||||
|
#endif
|
||||||
|
#include "fluid_system.h"
|
||||||
|
#include "gl_helper.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER // Windows
|
||||||
|
#include <gl/glut.h>
|
||||||
|
#else // Linux
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool bTiming = false;
|
||||||
|
bool bRec = false;
|
||||||
|
int mFrame = 0;
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
FluidSystem psys;
|
||||||
|
|
||||||
|
float window_width = 1024;
|
||||||
|
float window_height = 768;
|
||||||
|
|
||||||
|
Vector3DF cam_from, cam_angs, cam_to; // Camera stuff
|
||||||
|
Vector3DF obj_from, obj_angs, obj_dang;
|
||||||
|
Vector3DF light[2], light_to[2]; // Light stuff
|
||||||
|
float light_fov, cam_fov;
|
||||||
|
|
||||||
|
int psys_rate = 0; // Particle stuff
|
||||||
|
int psys_freq = 1;
|
||||||
|
int psys_demo = 0;
|
||||||
|
int psys_nmax = 4096;
|
||||||
|
|
||||||
|
bool bHelp = false; // Toggles
|
||||||
|
int iShade = 1;
|
||||||
|
int iClrMode = 0;
|
||||||
|
bool bPntDraw = false;
|
||||||
|
bool bPause = false;
|
||||||
|
|
||||||
|
// View matricies
|
||||||
|
float view_matrix[16]; // View matrix (V)
|
||||||
|
float model_matrix[16]; // Model matrix (M)
|
||||||
|
float proj_matrix[16]; // Projective matrix
|
||||||
|
|
||||||
|
// Mouse control
|
||||||
|
#define DRAG_OFF 0 // mouse states
|
||||||
|
#define DRAG_LEFT 1
|
||||||
|
#define DRAG_RIGHT 2
|
||||||
|
int last_x = -1, last_y = -1; // mouse vars
|
||||||
|
int mode = 0;
|
||||||
|
int dragging = 0;
|
||||||
|
int psel;
|
||||||
|
|
||||||
|
GLuint screen_id;
|
||||||
|
GLuint depth_id;
|
||||||
|
|
||||||
|
|
||||||
|
// Different things we can move around
|
||||||
|
#define MODE_CAM 0
|
||||||
|
#define MODE_CAM_TO 1
|
||||||
|
#define MODE_OBJ 2
|
||||||
|
#define MODE_OBJPOS 3
|
||||||
|
#define MODE_OBJGRP 4
|
||||||
|
#define MODE_LIGHTPOS 5
|
||||||
|
|
||||||
|
#define MODE_DOF 6
|
||||||
|
|
||||||
|
GLuint screenBufferObject;
|
||||||
|
GLuint depthBufferObject;
|
||||||
|
GLuint envid;
|
||||||
|
|
||||||
|
void drawScene ( float* viewmat, bool bShade )
|
||||||
|
{
|
||||||
|
if ( iShade <= 1 && bShade ) {
|
||||||
|
glEnable ( GL_LIGHT0 );
|
||||||
|
GLfloat diff[4];
|
||||||
|
GLfloat spec[4];
|
||||||
|
GLfloat shininess = 60.0;
|
||||||
|
|
||||||
|
diff[0] = 0.8f; diff[1] = 0.8f; diff[2] = 0.8f; diff[3] = 1.0f;
|
||||||
|
spec[0] = 1.0f; spec[1] = 1.0f; spec[2] = 1.0f; spec[3] = 1.0f;
|
||||||
|
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, &diff[0]);
|
||||||
|
glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, &spec[0]);
|
||||||
|
glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &shininess);
|
||||||
|
glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
|
||||||
|
|
||||||
|
glColor3f ( 1, 1, 1 );
|
||||||
|
glLoadMatrixf ( viewmat );
|
||||||
|
glBegin ( GL_QUADS );
|
||||||
|
glNormal3f ( 0, 0, 1 );
|
||||||
|
glVertex3f ( -1000, -1000, 0.0 );
|
||||||
|
glVertex3f ( 1000, -1000, 0.0 );
|
||||||
|
glVertex3f ( 1000, 1000, 0.0 );
|
||||||
|
glVertex3f ( -1000, 1000, 0.0 );
|
||||||
|
glEnd ();
|
||||||
|
glBegin ( GL_LINES );
|
||||||
|
for (float n=-100; n <= 100; n += 20.0 ) {
|
||||||
|
glVertex3f ( -100, n, 0.1 );
|
||||||
|
glVertex3f ( 100, n, 0.1 );
|
||||||
|
glVertex3f ( n, -100, 0.1 );
|
||||||
|
glVertex3f ( n, 100, 0.1 );
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
|
||||||
|
psys.Draw ( &viewmat[0], 0.8 ); // Draw particles
|
||||||
|
|
||||||
|
} else {
|
||||||
|
glDisable ( GL_LIGHTING );
|
||||||
|
psys.Draw ( &viewmat[0], 0.55 ); // Draw particles
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw2D ()
|
||||||
|
{
|
||||||
|
|
||||||
|
mint::Time start, stop;
|
||||||
|
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
disableShadows ();
|
||||||
|
#endif
|
||||||
|
glDisable ( GL_LIGHTING );
|
||||||
|
glDisable ( GL_DEPTH_TEST );
|
||||||
|
|
||||||
|
glMatrixMode ( GL_PROJECTION );
|
||||||
|
glLoadIdentity ();
|
||||||
|
glScalef ( 2.0/window_width, -2.0/window_height, 1 ); // Setup view (0,0) to (800,600)
|
||||||
|
glTranslatef ( -window_width/2.0, -window_height/2, 0.0);
|
||||||
|
|
||||||
|
glMatrixMode ( GL_MODELVIEW );
|
||||||
|
glLoadIdentity ();
|
||||||
|
glPushMatrix ();
|
||||||
|
glGetFloatv ( GL_MODELVIEW_MATRIX, view_matrix );
|
||||||
|
glPopMatrix ();
|
||||||
|
|
||||||
|
char disp[200];
|
||||||
|
glColor4f ( 1.0, 1.0, 1.0, 1.0 );
|
||||||
|
|
||||||
|
strcpy ( disp, "Press H for help." ); drawText ( 10, 20, disp );
|
||||||
|
|
||||||
|
if ( bHelp ) {
|
||||||
|
|
||||||
|
if ( psys.GetToggle ( USE_CUDA ) ) {
|
||||||
|
sprintf ( disp, "Kernel: USING CUDA (GPU)" ); drawText ( 20, 40, disp );
|
||||||
|
} else {
|
||||||
|
sprintf ( disp, "Kernel: USING CPU" ); drawText ( 20, 40, disp );
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf ( disp, "KEYBOARD" ); drawText ( 20, 60, disp );
|
||||||
|
sprintf ( disp, "[ ] Next/Prev Demo" ); drawText ( 20, 70, disp );
|
||||||
|
sprintf ( disp, "N M Adjust Max Particles" ); drawText ( 20, 80, disp );
|
||||||
|
sprintf ( disp, "space Pause" ); drawText ( 20, 90, disp );
|
||||||
|
sprintf ( disp, "S Shading mode" ); drawText ( 20, 100, disp );
|
||||||
|
sprintf ( disp, "G Toggle CUDA vs CPU" ); drawText ( 20, 110, disp );
|
||||||
|
sprintf ( disp, "< > Change emitter rate" ); drawText ( 20, 120, disp );
|
||||||
|
sprintf ( disp, "C Move camera /w mouse" ); drawText ( 20, 130, disp );
|
||||||
|
sprintf ( disp, "I Move emitter /w mouse" ); drawText ( 20, 140, disp );
|
||||||
|
sprintf ( disp, "O Change emitter angle" ); drawText ( 20, 150, disp );
|
||||||
|
sprintf ( disp, "L Move light /w mouse" ); drawText ( 20, 160, disp );
|
||||||
|
sprintf ( disp, "X Draw velocity/pressure/color" ); drawText ( 20, 170, disp );
|
||||||
|
|
||||||
|
Vector3DF vol = psys.GetVec(SPH_VOLMAX);
|
||||||
|
vol -= psys.GetVec(SPH_VOLMIN);
|
||||||
|
sprintf ( disp, "Volume Size: %3.5f %3.2f %3.2f", vol.x, vol.y, vol.z ); drawText ( 20, 190, disp );
|
||||||
|
sprintf ( disp, "Time Step (dt): %3.5f", psys.GetDT () ); drawText ( 20, 200, disp );
|
||||||
|
sprintf ( disp, "Num Particles: %d", psys.NumPoints() ); drawText ( 20, 210, disp );
|
||||||
|
sprintf ( disp, "Simulation Scale: %3.5f", psys.GetParam(SPH_SIMSIZE) ); drawText ( 20, 220, disp );
|
||||||
|
sprintf ( disp, "Simulation Size (m): %3.5f", psys.GetParam(SPH_SIMSCALE) ); drawText ( 20, 230, disp );
|
||||||
|
sprintf ( disp, "Smooth Radius (m): %3.3f", psys.GetParam(SPH_SMOOTHRADIUS) ); drawText ( 20, 240, disp );
|
||||||
|
sprintf ( disp, "Particle Radius (m): %3.3f", psys.GetParam(SPH_PRADIUS) ); drawText ( 20, 250, disp );
|
||||||
|
sprintf ( disp, "Particle Mass (kg): %0.8f", psys.GetParam(SPH_PMASS) ); drawText ( 20, 260, disp );
|
||||||
|
sprintf ( disp, "Rest Density (kg/m^3): %3.3f", psys.GetParam(SPH_RESTDENSITY) ); drawText ( 20, 270, disp );
|
||||||
|
sprintf ( disp, "Viscosity: %3.3f", psys.GetParam(SPH_VISC) ); drawText ( 20, 280, disp );
|
||||||
|
sprintf ( disp, "Internal Stiffness: %3.3f", psys.GetParam(SPH_INTSTIFF) ); drawText ( 20, 290, disp );
|
||||||
|
sprintf ( disp, "Boundary Stiffness: %6.0f", psys.GetParam(SPH_EXTSTIFF) ); drawText ( 20, 300, disp );
|
||||||
|
sprintf ( disp, "Boundary Dampening: %4.3f", psys.GetParam(SPH_EXTDAMP) ); drawText ( 20, 310, disp );
|
||||||
|
sprintf ( disp, "Speed Limiting: %4.3f", psys.GetParam(SPH_LIMIT) ); drawText ( 20, 320, disp );
|
||||||
|
vol = psys.GetVec ( PLANE_GRAV_DIR );
|
||||||
|
sprintf ( disp, "Gravity: %3.2f %3.2f %3.2f", vol.x, vol.y, vol.z ); drawText ( 20, 330, disp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void computeFromPositions ()
|
||||||
|
{
|
||||||
|
cam_from.x = cam_to.x + sin( cam_angs.x * DEGtoRAD) * sin( cam_angs.y * DEGtoRAD) * cam_angs.z;
|
||||||
|
cam_from.y = cam_to.y + -cos( cam_angs.x * DEGtoRAD) * sin( cam_angs.y * DEGtoRAD) * cam_angs.z;
|
||||||
|
cam_from.z = cam_to.z + cos( cam_angs.y * DEGtoRAD) * cam_angs.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void computeProjection ()
|
||||||
|
{
|
||||||
|
// ---- Create projection matrix for eye-coordinate transformations
|
||||||
|
glMatrixMode( GL_PROJECTION );
|
||||||
|
glLoadIdentity();
|
||||||
|
gluPerspective ( cam_fov, window_width / ( float ) window_height, 10.0, 800.0 );
|
||||||
|
glPushMatrix ();
|
||||||
|
glGetFloatv ( GL_MODELVIEW_MATRIX, proj_matrix );
|
||||||
|
glPopMatrix ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void computeView ()
|
||||||
|
{
|
||||||
|
glMatrixMode ( GL_MODELVIEW );
|
||||||
|
glLoadIdentity ();
|
||||||
|
gluLookAt ( cam_from.x, cam_from.y, cam_from.z, cam_to.x, cam_to.y, cam_to.z, 0, 0, 1 );
|
||||||
|
glPushMatrix ();
|
||||||
|
glGetFloatv ( GL_MODELVIEW_MATRIX, view_matrix );
|
||||||
|
glPopMatrix ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int frame;
|
||||||
|
|
||||||
|
void display ()
|
||||||
|
{
|
||||||
|
mint::Time start, stop;
|
||||||
|
|
||||||
|
// iso = sin(frame*0.01f );
|
||||||
|
|
||||||
|
// Do simulation!
|
||||||
|
if ( !bPause ) psys.Run ();
|
||||||
|
|
||||||
|
frame++;
|
||||||
|
measureFPS ();
|
||||||
|
|
||||||
|
glEnable ( GL_DEPTH_TEST );
|
||||||
|
|
||||||
|
// Render depth map shadows
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
disableShadows ();
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
if ( iShade==1 ) {
|
||||||
|
renderDepthMap_FrameBuffer ( 0, window_width, window_height );
|
||||||
|
} else {
|
||||||
|
renderDepthMap_Clear ( window_width, window_height );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Clear frame buffer
|
||||||
|
if ( iShade<=1 ) glClearColor( 0.29, 0.29, 0.29, 1.0 );
|
||||||
|
else glClearColor ( 0, 0, 0, 0 );
|
||||||
|
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
glDisable ( GL_CULL_FACE );
|
||||||
|
glShadeModel ( GL_SMOOTH );
|
||||||
|
|
||||||
|
// Compute camera view
|
||||||
|
computeFromPositions ();
|
||||||
|
computeProjection ();
|
||||||
|
computeView ();
|
||||||
|
|
||||||
|
// Draw Shadows (if on)
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
if ( iShade==1 ) renderShadows ( view_matrix );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Draw 3D
|
||||||
|
start.SetSystemTime ( ACC_NSEC );
|
||||||
|
glEnable ( GL_LIGHTING );
|
||||||
|
glLoadMatrixf ( view_matrix );
|
||||||
|
drawScene ( view_matrix, true );
|
||||||
|
if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "SCENE: %s\n", stop.GetReadableTime().c_str() ); }
|
||||||
|
|
||||||
|
// Draw 2D overlay
|
||||||
|
draw2D ();
|
||||||
|
|
||||||
|
// Swap buffers
|
||||||
|
glutSwapBuffers();
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reshape ( int width, int height )
|
||||||
|
{
|
||||||
|
// set window height and width
|
||||||
|
window_width = (float) width;
|
||||||
|
window_height = (float) height;
|
||||||
|
glViewport( 0, 0, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateEmit ()
|
||||||
|
{
|
||||||
|
obj_from = psys.GetVec ( EMIT_POS );
|
||||||
|
obj_angs = psys.GetVec ( EMIT_ANG );
|
||||||
|
obj_dang = psys.GetVec ( EMIT_RATE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void keyboard_func ( unsigned char key, int x, int y )
|
||||||
|
{
|
||||||
|
switch( key ) {
|
||||||
|
case 'M': case 'm': {
|
||||||
|
psys_nmax *= 2;
|
||||||
|
if ( psys_nmax > 65535 ) psys_nmax = 65535;
|
||||||
|
psys.SPH_CreateExample ( psys_demo, psys_nmax );
|
||||||
|
} break;
|
||||||
|
case 'N': case 'n': {
|
||||||
|
psys_nmax /= 2;
|
||||||
|
if ( psys_nmax < 64 ) psys_nmax = 64;
|
||||||
|
psys.SPH_CreateExample ( psys_demo, psys_nmax );
|
||||||
|
} break;
|
||||||
|
case '0':
|
||||||
|
UpdateEmit ();
|
||||||
|
psys_freq++;
|
||||||
|
psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
|
||||||
|
break;
|
||||||
|
case '9':
|
||||||
|
UpdateEmit ();
|
||||||
|
psys_freq--; if ( psys_freq < 0 ) psys_freq = 0;
|
||||||
|
psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
|
||||||
|
break;
|
||||||
|
case '.': case '>':
|
||||||
|
UpdateEmit ();
|
||||||
|
if ( ++psys_rate > 100 ) psys_rate = 100;
|
||||||
|
psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
|
||||||
|
break;
|
||||||
|
case ',': case '<':
|
||||||
|
UpdateEmit ();
|
||||||
|
if ( --psys_rate < 0 ) psys_rate = 0;
|
||||||
|
psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
|
||||||
|
break;
|
||||||
|
case 'g': case 'G': psys.Toggle ( USE_CUDA ); break;
|
||||||
|
case 'f': case 'F': mode = MODE_DOF; break;
|
||||||
|
|
||||||
|
case 'z': case 'Z': mode = MODE_CAM_TO; break;
|
||||||
|
case 'c': case 'C': mode = MODE_CAM; break;
|
||||||
|
case 'h': case 'H': bHelp = !bHelp; break;
|
||||||
|
case 'i': case 'I':
|
||||||
|
UpdateEmit ();
|
||||||
|
mode = MODE_OBJPOS;
|
||||||
|
break;
|
||||||
|
case 'o': case 'O':
|
||||||
|
UpdateEmit ();
|
||||||
|
mode = MODE_OBJ;
|
||||||
|
break;
|
||||||
|
case 'x': case 'X':
|
||||||
|
if ( ++iClrMode > 2) iClrMode = 0;
|
||||||
|
psys.SetParam ( CLR_MODE, iClrMode );
|
||||||
|
break;
|
||||||
|
case 'l': case 'L': mode = MODE_LIGHTPOS; break;
|
||||||
|
case 'd': case 'D': {
|
||||||
|
int d = psys.GetParam ( PNT_DRAWMODE ) + 1;
|
||||||
|
if ( d > 2 ) d = 0;
|
||||||
|
psys.SetParam ( PNT_DRAWMODE, d );
|
||||||
|
} break;
|
||||||
|
case 's': case 'S': if ( ++iShade > 2 ) iShade = 0; break;
|
||||||
|
case 27: exit( 0 ); break;
|
||||||
|
|
||||||
|
case '`':
|
||||||
|
bRec = !bRec; break;
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
//psys.Run (); ptris.Rebuild (); break;
|
||||||
|
bPause = !bPause; break;
|
||||||
|
|
||||||
|
case '\'': case ';': psys.SPH_CreateExample ( psys_demo, psys_nmax ); break;
|
||||||
|
case 'r': case 'R': psys.SPH_CreateExample ( psys_demo, psys_nmax ); break;
|
||||||
|
case '[':
|
||||||
|
psys_demo--;
|
||||||
|
if (psys_demo < 0 ) psys_demo = 10;
|
||||||
|
psys.SPH_CreateExample ( psys_demo, psys_nmax );
|
||||||
|
UpdateEmit ();
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
psys_demo++;
|
||||||
|
if (psys_demo > 10 ) psys_demo = 0;
|
||||||
|
psys.SPH_CreateExample ( psys_demo, psys_nmax );
|
||||||
|
UpdateEmit ();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mouse_click_func ( int button, int state, int x, int y )
|
||||||
|
{
|
||||||
|
if( state == GLUT_DOWN ) {
|
||||||
|
if ( button == GLUT_LEFT_BUTTON ) dragging = DRAG_LEFT;
|
||||||
|
else if ( button == GLUT_RIGHT_BUTTON ) dragging = DRAG_RIGHT;
|
||||||
|
last_x = x;
|
||||||
|
last_y = y;
|
||||||
|
} else {
|
||||||
|
dragging = DRAG_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_move_func ( int x, int y )
|
||||||
|
{
|
||||||
|
int dx = x - last_x;
|
||||||
|
int dy = y - last_y;
|
||||||
|
|
||||||
|
switch ( mode ) {
|
||||||
|
case MODE_CAM:
|
||||||
|
if ( dragging == DRAG_LEFT ) {
|
||||||
|
cam_angs.x += dx;
|
||||||
|
cam_angs.y += dy;
|
||||||
|
if ( cam_angs.x >= 360.0 ) cam_angs.x -= 360.0;
|
||||||
|
if ( cam_angs.x < 0 ) cam_angs.x += 360.0;
|
||||||
|
if ( cam_angs.y >= 180.0 ) cam_angs.y = 180.0;
|
||||||
|
if ( cam_angs.y <= -180.0 ) cam_angs.y = -180.0;
|
||||||
|
printf ( "Cam Ang: %f %f %f\n", cam_angs.x, cam_angs.y, cam_angs.z );
|
||||||
|
printf ( "Cam To: %f %f %f\n", cam_to.x, cam_to.y, cam_to.z );
|
||||||
|
printf ( "Cam FOV: %f\n", cam_fov);
|
||||||
|
} else if ( dragging == DRAG_RIGHT ) {
|
||||||
|
cam_angs.z += dy*.15;
|
||||||
|
if ( cam_angs.z < 0) cam_angs.z = 0;
|
||||||
|
printf ( "Cam Ang: %f %f %f\n", cam_angs.x, cam_angs.y, cam_angs.z );
|
||||||
|
printf ( "Cam To: %f %f %f\n", cam_to.x, cam_to.y, cam_to.z );
|
||||||
|
printf ( "Cam FOV: %f\n", cam_fov );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MODE_CAM_TO:
|
||||||
|
if ( dragging == DRAG_LEFT ) {
|
||||||
|
cam_to.x += dx;
|
||||||
|
cam_to.y += dy;
|
||||||
|
} else if ( dragging == DRAG_RIGHT ) {
|
||||||
|
cam_to.z += dy*.05;
|
||||||
|
if ( cam_to.z < 0) cam_to.z = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MODE_OBJ:
|
||||||
|
if ( dragging == DRAG_LEFT ) {
|
||||||
|
obj_angs.x -= dx*0.1;
|
||||||
|
obj_angs.y += dy*0.1;
|
||||||
|
printf ( "Obj Angs: %f %f %f\n", obj_angs.x, obj_angs.y, obj_angs.z );
|
||||||
|
//force_x += dx*.1;
|
||||||
|
//force_y += dy*.1;
|
||||||
|
} else if (dragging == DRAG_RIGHT) {
|
||||||
|
obj_angs.z -= dy*.005;
|
||||||
|
printf ( "Obj Angs: %f %f %f\n", obj_angs.x, obj_angs.y, obj_angs.z );
|
||||||
|
}
|
||||||
|
psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) );
|
||||||
|
break;
|
||||||
|
case MODE_OBJPOS:
|
||||||
|
if ( dragging == DRAG_LEFT ) {
|
||||||
|
obj_from.x -= dx*.1;
|
||||||
|
obj_from.y += dy*.1;
|
||||||
|
printf ( "Obj: %f %f %f\n", obj_from.x, obj_from.y, obj_from.z );
|
||||||
|
} else if (dragging == DRAG_RIGHT) {
|
||||||
|
obj_from.z -= dy*.1;
|
||||||
|
printf ( "Obj: %f %f %f\n", obj_from.x, obj_from.y, obj_from.z );
|
||||||
|
}
|
||||||
|
psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) );
|
||||||
|
//psys.setPos ( obj_x, obj_y, obj_z, obj_ang, obj_tilt, obj_dist );
|
||||||
|
break;
|
||||||
|
case MODE_LIGHTPOS:
|
||||||
|
if ( dragging == DRAG_LEFT ) {
|
||||||
|
light[0].x -= dx*.1;
|
||||||
|
light[0].y += dy*.1;
|
||||||
|
printf ( "Light: %f %f %f\n", light[0].x, light[0].y, light[0].z );
|
||||||
|
} else if (dragging == DRAG_RIGHT) {
|
||||||
|
light[0].z -= dy*.1;
|
||||||
|
printf ( "Light: %f %f %f\n", light[0].x, light[0].y, light[0].z );
|
||||||
|
}
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
setShadowLight ( light[0].x, light[0].y, light[0].z, light_to[0].x, light_to[0].y, light_to[0].z, light_fov );
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( x < 10 || y < 10 || x > 1000 || y > 700 ) {
|
||||||
|
glutWarpPointer ( 1024/2, 768/2 );
|
||||||
|
last_x = 1024/2;
|
||||||
|
last_y = 768/2;
|
||||||
|
} else {
|
||||||
|
last_x = x;
|
||||||
|
last_y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void idle_func ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void init ()
|
||||||
|
{
|
||||||
|
|
||||||
|
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||||
|
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
||||||
|
|
||||||
|
srand ( time ( 0x0 ) );
|
||||||
|
|
||||||
|
glClearColor( 0.49, 0.49, 0.49, 1.0 );
|
||||||
|
glShadeModel( GL_SMOOTH );
|
||||||
|
|
||||||
|
glEnable ( GL_COLOR_MATERIAL );
|
||||||
|
glEnable (GL_DEPTH_TEST);
|
||||||
|
glEnable (GL_BLEND);
|
||||||
|
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glDepthMask ( 1 );
|
||||||
|
glEnable ( GL_TEXTURE_2D );
|
||||||
|
|
||||||
|
// callbacks
|
||||||
|
glutDisplayFunc( display );
|
||||||
|
glutReshapeFunc( reshape );
|
||||||
|
glutKeyboardFunc( keyboard_func );
|
||||||
|
glutMouseFunc( mouse_click_func );
|
||||||
|
glutMotionFunc( mouse_move_func );
|
||||||
|
glutIdleFunc( idle_func );
|
||||||
|
glutSetCursor ( GLUT_CURSOR_NONE );
|
||||||
|
|
||||||
|
cam_angs.x = 29; cam_angs.y = 75; cam_angs.z = 80.0;
|
||||||
|
cam_to.x = 0; cam_to.y = 0; cam_to.z = 5;
|
||||||
|
cam_fov = 35.0;
|
||||||
|
|
||||||
|
light[0].x = 39; light[0].y = -60; light[0].z = 43;
|
||||||
|
light_to[0].x = 0; light_to[0].y = 0; light_to[0].z = 0;
|
||||||
|
|
||||||
|
light[1].x = 15; light[1].y = -5; light[1].z = 145;
|
||||||
|
light_to[1].x = 0; light_to[1].y = 0; light_to[1].z = 0;
|
||||||
|
|
||||||
|
light_fov = 45;
|
||||||
|
|
||||||
|
#ifdef USE_SHADOWS
|
||||||
|
createShadowTextures();
|
||||||
|
createFrameBuffer ();
|
||||||
|
setShadowLight ( light[0].x, light[0].y, light[0].z, light_to[0].x, light_to[0].y, light_to[0].z, light_fov );
|
||||||
|
setShadowLightColor ( .7, .7, .7, 0.2, 0.2, 0.2 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
obj_from.x = 0; obj_from.y = 0; obj_from.z = 20; // emitter
|
||||||
|
obj_angs.x = 118.7; obj_angs.y = 200; obj_angs.z = 1.0;
|
||||||
|
obj_dang.x = 1; obj_dang.y = 1; obj_dang.z = 0;
|
||||||
|
|
||||||
|
psys.Initialize ( BFLUID, psys_nmax );
|
||||||
|
psys.SPH_CreateExample ( 0, psys_nmax );
|
||||||
|
psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) );
|
||||||
|
psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) );
|
||||||
|
|
||||||
|
psys.SetParam ( PNT_DRAWMODE, int(bPntDraw ? 1:0) );
|
||||||
|
psys.SetParam ( CLR_MODE, iClrMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main ( int argc, char **argv )
|
||||||
|
{
|
||||||
|
#ifdef BUILD_CUDA
|
||||||
|
// Initialize CUDA
|
||||||
|
cudaInit( argc, argv );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// set up the window
|
||||||
|
glutInit( &argc, &argv[0] );
|
||||||
|
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
|
||||||
|
glutInitWindowPosition( 100, 100 );
|
||||||
|
glutInitWindowSize( (int) window_width, (int) window_height );
|
||||||
|
glutCreateWindow ( "Fluids v.1 (c) 2008, R. Hoetzlein (ZLib)" );
|
||||||
|
|
||||||
|
// glutFullScreen ();
|
||||||
|
|
||||||
|
// initialize parameters
|
||||||
|
init();
|
||||||
|
|
||||||
|
// wait for something to happen
|
||||||
|
glutMainLoop();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user