Made the vegetation impostors face the camera
This commit is contained in:
parent
9d7a7a0ff7
commit
d2efb599d9
17 changed files with 192 additions and 79 deletions
5
Makefile
5
Makefile
|
@ -62,6 +62,11 @@ profile_cli:build
|
|||
LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS)
|
||||
perf report -g
|
||||
|
||||
gltrace:build
|
||||
rm -f *.trace
|
||||
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/apitrace/wrappers/glxtrace.so LD_LIBRARY_PATH=$(LIBRARY_PATH) ${BUILDPATH}/interface/modeler/quickapp/paysages-modeler $(ARGS)
|
||||
qapitrace paysages-modeler.trace
|
||||
|
||||
package:build
|
||||
rm -rf paysages3d-linux
|
||||
rm -f paysages3d-linux.tar.bz2
|
||||
|
|
|
@ -44,8 +44,7 @@ bool VegetationPresenceDefinition::collectInstances(std::vector<VegetationInstan
|
|||
double angle = 3.0 * generator->get2DTotal(-x * 20.0, z * 20.0); // TODO balanced distribution
|
||||
double xo = x + fabs(generator->get2DTotal(x * 12.0, -z * 12.0));
|
||||
double zo = z + fabs(generator->get2DTotal(-x * 27.0, -z * 27.0));
|
||||
if (xo >= xmin and xo < xmax and zo >= zmin and zo < zmax)
|
||||
{
|
||||
if (xo >= xmin and xo < xmax and zo >= zmin and zo < zmax) {
|
||||
double y = getScenery()->getTerrain()->getInterpolatedHeight(xo, zo, true, true);
|
||||
result->push_back(VegetationInstance(model, Vector3(xo, y, zo), size, angle));
|
||||
added++;
|
||||
|
|
|
@ -296,16 +296,21 @@ static void testVegetationModels() {
|
|||
}
|
||||
|
||||
static void testOpenGLVegetationImpostor() {
|
||||
std::string filename = getFileName("opengl_vegetation_impostor");
|
||||
std::cout << "Rendering " << filename << "..." << std::endl;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
std::string filename = getFileName("opengl_vegetation_impostor", i);
|
||||
std::cout << "Rendering " << filename << "..." << std::endl;
|
||||
|
||||
Scenery scenery;
|
||||
scenery.autoPreset(1);
|
||||
OpenGLVegetationImpostor impostor(200);
|
||||
VegetationModelDefinition model(NULL);
|
||||
bool interrupted = false;
|
||||
impostor.prepareTexture(model, scenery, &interrupted);
|
||||
impostor.getTexture()->saveToFile(filename);
|
||||
Scenery scenery;
|
||||
scenery.autoPreset(i);
|
||||
|
||||
OpenGLVegetationImpostor impostor(128);
|
||||
VegetationModelDefinition model(NULL);
|
||||
|
||||
bool interrupted = false;
|
||||
impostor.prepareTexture(model, scenery, &interrupted);
|
||||
|
||||
impostor.getTexture()->saveToFile(filename);
|
||||
}
|
||||
}
|
||||
|
||||
void runTestSuite() {
|
||||
|
|
|
@ -41,12 +41,10 @@ void OpenGLPart::updateScenery(bool onlyCommon) {
|
|||
}
|
||||
}
|
||||
|
||||
Scenery *OpenGLPart::getScenery() const
|
||||
{
|
||||
Scenery *OpenGLPart::getScenery() const {
|
||||
return renderer->getScenery();
|
||||
}
|
||||
|
||||
OpenGLFunctions *OpenGLPart::getOpenGlFunctions() const
|
||||
{
|
||||
OpenGLFunctions *OpenGLPart::getOpenGlFunctions() const {
|
||||
return renderer->getOpenGlFunctions();
|
||||
}
|
||||
|
|
|
@ -75,13 +75,13 @@ void OpenGLShaderProgram::release() {
|
|||
void OpenGLShaderProgram::drawTriangles(float *vertices, int triangle_count) {
|
||||
bind();
|
||||
|
||||
GLuint vertex = program->attributeLocation("vertex");
|
||||
program->setAttributeArray(vertex, GL_FLOAT, vertices, 3);
|
||||
program->enableAttributeArray(vertex);
|
||||
GLuint array_vertex = program->attributeLocation("vertex");
|
||||
program->setAttributeArray(array_vertex, GL_FLOAT, vertices, 3);
|
||||
program->enableAttributeArray(array_vertex);
|
||||
|
||||
functions->glDrawArrays(GL_TRIANGLES, 0, triangle_count * 3);
|
||||
|
||||
program->disableAttributeArray(vertex);
|
||||
program->disableAttributeArray(array_vertex);
|
||||
|
||||
release();
|
||||
}
|
||||
|
@ -89,13 +89,51 @@ void OpenGLShaderProgram::drawTriangles(float *vertices, int triangle_count) {
|
|||
void OpenGLShaderProgram::drawTriangleStrip(float *vertices, int vertex_count) {
|
||||
bind();
|
||||
|
||||
GLuint vertex = program->attributeLocation("vertex");
|
||||
program->setAttributeArray(vertex, GL_FLOAT, vertices, 3);
|
||||
program->enableAttributeArray(vertex);
|
||||
GLuint array_vertex = program->attributeLocation("vertex");
|
||||
program->setAttributeArray(array_vertex, GL_FLOAT, vertices, 3);
|
||||
program->enableAttributeArray(array_vertex);
|
||||
|
||||
functions->glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count);
|
||||
|
||||
program->disableAttributeArray(vertex);
|
||||
program->disableAttributeArray(array_vertex);
|
||||
|
||||
release();
|
||||
}
|
||||
|
||||
void OpenGLShaderProgram::drawTrianglesUV(float *vertices, float *uv, int triangle_count) {
|
||||
bind();
|
||||
|
||||
GLuint array_vertex = program->attributeLocation("vertex");
|
||||
program->setAttributeArray(array_vertex, GL_FLOAT, vertices, 3);
|
||||
program->enableAttributeArray(array_vertex);
|
||||
|
||||
GLuint array_uv = program->attributeLocation("uv");
|
||||
program->setAttributeArray(array_uv, GL_FLOAT, uv, 2);
|
||||
program->enableAttributeArray(array_uv);
|
||||
|
||||
functions->glDrawArrays(GL_TRIANGLES, 0, triangle_count * 3);
|
||||
|
||||
program->disableAttributeArray(array_vertex);
|
||||
program->disableAttributeArray(array_uv);
|
||||
|
||||
release();
|
||||
}
|
||||
|
||||
void OpenGLShaderProgram::drawTriangleStripUV(float *vertices, float *uv, int vertex_count) {
|
||||
bind();
|
||||
|
||||
GLuint array_vertex = program->attributeLocation("vertex");
|
||||
program->setAttributeArray(array_vertex, GL_FLOAT, vertices, 3);
|
||||
program->enableAttributeArray(array_vertex);
|
||||
|
||||
GLuint array_uv = program->attributeLocation("uv");
|
||||
program->setAttributeArray(array_uv, GL_FLOAT, uv, 2);
|
||||
program->enableAttributeArray(array_uv);
|
||||
|
||||
functions->glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count);
|
||||
|
||||
program->disableAttributeArray(array_vertex);
|
||||
program->disableAttributeArray(array_uv);
|
||||
|
||||
release();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ class OPENGLSHARED_EXPORT OpenGLShaderProgram {
|
|||
void drawTriangles(float *vertices, int triangle_count);
|
||||
void drawTriangleStrip(float *vertices, int vertex_count);
|
||||
|
||||
void drawTrianglesUV(float *vertices, float *uv, int triangle_count);
|
||||
void drawTriangleStripUV(float *vertices, float *uv, int vertex_count);
|
||||
|
||||
void bind();
|
||||
void release();
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
OpenGLSharedState::OpenGLSharedState() {
|
||||
}
|
||||
|
||||
OpenGLSharedState::~OpenGLSharedState()
|
||||
{
|
||||
OpenGLSharedState::~OpenGLSharedState() {
|
||||
for (const auto &pair : variables) {
|
||||
delete pair.second;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace opengl {
|
|||
class OPENGLSHARED_EXPORT OpenGLSharedState {
|
||||
public:
|
||||
OpenGLSharedState();
|
||||
~OpenGLSharedState();
|
||||
~OpenGLSharedState();
|
||||
|
||||
/*!
|
||||
* \brief Apply the stored variables to the bound program.
|
||||
|
|
|
@ -91,8 +91,7 @@ void OpenGLVariable::set(const Texture4D *texture, bool repeat, bool color) {
|
|||
texture_color = color;
|
||||
}
|
||||
|
||||
void OpenGLVariable::set(int value)
|
||||
{
|
||||
void OpenGLVariable::set(int value) {
|
||||
assert(type == TYPE_NONE or type == TYPE_INTEGER);
|
||||
|
||||
type = TYPE_INTEGER;
|
||||
|
|
|
@ -27,7 +27,7 @@ class paysages::opengl::VegetationUpdater : public Thread {
|
|||
while (not interrupted) {
|
||||
std::vector<OpenGLVegetationLayer *> layers;
|
||||
vegetation->acquireLayers(layers);
|
||||
for (auto layer: layers) {
|
||||
for (auto layer : layers) {
|
||||
layer->threadedUpdate();
|
||||
}
|
||||
vegetation->releaseLayers(layers);
|
||||
|
@ -50,7 +50,7 @@ OpenGLVegetation::OpenGLVegetation(OpenGLRenderer *renderer) : OpenGLPart(render
|
|||
}
|
||||
|
||||
OpenGLVegetation::~OpenGLVegetation() {
|
||||
for (auto layer: layers) {
|
||||
for (auto layer : layers) {
|
||||
delete layer;
|
||||
}
|
||||
layers.clear();
|
||||
|
@ -81,7 +81,7 @@ void OpenGLVegetation::render() {
|
|||
if (enabled) {
|
||||
std::vector<OpenGLVegetationLayer *> layers;
|
||||
acquireLayers(layers);
|
||||
for (auto layer: layers) {
|
||||
for (auto layer : layers) {
|
||||
layer->render();
|
||||
}
|
||||
releaseLayers(layers);
|
||||
|
@ -94,16 +94,14 @@ void OpenGLVegetation::nodeChanged(const DefinitionNode *node, const DefinitionD
|
|||
}
|
||||
}
|
||||
|
||||
Scenery *OpenGLVegetation::getScenery() const
|
||||
{
|
||||
Scenery *OpenGLVegetation::getScenery() const {
|
||||
return renderer->getScenery();
|
||||
}
|
||||
|
||||
void OpenGLVegetation::cameraChanged(const CameraDefinition *camera)
|
||||
{
|
||||
void OpenGLVegetation::cameraChanged(const CameraDefinition *camera) {
|
||||
std::vector<OpenGLVegetationLayer *> layers;
|
||||
acquireLayers(layers);
|
||||
for (auto layer: layers) {
|
||||
for (auto layer : layers) {
|
||||
layer->setCamera(camera);
|
||||
}
|
||||
releaseLayers(layers);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "OpenGLVegetationImpostor.h"
|
||||
|
||||
#include <cassert>
|
||||
#include "OpenGLShaderProgram.h"
|
||||
#include "OpenGLSharedState.h"
|
||||
#include "OpenGLVegetationInstance.h"
|
||||
|
@ -16,16 +17,30 @@
|
|||
#include "LightingManager.h"
|
||||
#include "CameraDefinition.h"
|
||||
|
||||
OpenGLVegetationImpostor::OpenGLVegetationImpostor(int partsize) {
|
||||
vertices = new float[4 * 3];
|
||||
texture_size = partsize * 4;
|
||||
texture = new Texture2D(texture_size, texture_size);
|
||||
texture_changed = true;
|
||||
// Get the rotation matrix for an impostor grid index
|
||||
static inline Matrix4 matrixForIndex(int index) {
|
||||
if (index == 0) {
|
||||
return Matrix4::newRotateZ(M_PI_2);
|
||||
} else if (index < 6) {
|
||||
return Matrix4::newRotateY(M_2PI * (double)(index - 1) * 0.2).mult(Matrix4::newRotateZ(M_PI_4));
|
||||
} else {
|
||||
return Matrix4::newRotateY(M_2PI * (double)(index - 6) * 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
setVertex(0, 0.0f, 0.0f, 0.0f);
|
||||
setVertex(1, 0.0f, 0.0f, 1.0f);
|
||||
setVertex(2, 0.0f, 1.0f, 0.0f);
|
||||
setVertex(3, 0.0f, 1.0f, 1.0f);
|
||||
OpenGLVegetationImpostor::OpenGLVegetationImpostor(int partsize) {
|
||||
int parts = 4;
|
||||
|
||||
vertices = new float[4 * parts * parts * 3];
|
||||
uv = new float[4 * 2];
|
||||
texture_size = partsize * parts;
|
||||
texture = new Texture2D(texture_size, texture_size);
|
||||
texture_changed = false;
|
||||
|
||||
setVertex(0, 0.0f, 0.0f);
|
||||
setVertex(1, 0.0f, 1.0f);
|
||||
setVertex(2, 1.0f, 0.0f);
|
||||
setVertex(3, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
OpenGLVegetationImpostor::~OpenGLVegetationImpostor() {
|
||||
|
@ -34,15 +49,17 @@ OpenGLVegetationImpostor::~OpenGLVegetationImpostor() {
|
|||
}
|
||||
|
||||
void OpenGLVegetationImpostor::render(OpenGLShaderProgram *program, const OpenGLVegetationInstance *instance,
|
||||
int index) {
|
||||
if (index == 0 or texture_changed) {
|
||||
int instance_index, const Vector3 &camera_location) {
|
||||
if (instance_index == 0 or texture_changed) {
|
||||
texture_changed = false;
|
||||
program->getState()->set("impostorTexture", texture);
|
||||
}
|
||||
program->getState()->setInt("index", 15); // TODO
|
||||
|
||||
int index = getIndex(camera_location, instance->getBase());
|
||||
program->getState()->setInt("index", index);
|
||||
program->getState()->set("offset", instance->getBase());
|
||||
program->getState()->set("size", instance->getSize());
|
||||
program->drawTriangleStrip(vertices, 4);
|
||||
program->getState()->set("size", 2.0 * instance->getSize());
|
||||
program->drawTriangleStripUV(vertices + index * 4 * 3, uv, 4);
|
||||
}
|
||||
|
||||
void OpenGLVegetationImpostor::prepareTexture(const VegetationModelDefinition &model, const Scenery &environment,
|
||||
|
@ -58,19 +75,12 @@ void OpenGLVegetationImpostor::prepareTexture(const VegetationModelDefinition &m
|
|||
|
||||
int parts = 4;
|
||||
int partsize = texture_size / parts;
|
||||
Matrix4 rotation;
|
||||
for (int py = 0; py < parts; py++) {
|
||||
for (int px = 0; px < parts; px++) {
|
||||
int index = py * parts + px;
|
||||
if (index == 0) {
|
||||
rotation = Matrix4::newRotateX(-M_PI_2);
|
||||
} else if (index < 6) {
|
||||
rotation = Matrix4::newRotateY(M_2PI * (double)(index - 1) * 0.2).mult(Matrix4::newRotateX(-M_PI_4));
|
||||
} else {
|
||||
rotation = Matrix4::newRotateY(M_2PI * (double)(index - 6) * 0.1);
|
||||
}
|
||||
Matrix4 rotation = matrixForIndex(index);
|
||||
|
||||
Vector3 cam(0.0, 0.0, 5.0);
|
||||
Vector3 cam(5.0, 0.0, 0.0);
|
||||
scenery.getCamera()->setLocation(rotation.multPoint(cam));
|
||||
scenery.getCamera()->setTarget(VECTOR_ZERO);
|
||||
renderer.prepare();
|
||||
|
@ -83,10 +93,10 @@ void OpenGLVegetationImpostor::prepareTexture(const VegetationModelDefinition &m
|
|||
for (int y = 0; y < partsize; y++) {
|
||||
double dy = (double)y / (double)partsize;
|
||||
|
||||
Vector3 near(dx - 0.5, dy - 0.5, 5.0);
|
||||
Vector3 far(dx - 0.5, dy - 0.5, -5.0);
|
||||
SpaceSegment segment(rotation.multPoint(near.scale(1.3)).add(VECTOR_UP.scale(0.5)),
|
||||
rotation.multPoint(far.scale(1.3)).add(VECTOR_UP.scale(0.5)));
|
||||
Vector3 near(5.0, dy - 0.5, -(dx - 0.5));
|
||||
Vector3 far(-5.0, dy - 0.5, -(dx - 0.5));
|
||||
SpaceSegment segment(rotation.multPoint(near.scale(2.0)).add(VECTOR_UP.scale(0.5)),
|
||||
rotation.multPoint(far.scale(2.0)).add(VECTOR_UP.scale(0.5)));
|
||||
|
||||
RayCastingResult result = vegetation->renderInstance(segment, instance, false, true);
|
||||
texture->setPixel(startx + x, starty + y,
|
||||
|
@ -99,8 +109,40 @@ void OpenGLVegetationImpostor::prepareTexture(const VegetationModelDefinition &m
|
|||
texture_changed = true;
|
||||
}
|
||||
|
||||
void OpenGLVegetationImpostor::setVertex(int i, float x, float y, float z) {
|
||||
vertices[i * 3] = x;
|
||||
vertices[i * 3 + 1] = y;
|
||||
vertices[i * 3 + 2] = z;
|
||||
int OpenGLVegetationImpostor::getIndex(const Vector3 &camera, const Vector3 &instance) const {
|
||||
int result;
|
||||
|
||||
VectorSpherical diff = camera.sub(instance).toSpherical();
|
||||
if (diff.theta > 1.0) {
|
||||
return 0;
|
||||
} else {
|
||||
double angle = diff.phi / M_2PI;
|
||||
if (diff.theta > 0.4) {
|
||||
angle = (angle >= 0.9) ? 0.0 : (angle + 0.1);
|
||||
return 1 + (int)(5.0 * angle);
|
||||
} else {
|
||||
angle = (angle >= 0.95) ? 0.0 : (angle + 0.05);
|
||||
return 6 + (int)(10.0 * angle);
|
||||
}
|
||||
}
|
||||
|
||||
assert(result >= 0 and result <= 16);
|
||||
return result;
|
||||
}
|
||||
|
||||
void OpenGLVegetationImpostor::setVertex(int i, float u, float v) {
|
||||
int parts = 4;
|
||||
for (int py = 0; py < parts; py++) {
|
||||
for (int px = 0; px < parts; px++) {
|
||||
int index = py * parts + px;
|
||||
Matrix4 rotation = matrixForIndex(index);
|
||||
|
||||
Vector3 vertex = rotation.multPoint(Vector3(1.0, u, -(v - 0.5)));
|
||||
vertices[index * 4 * 3 + i * 3] = vertex.x;
|
||||
vertices[index * 4 * 3 + i * 3 + 1] = vertex.y;
|
||||
vertices[index * 4 * 3 + i * 3 + 2] = vertex.z;
|
||||
}
|
||||
}
|
||||
uv[i * 2] = u;
|
||||
uv[i * 2 + 1] = v;
|
||||
}
|
||||
|
|
|
@ -21,18 +21,25 @@ class OPENGLSHARED_EXPORT OpenGLVegetationImpostor {
|
|||
/**
|
||||
* Render a single instance using this impostor.
|
||||
*/
|
||||
void render(OpenGLShaderProgram *program, const OpenGLVegetationInstance *instance, int index);
|
||||
void render(OpenGLShaderProgram *program, const OpenGLVegetationInstance *instance, int instance_index,
|
||||
const Vector3 &camera_location);
|
||||
|
||||
/**
|
||||
* Prepare the texture grid for a given model.
|
||||
*/
|
||||
void prepareTexture(const VegetationModelDefinition &model, const Scenery &environment, bool *interrupt);
|
||||
|
||||
/**
|
||||
* Get the impostor grid index for an instance, to face the camera.
|
||||
*/
|
||||
int getIndex(const Vector3 &camera, const Vector3 &instance) const;
|
||||
|
||||
private:
|
||||
void setVertex(int i, float x, float y, float z);
|
||||
void setVertex(int i, float u, float v);
|
||||
|
||||
private:
|
||||
float *vertices;
|
||||
float *uv;
|
||||
int texture_size;
|
||||
bool texture_changed;
|
||||
Texture2D *texture;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
OpenGLVegetationInstance::OpenGLVegetationInstance(const VegetationInstance &wrapped) : wrapped(wrapped) {
|
||||
}
|
||||
|
||||
void OpenGLVegetationInstance::setDistance(double distance)
|
||||
{
|
||||
void OpenGLVegetationInstance::setDistance(double distance) {
|
||||
this->distance = distance;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ class OPENGLSHARED_EXPORT OpenGLVegetationInstance {
|
|||
*/
|
||||
void setDistance(double distance);
|
||||
|
||||
private:
|
||||
private:
|
||||
VegetationInstance wrapped;
|
||||
double distance;
|
||||
};
|
||||
|
|
|
@ -93,7 +93,7 @@ void OpenGLVegetationLayer::threadedUpdate() {
|
|||
zmax = newzmax;
|
||||
removeInstancesOutsideArea(xmin, xmax, zmin, zmax, &instances);
|
||||
instances.insert(instances.end(), new_instances.begin(), new_instances.end());
|
||||
for (auto instance: instances) {
|
||||
for (auto instance : instances) {
|
||||
instance->setDistance(instance->getBase().sub(*camera_location).getNorm());
|
||||
}
|
||||
std::sort(instances.begin(), instances.end(), compareInstances);
|
||||
|
@ -111,7 +111,7 @@ void OpenGLVegetationLayer::render() {
|
|||
// TODO Instanced rendering
|
||||
int index = 0;
|
||||
for (auto instance : instances) {
|
||||
impostor->render(parent->getProgram(), instance, index++);
|
||||
impostor->render(parent->getProgram(), instance, index++, *camera_location);
|
||||
}
|
||||
|
||||
lock_instances->release();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
attribute highp vec4 vertex;
|
||||
attribute highp vec3 vertex;
|
||||
attribute highp vec2 uv;
|
||||
uniform highp mat4 viewMatrix;
|
||||
uniform highp vec3 offset;
|
||||
uniform float size;
|
||||
|
@ -9,8 +10,7 @@ uniform float waterOffset;
|
|||
|
||||
void main(void)
|
||||
{
|
||||
vec3 final = offset + size * (vertex.xyz - vec3(0.0, 0.0, 0.5)); // + vec3(0, waterOffset, 0)
|
||||
unprojected = final.xyz;
|
||||
texcoord = vec2(0.25 * (vertex.z + float(mod(index, 4))), 0.25 * (vertex.y + float(index / 4)));
|
||||
gl_Position = viewMatrix * vec4(final.xyz, 1.0);
|
||||
unprojected = offset + size * vertex; // + vec3(0, waterOffset, 0)
|
||||
texcoord = vec2(0.25 * (uv.s + float(mod(index, 4))), 0.25 * (uv.t + float(index / 4)));
|
||||
gl_Position = viewMatrix * vec4(unprojected, 1.0);
|
||||
}
|
||||
|
|
21
src/tests/OpenGLVegetationImpostor_Test.cpp
Normal file
21
src/tests/OpenGLVegetationImpostor_Test.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "BaseTestCase.h"
|
||||
#include "OpenGLVegetationImpostor.h"
|
||||
|
||||
#include "Vector3.h"
|
||||
|
||||
TEST(OpenGLVegetationImpostor, getIndex) {
|
||||
OpenGLVegetationImpostor impostor;
|
||||
|
||||
EXPECT_EQ(0, impostor.getIndex(Vector3(0.0, 1.0, 0.0), VECTOR_ZERO));
|
||||
|
||||
EXPECT_EQ(1, impostor.getIndex(Vector3(1.0, 1.0, 0.0), VECTOR_ZERO));
|
||||
EXPECT_EQ(1, impostor.getIndex(Vector3(1.0, 1.0, 0.1), VECTOR_ZERO));
|
||||
EXPECT_EQ(1, impostor.getIndex(Vector3(1.0, 1.0, -0.1), VECTOR_ZERO));
|
||||
|
||||
EXPECT_EQ(2, impostor.getIndex(Vector3(1.0, 1.0, -1.0), VECTOR_ZERO));
|
||||
EXPECT_EQ(5, impostor.getIndex(Vector3(1.0, 1.0, 1.0), VECTOR_ZERO));
|
||||
|
||||
EXPECT_EQ(6, impostor.getIndex(Vector3(1.0, 0.0, 0.0), VECTOR_ZERO));
|
||||
EXPECT_EQ(6, impostor.getIndex(Vector3(1.0, 0.0, 0.1), VECTOR_ZERO));
|
||||
EXPECT_EQ(6, impostor.getIndex(Vector3(1.0, 0.0, -0.1), VECTOR_ZERO));
|
||||
}
|
Loading…
Reference in a new issue