some working perlin noise rubbish and subdivision of sphere with some edge fixup...
git-svn-id: https://pioneer.svn.sourceforge.net/svnroot/pioneer/trunk@222 e632f14b-6550-0410-b89e-a82653faca30master
parent
06c1d43c4e
commit
b904be91c1
File diff suppressed because it is too large
Load Diff
|
@ -10,7 +10,7 @@ include_HEADERS = Body.h Frame.h GenericSystemView.h glfreetype.h GuiButton.h Gu
|
|||
SystemView.h vector3.h View.h WorldView.h utils.h SpaceStation.h SpaceStationView.h ModelBody.h GuiISelectable.h \
|
||||
ShipType.h Object.h InfoView.h ModelCollMeshData.h ObjectViewerView.h custom_starsystems.h Aabb.h Serializer.h \
|
||||
Sfx.h GuiVScrollPortal.h GuiVScrollBar.h GuiAdjustment.h MarketAgent.h GuiTabbed.h EquipType.h CargoBody.h \
|
||||
NameGenerator.h
|
||||
NameGenerator.h perlin.h
|
||||
|
||||
libgui_a_SOURCES = GuiButton.cpp Gui.cpp GuiFixed.cpp GuiScreen.cpp GuiLabel.cpp GuiToolTip.cpp GuiToggleButton.cpp GuiRadioButton.cpp \
|
||||
GuiRadioGroup.cpp GuiImageButton.cpp GuiImage.cpp GuiImageRadioButton.cpp GuiMultiStateImageButton.cpp GuiWidget.cpp \
|
||||
|
@ -21,7 +21,7 @@ pioneer_SOURCES = main.cpp glfreetype.cpp Body.cpp Space.cpp Ship.cpp Player.cpp
|
|||
StarSystem.cpp Sector.cpp SystemInfoView.cpp GenericSystemView.cpp utils.cpp SpaceStation.cpp \
|
||||
SpaceStationView.cpp ModelBody.cpp ShipType.cpp InfoView.cpp ModelCollMeshData.cpp \
|
||||
ObjectViewerView.cpp custom_starsystems.cpp Serializer.cpp Sfx.cpp Ship-AI.cpp MarketAgent.cpp \
|
||||
EquipType.cpp CargoBody.cpp NameGenerator.cpp
|
||||
EquipType.cpp CargoBody.cpp NameGenerator.cpp perlin.cpp
|
||||
pioneer_LDADD = sbre/libsbre.a collider/libcollider.a mods/libmods.a libgui.a
|
||||
|
||||
sbreviewer_SOURCES = SbreViewer.cpp glfreetype.cpp
|
||||
|
|
241
src/Planet.cpp
241
src/Planet.cpp
|
@ -5,6 +5,7 @@
|
|||
#include "WorldView.h"
|
||||
#include "Serializer.h"
|
||||
#include "StarSystem.h"
|
||||
#include "perlin.h"
|
||||
|
||||
Planet::Planet(SBody *sbody): Body()
|
||||
{
|
||||
|
@ -884,21 +885,55 @@ static float nus_vdata[12][3] = {
|
|||
};
|
||||
|
||||
static int nus_tindices[20][3] = {
|
||||
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
|
||||
{8,10,1}, {8,3,10},{5,3,8}, {5,2,3}, {2,7,3},
|
||||
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
|
||||
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11}
|
||||
{0,4,1}, // 0
|
||||
{0,9,4}, // 1
|
||||
{9,5,4}, // 2
|
||||
{4,5,8}, // 3
|
||||
{4,8,1}, // 4
|
||||
{8,10,1}, //5
|
||||
{8,3,10}, //6
|
||||
{5,3,8}, // 7
|
||||
{5,2,3}, // 8
|
||||
{2,7,3}, // 9
|
||||
{7,10,3}, // 10
|
||||
{7,6,10}, // 11
|
||||
{7,11,6}, // 12
|
||||
{11,0,6}, // 13
|
||||
{0,1,6}, // 14
|
||||
{6,1,10}, // 15
|
||||
{9,0,11}, // 16
|
||||
{9,11,2}, // 17
|
||||
{9,2,5}, // 18
|
||||
{7,2,11} // 19
|
||||
};
|
||||
|
||||
// which face (of the 20) is on our edge for edge {v01, v12, v20}
|
||||
static int nus_edgecomrade[20][3] = {
|
||||
{1,4,14}, {16,2,0}, {18,3,1}, {2,7,4}, {3,5,0},
|
||||
{6,15,4}, {7,10,5}, {8,6,3}, {18,9,7}, {19,10,8},
|
||||
{11,6,9}, {12,15,10}, {19,13,11}, {16,14,12}, {0,15,13},
|
||||
{14,5,11}, {1,13,17}, {16,19,18}, {17,8,2}, {9,17,12}
|
||||
};
|
||||
|
||||
// tri edge lengths
|
||||
#define GEOPATCH_SUBDIVIDE_AT_CAMDIST 0.5
|
||||
#define GEOPATCH_MAX_DEPTH 4
|
||||
#define GEOPATCH_MAX_DEPTH 6
|
||||
// should be power of two + 1
|
||||
#define GEOPATCH_EDGELEN 33
|
||||
static unsigned short *geovtxidx;
|
||||
|
||||
#define PRINT_VECTOR(_v) printf("%.2f,%.2f,%.2f\n", (_v).x, (_v).y, (_v).z);
|
||||
|
||||
class GeoPatch {
|
||||
public:
|
||||
vector3d v[3];
|
||||
GLdouble *vertices;
|
||||
GLdouble *normals;
|
||||
GLuint *indices;
|
||||
GeoPatch *kids[4];
|
||||
GeoPatch *parent;
|
||||
GeoPatch *edgeFriend[3]; // [0]=v01, [1]=v12, [2]=v20
|
||||
int m_numVertices;
|
||||
int m_depth;
|
||||
GeoPatch() {
|
||||
memset(this, 0, sizeof(GeoPatch));
|
||||
|
@ -912,13 +947,88 @@ public:
|
|||
if (vertices) delete vertices;
|
||||
if (indices) delete indices;
|
||||
}
|
||||
void Render(vector3d &campos) {
|
||||
// should be power of two + 1
|
||||
#define GEOPATCH_EDGELEN 33
|
||||
void GetEdgeVertices(int edge, GLdouble ev[3*GEOPATCH_EDGELEN]) {
|
||||
int pos, elen;
|
||||
if (edge == 1) {
|
||||
pos = m_numVertices - GEOPATCH_EDGELEN;
|
||||
for (; pos<m_numVertices; pos++) {
|
||||
ev[0] = vertices[3*pos];
|
||||
ev[1] = vertices[3*pos+1];
|
||||
ev[2] = vertices[3*pos+2];
|
||||
ev += 3;
|
||||
}
|
||||
} else {
|
||||
pos = 0;
|
||||
elen = ((edge == 0) ? 1 : 2);
|
||||
|
||||
for (; pos<m_numVertices; pos+=elen, elen++) {
|
||||
ev[0] = vertices[3*pos];
|
||||
ev[1] = vertices[3*pos+1];
|
||||
ev[2] = vertices[3*pos+2];
|
||||
ev += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
void SetEdgeVertices(int edge, GLdouble ev[3*GEOPATCH_EDGELEN]) {
|
||||
int pos, elen;
|
||||
//memset(ev, 0, sizeof(double)*3*GEOPATCH_EDGELEN);
|
||||
if (edge == 1) {
|
||||
pos = m_numVertices - GEOPATCH_EDGELEN;
|
||||
for (; pos<m_numVertices; pos++) {
|
||||
vertices[3*pos] = ev[0];
|
||||
vertices[3*pos+1] = ev[1];
|
||||
vertices[3*pos+2] = ev[2];
|
||||
ev += 3;
|
||||
}
|
||||
} else {
|
||||
pos = 0;
|
||||
elen = ((edge == 0) ? 1 : 2);
|
||||
|
||||
for (; pos<m_numVertices; pos+=elen, elen++) {
|
||||
vertices[3*pos] = ev[0];
|
||||
vertices[3*pos+1] = ev[1];
|
||||
vertices[3*pos+2] = ev[2];
|
||||
ev += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
void SetEdgeVerticesFlipped(int edge, GLdouble ev[3*GEOPATCH_EDGELEN]) {
|
||||
int pos, elen;
|
||||
ev += 3*GEOPATCH_EDGELEN;
|
||||
//memset(ev, 0, sizeof(double)*3*GEOPATCH_EDGELEN);
|
||||
if (edge == 1) {
|
||||
pos = m_numVertices - GEOPATCH_EDGELEN;
|
||||
for (; pos<m_numVertices; pos++) {
|
||||
ev -= 3;
|
||||
vertices[3*pos] = ev[0];
|
||||
vertices[3*pos+1] = ev[1];
|
||||
vertices[3*pos+2] = ev[2];
|
||||
}
|
||||
} else {
|
||||
pos = 0;
|
||||
elen = ((edge == 0) ? 1 : 2);
|
||||
|
||||
for (; pos<m_numVertices; pos+=elen, elen++) {
|
||||
ev -= 3;
|
||||
vertices[3*pos] = ev[0];
|
||||
vertices[3*pos+1] = ev[1];
|
||||
vertices[3*pos+2] = ev[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
int GetEdgeIdxOf(GeoPatch *e) {
|
||||
for (int i=0; i<3; i++) {
|
||||
if (edgeFriend[i] == e) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Generate() {
|
||||
if (!vertices) {
|
||||
int num_verts = 0;
|
||||
for (int i=1; i<=GEOPATCH_EDGELEN; i++) num_verts += i;
|
||||
vertices = new GLdouble[3*num_verts];
|
||||
m_numVertices = 0;
|
||||
for (int i=1; i<=GEOPATCH_EDGELEN; i++) m_numVertices += i;
|
||||
vertices = new GLdouble[3*m_numVertices];
|
||||
normals = new GLdouble[3*m_numVertices];
|
||||
GLdouble *vts = vertices;
|
||||
for (int elen = 1; elen<=GEOPATCH_EDGELEN; elen++) {
|
||||
for (int pos=0; pos<elen; pos++) {
|
||||
|
@ -931,12 +1041,16 @@ public:
|
|||
ucoord = jizz*pos/(double)(elen-1);
|
||||
vcoord = jizz*((elen-1)-pos)/(double)(elen-1);
|
||||
}
|
||||
vector3d p = (v[0] + ucoord*(v[1]-v[0]) + vcoord*(v[2]-v[0])).Normalized();
|
||||
vector3d p = (v[0] + vcoord*(v[1]-v[0]) + ucoord*(v[2]-v[0])).Normalized();
|
||||
double n = noise(100*p.x, 100*p.y, 100*p.z);
|
||||
n = n*n*noise(10*p.x, 10*p.y, 10*p.z);
|
||||
p = p + p*0.01*n;
|
||||
vts[0] = p.x; vts[1] = p.y; vts[2] = p.z;
|
||||
vts+=3;
|
||||
}
|
||||
}
|
||||
assert(vts == &vertices[3*num_verts]);
|
||||
|
||||
assert(vts == &vertices[3*m_numVertices]);
|
||||
indices = new GLuint[(GEOPATCH_EDGELEN-1)*(GEOPATCH_EDGELEN-1)*3];
|
||||
GLuint *idx = indices;
|
||||
int abspos = 0;
|
||||
|
@ -944,14 +1058,14 @@ public:
|
|||
for (int elen = 1; elen<GEOPATCH_EDGELEN; elen++) {
|
||||
for (int pos=0; pos<elen; pos++) {
|
||||
idx[0] = abspos;
|
||||
idx[1] = abspos+elen;
|
||||
idx[2] = abspos+elen+1;
|
||||
idx[1] = abspos+elen+1;
|
||||
idx[2] = abspos+elen;
|
||||
idx+=3;
|
||||
wank++;
|
||||
if (pos < elen-1) {
|
||||
idx[0] = abspos;
|
||||
idx[1] = abspos+elen+1;
|
||||
idx[2] = abspos+1;
|
||||
idx[1] = abspos+1;
|
||||
idx[2] = abspos+elen+1;
|
||||
idx+=3;
|
||||
wank++;
|
||||
}
|
||||
|
@ -959,25 +1073,82 @@ public:
|
|||
}
|
||||
}
|
||||
assert(wank == (GEOPATCH_EDGELEN-1)*(GEOPATCH_EDGELEN-1));
|
||||
|
||||
/* take edge vertices from adjacent tiles if they
|
||||
* exist, so there are no breaks in the terrain */
|
||||
GLdouble ev[3*GEOPATCH_EDGELEN];
|
||||
for (int j=0; j<3; j++) {
|
||||
GeoPatch *edge = edgeFriend[j];
|
||||
if (!edge->vertices) continue;
|
||||
int we_are = edge->GetEdgeIdxOf(this);
|
||||
if (we_are == -1) {
|
||||
continue;
|
||||
/// not joined to edge properly. TODO
|
||||
//TODO TODO for kids on edge!!
|
||||
}
|
||||
edge->GetEdgeVertices(we_are, ev);
|
||||
if (we_are == 2) {
|
||||
assert(j==0);
|
||||
// dunno what to do when j=1,2.
|
||||
// should it be flipped or what??
|
||||
}
|
||||
if (we_are == 2) {
|
||||
SetEdgeVertices(j, ev);
|
||||
} else if (j==2) {
|
||||
SetEdgeVertices(j, ev);
|
||||
} else {
|
||||
SetEdgeVerticesFlipped(j, ev);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* XXX some tests to ensure vertices match */
|
||||
for (int i=0; i<3; i++) {
|
||||
GeoPatch *edge = edgeFriend[i];
|
||||
if (edge) {
|
||||
int we_are = edge->GetEdgeIdxOf(this);
|
||||
assert(v[i] == edge->v[(1+we_are)%3]);
|
||||
assert(v[(i+1)%3] == edge->v[(we_are)%3]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
void Render(vector3d &campos) {
|
||||
Generate();
|
||||
|
||||
vector3d centroid = (v[0]+v[1]+v[2])*0.33333333333333333333333333333333333333333333;
|
||||
if ((m_depth < GEOPATCH_MAX_DEPTH) &&
|
||||
((campos - centroid).Length() < (v[0]-v[1]).Length()*GEOPATCH_SUBDIVIDE_AT_CAMDIST)) {
|
||||
|
||||
|
||||
if (!kids[0]) {
|
||||
vector3d v01, v12, v20;
|
||||
v01 = (v[0]+v[1]).Normalized();
|
||||
v12 = (v[1]+v[2]).Normalized();
|
||||
v20 = (v[2]+v[0]).Normalized();
|
||||
kids[0] = new GeoPatch(v[0], v01, v20);
|
||||
kids[1] = new GeoPatch(v[1], v12, v01);
|
||||
kids[2] = new GeoPatch(v[2], v20, v12);
|
||||
kids[1] = new GeoPatch(v01, v[1], v12);
|
||||
kids[2] = new GeoPatch(v20, v12, v[2]);
|
||||
kids[3] = new GeoPatch(v01, v12, v20);
|
||||
kids[0]->m_depth = m_depth+1;
|
||||
kids[1]->m_depth = m_depth+1;
|
||||
kids[2]->m_depth = m_depth+1;
|
||||
kids[3]->m_depth = m_depth+1;
|
||||
// hm.. edges.
|
||||
kids[0]->edgeFriend[0] = edgeFriend[0]; // XXX giving parent's neighbour...
|
||||
kids[0]->edgeFriend[1] = kids[3];
|
||||
kids[0]->edgeFriend[2] = edgeFriend[2]; // XXX
|
||||
kids[1]->edgeFriend[0] = edgeFriend[0]; // XXX
|
||||
kids[1]->edgeFriend[1] = edgeFriend[1]; // XXX
|
||||
kids[1]->edgeFriend[2] = kids[3];
|
||||
kids[2]->edgeFriend[0] = kids[3];
|
||||
kids[2]->edgeFriend[1] = edgeFriend[1]; // XXX
|
||||
kids[2]->edgeFriend[2] = edgeFriend[2]; // XXX
|
||||
kids[3]->edgeFriend[0] = kids[1];
|
||||
kids[3]->edgeFriend[1] = kids[2];
|
||||
kids[3]->edgeFriend[2] = kids[0];
|
||||
kids[0]->parent = kids[1]->parent = kids[2]->parent = kids[3]->parent = this;
|
||||
}
|
||||
for (int i=0; i<4; i++) kids[i]->Render(campos);
|
||||
} else {
|
||||
|
@ -1001,9 +1172,15 @@ public:
|
|||
GeoSphere() {
|
||||
for (int i=0; i<20; i++) {
|
||||
GeoPatch *p = &m_patches[i];
|
||||
p->v[0] = vector3d(nus_vdata[nus_tindices[i][0]]);
|
||||
p->v[1] = vector3d(nus_vdata[nus_tindices[i][1]]);
|
||||
p->v[2] = vector3d(nus_vdata[nus_tindices[i][2]]);
|
||||
*p = GeoPatch(vector3d(nus_vdata[nus_tindices[i][0]]),
|
||||
vector3d(nus_vdata[nus_tindices[i][1]]),
|
||||
vector3d(nus_vdata[nus_tindices[i][2]]));
|
||||
for (int j=0; j<3; j++) {
|
||||
p->edgeFriend[j] = &m_patches[nus_edgecomrade[i][j]];
|
||||
}
|
||||
}
|
||||
for (int i=0; i<20; i++) {
|
||||
m_patches[i].Generate();
|
||||
}
|
||||
}
|
||||
void Render(vector3d campos) {
|
||||
|
@ -1016,6 +1193,26 @@ public:
|
|||
|
||||
void Planet::Render(const Frame *a_camFrame)
|
||||
{
|
||||
if (!geovtxidx) {
|
||||
/* build this funny array to make indexing the vertices less
|
||||
* of a total fucking nightmare */
|
||||
/* looks like: {
|
||||
* 0, -1, -1, -1, ..
|
||||
* 1, 2, -1, -1, ..
|
||||
* 3, 4, 5, -1, .. */
|
||||
geovtxidx = new unsigned short[GEOPATCH_EDGELEN*GEOPATCH_EDGELEN];
|
||||
unsigned short *p = geovtxidx;
|
||||
int abspos = 0;
|
||||
for (int elen=1; elen<=GEOPATCH_EDGELEN; elen++) {
|
||||
int i=0;
|
||||
for (; i<elen; i++) {
|
||||
*(p++) = abspos++;
|
||||
}
|
||||
for (; i<GEOPATCH_EDGELEN; i++) {
|
||||
*(p++) = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
glPushMatrix();
|
||||
|
||||
if (!m_geosphere) m_geosphere = new GeoSphere();
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "Serializer.h"
|
||||
#include "NameGenerator.h"
|
||||
#include "mods/Mods.h"
|
||||
#include "perlin.h"
|
||||
|
||||
float Pi::timeAccel = 1.0f;
|
||||
int Pi::scrWidth;
|
||||
|
@ -671,6 +672,7 @@ int main(int argc, char**)
|
|||
{
|
||||
printf("Pioneer ultra high tech tech demo dude!\n");
|
||||
signal(SIGSEGV, sigsegv_handler);
|
||||
perlin_init();
|
||||
IniConfig cfg("config.ini");
|
||||
Pi::Init(cfg);
|
||||
Pi::Start();
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#include <math.h>
|
||||
|
||||
static double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); }
|
||||
static double lerp(double t, double a, double b) { return a + t * (b - a); }
|
||||
static double grad(int hash, double x, double y, double z) {
|
||||
int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
|
||||
double u = h<8 ? x : y, // INTO 12 GRADIENT DIRECTIONS.
|
||||
v = h<4 ? y : h==12||h==14 ? x : z;
|
||||
return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
|
||||
}
|
||||
static int p[512];
|
||||
static const int permutation[] = { 151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
|
||||
};
|
||||
double noise(double x, double y, double z) {
|
||||
int X = (int)floor(x) & 255, // FIND UNIT CUBE THAT
|
||||
Y = (int)floor(y) & 255, // CONTAINS POINT.
|
||||
Z = (int)floor(z) & 255;
|
||||
x -= floor(x); // FIND RELATIVE X,Y,Z
|
||||
y -= floor(y); // OF POINT IN CUBE.
|
||||
z -= floor(z);
|
||||
double u = fade(x), // COMPUTE FADE CURVES
|
||||
v = fade(y), // FOR EACH OF X,Y,Z.
|
||||
w = fade(z);
|
||||
int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z, // HASH COORDINATES OF
|
||||
B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z; // THE 8 CUBE CORNERS,
|
||||
|
||||
return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD
|
||||
grad(p[BA ], x-1, y , z )), // BLENDED
|
||||
lerp(u, grad(p[AB ], x , y-1, z ), // RESULTS
|
||||
grad(p[BB ], x-1, y-1, z ))),// FROM 8
|
||||
lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), // CORNERS
|
||||
grad(p[BA+1], x-1, y , z-1 )), // OF CUBE
|
||||
lerp(u, grad(p[AB+1], x , y-1, z-1 ),
|
||||
grad(p[BB+1], x-1, y-1, z-1 ))));
|
||||
}
|
||||
void perlin_init() { for (int i=0; i < 256 ; i++) p[256+i] = p[i] = permutation[i]; }
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _PERLIN_H
|
||||
#define _PERLIN_H
|
||||
|
||||
double noise(double x, double y, double z);
|
||||
void perlin_init();
|
||||
|
||||
#endif /* _PERLIN_H */
|
Loading…
Reference in New Issue