Drawing little snowman and smaller goodies

- Character properties window
- Normalized ImGui::DragFloat4 that can be used for Quaternions
- Fixed issue of skymap movement
The snowman has unfortunately some shadow mapping issues...
master
Martin Felis 2017-01-08 22:47:54 +01:00
parent b5141c3b6a
commit 84efe9b9aa
3 changed files with 149 additions and 33 deletions

View File

@ -769,9 +769,9 @@ void Camera::updateMatrices() {
bx::vec3Cross(tmp, dirNorm, right);
bx::vec3Norm(up, tmp);
mtxEnv[ 0] = right[0];
mtxEnv[ 1] = right[1];
mtxEnv[ 2] = right[2];
mtxEnv[ 0] = -right[0];
mtxEnv[ 1] = -right[1];
mtxEnv[ 2] = -right[2];
mtxEnv[ 3] = 0.0f;
mtxEnv[ 4] = up[0];
mtxEnv[ 5] = up[1];
@ -1276,13 +1276,16 @@ void Renderer::paintGL() {
bx::mtxLookAtRh(lights[i].mtxView, eye, at);
lights[i].area = 20.0f;
lights[i].near = 0.f;
lights[i].far = 40.f;
lights[i].area = 10.0f;
lights[i].near = 10.f;
lights[i].far = 20.f;
// bx::mtxProj(lightProj, 20.0f, 1., 5.f, 10.0f);
bx::mtxOrthoRh(lights[i].mtxProj, -lights[i].area, lights[i].area, -lights[i].area, lights[i].area, lights[i].near, lights[i].far);
bx::mtxOrthoRh(lights[i].mtxProj,
lights[i].area, -lights[i].area,
lights[i].area, -lights[i].area,
lights[i].near, lights[i].far);
// lights: shadow matrix
const float sy = flipV ? 0.5f : -0.5f;
@ -1323,6 +1326,11 @@ void Renderer::paintGL() {
bgfx::setViewRect(RenderState::Debug, 0, 0, width, height);
bgfx::setViewTransform(RenderState::Debug, cameras[activeCameraIndex].mtxView, cameras[activeCameraIndex].mtxProj);
//
// Pass: floor
//
// setup floor
float mtxFloor[16];
bx::mtxSRT(mtxFloor
@ -1356,6 +1364,10 @@ void Renderer::paintGL() {
bgfx::touch(RenderState::Scene);
bgfx::touch(RenderState::Skybox);
//
// Pass: skybox
//
if (drawSkybox) {
// Skybox pass
memcpy (IBL::uniforms.m_cameraPos, cameras[activeCameraIndex].eye.data(), 3 * sizeof(float));
@ -1419,7 +1431,7 @@ void Renderer::paintGL() {
}
//
// Shadow map and scene pass
// Pass: shadow map and scene pass
//
// render entities
@ -1429,14 +1441,11 @@ void Renderer::paintGL() {
// shadow map pass
bx::mtxMul(lightMtx, entities[i]->transform.toMatrix().data(), lights[0].mtxShadow);
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
bgfx::setUniform(lights[0].u_lightPos, lights[0].pos);
bgfx::setUniform(u_color, entities[i]->color, 4);
entities[i]->mesh.submit (&s_renderStates[RenderState::ShadowMap]);
// scene pass
bx::mtxMul(lightMtx, entities[i]->transform.toMatrix().data(), lights[0].mtxShadow);
bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
bgfx::setUniform(lights[0].u_lightPos, lights[0].pos);
bgfx::setUniform(u_color, entities[i]->color, 4);
entities[i]->mesh.submit (&s_renderStates[RenderState::Scene]);
}

View File

@ -1115,11 +1115,11 @@ Mesh *createUVSphere (int rows, int segments) {
float alpha0 = j * row_d * M_PI;
float alpha1 = (j + 1) * row_d * M_PI;
float r0 = sin (alpha0);
float r1 = sin (alpha1);
float r0 = sin (alpha0) * 0.5f;
float r1 = sin (alpha1) * 0.5f;
float h0 = cos (alpha0);
float h1 = cos (alpha1);
float h0 = cos (alpha0) * 0.5f;
float h1 = cos (alpha1) * 0.5f;
for (unsigned int i = 0; i < segments; i++) {
Vector3f v0, v1, v2, v3;
@ -1131,22 +1131,22 @@ Mesh *createUVSphere (int rows, int segments) {
v2 = Vector3f (r0 * cos(a1), h0, r0 * sin (a1));
v3 = Vector3f (r0 * cos(a0), h0, r0 * sin (a0));
vertices.push_back (Vector4f(v0[0], v0[1], v0[2], 0.f));
vertices.push_back (Vector4f(v0[0], v0[1], v0[2], 1.f));
normals.push_back (v0 * 1.f/ v0.norm());
vertices.push_back (Vector4f(v2[0], v2[1], v2[2], 0.f));
vertices.push_back (Vector4f(v2[0], v2[1], v2[2], 1.f));
normals.push_back (v2 * 1.f/ v2.norm());
vertices.push_back (Vector4f(v1[0], v1[1], v1[2], 0.f));
vertices.push_back (Vector4f(v1[0], v1[1], v1[2], 1.f));
normals.push_back (v1 * 1.f/ v1.norm());
vertices.push_back (Vector4f(v0[0], v0[1], v0[2], 0.f));
vertices.push_back (Vector4f(v0[0], v0[1], v0[2], 1.f));
normals.push_back (v0 * 1.f/ v0.norm());
vertices.push_back (Vector4f(v3[0], v3[1], v3[2], 0.f));
vertices.push_back (Vector4f(v3[0], v3[1], v3[2], 1.f));
normals.push_back (v3 * 1.f/ v3.norm());
vertices.push_back (Vector4f(v2[0], v2[1], v2[2], 0.f));
vertices.push_back (Vector4f(v2[0], v2[1], v2[2], 1.f));
normals.push_back (v2 * 1.f/ v2.norm());
}
}

View File

@ -46,6 +46,13 @@ struct CharacterController {
};
};
const float cJumpVelocity = 4.0f;
const float cVelocityDamping = 4.0f;
const float cGravity = 9.81f;
const float cGroundAcceleration = 30.0f;
const float cCharacterHeight = 1.8f;
const float cCharacterWidth = 1.f;
struct CharacterEntity {
/// Render entity
Entity *entity;
@ -53,10 +60,11 @@ struct CharacterEntity {
Vector3f velocity;
CharacterController controller;
float cJumpVelocity = 20.0f;
float cVelocityDamping = 2.0f;
float cGravity = 30.0f;
float cGroundAcceleration = 30.0f;
void reset() {
position.setZero();
velocity.setZero();
controller.reset();
}
void update(float dt) {
Vector3f controller_acceleration (
@ -78,7 +86,7 @@ struct CharacterEntity {
if (position[1] == 0.0f
&& controller.state[CharacterController::ControlJump]) {
velocity[1] += cJumpVelocity;
velocity[1] = cJumpVelocity;
}
// integrate position
@ -86,12 +94,13 @@ struct CharacterEntity {
if (position[1] < 0.f) {
position[1] = 0.f;
velocity[1] = 0.0f;
}
// apply transformation
entity->transform.translation.set(
position[0],
position[1] + 1.0f,
position[1],
position[2]);
entity->mesh.updateMatrices(entity->transform.toMatrix());
@ -285,15 +294,30 @@ static void module_reload(struct module_state *state) {
cout << "Creating render entity ..." << endl;
state->character->entity = gRenderer->createEntity();
state->character->position = Vector3f (0.f, 0.74f, 0.0f);
state->character->position = Vector3f (0.f, 0.0f, 0.0f);
cout << "Creating render entity ... success!" << endl;
cout << "Creating render entity mesh ..." << endl;
state->character->entity->mesh.addMesh(
-1,
Transform(),
bgfxutils::createUVSphere (45, 45)
);
Vector3f snowman_offsets (0.45f, 0.35f, 0.25f);
float height_offset = 0.0f;
for (int i = 0; i < 3; i++) {
float radius = cCharacterHeight * snowman_offsets[i];
Transform transform = Transform::fromTransRotScale(
Vector3f(0.f, height_offset + radius * 0.5f, 0.0f),
Quaternion(0.0f, 0.0f, 0.0f, 1.0f),
Vector3f(radius, radius, radius)
);
state->character->entity->mesh.addMesh(
-1,
transform,
bgfxutils::createUVSphere (45, 45)
);
height_offset += radius * 0.8;
}
// state->character->entity->mesh = bgfxutils::createCuboid (1.f, 1.f, 1.f);
// state->character->entity->mesh = bgfxutils::createCylinder (20);
cout << "Creating render entity mesh ... success!" << endl;
@ -385,13 +409,96 @@ void ShowModulesWindow(struct module_state *state) {
ImGui::End();
}
// Returns a normalized vector where the value at the modified index
// is kept and only the other values are being modified so that the
// resulting vector is normalized.
bool DragFloat4Normalized(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f)
{
float old_values[4];
memcpy (old_values, v, sizeof(float) * 4);
bool modified = ImGui::DragFloat4(label, v, v_speed, v_min, v_max, display_format, power);
if (modified) {
int mod_index = -1;
Vector3f other_values;
int other_index = 0;
// determine the modified index and copy the unmodified values to
// other_values
for (int i = 0; i < 4; ++i) {
if (old_values[i] != v[i]) {
mod_index = i;
} else {
other_values[other_index] = v[i];
other_index++;
}
}
// normalize, but take zero length of other values into account and
// also modification of vectors with a single 1.
float other_length = other_values.norm();
if (fabs(v[mod_index]) >= 1.0f - 1.0e-6f || other_length == 0.0f) {
other_values.setZero();
v[mod_index] = 1.0f * v[mod_index] < 0.0f ? -1.0f : 1.0f;
} else {
// normalize other_values to have the remaining length
other_values = other_values * (1.f / other_length) * (sqrt(1.0f - v[mod_index] * v[mod_index]));
}
// construct the new vector
other_index = 0;
for (int i = 0; i < 4; ++i) {
if (i != mod_index) {
v[i] = other_values[other_index];
other_index++;
}
}
}
return modified;
}
void ShowCharacterPropertiesWindow (CharacterEntity* character) {
assert (character != nullptr);
ImGui::SetNextWindowSize (ImVec2(600.f, 300.0f), ImGuiSetCond_Once);
ImGui::SetNextWindowPos (ImVec2(400.f, 16.0f), ImGuiSetCond_Once);
ImGui::Begin("Character");
if (ImGui::Button ("Reset")) {
character->reset();
}
ImGui::DragFloat3 ("Position", character->position.data(), 0.01, -10.0f, 10.0f);
ImGui::DragFloat3 ("Velocity", character->velocity.data(), 0.01, -10.0f, 10.0f);
for (int i = 0; i < character->entity->mesh.meshes.size(); ++i) {
char buf[32];
snprintf (buf, 32, "Mesh %d", i);
ImGuiTreeNodeFlags node_flags = 0;
bool node_open = ImGui::TreeNodeEx(
buf,
node_flags);
if (node_open) {
Transform &transform = character->entity->mesh.localTransforms[i];
ImGui::DragFloat3 ("Position", transform.translation.data(), 0.01, -10.0f, 10.0f);
if (DragFloat4Normalized ("Rotation", transform.rotation.data(), 0.001, -1.0f, 1.0f)) {
if (isnan(transform.rotation.squaredNorm())) {
cout << "nan! " << transform.rotation.transpose() << endl;
abort();
}
}
ImGui::DragFloat3 ("Scale", transform.scale.data(), 0.01, 0.001f, 10.0f);
ImGui::TreePop();
}
}
ImGui::End();
}