bool Player::unmount() { if (!mount) { return true; } printf_fvec3(get_world_pos()); printf("\n"); mount->remove_entity(this); // try setting pos to about 2 blocks above current position set_pos(fvec3(pos.x, pos.y + 2.0f, pos.z)); if (get_world()->will_collide_with_anything(this)) { // return false if we can't unmount...because not room for player set_pos(fvec3(pos.x, pos.y - 2.0f, pos.z)); mount->add_entity(this); return false; } velocity = mount->velocity; mount = 0; can_collide = true; printf_fvec3(get_world_pos()); get_world()->add_entity(this); toggle_mount(false); return true; }
Player::Player(uint32_t p) { vid = 0; pid = p; entity_class = EntityType::PLAYER; can_collide = true; can_rotate = false; // initialize things pos = fvec3(0.0f, 8.0f, 0.0f); //lower_bound = fvec3(-0.4f, -0.9f, 0.4f); //upper_bound = fvec3(0.4f, 0.9f, 0.4f); fvec3 lower_bound = fvec3(0.0f, 0.0f, 0.0f); fvec3 upper_bound = fvec3(0.9f, 0.9f, 0.9f); bounds = bounding_box(lower_bound, upper_bound); update_centerpos_smooth(); weight = 20; velocity_decay = 0.5f; update_direction(0.0, 0.0); id_assign = VID_UNIQUE_START; inventory = new PlayerInventory(); mount = 0; game_template = 0; }
static fmat3 rotation_normalized(float angle, const fvec3 &axis) { float sa = sinf(angle), ca = cosf(angle), omc = 1.f - ca; fvec3 axis_omc = omc * axis; return fmat3(axis[0] * axis_omc + fvec3(ca, axis[2] * sa, -axis[1] * sa), axis[1] * axis_omc + fvec3(-axis[2] * sa, ca, axis[0] * sa), axis[2] * axis_omc + fvec3(axis[1] * sa, -axis[0] * sa, ca)); }
void Entity::yaw_left(float force) { // 1 unit of force turns 1 weight by M_PI/2 float angular_force = get_speed(force)*RIGHT_ANGLE; turn_angle(fvec3(angular_force, 0, 0)); }
void WorldWeather::render(fmat4* transform) { // bind the skybox texture // scale the skybox fmat4 view; view = glm::scale(*transform, fvec3(radius, radius, radius)); skybox->render(&view); // bind back to default texture }
RenderableModel::RenderableModel() { name = ""; resistance = 0; weight = 0; vehicle = 0; bounds = bounding_box(); center_pos = fvec3(0,0,0); light = RenderableLight(); multiplexer = 0; }
Entity::Entity() { // identifying info for the entity. this should be overwritten vid = 0; pid = 0; entity_class = EntityType::ENTITY; can_collide = true; stable = false; bounds = bounding_box(); velocity = fvec3(0, 0, 0); angular_velocity = fvec3(0, 0, 0); velocity_decay = DEFAULT_VELOCITY_DECAY; weight = 0; // 0 is full health health = 0; selected = false; // start out with no parent // damn that's depresssing parent = 0; }
void WorldWeather::update_sky() { float frac_cycle = time * 1.0f / time_per_day; float frac_day = 0.5f + 0.5f * cosf(frac_cycle * 2 * M_PI); float frac_night = 0.5f + 0.5f * sinf(frac_cycle * 2 * M_PI); Rotation* tilt = skybox->get_angle(); tilt->set_angle(glm::angleAxis((float)(frac_cycle * 2 * M_PI), fvec3(0,0,1))); dir_light.direction = fvec3(0.5f - frac_day, 0.4f, 0.2f); dir_light.direction = glm::normalize(dir_light.direction); float sun_x; if (frac_cycle < 0.5f) { // daytime sun_x = 0.5f; } else { sun_x = 0.0f; } }
Atom() { VL_DEBUG_SET_OBJECT_NAME() mId = 0; mAtomType = AT_Unknown; mCoordinates = fvec3(0,0,0); mColor = fvec4(1.0f,1.0f,1.0f,1.0f); mRadius = 0.25f; mVisited = false; mVisible = true; mShowAtomName= false; /*mAtomName = nothing*/ }
void Entity::update_centerpos(bounding_box bounds) { // this should be called whenever our bounds change // use bounds to set centerpos if (!can_rotate || bounds.lower.x == FLT_MAX || bounds.lower.x == FLT_MIN) { // TODO this is hack, do this properly center_pos = fvec3(0, 0, 0); return; } // we will always be pointing in the positive x-direction // we want to put the centerpos such that it is offset by 0.5 at each coordinate // or integer at each coordinate. this ensures nice rotations for our blocks // in addition, we want the vehicle to be perfectly centered in the positive x direction // first, get the center z coordinate (perpendicular to our direction) fvec3 exact_centerpos = fvec3((bounds.upper.x - bounds.lower.x) / 2.0f, (bounds.upper.y - bounds.lower.y) / 2.0f, (bounds.upper.z - bounds.lower.z) / 2.0f); exact_centerpos = exact_centerpos + bounds.lower; // see if it is closer to 0.5 or to 1.0 bool align_to_half = false; int rounded_centerz = roundf(exact_centerpos.z * 2.0f); if (get_positive_mod(rounded_centerz, 2) == 1) { align_to_half = true; } if (align_to_half) { set_centerpos(fvec3(roundf(exact_centerpos.x - 0.5f) + 0.5f, roundf(exact_centerpos.y - 0.5f) + 0.5f, roundf(exact_centerpos.z - 0.5f) + 0.5f)); } else { set_centerpos(fvec3(roundf(exact_centerpos.x), roundf(exact_centerpos.y), roundf(exact_centerpos.z))); } // TODO update position so that despite center pos having changed, blocks are still where they used to be }
WorldWeather::WorldWeather() { radius = 450; time = 0; time_per_day = 24000; time_update = 5; dir_light = DirectionalRenderableLight(); skybox = get_sprite_instance(3); skybox->set_track_player(true); skybox->set_pos(fvec3(0,0,0)); }
void RenderableModel::refresh() { bounds = bounding_box(); for (auto &i: model_vertices) { bounds.expand(i); } // now set it so that our lower is at 0,0,0 fvec3 lower_bound = bounds.lower; bounds.upper -= lower_bound; bounds.lower = fvec3(0,0,0); center_pos = bounds.get_world_pos(); fvec3 aligned_center_pos = get_nearest_half_or_whole(center_pos); if (aligned_center_pos.x < 0.5f) { aligned_center_pos.x = 0.5f; } if (aligned_center_pos.y < 0.5f) { aligned_center_pos.y = 0.5f; } if (aligned_center_pos.z < 0.5f) { aligned_center_pos.z = 0.5f; } fvec3 center_offset = aligned_center_pos - center_pos; bounds.lower += center_offset; bounds.upper += center_offset; fvec3 offset = center_offset - lower_bound; for (unsigned int i = 0; i < model_vertices.size(); i++) { model_vertices[i] += offset; } bounds.lower = get_round_from_fvec3(bounds.lower); bounds.upper = get_round_from_fvec3(bounds.upper); // nothing should be 0 wide... if (bounds.upper.x == 0) { bounds.upper.x = 1.0f; } if (bounds.upper.y == 0) { bounds.upper.y = 1.0f; } if (bounds.upper.z == 0) { bounds.upper.z = 1.0f; } center_pos = bounds.get_world_pos(); }
void SpriteRender::render_rectangle(fmat4* transform, float width, float height, fvec3 texture_corners[4]) { fmat4 view; get_mvp(&view); view = *transform * view; // add to the transformation matrix a scaling factor for the radius view = glm::scale(view, fvec3(0, height, width)); OGLAttr::current_shader->set_transform_matrix(&view); int num_triangles = 6; GLfloat rectangle_vertex_data[6][3] = { {0, -1, -1}, {0, -1, 1}, {0, 1, -1}, {0, 1, -1}, {0, -1, 1}, {0, 1, 1}, }; fvec3 texture_binds[6]; texture_binds[0] = texture_corners[0]; texture_binds[1] = texture_corners[1]; texture_binds[2] = texture_corners[2]; texture_binds[3] = texture_corners[2]; texture_binds[4] = texture_corners[1]; texture_binds[5] = texture_corners[3]; glBindBuffer(GL_ARRAY_BUFFER, OGLAttr::common_vertex_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof rectangle_vertex_data, rectangle_vertex_data, GL_DYNAMIC_DRAW); OGLAttr::current_shader->set_coord_attribute(GL_FLOAT); glBindBuffer(GL_ARRAY_BUFFER, OGLAttr::common_texture_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof texture_binds, &(texture_binds[0]), GL_DYNAMIC_DRAW); OGLAttr::current_shader->set_texture_coord_attribute(GL_FLOAT); glDrawArrays(GL_TRIANGLES, 0, num_triangles); }
void Player::set_mount(SuperObject* m, fvec3 rwc) { if (!m) { unmount(); return; } if (mount) { // unmount first mount->remove_entity(this); } printf_fvec3(get_world_pos()); printf("\n"); mount = m; // no moving around while mounted! velocity = fvec3(0, 0, 0); // TODO this is hack fix this->set_pos(rwc - get_center_offset()); mount->add_entity(this); //m->transform_into_my_coordinates_smooth(&offset_to_mount, pos.x, pos.y, pos.z); //set_pos(pos - this->center_pos); can_collide = false; printf_fvec3(get_world_pos()); toggle_mount(true); }
void Player::update_direction(double xdiff, double ydiff) { float anglex = -xdiff*STRAIGHT_ANGLE; float angley = -ydiff*STRAIGHT_ANGLE; angle.set_free_y(false); angle.apply_angles(fvec3(anglex, angley, 0)); }
void GPURayTracer::RenderFrame(const Camera &camera) { PROFILE_TIMER_START("frame"); frame_stopwatch_.Restart(); CLEvent ev; PROFILE_TIMER_START("GPU"); PROFILE_TIMER_START("GPU init tracing"); /*__kernel void InitTracingFrame(__global TracingState *tracing_states, float16 view_proj_inv, float lod_voxel_size)*/ init_frame_kernel_->SetBufferArg(0, tracing_states_.get()); init_frame_kernel_->SetFloat16Arg(1, camera.ViewProjectionMatrix().Inverse()); init_frame_kernel_->SetFloatArg(2, lod_voxel_size_); init_frame_kernel_->Run2D(frame_width_, frame_height_, NULL, &ev); ev.WaitFor(); PROFILE_TIMER_COMMIT("GPU init tracing"); PROFILE_TIMER_STOP(); cache_manager_->StartRequestSession(); int iterations; for (iterations = 0;; ++iterations) { PROFILE_TIMER_START("GPU"); PROFILE_TIMER_START("GPU tracing passes"); /*__kernel void RaytracingPass(__global int *faults_and_hits, // out __global TracingState *tracing_states, // in-out __global uint *node_links, __global uint *far_pointers, int root_node_index)*/ raytracing_pass_kernel_->SetBufferArg(0, faults_and_hits_.get()); raytracing_pass_kernel_->SetBufferArg(1, tracing_states_.get()); raytracing_pass_kernel_->SetBufferArg(2, cache_manager_->data()->ChannelByIndex(0)->cl_buffer()); raytracing_pass_kernel_->SetBufferArg(3, cache_manager_->data()->far_pointers_buffer()); raytracing_pass_kernel_->SetIntArg(4, cache_manager_->root_node_index()); const CLBuffer *b = NULL; if (cache_manager_->data()->ChannelByName("normals")) b = cache_manager_->data()->ChannelByName("normals")->cl_buffer(); raytracing_pass_kernel_->SetBufferArg(5, b); b = NULL; if (cache_manager_->data()->ChannelByName("colors")) b = cache_manager_->data()->ChannelByName("colors")->cl_buffer(); raytracing_pass_kernel_->SetBufferArg(6, b); raytracing_pass_kernel_->Run2D(frame_width_, frame_height_, NULL, &ev); ev.WaitFor(); PROFILE_TIMER_STOP(); PROFILE_TIMER_STOP(); // always give it at least one iteration of loading if (iterations > 0 && frame_stopwatch_.TimeSinceRestart() > frame_time_limit_) break; feedback_extractor_->Process(*faults_and_hits_, cache_manager_->data()->nodes_in_block()); cache_manager_->StartRequestTransaction(); PROFILE_TIMER_START("CPU mark as used"); const vector<int> &hits = feedback_extractor_->hit_blocks(); for (int i = 0; i < (int)hits.size(); ++i) { cache_manager_->MarkBlockAsUsed(hits[i]); } const vector<int> &dup_hits = feedback_extractor_->duplicate_hit_blocks(); for (int i = 0; i < (int)dup_hits.size(); ++i) { cache_manager_->MarkParentAsUsed(dup_hits[i]); } PROFILE_TIMER_STOP(); PROFILE_VALUE_COMMIT_SET("hits per pass", hits.size()); PROFILE_VALUE_COMMIT_SET("hits dup per pass", dup_hits.size()); PROFILE_TIMER_START("CPU request blocks"); const vector<int> &faults = feedback_extractor_->fault_blocks(); for (int i = 0; i < (int)faults.size(); ++i) { if (cache_manager_->TransactionFilledCache()) break; cache_manager_->RequestBlock(faults[i]); } PROFILE_TIMER_STOP(); PROFILE_VALUE_ADD("faults", faults.size()); cache_manager_->EndRequestTransaction(); if (faults.empty() || cache_manager_->SessionFilledCache()) break; } PROFILE_TIMER_COMMIT("CPU request blocks"); PROFILE_TIMER_COMMIT("CPU mark as used"); PROFILE_TIMER_COMMIT("GPU tracing passes"); PROFILE_VALUE_COMMIT_SET("tracing iterations", iterations); PROFILE_VALUE_COMMIT_SET("cache too small", cache_manager_->SessionFilledCache() ? 1 : 0); PROFILE_VALUE_COMMIT("faults"); PROFILE_VALUE_COMMIT("uploaded blocks"); PROFILE_VALUE_COMMIT("updated far pointers"); PROFILE_VALUE_COMMIT("updated pointers"); cache_manager_->EndRequestSession(); PROFILE_TIMER_START("GPU"); PROFILE_TIMER_START("GPU finish tracing"); /*__kernel void FinishTracingFrame(__global uchar4 *result_colors, __global TracingState *tracing_states, __constant float4 background_color)*/ finish_frame_kernel_->SetBufferArg(0, out_image_.get()); finish_frame_kernel_->SetBufferArg(1, tracing_states_.get()); finish_frame_kernel_->SetFloat4Arg(2, fvec3(0, 216/255., 1), 1); const CLBuffer *b = NULL; if (cache_manager_->data()->ChannelByName("normals")) b = cache_manager_->data()->ChannelByName("normals")->cl_buffer(); finish_frame_kernel_->SetBufferArg(3, b); b = NULL; if (cache_manager_->data()->ChannelByName("colors")) b = cache_manager_->data()->ChannelByName("colors")->cl_buffer(); finish_frame_kernel_->SetBufferArg(4, b); finish_frame_kernel_->Run2D(frame_width_, frame_height_, NULL, &ev); ev.WaitFor(); PROFILE_TIMER_COMMIT("GPU finish tracing"); PROFILE_TIMER_STOP(); PROFILE_TIMER_COMMIT("frame"); // this part kinda breaks encapsulation // the excuse for this is that it's just profiling code, not code that "matters" :) PROFILE_TIMER_COMMIT("GPU sort"); PROFILE_TIMER_COMMIT("GPU scan"); PROFILE_TIMER_COMMIT("GPU/BUS compr/size"); PROFILE_TIMER_COMMIT("BUS read faults"); PROFILE_TIMER_COMMIT("BUS read hits"); PROFILE_TIMER_COMMIT("HDD? load block"); PROFILE_TIMER_COMMIT("CPU process links"); PROFILE_TIMER_COMMIT("BUS upload block"); PROFILE_TIMER_COMMIT("BUS upload far ptr"); PROFILE_TIMER_COMMIT("BUS upload ptr"); PROFILE_TIMER_COMMIT("BUS unload pointer"); PROFILE_TIMER_COMMIT("GPU"); PROFILE_TIMER_COMMIT("BUS"); PROFILE_TIMER_COMMIT("HDD"); }
bool test_hfloat() { half ha, hb; ha = 2.0f; hb = 4.0f; float fa = ha, fb; // basic operations if (fa != 2.0) return false; if (ha * hb != 8.0f) return false; if (ha + hb != 6.0f) return false; if (ha - hb != -2.0f) return false; if (hb / ha != 2.0f) return false; // check no loss of precision between 0 and +-(1<<11) for(int i=0; i<=(1<<11); ++i) { ha = +i; hb = -i; int ifa = (int)(float)ha; int ifb = (int)(float)hb; if (ifa != +i) return false; if (ifb != -i) return false; } // infinity ha = half::infinity(); fa = ha; ha = fa; fa = ha; hb = -half::infinity(); fb = hb; hb = fb; fb = hb; if ( fa != +std::numeric_limits<float>::infinity()) return false; if ( fb != -std::numeric_limits<float>::infinity()) return false; ha = 3.14159265f; fa = ha; if ( ha != fa ) return false; std::vector<half> hvec; std::vector<float> fvec; const int count = 2000; hvec.resize(count); fvec.resize(count); float err = 0; // convertHalfToFloat() for (int i=0; i<count; ++i) { float ff = (i-count/2)*3.14159265358979323846f; hvec[i] = ff; err = err > fabs(ff-hvec[i]) ? err : fabs(ff-hvec[i]); } half::convertHalfToFloat(&hvec[0],&fvec[0],hvec.size()); for (int i=0; i<count; ++i) { if (hvec[i] != fvec[i]) return false; } if (err > 2.0f) return false; // convertFloatToHalf() err = 0; hvec.resize(0); hvec.resize(count); for (int i=0; i<count; ++i) { fvec[i] = (i-count/2)*3.14159265358979323846f; } half::convertFloatToHalf(&fvec[0],&hvec[0],hvec.size()); for (int i=0; i<count; ++i) { err = err > fabs(fvec[i]-hvec[i]) ? err : fabs(fvec[i]-hvec[i]); if (hvec[i] != fvec[i]) return false; } if (err > 2.0f) return false; // various compilation and conversion checks for vectors and matrices hvec3 v1, v2(1,2,3), v3(4,5,6); v1 = v2 + v3; v1 = v2 - v3; v1 = v2 * v3; v1 = v2 / v3; half l1 = v1.length(); half l2 = v1.lengthSquared(); v2 = v1 + (hvec3)fvec3(1,1,1); // hmat4 m = fmat4::getRotation( 90, 0, 1, 0 ); hmat4 m; m.translate(1,1,1); // m.rotate(90, 0, 1, 0 ); m.scale(10,10,10); m = (hmat4)fmat4::getRotation( 90, 0, 1, 0 ); v1 = m * hvec3(1,0,0); if (v1.x() != 0 || v1.y() != 0 || v1.z() != -1.0f) return false; return true; }
void RenderableChunk::update() { changed = false; lights.clear(); has_lights = false; // 6 faces per cube, plus 3+3 vertices on each triangle of quad // but half will not be visible for some reason...don't render? GLbyte vertex[CX * CY * CZ * 18][3]; // I use 2 bytes to denote block type, then 1 byte for flags GLbyte texture[CX * CY * CZ * 18][3]; int i = 0; int merged = 0; bool vis = false; model_vertices.clear(); model_normals.clear(); model_uvs.clear(); // View from negative x for(int x = CX - 1; x >= 0; x--) { for(int y = 0; y < CY; y++) { for(int z = 0; z < CZ; z++) { if (get_block_info(blk[x][y][z].type)->is_model) { // add to fill_game_models(model_vertices, model_normals, model_uvs, blk[x][y][z], x, y, z); } RenderableLight* light = &(get_block_info(blk[x][y][z].type)->light); if (light->should_render()) { LightAndPosition light_and_pos; light_and_pos.light = light; // want to render the light at the center of our block light_and_pos.pos = fvec3(x + 0.5f, y + 0.5f, z + 0.5f); lights.push_back(light_and_pos); has_lights = true; } // Line of sight blocked? if(isblocked(x, y, z, x - 1, y, z)) { vis = false; continue; } block_type type = blk[x][y][z]; BlockOrientation flags = BlockOrientation::BACK; // Same block as previous one? Extend it. if(vis && z != 0 && blk[x][y][z].equals(blk[x][y][z - 1])) { set_coord_and_texture(vertex, texture, i - 5, x, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 2, x, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 1, x, y + 1, z + 1, type, flags); merged++; // Otherwise, add a new quad. } else { set_coord_and_texture(vertex, texture, i++, x, y, z, type, flags); set_coord_and_texture(vertex, texture, i++, x, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z + 1, type, flags); } vis = true; } } } // View from positive x for(int x = 0; x < CX; x++) { for(int y = 0; y < CY; y++) { for(int z = 0; z < CZ; z++) { if(isblocked(x, y, z, x + 1, y, z)) { vis = false; continue; } block_type type = blk[x][y][z]; BlockOrientation flags = BlockOrientation::FRONT; if(vis && z != 0 && blk[x][y][z].equals(blk[x][y][z - 1])) { set_coord_and_texture(vertex, texture, i - 4, x + 1, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 2, x + 1, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 1, x + 1, y, z + 1, type, flags); merged++; } else { set_coord_and_texture(vertex, texture, i++, x + 1, y, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z + 1, type, flags); } vis = true; } } } // View from negative y for(int x = 0; x < CX; x++) { for(int y = CY - 1; y >= 0; y--) { for(int z = 0; z < CZ; z++) { if(isblocked(x, y, z, x, y - 1, z)) { vis = false; continue; } block_type type = blk[x][y][z]; BlockOrientation flags = BlockOrientation::BOTTOM; if(vis && z != 0 && blk[x][y][z].equals(blk[x][y][z - 1])) { set_coord_and_texture(vertex, texture, i - 4, x, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 2, x + 1, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 1, x, y, z + 1, type, flags); merged++; } else { set_coord_and_texture(vertex, texture, i++, x, y, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z, type, flags); set_coord_and_texture(vertex, texture, i++, x, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x, y, z + 1, type, flags); } vis = true; } } } // View from positive y for(int x = 0; x < CX; x++) { for(int y = 0; y < CY; y++) { for(int z = 0; z < CZ; z++) { if(isblocked(x, y, z, x, y + 1, z)) { vis = false; continue; } block_type type = blk[x][y][z]; BlockOrientation flags = BlockOrientation::TOP; if(vis && z != 0 && blk[x][y][z].equals(blk[x][y][z - 1])) { set_coord_and_texture(vertex, texture, i - 5, x, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 2, x, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 1, x + 1, y + 1, z + 1, type, flags); merged++; } else { set_coord_and_texture(vertex, texture, i++, x, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y + 1, z + 1, type, flags); } vis = true; } } } // View from negative z for(int x = 0; x < CX; x++) { for(int z = CZ - 1; z >= 0; z--) { for(int y = 0; y < CY; y++) { if(isblocked(x, y, z, x, y, z - 1)) { vis = false; continue; } block_type type = blk[x][y][z]; BlockOrientation flags = BlockOrientation::RIGHT; if(vis && y != 0 && blk[x][y][z].equals(blk[x][y - 1][z])) { set_coord_and_texture(vertex, texture, i - 5, x, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i - 3, x, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i - 2, x + 1, y + 1, z, type, flags); merged++; } else { set_coord_and_texture(vertex, texture, i++, x, y, z, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y + 1, z, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z, type, flags); } vis = true; } } } // View from positive z for(int x = 0; x < CX; x++) { for(int z = 0; z < CZ; z++) { for(int y = 0; y < CY; y++) { if(isblocked(x, y, z, x, y, z + 1)) { vis = false; continue; } block_type type = blk[x][y][z]; BlockOrientation flags = BlockOrientation::LEFT; if(vis && y != 0 && blk[x][y][z].equals(blk[x][y - 1][z])) { set_coord_and_texture(vertex, texture, i - 4, x, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 3, x, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i - 1, x + 1, y + 1, z + 1, type, flags); merged++; } else { set_coord_and_texture(vertex, texture, i++, x, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x, y + 1, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y, z + 1, type, flags); set_coord_and_texture(vertex, texture, i++, x + 1, y + 1, z + 1, type, flags); } vis = true; } } } changed = false; elements = i; //printf("Finished generating %d elements\n", elements); // If this chunk is empty, no need to allocate a chunk slot. if(!elements) return; // If we don't have an active slot, find one if(chunk_slot[slot].owner != this) { int lru = 0; for(int i = 0; i < CHUNKSLOTS; i++) { // If there is an empty slot, use it if(!chunk_slot[i].owner) { lru = i; break; } // Otherwise try to find the least recently used slot if(chunk_slot[i].owner->lastused < chunk_slot[lru].owner->lastused) lru = i; } // If the slot is empty, create a new VBO if(!chunk_slot[lru].owner) { if (!(chunk_slot[lru].coord_vbo) || !(chunk_slot[lru].texture_vbo)) { glGenBuffers(1, &chunk_slot[lru].texture_vbo); glGenBuffers(1, &chunk_slot[lru].coord_vbo); } } else { // Otherwise, steal it from the previous slot owner chunk_slot[lru].owner->changed = true; } coord_vbo = chunk_slot[lru].coord_vbo; texture_vbo = chunk_slot[lru].texture_vbo; slot = lru; chunk_slot[slot].owner = this; } glBindBuffer(GL_ARRAY_BUFFER, coord_vbo); glBufferData(GL_ARRAY_BUFFER, elements * sizeof *vertex, vertex, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, texture_vbo); glBufferData(GL_ARRAY_BUFFER, elements * sizeof *texture, texture, GL_STATIC_DRAW); }
static fmat3 identity(void) { return fmat3(fvec3(1.f, 0.f, 0.f), fvec3(0.f, 1.f, 0.f), fvec3(0.f, 0.f, 1.f)); }
void Entity::pitch_down(float force) { float angular_force = -get_speed(force)*RIGHT_ANGLE; turn_angle(fvec3(0, angular_force, 0)); }
static fmat3 scaling(const fvec3 &v) { return fmat3(fvec3(v[0], 0.f, 0.f), fvec3(0.f, v[1], 0.f), fvec3(0.f, 0.f, v[2])); }
void Entity::move_right(float force) { fvec3 forward = angle.get_forward(); move_dist(fvec3(-forward.z * get_speed(force), 0, forward.x * get_speed(force))); }
void Entity::update_centerpos_smooth() { set_centerpos(bounds.lower + fvec3((bounds.upper.x - bounds.lower.x) / 2.0f, (bounds.upper.y - bounds.lower.y) / 2.0f, (bounds.upper.z - bounds.lower.z) / 2.0f)); }
void Extruder::extrude(){ if (silhouette().empty()) { Log::error("Extrusion::extrude(): no silhouette defined.\n"); this->errFlag = true; return ; } if (positionPath().empty()) { Log::error("Extrusion::extrude() needs at least a non empty positionPath().\n"); this->errFlag = true; return ; } if (!scalingPath().empty() && scalingPath().size() != positionPath().size()-2) { Log::error("Extrusion::extrude(): scalingPath() must have the same number of control points as positionPath().\n"); this->errFlag = true; return ; } if (!rotationPath().empty() && rotationPath().size() != positionPath().size()-2) { Log::error("Extrusion::extrude(): rotationPath() must have the same number of control points as positionPath().\n"); this->errFlag = true; return ; } if (!colorPath().empty() && colorPath().size() != positionPath().size()-2) { Log::error("Extrusion::extrude(): colorPath() must have the same number of control points as positionPath().\n"); this->errFlag = true; return ; } size_t segments = positionPath().size()-2; currPos = vertices.size(); vertices.resize( currPos + silhouette().size() * segments ); vl::fmat4 m = fmat4::getRotation(fvec3(0,1,0),positionPath()[1]-positionPath()[0]); // initialize silhouette on the x/z plane std::vector<vl::fvec3> projected_sil; projected_sil.resize(silhouette().size()); for(unsigned i=0; i<silhouette().size(); ++i) { projected_sil[i] = m * vl::fvec3(silhouette()[i].x(),0,silhouette()[i].y()) + positionPath()[0]; } // initialize plane normals from 1 to n-1 (end points are excluded) std::vector<fvec3> plane_normals; plane_normals.resize(positionPath().size()); for(unsigned i=1; i<plane_normals.size()-1; ++i) { fvec3 p0 = positionPath()[i-1] - positionPath()[i]; fvec3 p1 = positionPath()[i+1] - positionPath()[i]; p0.normalize(); p1.normalize(); plane_normals[i] = (p1-p0).normalize(); } for(unsigned i=1; i<positionPath().size()-1; ++i) { for(int j=0; j<(int)silhouette().size(); ++j) { fvec3 V = (positionPath()[i] - positionPath()[i-1]).normalize(); const fvec3& P = projected_sil[j]; const fvec3& orig = positionPath()[i]; const fvec3& N = plane_normals [i]; float d = dot(N,orig); float t = dot(V,N) ? (d-dot(P,N))/dot(V,N) : 0; // project current projected_sil on next plane along p0->p1 vector vertices.at(currPos+j+silhouette().size()*(i-1)) = projected_sil[j] = P + V*t; } } // rotation if(!rotationPath().empty()) { for(unsigned i=1; i<positionPath().size()-1; ++i) { fvec3 r = (positionPath()[i+1] - positionPath()[i]).normalize(); fmat4 mat = vl::fmat4::getRotation(rotationPath()[i-1],r); fvec3 c; for(int j=0; j<(int)silhouette().size(); ++j) c += vertices.at(currPos+j+silhouette().size()*(i-1)); c /= (float)silhouette().size(); for(int j=0; j<(int)silhouette().size(); ++j) vertices.at(currPos+j+silhouette().size()*(i-1)) = (mat*(vertices.at(currPos+j+silhouette().size()*(i-1))-c))+c; } } // scaling if(!scalingPath().empty()) { for(unsigned i=1; i<positionPath().size()-1; ++i) { float s = scalingPath()[i-1]; fvec3 c; for(int j=0; j<(int)silhouette().size(); ++j) c += vertices.at(currPos+j+silhouette().size()*(i-1)); c /= (float)silhouette().size(); for(int j=0; j<(int)silhouette().size(); ++j) vertices.at(currPos+j+silhouette().size()*(i-1)) = (s*(vertices.at(currPos+j+silhouette().size()*(i-1))-c))+c; } } int prof_count = silhouetteMode() == SilhouetteClosed ? (int)silhouette().size() : (int)silhouette().size()-1; currDE = de->indexBuffer()->size(); de->indexBuffer()->resize(currDE + 4 * prof_count * (segments-1)); for(size_t iseg=0; iseg<segments-1; ++iseg) { for(int iquad=0; iquad<prof_count; ++iquad) { de->indexBuffer()->at(currDE + iquad*4+iseg*4*prof_count + 3) = currPos + (iseg + 0) * (GLuint)silhouette().size() + iquad; de->indexBuffer()->at(currDE + iquad*4+iseg*4*prof_count + 2) = currPos +(iseg + 0) * (GLuint)silhouette().size() + (iquad+1)%silhouette().size(); de->indexBuffer()->at(currDE + iquad*4+iseg*4*prof_count + 1) = currPos +(iseg + 1) * (GLuint)silhouette().size() + (iquad+1)%silhouette().size(); de->indexBuffer()->at(currDE + iquad*4+iseg*4*prof_count + 0) = currPos +(iseg + 1) * (GLuint)silhouette().size() + iquad; } } // bottom/top caps size_t tess_bottom_count = 0; size_t tess_top_count = 0; if(fillBottom()) { size_t start = vertices.size(); Tessellator tessellator; tessellator.contours().push_back((int)silhouette().size()); for(unsigned i=0; i<silhouette().size(); ++i){ tessellator.contourVerts().push_back((dvec3)vertices[currPos+i]); } tessellator.setWindingRule(vl::TW_TESS_WINDING_NONZERO); tessellator.tessellate(); for(unsigned i=0; i<tessellator.tessellatedTris().size(); ++i){ vertices.push_back(tessellator.tessellatedTris()[i]); } if (tessellator.tessellatedTris().size()){ geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, start, tessellator.tessellatedTris().size()) ); }tess_bottom_count = tessellator.tessellatedTris().size(); } if(fillTop()) { size_t start = vertices.size(); Tessellator tessellator; tessellator.contours().push_back(silhouette().size()); for(unsigned i=0; i<silhouette().size(); ++i){ tessellator.contourVerts().push_back((dvec3)vertices[vertices.size()-i-1-tess_bottom_count]); } tessellator.setWindingRule(vl::TW_TESS_WINDING_NONZERO); tessellator.tessellate(); for(unsigned i=0; i<tessellator.tessellatedTris().size(); ++i){ vertices.push_back(tessellator.tessellatedTris()[i]); } if (tessellator.tessellatedTris().size()){ geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, start, tessellator.tessellatedTris().size()) ); } tess_top_count = tessellator.tessellatedTris().size(); } }
void Entity::move_down_flat(float force) { move_dist(fvec3(0.0, -get_speed(force), 0.0)); }
// Bawk // // Created by Eric Oh on 1/2/16. // Copyright (c) 2016 Eric Oh. All rights reserved. // #include "cursorscantool.h" #include "blocktracer.h" #include "worldrender.h" #include "uirenderhelper.h" #include "cursorsuperobject.h" #include "client_accessor.h" #include "basicrender.h" const fvec3 SELECTING_COLOR = fvec3(0.5f, 0.0f, 0.0f); const fvec3 SELECTED_COLOR = fvec3(0.0f, 0.5f, 0.0f); const fvec3 EXTENDED_COLOR = fvec3(0.0f, 0.0f, 0.5f); CursorScanTool::CursorScanTool(CursorItemInfo* i): CursorItem(i) { current_stage = ScanStages::SETTING_LOWER; show_item = false; } void CursorScanTool::reset() { current_stage = ScanStages::SETTING_LOWER; show_item = false; } bool CursorScanTool::clicked(Action mouse) { if (current_stage == ScanStages::SETTING_LOWER) {
void Entity::yaw_right(float force) { float angular_force = -get_speed(force)*RIGHT_ANGLE; turn_angle(fvec3(angular_force, 0, 0)); }
operator fvec3(void) const { return fvec3(v[0], v[1], v[2]); }
void Entity::roll_right(float force) { float angular_force = get_speed(force)*RIGHT_ANGLE; turn_angle(fvec3(0, 0, angular_force)); }
static fvec3d zero(void) { return fvec3(0., 0., 0.); }