mirror of
https://github.com/celisej567/source-engine-metaballs.git
synced 2025-12-31 05:48:11 +03:00
Init
This commit is contained in:
179
game/client/metaballs/CUBE_GRID.cpp
Normal file
179
game/client/metaballs/CUBE_GRID.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CUBE_GRID.cpp
|
||||
// function definitions for grid of cubes for "marching cubes" algorithm
|
||||
// Downloaded from: www.paulsprojects.net
|
||||
// Created: 20th July 2002
|
||||
//
|
||||
// Copyright (c) 2006, Paul Baker
|
||||
// Distributed under the New BSD Licence. (See accompanying file License.txt or copy at
|
||||
// http://www.paulsprojects.net/NewBSDLicense.txt)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cbase.h"
|
||||
#include "CUBE_GRID.h"
|
||||
#include "cbase.h"
|
||||
|
||||
ConVar cl_blobs_resolution_max("cl_blobs_resolution_max", "20", FCVAR_CLIENTDLL);
|
||||
|
||||
bool CUBE_GRID::CreateMemory()
|
||||
{
|
||||
vertices=new CUBE_GRID_VERTEX[(cl_blobs_resolution_max.GetInt() + 1) * (cl_blobs_resolution_max.GetInt() + 1) * (cl_blobs_resolution_max.GetInt() + 1)];
|
||||
if(!vertices)
|
||||
{
|
||||
Msg("Unable to allocate memory for %d Grid Vertices", numVertices);
|
||||
return false;
|
||||
}
|
||||
|
||||
cubes=new CUBE_GRID_CUBE[cl_blobs_resolution_max.GetInt() * cl_blobs_resolution_max.GetInt() * cl_blobs_resolution_max.GetInt()];
|
||||
if(!cubes)
|
||||
{
|
||||
Msg("Unable to allocate memory for %d Grid Cubes", numCubes);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CUBE_GRID::Init(int gridSize, Vector Pos, Vector Bounds)
|
||||
{
|
||||
|
||||
//VERTICES
|
||||
numVertices=(gridSize+1)*(gridSize+1)*(gridSize+1);
|
||||
|
||||
int currentVertex=0;
|
||||
|
||||
for(int i=0; i<gridSize+1; i++)
|
||||
{
|
||||
for(int j=0; j<gridSize+1; j++)
|
||||
{
|
||||
for(int k=0; k<gridSize+1; k++)
|
||||
{
|
||||
vertices[currentVertex].position.x = ((Bounds.x / gridSize * i)) + Pos.x;
|
||||
vertices[currentVertex].position.y = ((Bounds.y / gridSize * j)) + Pos.y;
|
||||
vertices[currentVertex].position.z = ((Bounds.z / gridSize * k)) + Pos.z;
|
||||
|
||||
currentVertex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//CUBES
|
||||
numCubes=(gridSize)*(gridSize)*(gridSize);
|
||||
|
||||
int currentCube=0;
|
||||
|
||||
for(int i=0; i<gridSize; i++)
|
||||
{
|
||||
for(int j=0; j<gridSize; j++)
|
||||
{
|
||||
for(int k=0; k<gridSize; k++)
|
||||
{
|
||||
cubes[currentCube].vertices[0]=&vertices[(i*(gridSize+1)+j)*(gridSize+1)+k];
|
||||
cubes[currentCube].vertices[1]=&vertices[(i*(gridSize+1)+j)*(gridSize+1)+k+1];
|
||||
cubes[currentCube].vertices[2]=&vertices[(i*(gridSize+1)+(j+1))*(gridSize+1)+k+1];
|
||||
cubes[currentCube].vertices[3]=&vertices[(i*(gridSize+1)+(j+1))*(gridSize+1)+k];
|
||||
cubes[currentCube].vertices[4]=&vertices[((i+1)*(gridSize+1)+j)*(gridSize+1)+k];
|
||||
cubes[currentCube].vertices[5]=&vertices[((i+1)*(gridSize+1)+j)*(gridSize+1)+k+1];
|
||||
cubes[currentCube].vertices[6]=&vertices[((i+1)*(gridSize+1)+(j+1))*(gridSize+1)+k+1];
|
||||
cubes[currentCube].vertices[7]=&vertices[((i+1)*(gridSize+1)+(j+1))*(gridSize+1)+k];
|
||||
|
||||
currentCube++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CUBE_GRID::DrawSurface(float threshold)
|
||||
{
|
||||
/*
|
||||
numFacesDrawn=0;
|
||||
|
||||
static SURFACE_VERTEX edgeVertices[12];
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
{
|
||||
//loop through cubes
|
||||
for(int i=0; i<numCubes; i++)
|
||||
{
|
||||
//calculate which vertices are inside the surface
|
||||
unsigned char cubeIndex=0;
|
||||
|
||||
if(cubes[i].vertices[0]->value < threshold)
|
||||
cubeIndex |= 1;
|
||||
if(cubes[i].vertices[1]->value < threshold)
|
||||
cubeIndex |= 2;
|
||||
if(cubes[i].vertices[2]->value < threshold)
|
||||
cubeIndex |= 4;
|
||||
if(cubes[i].vertices[3]->value < threshold)
|
||||
cubeIndex |= 8;
|
||||
if(cubes[i].vertices[4]->value < threshold)
|
||||
cubeIndex |= 16;
|
||||
if(cubes[i].vertices[5]->value < threshold)
|
||||
cubeIndex |= 32;
|
||||
if(cubes[i].vertices[6]->value < threshold)
|
||||
cubeIndex |= 64;
|
||||
if(cubes[i].vertices[7]->value < threshold)
|
||||
cubeIndex |= 128;
|
||||
|
||||
//look this value up in the edge table to see which edges to interpolate along
|
||||
int usedEdges=edgeTable[cubeIndex];
|
||||
|
||||
//if the cube is entirely within/outside surface, no faces
|
||||
if(usedEdges==0 || usedEdges==255)
|
||||
continue;
|
||||
|
||||
//update these edges
|
||||
for(int currentEdge=0; currentEdge<12; currentEdge++)
|
||||
{
|
||||
if(usedEdges & 1<<currentEdge)
|
||||
{
|
||||
CUBE_GRID_VERTEX * v1=cubes[i].vertices[verticesAtEndsOfEdges[currentEdge*2 ]];
|
||||
CUBE_GRID_VERTEX * v2=cubes[i].vertices[verticesAtEndsOfEdges[currentEdge*2+1]];
|
||||
|
||||
float delta=(threshold - v1->value)/(v2->value - v1->value);
|
||||
//edgeVertices[currentEdge].position=v1->position + delta*(v2->position - v1->position);
|
||||
edgeVertices[currentEdge].position.x=v1->position.x + delta*(v2->position.x - v1->position.x);
|
||||
edgeVertices[currentEdge].position.y=v1->position.y + delta*(v2->position.y - v1->position.y);
|
||||
edgeVertices[currentEdge].position.z=v1->position.z + delta*(v2->position.z - v1->position.z);
|
||||
//edgeVertices[currentEdge].normal=v1->normal + delta*(v2->normal - v1->normal);
|
||||
edgeVertices[currentEdge].normal.x=v1->normal.x + delta*(v2->normal.x - v1->normal.x);
|
||||
edgeVertices[currentEdge].normal.y=v1->normal.y + delta*(v2->normal.y - v1->normal.y);
|
||||
edgeVertices[currentEdge].normal.z=v1->normal.z + delta*(v2->normal.z - v1->normal.z);
|
||||
}
|
||||
}
|
||||
|
||||
//send the vertices
|
||||
for(int k=0; triTable[cubeIndex][k]!=-1; k+=3)
|
||||
{
|
||||
glNormal3fv(edgeVertices[triTable[cubeIndex][k+0]].normal);
|
||||
glVertex3fv(edgeVertices[triTable[cubeIndex][k+0]].position);
|
||||
|
||||
glNormal3fv(edgeVertices[triTable[cubeIndex][k+2]].normal);
|
||||
glVertex3fv(edgeVertices[triTable[cubeIndex][k+2]].position);
|
||||
|
||||
glNormal3fv(edgeVertices[triTable[cubeIndex][k+1]].normal);
|
||||
glVertex3fv(edgeVertices[triTable[cubeIndex][k+1]].position);
|
||||
|
||||
numFacesDrawn++;
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
*/
|
||||
}
|
||||
|
||||
void CUBE_GRID::FreeMemory()
|
||||
{
|
||||
if(vertices)
|
||||
delete [] vertices;
|
||||
vertices=NULL;
|
||||
numVertices=0;
|
||||
|
||||
if(cubes)
|
||||
delete [] cubes;
|
||||
cubes=NULL;
|
||||
numCubes=0;
|
||||
}
|
||||
372
game/client/metaballs/CUBE_GRID.h
Normal file
372
game/client/metaballs/CUBE_GRID.h
Normal file
@@ -0,0 +1,372 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CUBE_GRID.h
|
||||
// Class declaration for grid of cubes for "marching cubes" algorithm
|
||||
// Downloaded from: www.paulsprojects.net
|
||||
// Created: 20th July 2002
|
||||
//
|
||||
// Copyright (c) 2006, Paul Baker
|
||||
// Distributed under the New BSD Licence. (See accompanying file License.txt or copy at
|
||||
// http://www.paulsprojects.net/NewBSDLicense.txt)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef C_CUBE_GRID_H
|
||||
#define C_CUBE_GRID_H
|
||||
|
||||
//wee need it to calc
|
||||
#include "cbase.h"
|
||||
|
||||
class CUBE_GRID_VERTEX
|
||||
{
|
||||
public:
|
||||
Vector position;
|
||||
float value; //the value of the scalar field at this point
|
||||
Vector normal;
|
||||
};
|
||||
|
||||
//vertex from linear interpolation along edge
|
||||
class SURFACE_VERTEX
|
||||
{
|
||||
public:
|
||||
Vector position;
|
||||
Vector normal;
|
||||
};
|
||||
|
||||
class CUBE_GRID_CUBE
|
||||
{
|
||||
public:
|
||||
CUBE_GRID_VERTEX * vertices[8]; //pointers to vertices
|
||||
};
|
||||
|
||||
class CUBE_GRID
|
||||
{
|
||||
public:
|
||||
int numVertices;
|
||||
CUBE_GRID_VERTEX * vertices;
|
||||
|
||||
int numCubes;
|
||||
CUBE_GRID_CUBE * cubes;
|
||||
|
||||
int numFacesDrawn;
|
||||
|
||||
bool CreateMemory();
|
||||
bool Init(int gridSize, Vector Pos, Vector Bounds);
|
||||
void DrawSurface(float threshold);
|
||||
void FreeMemory();
|
||||
|
||||
CUBE_GRID() : numVertices(0), vertices(NULL), numCubes(0), cubes(NULL),
|
||||
numFacesDrawn(0)
|
||||
{}
|
||||
~CUBE_GRID()
|
||||
{ FreeMemory(); }
|
||||
};
|
||||
|
||||
//gives the vertices at the end of each edge
|
||||
static const uint8_t verticesAtEndsOfEdges[24]=
|
||||
{ 0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
4, 5,
|
||||
5, 6,
|
||||
6, 7,
|
||||
7, 4,
|
||||
0, 4,
|
||||
1, 5,
|
||||
2, 6,
|
||||
3, 7};
|
||||
|
||||
//gives the edges to interpolate along given vertex inside/outside
|
||||
static const int edgeTable[256]={
|
||||
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
|
||||
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
||||
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
|
||||
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
|
||||
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
|
||||
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
|
||||
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
|
||||
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
|
||||
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
|
||||
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
|
||||
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
|
||||
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
|
||||
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
|
||||
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
|
||||
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
|
||||
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
|
||||
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
|
||||
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
|
||||
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
|
||||
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
|
||||
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
|
||||
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
|
||||
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
|
||||
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
|
||||
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
|
||||
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
|
||||
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
|
||||
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
|
||||
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
|
||||
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
|
||||
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
|
||||
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 };
|
||||
|
||||
//gives which vertices to join to form triangles for the surface
|
||||
static const int triTable[256][16] =
|
||||
{{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
||||
{8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
|
||||
{3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
|
||||
{4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
||||
{4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
|
||||
{9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
|
||||
{10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
|
||||
{5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
|
||||
{5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
|
||||
{8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
|
||||
{2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
||||
{2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
|
||||
{11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
|
||||
{5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
|
||||
{11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
|
||||
{11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
|
||||
{2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
|
||||
{6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
||||
{3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
|
||||
{6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
|
||||
{6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
|
||||
{8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
|
||||
{7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
|
||||
{3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
|
||||
{0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
|
||||
{9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
|
||||
{8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
|
||||
{5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
|
||||
{0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
|
||||
{6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
|
||||
{10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
||||
{1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
|
||||
{0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
|
||||
{3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
|
||||
{6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
|
||||
{9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
|
||||
{8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
|
||||
{3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
|
||||
{10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
|
||||
{10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
||||
{2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
|
||||
{7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
|
||||
{2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
|
||||
{1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
|
||||
{11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
|
||||
{8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
|
||||
{0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
|
||||
{7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
|
||||
{7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
|
||||
{10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
|
||||
{0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
|
||||
{7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
|
||||
{6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
|
||||
{4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
|
||||
{10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
|
||||
{8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
|
||||
{1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
|
||||
{10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
|
||||
{10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
|
||||
{9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
|
||||
{7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
|
||||
{3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
|
||||
{7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
|
||||
{3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
|
||||
{6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
|
||||
{9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
|
||||
{1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
|
||||
{4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
|
||||
{7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
|
||||
{6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
|
||||
{0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
|
||||
{6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
|
||||
{0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
|
||||
{11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
|
||||
{6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
|
||||
{5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
|
||||
{9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
|
||||
{1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
|
||||
{10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
|
||||
{0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
|
||||
{11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
|
||||
{9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
|
||||
{7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
|
||||
{2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
|
||||
{9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
|
||||
{9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
|
||||
{1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
|
||||
{0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
|
||||
{10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
|
||||
{2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
|
||||
{0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
|
||||
{0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
|
||||
{9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
|
||||
{5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
|
||||
{5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
|
||||
{8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
|
||||
{9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
|
||||
{1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
|
||||
{3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
|
||||
{4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
|
||||
{9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
|
||||
{11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
|
||||
{11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
|
||||
{2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
|
||||
{9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
|
||||
{3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
|
||||
{1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
|
||||
{4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
|
||||
{0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
|
||||
{9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
|
||||
{1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
|
||||
|
||||
#endif
|
||||
30
game/client/metaballs/METABALL.h
Normal file
30
game/client/metaballs/METABALL.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// METABALL.h
|
||||
// Class declaration for metaball
|
||||
// Downloaded from: www.paulsprojects.net
|
||||
// Created: 20th July 2002
|
||||
//
|
||||
// Copyright (c) 2006, Paul Baker
|
||||
// Distributed under the New BSD Licence. (See accompanying file License.txt or copy at
|
||||
// http://www.paulsprojects.net/NewBSDLicense.txt)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef C_METABALL_H
|
||||
#define C_METABALL_H
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
class METABALL
|
||||
{
|
||||
public:
|
||||
Vector position;
|
||||
float squaredRadius;
|
||||
|
||||
void Init(Vector newPosition, float newSquaredRadius)
|
||||
{
|
||||
position=newPosition;
|
||||
squaredRadius=newSquaredRadius;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
344
game/client/metaballs/c_point_blob_container.cpp
Normal file
344
game/client/metaballs/c_point_blob_container.cpp
Normal file
@@ -0,0 +1,344 @@
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_props.h"
|
||||
#include "METABALL.h"
|
||||
#include "CUBE_GRID.h"
|
||||
#include "debugoverlay_shared.h"
|
||||
#include "c_point_blob_element.h"
|
||||
#include "c_point_blob_container.h"
|
||||
|
||||
#include "materialsystem/imesh.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS(point_blob_container, C_PointBlobContainer);
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED(PointBlobContainer, DT_PointBlobContainer)
|
||||
BEGIN_NETWORK_TABLE(C_PointBlobContainer, DT_PointBlobContainer)
|
||||
RecvPropInt(RECVINFO(GridSize)),
|
||||
RecvPropVector(RECVINFO(GridBounds)),
|
||||
RecvPropInt(RECVINFO(color), 0, RecvProxy_IntToColor32),
|
||||
RecvPropInt(RECVINFO(Ambcolor), 0, RecvProxy_IntToColor32),
|
||||
RecvPropFloat(RECVINFO(colorBoost)),
|
||||
RecvPropString(RECVINFO(BlobMaterialName)),
|
||||
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
ConVar r_drawblobs("r_drawblobs", "1", FCVAR_CLIENTDLL);
|
||||
ConVar cl_blobs_updatecontainers("cl_blobs_updatecontainers", "1", FCVAR_CLIENTDLL);
|
||||
//ConVar cl_blobs_resolution("cl_blobs_resolution", "10", FCVAR_CLIENTDLL);
|
||||
ConVar cl_blobthreshold("cl_blobthreshold", "1.2", FCVAR_CLIENTDLL);
|
||||
ConVar cl_blobvaluethreshold("cl_blobvaluethreshold", "0.3", FCVAR_CLIENTDLL);
|
||||
ConVar cl_blobs_unroll_factor("cl_blobs_unroll_factor", "4", FCVAR_CLIENTDLL);
|
||||
|
||||
//why? why not! (it works better then Q_strcmp that redirects to V_strcmp that redirects to strcmp)
|
||||
int Quake_strcmp (const char* s1, const char* s2)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (*s1 != *s2)
|
||||
return -1; // strings not equal
|
||||
if (!*s1)
|
||||
return 0; // strings are equal
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void C_PointBlobContainer::Spawn()
|
||||
{
|
||||
//get already existed container to save compute resources and just use already existed one.
|
||||
///////
|
||||
size_t count = 0;
|
||||
// Iterate through all the entities in the clientside world
|
||||
for (int i = 0; i < cl_entitylist->GetHighestEntityIndex() + 1; i++)
|
||||
{
|
||||
if(parentedContainer != NULL)
|
||||
{
|
||||
C_BaseEntity* entity = cl_entitylist->GetBaseEntity(i);
|
||||
if (entity && entity->GetClientClass()->m_pNetworkName)
|
||||
{
|
||||
// Check if the entity is valid and matches the desired class name
|
||||
if (Quake_strcmp(entity->GetClientClass()->m_pNetworkName, "CPointBlobContainer") == 0)
|
||||
{
|
||||
//add entity into array
|
||||
parentedContainer = ((C_PointBlobContainer*)(entity));
|
||||
Msg("%u\n", count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
////////
|
||||
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
int C_PointBlobContainer::DrawModel(int flags)
|
||||
{
|
||||
if(r_drawblobs.GetBool())
|
||||
{
|
||||
if (metaballs.size() > 0)
|
||||
{
|
||||
|
||||
///Source dont like when you do CMeshBuilder stuff in DrawModel. So sometimes lighting looks like shit. Im making it unlit because i cant feagure out how to fix this
|
||||
|
||||
CMatRenderContextPtr pRenderContext(materials);
|
||||
|
||||
pRenderContext->Bind(CustomMat, NULL);
|
||||
pRenderContext->SetLightingOrigin(GetAbsOrigin());
|
||||
|
||||
g_pStudioRender->SetAmbientLightColors(white);
|
||||
|
||||
//// Disable all the lights..
|
||||
//pRenderContext->DisableAllLocalLights();
|
||||
|
||||
pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
|
||||
const float threshold = cl_blobthreshold.GetFloat();
|
||||
|
||||
meshBuilder.Begin(pMesh, MATERIAL_TRIANGLES, cubeGrid.numVertices);
|
||||
|
||||
//loop through cubes
|
||||
for (int i = 0; i < cubeGrid.numCubes; i++)
|
||||
{
|
||||
|
||||
//calculate which vertices are inside the surface
|
||||
unsigned char cubeIndex = 0;
|
||||
if (cubeGrid.cubes[i].vertices[0]->value < threshold)
|
||||
cubeIndex |= 1;
|
||||
if (cubeGrid.cubes[i].vertices[1]->value < threshold)
|
||||
cubeIndex |= 2;
|
||||
if (cubeGrid.cubes[i].vertices[2]->value < threshold)
|
||||
cubeIndex |= 4;
|
||||
if (cubeGrid.cubes[i].vertices[3]->value < threshold)
|
||||
cubeIndex |= 8;
|
||||
if (cubeGrid.cubes[i].vertices[4]->value < threshold)
|
||||
cubeIndex |= 16;
|
||||
if (cubeGrid.cubes[i].vertices[5]->value < threshold)
|
||||
cubeIndex |= 32;
|
||||
if (cubeGrid.cubes[i].vertices[6]->value < threshold)
|
||||
cubeIndex |= 64;
|
||||
if (cubeGrid.cubes[i].vertices[7]->value < threshold)
|
||||
cubeIndex |= 128;
|
||||
|
||||
//look this value up in the edge table to see which edges to interpolate along
|
||||
int usedEdges = edgeTable[cubeIndex];
|
||||
|
||||
|
||||
//if the cube is entirely within/outside surface, no faces
|
||||
if (usedEdges == 0 || usedEdges == 255)
|
||||
continue;
|
||||
|
||||
//update these edges
|
||||
for (int currentEdge = 0; currentEdge < 12; currentEdge++)
|
||||
{
|
||||
if (usedEdges & 1 << currentEdge)
|
||||
{
|
||||
CUBE_GRID_VERTEX* v1 = cubeGrid.cubes[i].vertices[verticesAtEndsOfEdges[currentEdge * 2]];
|
||||
CUBE_GRID_VERTEX* v2 = cubeGrid.cubes[i].vertices[verticesAtEndsOfEdges[currentEdge * 2 + 1]];
|
||||
|
||||
float delta = (threshold - v1->value) / (v2->value - v1->value);
|
||||
//edgeVertices[currentEdge].position=v1->position + delta*(v2->position - v1->position);
|
||||
edgeVertices[currentEdge].position.x = v1->position.x + delta * (v2->position.x - v1->position.x);
|
||||
edgeVertices[currentEdge].position.y = v1->position.y + delta * (v2->position.y - v1->position.y);
|
||||
edgeVertices[currentEdge].position.z = v1->position.z + delta * (v2->position.z - v1->position.z);
|
||||
//edgeVertices[currentEdge].normal=v1->normal + delta*(v2->normal - v1->normal);
|
||||
edgeVertices[currentEdge].normal.x = v1->normal.x + delta * (v2->normal.x - v1->normal.x);
|
||||
edgeVertices[currentEdge].normal.y = v1->normal.y + delta * (v2->normal.y - v1->normal.y);
|
||||
edgeVertices[currentEdge].normal.z = v1->normal.z + delta * (v2->normal.z - v1->normal.z);
|
||||
}
|
||||
}
|
||||
|
||||
//send the vertices
|
||||
for (int k = 0; triTable[cubeIndex][k] != -1; k += 3)
|
||||
{
|
||||
//Vector pos = Vector(edgeVertices[triTable[cubeIndex][k + 0]].position.x, edgeVertices[triTable[cubeIndex][k + 0]].position.y, edgeVertices[triTable[cubeIndex][k + 0]].position.z);
|
||||
//Vector vertnormal = Vector(edgeVertices[triTable[cubeIndex][k + 0]].normal.x, edgeVertices[triTable[cubeIndex][k + 0]].normal.y, edgeVertices[triTable[cubeIndex][k + 0]].normal.z);
|
||||
|
||||
meshBuilder.Normal3fv(edgeVertices[triTable[cubeIndex][k + 0]].normal.Base());
|
||||
meshBuilder.Position3fv(edgeVertices[triTable[cubeIndex][k + 0]].position.Base());
|
||||
meshBuilder.TexCoord2f(0, 1, 1);
|
||||
meshBuilder.Color3f(1,0,0);
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
//pos = Vector(edgeVertices[triTable[cubeIndex][k + 1]].position.x, edgeVertices[triTable[cubeIndex][k + 1]].position.y, edgeVertices[triTable[cubeIndex][k + 1]].position.z);
|
||||
//vertnormal = Vector(edgeVertices[triTable[cubeIndex][k + 1]].normal.x, edgeVertices[triTable[cubeIndex][k + 1]].normal.y, edgeVertices[triTable[cubeIndex][k + 1]].normal.z);
|
||||
|
||||
meshBuilder.Normal3fv(edgeVertices[triTable[cubeIndex][k + 1]].normal.Base());
|
||||
meshBuilder.Position3fv(edgeVertices[triTable[cubeIndex][k + 1]].position.Base());
|
||||
meshBuilder.TexCoord2f(0, 1, 0);
|
||||
meshBuilder.Color3f(0, 1, 0);
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
//pos = Vector(edgeVertices[triTable[cubeIndex][k + 2]].position.x, edgeVertices[triTable[cubeIndex][k + 2]].position.y, edgeVertices[triTable[cubeIndex][k + 2]].position.z);
|
||||
//vertnormal = Vector(edgeVertices[triTable[cubeIndex][k + 2]].normal.x, edgeVertices[triTable[cubeIndex][k + 2]].normal.y, edgeVertices[triTable[cubeIndex][k + 2]].normal.z);
|
||||
|
||||
meshBuilder.Normal3fv(edgeVertices[triTable[cubeIndex][k + 2]].normal.Base());
|
||||
meshBuilder.Position3fv(edgeVertices[triTable[cubeIndex][k + 2]].position.Base());
|
||||
meshBuilder.TexCoord2f(0, 0, 1);
|
||||
meshBuilder.Color3f(0, 0, 1);
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
}
|
||||
}
|
||||
//pRenderContext->SetFlashlightMode(false);
|
||||
meshBuilder.End();
|
||||
//modelrender->SuppressEngineLighting(false);
|
||||
|
||||
pMesh->Draw();
|
||||
pRenderContext->Flush();
|
||||
|
||||
//delete pMesh;
|
||||
//pRenderContext->PopMatrix();
|
||||
//pRenderContext->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
//return BaseClass::DrawModel(flags);
|
||||
//return InternalDrawModel(STUDIO_RENDER | extraFlags);
|
||||
}
|
||||
|
||||
void C_PointBlobContainer::GetRenderBounds(Vector& theMins, Vector& theMaxs)
|
||||
{
|
||||
|
||||
theMaxs = Vector(GridBounds.x, GridBounds.y, GridBounds.z);
|
||||
theMins = Vector(0,0,0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void C_PointBlobContainer::UpdateResolution()
|
||||
{
|
||||
//GridSize = cl_blobs_resolution.GetInt();
|
||||
cubeGrid.FreeMemory();
|
||||
cubeGrid.CreateMemory();
|
||||
}
|
||||
|
||||
void C_PointBlobContainer::UpdateBalls()
|
||||
{
|
||||
|
||||
//cubeGrid->Init(GridSize, GetAbsOrigin(), GridBounds);
|
||||
if(parentedContainer == NULL)
|
||||
{
|
||||
metaballs.clear();
|
||||
|
||||
// Iterate through all the entities in the clientside world
|
||||
for (int i = 0; i < cl_entitylist->GetHighestEntityIndex()+1; i++)
|
||||
{
|
||||
C_BaseEntity* entity = cl_entitylist->GetBaseEntity(i);
|
||||
if (entity && entity->GetClientClass()->m_pNetworkName)
|
||||
{
|
||||
// Check if the entity is valid and matches the desired class name
|
||||
if (Quake_strcmp(entity->GetClientClass()->m_pNetworkName, "CPointBlobElement") == 0)
|
||||
{
|
||||
//add entity into array
|
||||
metaballs.push_back((C_PointBlobElement*)(entity));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
metaballs = parentedContainer->metaballs;
|
||||
}
|
||||
|
||||
if (cl_blobs_updatecontainers.GetBool())
|
||||
{
|
||||
//clear the field
|
||||
for (int i = 0; i < cubeGrid.numVertices; i++)
|
||||
{
|
||||
cubeGrid.vertices[i].value = 0.0f;
|
||||
cubeGrid.vertices[i].normal = {0,0,0};
|
||||
}
|
||||
|
||||
Vector ballToPoint;
|
||||
float squaredRadius;
|
||||
Vector ballPosition;
|
||||
float normalScale = 0;
|
||||
const float ValueThreshold = cl_blobvaluethreshold.GetFloat();
|
||||
|
||||
for (unsigned int i = 0; i < metaballs.size(); i++)
|
||||
{
|
||||
ballPosition = metaballs[i]->GetAbsOrigin();
|
||||
squaredRadius = metaballs[i]->radiusSquared;
|
||||
|
||||
for (int j = 0; j < cubeGrid.numVertices; j++)
|
||||
{
|
||||
ballToPoint = cubeGrid.vertices[j].position - ballPosition;
|
||||
vec_t squareDistance = ballToPoint.LengthSqr();
|
||||
|
||||
if (squareDistance != 0)
|
||||
{
|
||||
float valueIncrement = squaredRadius / squareDistance;
|
||||
cubeGrid.vertices[j].value += (squareDistance > ValueThreshold) ? valueIncrement : 0;
|
||||
|
||||
normalScale = squaredRadius / (squareDistance * squareDistance);
|
||||
cubeGrid.vertices[j].normal += ballToPoint * normalScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_PointBlobContainer::Simulate()
|
||||
{
|
||||
BaseClass::Simulate();
|
||||
//if(cl_blobs_updatecontainers.GetBool())
|
||||
UpdateBalls();
|
||||
//if((cl_blobs_resolution.GetInt() != GridSize) || ((ConVarRef("cl_blobs_resolution_max").GetInt()) != ( cbrtf(cubeGrid->numVertices) - 3 )))
|
||||
// UpdateResolution();
|
||||
if(developer.GetInt() > 0)
|
||||
{
|
||||
Vector min;
|
||||
Vector max;
|
||||
GetRenderBounds(min,max);
|
||||
NDebugOverlay::Box(GetAbsOrigin(), min, max, 255, 0, 0, 0, 0.0015f);
|
||||
}
|
||||
|
||||
// Why like this?
|
||||
// When you spawn entity using ent_create, engine spawns entity at 0 0 0, calls Spawn(), transfer all the netvar data and only then he changes position to view point.
|
||||
// Simulate() called only AFTER changing position, so this shit will work more reliably here.
|
||||
// (Yes, that means game dont transfer data before Spawn(), but after. Thats why i put BlobMaterialName check here.)
|
||||
if (!first)
|
||||
{
|
||||
cubeGrid.Init(GridSize, GetAbsOrigin(), GridBounds);
|
||||
|
||||
for(size_t i=0; i<6; i++)
|
||||
{
|
||||
//white[i] = Vector(RemapVal(color.GetR(), 0, 255, 0, 1) * colorBoost, RemapVal(color.GetG(), 0, 255, 0, 1) * colorBoost, RemapVal(color.GetB(), 0, 255, 0, 1) * colorBoost);
|
||||
white[i] = Vector(((float)Ambcolor.GetR()/255) * colorBoost, ((float)Ambcolor.GetG()/255) * colorBoost, ((float)Ambcolor.GetB()/255) * colorBoost);
|
||||
//white[i] = Vector((Ambcolor.GetR()/0xFF) * colorBoost, (Ambcolor.GetG()/0xFF) * colorBoost, (Ambcolor.GetB()/0xFF) * colorBoost);
|
||||
//white[i] = Vector(1 * colorBoost,1 * colorBoost,1 * colorBoost);
|
||||
}
|
||||
|
||||
if (BlobMaterialName == 0x00000000)
|
||||
{
|
||||
char* buff = new char[20];
|
||||
V_snprintf(buff, 20, "{ %i %i %i }", color.GetR(), color.GetG(), color.GetB());
|
||||
kval = new KeyValues("UnlitGeneric");
|
||||
kval->SetString("$color", buff);
|
||||
//kval->SetString("$vertexcolor", "1");
|
||||
//kval->SetString("$vertexalpha", "1");
|
||||
//kval->SetString("$envmap", "editor/cubemap");
|
||||
CustomMat = materials->CreateMaterial("blobik.vmt", kval);
|
||||
|
||||
}
|
||||
else{
|
||||
PrecacheMaterial(BlobMaterialName);
|
||||
CustomMat = materials->FindMaterial(BlobMaterialName, TEXTURE_GROUP_OTHER);
|
||||
}
|
||||
first = true;
|
||||
}
|
||||
|
||||
//if (GridSize != cl_blobs_resolution.GetInt())
|
||||
//{
|
||||
// GridSize = cl_blobs_resolution.GetInt();
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
86
game/client/metaballs/c_point_blob_container.h
Normal file
86
game/client/metaballs/c_point_blob_container.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef C_BLOBCONTAINER_H
|
||||
#define C_BLOBCONTAINER_H
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_props.h"
|
||||
#include "METABALL.h"
|
||||
#include "CUBE_GRID.h"
|
||||
#include "c_point_blob_element.h"
|
||||
#include "model_types.h"
|
||||
#include "studio_stats.h"
|
||||
#include <vector>
|
||||
|
||||
class C_PointBlobContainer : public C_BreakableProp
|
||||
{
|
||||
DECLARE_CLASS(C_PointBlobContainer, C_BreakableProp);
|
||||
public:
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
C_PointBlobContainer()
|
||||
{
|
||||
GridSize = 10;
|
||||
cubeGrid = CUBE_GRID();
|
||||
GridBounds = {50,50,50};
|
||||
colorBoost = 1;
|
||||
|
||||
Ambcolor.SetR(88);
|
||||
Ambcolor.SetG(88);
|
||||
Ambcolor.SetB(88);
|
||||
Ambcolor.SetA(255);
|
||||
|
||||
color.SetR(100);
|
||||
color.SetG(100);
|
||||
color.SetB(100);
|
||||
color.SetA(255);
|
||||
|
||||
cubeGrid.CreateMemory();
|
||||
}
|
||||
|
||||
~C_PointBlobContainer()
|
||||
{
|
||||
cubeGrid.FreeMemory();
|
||||
//delete cubeGrid;
|
||||
metaballs.clear();
|
||||
}
|
||||
|
||||
void UpdateBalls();
|
||||
void UpdateResolution();
|
||||
|
||||
virtual int DrawModel(int flags);
|
||||
virtual void GetRenderBounds(Vector& theMins, Vector& theMaxs);
|
||||
|
||||
virtual void Spawn(void);
|
||||
virtual void ClientThink(){}
|
||||
//virtual void PostDataUpdate(DataUpdateType_t updateType);
|
||||
virtual bool ShouldDraw() {return true;}
|
||||
|
||||
virtual void Simulate();
|
||||
|
||||
virtual void OnDataChanged(DataUpdateType_t type){}
|
||||
|
||||
CUBE_GRID cubeGrid;
|
||||
int GridSize;
|
||||
float colorBoost;
|
||||
Vector GridBounds;
|
||||
CNetworkColor32(Ambcolor);
|
||||
CNetworkColor32(color);
|
||||
std::vector<C_PointBlobElement*> metaballs;
|
||||
|
||||
IMesh* pMesh;
|
||||
|
||||
C_PointBlobContainer* parentedContainer;
|
||||
|
||||
Vector white[6];
|
||||
|
||||
char BlobMaterialName[MAX_PATH];
|
||||
|
||||
KeyValues* kval;
|
||||
IMaterial* CustomMat;
|
||||
private:
|
||||
SURFACE_VERTEX edgeVertices[12];
|
||||
|
||||
bool first = false;
|
||||
|
||||
};
|
||||
|
||||
#endif // !C_BLOBCONTAINER_H
|
||||
62
game/client/metaballs/c_point_blob_element.cpp
Normal file
62
game/client/metaballs/c_point_blob_element.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
|
||||
#include "cbase.h"
|
||||
//#include "c_props.h"
|
||||
#include "METABALL.h"
|
||||
#include "c_point_blob_element.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!! :apple_advertisement:
|
||||
//#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS(point_blob_element, C_PointBlobElement);
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED(PointBlobElement, DT_PointBlobElement)
|
||||
|
||||
BEGIN_NETWORK_TABLE(C_PointBlobElement, DT_PointBlobElement)
|
||||
RecvPropFloat(RECVINFO(radius)),
|
||||
RecvPropFloat(RECVINFO(radiusSquared)),
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
void C_PointBlobElement::Spawn()
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
}
|
||||
|
||||
C_PointBlobElement::C_PointBlobElement()
|
||||
{
|
||||
radius = 10;
|
||||
radiusSquared = radius * radius;
|
||||
metaball = METABALL();
|
||||
|
||||
}
|
||||
|
||||
C_PointBlobElement::C_PointBlobElement(int newRadius)
|
||||
{
|
||||
radius = newRadius;
|
||||
radiusSquared = radius * radius;
|
||||
metaball = METABALL();
|
||||
|
||||
}
|
||||
|
||||
void C_PointBlobElement::Simulate()
|
||||
{
|
||||
BaseClass::Simulate();
|
||||
//if(!First)
|
||||
//{
|
||||
// pos = GetAbsOrigin();
|
||||
// SpawnTime = gpGlobals->curtime;
|
||||
// First = true;
|
||||
//}
|
||||
|
||||
//Vector ghgh;
|
||||
//ghgh.x = pos.x + sin(gpGlobals->curtime - SpawnTime);
|
||||
//ghgh.y = pos.y + sin(gpGlobals->curtime - SpawnTime);
|
||||
//ghgh.z = pos.z + sin(gpGlobals->curtime - SpawnTime);
|
||||
//SetAbsOrigin(ghgh);
|
||||
|
||||
//metaball.squaredRadius = radius * radius;
|
||||
//metaball.position = GetAbsOrigin();
|
||||
//NDebugOverlay::Sphere(GetAbsOrigin(), sqrt(radius), 255, 0, 0, true, 0.0015f);
|
||||
//Msg("dkgsfhgkklgsfklgjdfjklbujdfhgu");
|
||||
}
|
||||
42
game/client/metaballs/c_point_blob_element.h
Normal file
42
game/client/metaballs/c_point_blob_element.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef C_BLOBELEMENT_H
|
||||
#define C_BLOBELEMENT_H
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_props.h"
|
||||
#include "debugoverlay_shared.h"
|
||||
#include "METABALL.h"
|
||||
|
||||
/////////////////////////////////////
|
||||
///
|
||||
/// This is a blob element, or single blob if you prefer. He needs to initialise METABALL variable.
|
||||
/// You have to use this with C_PointBlobContainer to see the blob itself.
|
||||
///
|
||||
/////////////////////////////////////
|
||||
|
||||
class C_PointBlobElement : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS(C_PointBlobElement, C_BaseEntity);
|
||||
public:
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
C_PointBlobElement();
|
||||
C_PointBlobElement(int newRadius);
|
||||
~C_PointBlobElement(){}
|
||||
|
||||
|
||||
virtual void Spawn(void);
|
||||
virtual void ClientThink(){}
|
||||
|
||||
virtual void OnDataChanged(DataUpdateType_t type){}
|
||||
|
||||
virtual void Simulate();
|
||||
|
||||
float radius;
|
||||
float radiusSquared;
|
||||
METABALL metaball;
|
||||
Vector pos;
|
||||
float SpawnTime = 0;
|
||||
bool First = false;
|
||||
};
|
||||
|
||||
#endif // C_BLOBELEMENT_H
|
||||
17
game/client/metaballs/metaballs.vpc
Normal file
17
game/client/metaballs/metaballs.vpc
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
$Project
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$Folder "Metaballs"
|
||||
{
|
||||
$File "metaballs/c_point_blob_element.cpp"
|
||||
$File "metaballs/c_point_blob_element.h"
|
||||
$File "metaballs/c_point_blob_container.cpp"
|
||||
$File "metaballs/c_point_blob_container.h"
|
||||
$File "metaballs/CUBE_GRID.cpp"
|
||||
$File "metaballs/CUBE_GRID.h"
|
||||
$File "metaballs/METABALL.h"
|
||||
}
|
||||
}
|
||||
}
|
||||
14
game/server/metaballs/metaballs.vpc
Normal file
14
game/server/metaballs/metaballs.vpc
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
$Project
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$Folder "Metaballs"
|
||||
{
|
||||
$File "metaballs/point_blob_element.cpp"
|
||||
$File "metaballs/point_blob_element.h"
|
||||
$File "metaballs/point_blob_container.cpp"
|
||||
$File "metaballs/point_blob_container.h"
|
||||
}
|
||||
}
|
||||
}
|
||||
34
game/server/metaballs/point_blob_container.cpp
Normal file
34
game/server/metaballs/point_blob_container.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
#include "cbase.h"
|
||||
#include "point_blob_element.h"
|
||||
#include "point_blob_container.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS(point_blob_container, CPointBlobContainer);
|
||||
|
||||
//i should change the way how i do keyvalue shit later
|
||||
|
||||
BEGIN_DATADESC(CPointBlobContainer)
|
||||
DEFINE_KEYFIELD(GridSize, FIELD_INTEGER, "resolution"),
|
||||
DEFINE_KEYFIELD(GridBounds, FIELD_VECTOR, "bounds"),
|
||||
DEFINE_KEYFIELD(color, FIELD_COLOR32, "color"),
|
||||
DEFINE_KEYFIELD(Ambcolor, FIELD_COLOR32, "ambientcolor"),
|
||||
DEFINE_KEYFIELD(colorBoost, FIELD_FLOAT, "brightness"),
|
||||
DEFINE_KEYFIELD(BlobMaterialName, FIELD_STRING, "materialpath"),
|
||||
END_DATADESC()
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CPointBlobContainer, DT_PointBlobContainer)
|
||||
SendPropInt(SENDINFO(GridSize)),
|
||||
#if HL2MP //idk how is it different, but it is different
|
||||
SendPropVector(SENDINFO(GridBounds), -1, SPROP_COORD_MP),
|
||||
#else
|
||||
SendPropVector(SENDINFO(GridBounds), -1, SPROP_COORD),
|
||||
#endif
|
||||
SendPropInt( SENDINFO(color), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt),
|
||||
SendPropInt( SENDINFO(Ambcolor), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt),
|
||||
SendPropFloat(SENDINFO(colorBoost)),
|
||||
SendPropStringT(SENDINFO(BlobMaterialName)),
|
||||
END_SEND_TABLE()
|
||||
|
||||
|
||||
|
||||
|
||||
55
game/server/metaballs/point_blob_container.h
Normal file
55
game/server/metaballs/point_blob_container.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef C_BLOBCONTAINER_H
|
||||
#define C_BLOBCONTAINER_H
|
||||
|
||||
#include "cbase.h"
|
||||
#include "props.h"
|
||||
#include "point_blob_element.h"
|
||||
|
||||
//just empty shit to be able to spawn entity using ent_create and use entity for fgd for map
|
||||
|
||||
class CPointBlobContainer : public CBreakableProp
|
||||
{
|
||||
DECLARE_CLASS(CPointBlobContainer, CBreakableProp);
|
||||
public:
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
CPointBlobContainer()
|
||||
{
|
||||
GridSize = 10;
|
||||
GridBounds = Vector(50,50,50);
|
||||
color = {255,255,255};
|
||||
}
|
||||
|
||||
virtual void Spawn()
|
||||
{
|
||||
SetTransmitState(FL_EDICT_PVSCHECK);
|
||||
|
||||
m_nRenderMode = kRenderNormal;
|
||||
m_nRenderFX = kRenderFxNone;
|
||||
SetLightingOrigin(this);
|
||||
|
||||
//PrecacheModel("models/error.mdl");
|
||||
//SetModel("models/error.mdl");
|
||||
//BaseClass::Spawn();
|
||||
|
||||
// to shut up everything
|
||||
SetMoveType(MOVETYPE_NONE);
|
||||
m_takedamage = DAMAGE_NO;
|
||||
SetNextThink(TICK_NEVER_THINK);
|
||||
|
||||
m_flAnimTime = gpGlobals->curtime;
|
||||
m_flPlaybackRate = 0.0;
|
||||
SetCycle(0);
|
||||
}
|
||||
|
||||
CNetworkVar(int, GridSize);
|
||||
CNetworkVar(float, colorBoost);
|
||||
CNetworkVar(Vector, GridBounds);
|
||||
CNetworkVar(string_t, BlobMaterialName);
|
||||
CNetworkColor32(color);
|
||||
CNetworkColor32(Ambcolor);
|
||||
|
||||
};
|
||||
|
||||
#endif // !C_BLOBCONTAINER_H
|
||||
23
game/server/metaballs/point_blob_element.cpp
Normal file
23
game/server/metaballs/point_blob_element.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
#include "cbase.h"
|
||||
//#include "c_props.h"
|
||||
#include "point_blob_element.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!! :apple_advertisement:
|
||||
//#include "tier0/memdbgon.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS(point_blob_element, CPointBlobElement);
|
||||
|
||||
BEGIN_DATADESC(CPointBlobElement)
|
||||
//DEFINE_KEYFIELD(radius, FIELD_FLOAT, "radius"),
|
||||
END_DATADESC()
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CPointBlobElement, DT_PointBlobElement)
|
||||
SendPropFloat(SENDINFO(radius)),
|
||||
SendPropFloat(SENDINFO(radiusSquared)),
|
||||
END_SEND_TABLE()
|
||||
|
||||
|
||||
|
||||
|
||||
49
game/server/metaballs/point_blob_element.h
Normal file
49
game/server/metaballs/point_blob_element.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef C_BLOBELEMENT_H
|
||||
#define C_BLOBELEMENT_H
|
||||
|
||||
#include "cbase.h"
|
||||
#include "props.h"
|
||||
#include "props_shared.h"
|
||||
|
||||
/////////////////////////////////////
|
||||
///
|
||||
/// This is a blob element, or single blob if you prefer. He needs to initialise METABALL variable.
|
||||
/// You have to use this with C_PointBlobContainer to see the blob itself.
|
||||
///
|
||||
/////////////////////////////////////
|
||||
|
||||
class CPointBlobElement : public CBaseEntity
|
||||
{
|
||||
DECLARE_CLASS(CPointBlobElement, CBaseEntity);
|
||||
public:
|
||||
DECLARE_SERVERCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
CPointBlobElement(){}
|
||||
|
||||
virtual void Spawn()
|
||||
{
|
||||
|
||||
SetTransmitState(FL_EDICT_ALWAYS);
|
||||
|
||||
m_nRenderMode = kRenderNormal;
|
||||
m_nRenderFX = kRenderFxNone;
|
||||
|
||||
}
|
||||
|
||||
bool KeyValue(const char* szKeyName, const char* szValue)
|
||||
{
|
||||
if (FStrEq(szKeyName, "radius"))
|
||||
{
|
||||
radius = atof(szValue);
|
||||
radiusSquared = radius * radius;
|
||||
}
|
||||
return BaseClass::KeyValue(szKeyName, szValue);
|
||||
}
|
||||
|
||||
CNetworkVar(float, radius);
|
||||
CNetworkVar(float, radiusSquared);
|
||||
|
||||
};
|
||||
|
||||
#endif // C_BLOBELEMENT_H
|
||||
Reference in New Issue
Block a user