#define _USE_MATH_DEFINES // for M_PI
#include <math.h>
#include <sstream>
#include <fstream>
#include <iostream>
#include <map>
#include <limits>
#include "objreader.h"
#include "primitives.h"
#include "textures.h"
#include "xmlwriter.h"
#ifdef UNICODE
#define tcout std::wcout
#else
#define tcout std::cout
#endif
const unsigned int SPHERES = 50;
const float SPHERE_RADIUS = 1.0f;
static ILBMeshHandle constructMesh(
const bex::tstring& name,
const std::vector<bex::Vec3>& vertices,
const std::vector<bex::Vec3>& normals,
const std::vector<bex::Vec2>& uvs, bex::tstring mat,
ILBManagerHandle manager) {
bex::apiCall(
ILBAddVertexData(mesh, &vertices[0], &normals[0], static_cast<int32>(vertices.size())));
std::vector<int32> indices;
for (size_t idx=0; idx < vertices.size(); idx++) {
indices.push_back((int32)idx);
}
bex::apiCall(
ILBAddUVData(mesh, &uvs[0], static_cast<int32>(uvs.size())));
return mesh;
}
class TargetEntity {
public:
m_transform(transform),
m_mesh(mesh),
m_name(name.c_str()),
m_type(type),
m_width(width),
m_height(height)
{
}
const bex::tstring& getName() const {
return m_name;
}
m_type = type;
m_width = width;
m_height = height;
}
bex::apiCall(
ILBCreateInstance(scene, m_mesh, m_name.c_str(), &m_transform, &m_instance));
}
if (m_width > 0 && m_height > 0) {
} else {
}
}
}
private:
bex::Matrix4x4 m_transform;
bex::tstring m_name;
int32 m_width;
int32 m_height;
};
class TargetManager {
private:
typedef std::map<bex::tstring, TargetEntity*> TargetMap;
public:
~TargetManager() {
TargetMap::iterator it = m_targets.begin();
for (;it != m_targets.end(); it++) {
delete it->second;
}
}
void addTarget(TargetEntity* target) {
TargetMap::iterator it = m_targets.find(target->getName());
if (it != m_targets.end()) {
delete it->second;
m_targets.erase(it);
}
m_targets[target->getName()] = target;
}
TargetMap::iterator it = m_targets.find(name);
if (it != m_targets.end()) {
it->second->update(type, width, height);
}
}
TargetMap::const_iterator it = m_targets.begin();
for (;it != m_targets.end(); it++) {
it->second->createScene(scene);
}
}
TargetMap::const_iterator it = m_targets.begin();
for (;it != m_targets.end(); it++) {
it->second->create(objVertexTarget, objAtlasTarget);
}
}
private:
TargetMap m_targets;
};
class Camera {
public:
Camera(const bex::tstring& name,
const bex::Matrix4x4& transform,
float horizontalFov,
float pixelAspectRatio) :
m_name(name),
m_transform(transform),
m_horizontalFov(horizontalFov),
m_pixelAspectRatio(pixelAspectRatio) {}
bex::apiCall(
ILBSetFov(camera, m_horizontalFov, m_pixelAspectRatio));
return camera;
}
private:
bex::tstring m_name;
bex::Matrix4x4 m_transform;
float m_horizontalFov;
float m_pixelAspectRatio;
};
bex::tstring name = bex::convertStringHandle(namehandle);
bex::Matrix4x4 transform;
float hfov, par;
return Camera(name, transform, hfov, par);
}
class LightSource {
public:
LightSource(const bex::tstring& name,
const bex::Matrix4x4& transform,
const bex::ColorRGB& color) :
m_name(name),
m_displayName(name),
m_transform(transform),
m_color(color),
m_intensity(1.0f),
m_castShadows(true),
m_shadowSamples(1),
m_directScale(1.0f),
m_indirectScale(1.0f),
m_visibleForEye(true),
m_visibleForRefl(true),
m_visibleForRefr(true),
m_visibleForGI(true)
{}
virtual ~LightSource() {}
void setDisplayName(const bex::tstring& displayName) {
m_displayName = displayName;
}
void setTransform(const bex::Matrix4x4& transform) {
m_transform = transform;
}
void setColor(const bex::ColorRGB& color) {
m_color = color;
}
void setIntensity(float intensity) {
m_intensity = intensity;
}
void setCastShadows(bool castShadows) {
m_castShadows = castShadows;
}
void setShadowSamples(int32 shadowSamples) {
m_shadowSamples = shadowSamples;
}
void setIntensityScale(float directScale, float indirectScale) {
m_directScale = directScale;
m_indirectScale = indirectScale;
}
void setVisibleForEye(bool v) {
m_visibleForEye = v;
}
void setVisibleForRefl(bool v) {
m_visibleForRefl = v;
}
void setVisibleForRefr(bool v) {
m_visibleForRefr = v;
}
void setVisibleForGI(bool v) {
m_visibleForGI = v;
}
const bex::tstring& getName() const {
return m_name;
}
protected:
}
bex::tstring m_name;
bex::tstring m_displayName;
bex::Matrix4x4 m_transform;
bex::ColorRGB m_color;
bool m_castShadows;
int32 m_shadowSamples;
float m_intensity;
float m_directScale;
float m_indirectScale;
bool m_visibleForEye;
bool m_visibleForRefl;
bool m_visibleForRefr;
bool m_visibleForGI;
};
class FalloffLightSource : public LightSource {
public:
FalloffLightSource(const bex::tstring& name,
const bex::Matrix4x4& transform,
const bex::ColorRGB& color) :
LightSource(name, transform, color),
m_falloffType(EXPONENT_FALLOFF),
m_exponent(0.0f),
m_constant(0.0f),
m_linear(0.0f),
m_quadratic(1.0f),
m_cutoff(std::numeric_limits<float>::max()),
m_clamp(true)
{}
void setExponentFalloff(float cutoff, float exponent, bool clamp) {
m_falloffType = EXPONENT_FALLOFF;
m_cutoff = cutoff;
m_exponent = exponent;
m_clamp = clamp;
}
void setMaxrangeFalloff(float cutoff, float exponent) {
m_falloffType = MAXRANGE_FALLOFF;
m_cutoff = cutoff;
m_exponent = exponent;
}
void setPolynomialFalloff(float cutoff, float constant, float linear, float quadratic, bool clamp) {
m_falloffType = POLYNOMIAL_FALLOFF;
m_cutoff = cutoff;
m_constant = constant;
m_linear = linear;
m_quadratic = quadratic;
m_clamp = clamp;
}
protected:
LightSource::setBasicParameters(light);
switch (m_falloffType) {
case EXPONENT_FALLOFF:
break;
case MAXRANGE_FALLOFF:
break;
case POLYNOMIAL_FALLOFF:
break;
}
}
enum FallOffType {
EXPONENT_FALLOFF,
MAXRANGE_FALLOFF,
POLYNOMIAL_FALLOFF
};
FallOffType m_falloffType;
float m_cutoff;
float m_exponent;
float m_constant;
float m_linear;
float m_quadratic;
bool m_clamp;
};
class PointLightSource : public FalloffLightSource {
public:
PointLightSource(const bex::tstring& name,
const bex::Matrix4x4& transform,
const bex::ColorRGB& color) :
FalloffLightSource(name, transform, color),
m_shadowRadius(0.0f)
{}
setBasicParameters(light);
return light;
}
void setShadowRadius(float shadowRadius) {
m_shadowRadius = shadowRadius;
}
protected:
FalloffLightSource::setBasicParameters(light);
}
float m_shadowRadius;
};
class SpotLightSource : public PointLightSource {
public:
SpotLightSource(const bex::tstring& name,
const bex::Matrix4x4& transform,
const bex::ColorRGB& color) :
PointLightSource(name, transform, color),
m_angle((float)(M_PI/2.0f)),
m_penumbraAngle(0.0f),
m_penumbraExponent(1.0f)
{}
setBasicParameters(light);
return light;
}
void setCone(float angle, float penumbraAngle, float penumbraExponent) {
m_angle = angle;
m_penumbraAngle = penumbraAngle;
m_penumbraExponent = penumbraExponent;
}
protected:
PointLightSource::setBasicParameters(light);
}
float m_angle;
float m_penumbraAngle;
float m_penumbraExponent;
};
class AreaLightSource : public FalloffLightSource {
public:
AreaLightSource(const bex::tstring& name,
const bex::Matrix4x4& transform,
const bex::ColorRGB& color) :
FalloffLightSource(name, transform, color)
{}
setBasicParameters(light);
return light;
}
};
class DirectionalLightSource : public LightSource {
public:
DirectionalLightSource(const bex::tstring& name,
const bex::Matrix4x4& transform,
const bex::ColorRGB& color) :
LightSource(name, transform, color),
m_shadowAngle(0.0f)
{}
void setShadowAngle(float shadowAngle) {
m_shadowAngle = shadowAngle;
}
setBasicParameters(light);
return light;
}
protected:
LightSource::setBasicParameters(light);
}
float m_shadowAngle;
};
class SkyLightSource : public LightSource {
public:
SkyLightSource(const bex::tstring& name,
const bex::Matrix4x4& transform,
const bex::ColorRGB& color) :
LightSource(name, transform, color),
m_texture(L"")
{}
bex::apiCall(
ILBCreateSkyLight(scene, m_name.c_str(), &m_transform, &m_color, &light));
setBasicParameters(light);
if (m_texture.size()) {
}
}
return light;
}
m_volumeType = volumeType;
}
void setTexture(const bex::tstring& texture) {
m_texture = texture;
}
protected:
LightSource::setBasicParameters(light);
}
bex::tstring m_texture;
};
class AmbientLightSource : public LightSource {
public:
AmbientLightSource(const bex::tstring& name,
const bex::Matrix4x4& transform,
const bex::ColorRGB& color) :
LightSource(name, transform, color),
{}
setBasicParameters(light);
return light;
}
m_volumeType = volumeType;
}
protected:
LightSource::setBasicParameters(light);
}
};
class LightManager {
private:
typedef std::map<bex::tstring, LightSource*> LightMap;
public:
~LightManager() {
LightMap::iterator it = m_lights.begin();
for (;it != m_lights.end(); it++) {
delete it->second;
}
}
void addLight(LightSource* light) {
LightMap::iterator it = m_lights.find(light->getName());
if (it != m_lights.end()) {
delete it->second;
m_lights.erase(it);
}
m_lights[light->getName()] = light;
}
void deleteLight(const bex::tstring& name) {
LightMap::iterator it = m_lights.find(name);
if (it != m_lights.end()) {
delete it->second;
m_lights.erase(it);
}
}
LightMap::iterator it = m_lights.begin();
for (;it != m_lights.end(); it++) {
it->second->create(beastManager, scene);
}
}
private:
LightMap m_lights;
};
bex::tstring name = bex::convertStringHandle(nameHandle);
bex::ColorRGB color(0,0,0);
bex::Matrix4x4 transform;
LightSource* light = 0;
FalloffLightSource* falloffLight = 0;
switch(type) {
SpotLightSource* spotLight = new SpotLightSource(name, transform, color);
float shadowRadius;
spotLight->setShadowRadius(shadowRadius);
float angleRadians, penumbraAngleRadians, penumbraExponent;
spotLight->setCone(angleRadians, penumbraAngleRadians, penumbraExponent);
light = falloffLight = spotLight;
break;
}
PointLightSource* pointLight = new PointLightSource(name, transform, color);
float shadowRadius;
pointLight->setShadowRadius(shadowRadius);
light = falloffLight = pointLight;
break;
}
AreaLightSource* areaLight = new AreaLightSource(name, transform, color);
light = falloffLight = areaLight;
break;
}
DirectionalLightSource* dirLight = new DirectionalLightSource(name, transform, color);
float shadowAngle;
dirLight->setShadowAngle(shadowAngle);
light = dirLight;
break;
}
SkyLightSource* skyLight = new SkyLightSource(name, transform, color);
skyLight->setVolumeType(volumeType);
light = skyLight;
break;
}
AmbientLightSource* ambientLight = new AmbientLightSource(name, transform, color);
ambientLight->setVolumeType(volumeType);
light = ambientLight;
break;
}
default:
return 0;
}
bex::tstring displayName = bex::convertStringHandle(displayNameHandle);
light->setDisplayName(displayName);
float intensity;
light->setIntensity(intensity);
float directScale, indirectScale;
light->setIntensityScale(directScale, indirectScale);
light->setVisibleForEye(statsResult != 0);
light->setVisibleForRefl(statsResult != 0);
light->setVisibleForRefr(statsResult != 0);
light->setVisibleForGI(statsResult != 0);
light->setCastShadows(castShadows!=0);
int32 shadowSamples;
light->setShadowSamples(shadowSamples);
if (falloffLight) {
switch(ft) {
float cutoff, exponent;
falloffLight->setExponentFalloff(cutoff, exponent, clamp!=0);
break;
}
float cutoff, exponent;
falloffLight->setMaxrangeFalloff(cutoff, exponent);
break;
}
float cutoff, constant, linear, quadratic;
falloffLight->setPolynomialFalloff(cutoff, constant, linear, quadratic, clamp!=0);
break;
}
}
}
return light;
}
int main(char argc, char** argv) {
try {
#if defined(WIN32)
#else
#endif
bex::OBJReader objReader;
std::wstring objFileName = L"../../data/hangar.obj";
tcout << "Starting to load file" << std::endl;
objReader.loadObjFile(objFileName);
tcout << "Done Loading File file" << std::endl;
typedef std::pair<std::string, ILBMeshHandle> MeshNameHandle;
std::vector<MeshNameHandle> meshHandles;
std::vector<std::string> allMeshes;
objReader.getMeshNames(allMeshes);
for (unsigned int i=0; i<allMeshes.size();i++) {
std::vector<bex::Vec3> vertices;
std::vector<bex::Vec3> normals;
std::vector<bex::Vec2> uvs;
std::string materialName;
objReader.getMeshData(allMeshes[i], vertices, normals, uvs, materialName);
if (vertices.size() != 0) {
const std::string& name = allMeshes[i];
ILBMeshHandle handle = constructMesh(bex::string2tstring(name), vertices, normals, uvs, bex::string2tstring(materialName), bmh);
meshHandles.push_back(MeshNameHandle(name, handle));
}
}
LightManager lightManager;
DirectionalLightSource* sun = new DirectionalLightSource(L"Sun",
bex::translation(bex::Vec3(0.0f, 7.5f, -20.0f)) * bex::directionalLightOrientation(normalize(bex::Vec3(-1.0f, -1.0f, -0.25f))),
bex::ColorRGB(0.6f, 0.6f, .5f));
sun->setCastShadows(true);
sun->setShadowSamples(32);
sun->setShadowAngle(.025f);
lightManager.addLight(sun);
SkyLightSource* sky = new SkyLightSource(L"Sky",
bex::translation(bex::Vec3(0.0f, 5.0f, -20.0f)),
bex::ColorRGB(0.25f, 0.3f, 0.4f));
lightManager.addLight(sky);
float sceneScale = 1.0f;
Camera perspCamera(_T("Camera"), bex::translation(bex::Vec3(-5.0f, 5.0f, -10.0f)) * bex::cameraOrientation(normalize(bex::Vec3(0.25f, -0.25f, -1.0f)), bex::Vec3(0.0f, 1.0f, 0.0f)), (float)M_PI_2, 1.0f);
TargetManager targetManager;
bex::Matrix4x4 objTrans = bex::scaleTranslation(bex::Vec3(1.0f, 1.0f, 1.0f), bex::Vec3(0.0f, 0.0f, 0.0f));
for(size_t i = 0; i < meshHandles.size(); ++i) {
if(meshHandles[i].first == "hangar:Ground") {
targetManager.addTarget(
new TargetEntity(objTrans, meshHandles[i].second, bex::string2tstring(meshHandles[i].first),
ILB_TT_VERTEX));
} else {
targetManager.addTarget(
new TargetEntity(objTrans, meshHandles[i].second, bex::string2tstring(meshHandles[i].first),
ILB_TT_TEXTURE));
}
}
while (true) {
const std::string xmlFileName = "../../data/ernst.xml";
{
using namespace bex;
std::ofstream ofs(xmlFileName.c_str(), std::ios_base::out | std::ios_base::trunc);
XMLWriter xml(ofs);
{ScopedTag _x(xml, "ILConfig");
{ScopedTag _x(xml, "AASettings");
xml.data("minSampleRate", 0);
xml.data("maxSampleRate", 2);
}
{ScopedTag _x(xml, "RenderSettings");
xml.data("bias", 0.00001f);
}
{ScopedTag _x(xml, "GISettings");
xml.data("enableGI", true);
xml.data("fgRays", 1000);
xml.data("fgContrastThreshold", 0.1);
xml.data("fgInterpolationPoints", 15);
xml.data("primaryIntegrator", "FinalGather");
xml.data("secondaryIntegrator", "PathTracer");
}
}
}
lightManager.create(bmh, scene);
targetManager.createScene(scene);
const std::map<std::string, bex::OBJReader::Material>& map = objReader.getMaterials();
std::map<std::string, bex::OBJReader::Material>::const_iterator it = map.begin();
for (;it != map.end(); ++it) {
bex::apiCall(
ILBCreateMaterial(scene, bex::string2tstring(it->first).c_str(), &mat));
if(it->second.shininess > 0.0f) {
}
}
ILBCreateJob(bmh, L
"RenderJob", scene, bex::string2tstring(xmlFileName).c_str(), &renderJob);
bex::apiCall(
ILBCreateCameraTarget(renderJob, _T(
"cameraTarget"), cameraHandle, 640, 480, &cameraTarget));
if (!bex::renderJob(renderJob, tcout)) {
return 1;
}
bex::apiCall(
ILBCreateErnstJob(bmh, L
"ErnstJob", scene, bex::string2tstring(xmlFileName).c_str(), &ernstJob));
targetManager.create(ernstJob);
while (isRunning) {
while (true) {
if (!hasUpdate) {
break;
}
switch (updateType) {
lightManager.addLight(getLightFromHandle(lh));
break;
}
lightManager.addLight(getLightFromHandle(lh));
break;
}
lightManager.deleteLight(bex::convertStringHandle(sh));
break;
}
perspCamera = getCameraFromHandle(ch);
break;
}
float ss;
sceneScale = ss;
sceneUpVector = uv;
break;
}
std::wstring instanceName = bex::convertStringHandle(sh);
int32 width, height;
width = height = 0;
}
targetManager.update(instanceName, tt, width, height);
break;
}
}
}
}
switch(jobStatus) {
tcout << L"Could not find license for Ernst" << std::endl;
break;
tcout << L"Ernst crashed" << std::endl;
break;
}
}
return 0;
} catch(bex::Exception& ex) {
tcout << L"Beast API error" << std::endl;
tcout << L"Error: " << bex::convertStringHandle(errorString) << std::endl;
tcout << L"Info: " << bex::convertStringHandle(extendedError) << std::endl;
return 1;
} catch(std::exception& ex) {
tcout << L"Standard exception" << std::endl;
tcout << L"Error: " << ex.what() << std::endl;;
return 1;
}
}