1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846264
#endif
#include "main/interferenceheightmaphandler.h"
#include "math/vector.h"
#include "exception.h"
#include "demolib_prefs.h"
#if DEMOLIB_MAINLOOP
InterferenceHeightmapHandler::InterferenceHeightmapHandler(MainLoop *ml, const char *title, const char *elem, Hashtable *attr) :
Object(ml, title, elem, attr)
{
this->xlod = attr->get_int("xlod");
this->ylod = attr->get_int("ylod");
this->speedlin = attr->get_float("speedlin");
this->freqlinx = attr->get_float("freqlinx");
this->freqliny = attr->get_float("freqliny");
this->ampllin = attr->get_float("ampllin");
this->speedcirc = attr->get_float("speedcirc");
this->freqcirc = attr->get_float("freqcirc");
this->amplcirc = attr->get_float("amplcirc");
this->pure_indices = true;
this->vertices_per_face = 4;
float xscale = 1.0f / (float)xlod;
float yscale = 1.0f / (float)ylod;
int x, y;
float xf, yf;
for (y = 0, yf = -0.5f; y < ylod; y++, yf += yscale) {
for (x = 0, xf = -0.5f; x < xlod; x++, xf += xscale) {
struct vertex v = { xf * 10.0f, yf * 10.0f, 0.0f };
struct texcoord t = { xf + 0.5f, yf + 0.5f };
struct normal n = { 0.0f, 1.0f, 0.0f };
this->vertices.add_end(v);
this->texcoords.add_end(t);
this->normals.add_end(n);
}
}
for (y = 0; y < ylod-1; y++) {
for (x = 0; x < xlod-1; x++) {
this->faces.add_end(y*ylod + x);
this->faces.add_end((y+1)*ylod + x);
this->faces.add_end((y+1)*ylod + x+1);
this->faces.add_end(y*ylod + x+1);
}
}
}
InterferenceHeightmapHandler::~InterferenceHeightmapHandler()
{
}
void InterferenceHeightmapHandler::start_effect()
{
Object::start_effect();
}
void InterferenceHeightmapHandler::draw_scene(float progress)
{
this->unlock_object();
float u1 = this->get_val("user1", progress);
float u2 = this->get_val("user2", progress);
float u3 = this->get_val("user3", progress);
float u4 = this->get_val("user4", progress);
float xscale = 1.0f / (float)xlod;
float yscale = 1.0f / (float)ylod;
float xscale2 = freqlinx * xscale;
float yscale2 = freqliny * yscale;
float yf = -u4;
float yfs = 0.0f;
const float p_sl = progress * speedlin;
const float flx_al = freqlinx * ampllin;
const float fly_al = freqliny * ampllin;
for (int y = 0; y < ylod; y++, yf += yscale, yfs += yscale2) {
float xf = -u3, xfs = 0.0f;
for (int x = 0; x < xlod; x++, xf += xscale, xfs += xscale2) {
/* calculate the height */
/*
* calculate H, dH/dx and dH/dy... this code is unreadable, sorry,
* it's for the sake of speed :-)
*/
const float dist = hypot(xf, yf);
#if __GNUC__ && defined(__i386__)
float sin_v, cos_v;
__asm__("fsincos" : "=t" (cos_v), "=u" (sin_v) :
"0" (dist * freqcirc + progress * speedcirc));
#else
const float temp = dist * freqcirc + progress * speedcirc;
const float sin_v = sin(temp);
const float cos_v = cos(temp);
#endif
const float divval = freqcirc * amplcirc / dist;
const float z = sin_v * amplcirc +
(sin(xfs + p_sl + u1) +
sin(yfs + p_sl + u2)) * ampllin;
const float dx = cos_v * xf * divval
+ flx_al * cos(xfs + p_sl + u1);
const float dy = cos_v * yf * divval
+ fly_al * cos(yfs + p_sl + u2);
Vector normal(dx * -0.2f, dy * -0.2f, 1.0f);
normal.normalize();
vertices[y * xlod + x].z = z;
normals[y * xlod + x].nx = normal.x;
normals[y * xlod + x].ny = normal.y;
normals[y * xlod + x].nz = normal.z;
}
}
Object::draw_scene(progress);
}
void InterferenceHeightmapHandler::end_effect()
{
Object::end_effect();
}
#endif /* DEMOLIB_MAINLOOP */
|