Open source Star Ruler 2 source code!

This commit is contained in:
Lucas de Vries
2018-07-17 14:15:37 +02:00
commit cc307720ff
4342 changed files with 2365070 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
#include "scene/mesh_icon_node.h"
#include "render/driver.h"
#include "render/render_mesh.h"
#include "render/spritesheet.h"
#include "render/vertexBuffer.h"
#include "constants.h"
#include "frustum.h"
namespace scene {
//Maximum distance away from the camera something can render (according to its scale)
const double MaxRenderDistFactor = 8000.0;
const double IconRenderDistFactor = 1000.0;
const double BothRenderDistFactor = 500.0;
bool MeshIconNode::render3DIcons = true;
MeshIconNode::MeshIconNode(
const render::RenderMesh* Mesh, const render::RenderState* Material,
const render::SpriteSheet* Sheet, unsigned Index)
: mesh(Mesh), material(Material), iconSheet(Sheet), iconIndex(Index) {
if(Material->baseMat != render::MAT_Solid || (Sheet && Sheet->material.baseMat != render::MAT_Solid))
setFlag(NF_Transparent, true);
setFlag(NF_AnimOnlyVisible, true);
}
bool MeshIconNode::preRender(render::RenderDriver& driver) {
auto fromCamera = abs_position + (driver.cam_facing * abs_scale) - driver.cam_pos;
sortDistance = fromCamera.getLength();
if(sortDistance > MaxRenderDistFactor * abs_scale || !driver.getViewFrustum().overlaps(abs_position,abs_scale))
return false;
else
return true;
}
void MeshIconNode::render(render::RenderDriver& driver) {
if(render3DIcons) {
double scaleMod = pow(abs_scale, 0.3);
if(iconSheet) {
if(sortDistance > BothRenderDistFactor * scaleMod) {
double iconScale = sqrt(sortDistance / abs_scale) * abs_scale * 0.25;
//Calculate best-fit facing of the 2D sprite (Assuming the sprite is facing +x)
auto& cam_facing = driver.cam_facing;
auto& cam_up = driver.cam_up;
double rot;
vec3d obj_facing = rotation * vec3d::front();
double alongDot = cam_facing.dot(obj_facing);
//If it's facing along the camera vector, we can't get an accurate angle
if(alongDot > -0.9999 && alongDot < 0.9999) {
obj_facing -= cam_facing * alongDot;
obj_facing.normalize();
vec3d cam_right = cam_facing.cross(cam_up).normalized();
rot = acos(cam_right.dot(obj_facing));
if(cam_right.cross(cam_facing).dot(obj_facing) < 0)
rot = -rot;
}
else {
//Point up when going away, down when coming toward
rot = alongDot > 0 ? pi * 0.5 : pi * -0.5;
}
color.a = std::min(1.0, (sortDistance / scaleMod - BothRenderDistFactor) / (IconRenderDistFactor - BothRenderDistFactor));
Color c = color;
driver.drawBillboard(abs_position, iconScale,
iconSheet->material, iconSheet->getSource(iconIndex), rot, c);
if(sortDistance > IconRenderDistFactor * scaleMod)
return;
}
}
else if(sortDistance > IconRenderDistFactor * scaleMod) {
return;
}
}
if(material->baseMat != render::MAT_Solid)
render::renderVertexBuffers();
driver.setTransformation(transformation);
driver.switchToRenderState(*material);
mesh->selectLOD(sortDistance / abs_scale)->render();
driver.resetTransformation();
}
};