//* This only mostly works float Camera::getScreenRadius( const Sphere &sphere, float screenWidth, float screenHeight ) const { Vec2f screenCenter( worldToScreen( sphere.getCenter(), screenWidth, screenHeight ) ); Vec3f orthog = mViewDirection.getOrthogonal().normalized(); Vec2f screenPerimeter = worldToScreen( sphere.getCenter() + sphere.getRadius() * orthog, screenWidth, screenHeight ); return screenPerimeter.distance( screenCenter ); }
//* This only mostly works float Camera::getScreenRadius( const Sphere &sphere, float screenWidth, float screenHeight ) const { vec2 screenCenter( worldToScreen( sphere.getCenter(), screenWidth, screenHeight ) ); vec3 orthog = normalize( orthogonal( mViewDirection ) ); vec2 screenPerimeter = worldToScreen( sphere.getCenter() + sphere.getRadius() * orthog, screenWidth, screenHeight ); return distance( screenPerimeter, screenCenter ); }
/** * Draw the view frustum. * * @param dc The drawing context. */ void ChunkWatchControl::drawFrustum(CDC &dc) { Matrix view = WorldEditorCamera::instance().currentCamera().view(); view.invert(); float fov = Moo::rc().camera().fov(); float clipDist = Moo::rc().camera().farPlane(); Vector3 userPos = view.applyToOrigin(); Vector3 dir = view.applyToUnitAxisVector(2); Vector2 ndir = Vector2(dir.x, dir.z); float k = ::tanf(0.5f*fov)*clipDist; if (clipDist < SMALL_FRUSTUM) return; float ux, uz; worldToScreen(&ux, &uz, userPos.x, userPos.z); ndir.normalise(); float x1 = userPos.x + ndir.x*clipDist + k*ndir.y; float z1 = userPos.z + ndir.y*clipDist - k*ndir.x; float x2 = userPos.x + ndir.x*clipDist - k*ndir.y; float z2 = userPos.z + ndir.y*clipDist + k*ndir.x; worldToScreen(&x1, &z1, x1, z1); worldToScreen(&x2, &z2, x2, z2); CPen pen(PS_SOLID, 1, CLR_FRUSTUM); CPen *oldPen = dc.SelectObject(&pen); dc.MoveTo((int)ux, (int)uz); dc.LineTo((int)x1, (int)z1); dc.LineTo((int)x2, (int)z2); dc.LineTo((int)ux, (int)uz); dc.SelectObject(oldPen); }
GameScene::GameScene(const World& world) : animTicker() , portal(new QGraphicsPixmapItem(QPixmap(":/portal.png"))) { hover = this->addRect(0, 0, tile_width, tile_height, QColor(255, 64, 255), QColor(128,128,255,64)); hover->setZValue(100); player = this->addEllipse(0, 0, 20, 20, QColor(255, 0, 0), QColor(128, 32, 32)); player->setZValue(99); this->player->setPos(worldToScreen(world.playerPosition)); animTicker.setInterval(10); animTicker.start(); connect(&animTicker, SIGNAL(timeout()), this, SLOT(refreshAnimations())); portal->setPos(worldToScreen(QPoint(world.landscape.width - 22, world.landscape.height - 18))); portal->setZValue(50); this->addItem(portal); }
void InteractiveMarkerControl::moveAxis( const Ogre::Ray& mouse_ray, const ViewportMouseEvent& event ) { // compute control-axis ray based on grab_point_, etc. Ogre::Ray control_ray; control_ray.setOrigin( grab_point_ ); control_ray.setDirection( control_frame_node_->getOrientation() * control_orientation_.xAxis() ); // project control-axis ray onto screen. Ogre::Vector2 control_ray_screen_start, control_ray_screen_end; worldToScreen( control_ray.getOrigin(), event.viewport, control_ray_screen_start ); worldToScreen( control_ray.getPoint( 1 ), event.viewport, control_ray_screen_end ); Ogre::Vector2 mouse_point( event.x, event.y ); // Find closest point on projected ray to mouse point // Math: if P is the start of the ray, v is the direction vector of // the ray (not normalized), and X is the test point, then the // closest point on the line to X is given by: // // (X-P).v // P + v * ------- // v.v // where "." is the dot product. Ogre::Vector2 control_ray_screen_dir = control_ray_screen_end - control_ray_screen_start; double denominator = control_ray_screen_dir.dotProduct( control_ray_screen_dir ); if( fabs( denominator ) > Ogre::Matrix3::EPSILON ) // If the control ray is not straight in line with the view. { double factor = ( mouse_point - control_ray_screen_start ).dotProduct( control_ray_screen_dir ) / denominator; Ogre::Vector2 closest_screen_point = control_ray_screen_start + control_ray_screen_dir * factor; // make a new "mouse ray" for the point on the projected ray int width = event.viewport->getActualWidth() - 1; int height = event.viewport->getActualHeight() - 1; Ogre::Ray new_mouse_ray = event.viewport->getCamera()->getCameraToViewportRay( (closest_screen_point.x+.5) / width, (closest_screen_point.y+.5) / height ); new_mouse_ray.setOrigin( reference_node_->convertWorldToLocalPosition( new_mouse_ray.getOrigin() ) ); new_mouse_ray.setDirection( reference_node_->convertWorldToLocalOrientation( Ogre::Quaternion::IDENTITY ) * new_mouse_ray.getDirection() ); // find closest point on control-axis ray to new mouse ray (should intersect actually) Ogre::Vector3 closest_point; if( findClosestPoint( control_ray, new_mouse_ray, closest_point )) { // set position of parent to closest_point - grab_point_ + parent_position_at_mouse_down_. parent_->setPose( closest_point - grab_point_ + parent_position_at_mouse_down_, parent_->getOrientation(), name_ ); } } }
void View::update(const InputState &state) { if(state.isKeyDown('g')) { if(m_is_visible) { if(m_cell_size == 3) m_cell_size = 6; else if(m_cell_size == 6) m_cell_size = 9; else { m_cell_size = 1; m_is_visible = false; } } else { m_cell_size = 3; m_is_visible = true; } } int height_change = state.mouseWheelMove() + (state.isKeyDownAuto(InputKey::pagedown)? -1 : 0) + (state.isKeyDownAuto(InputKey::pageup)? 1 : 0); if(height_change) m_height = clamp(m_height + height_change, 0, (int)Grid::max_height); { int actions[TileGroup::Group::side_count] = { InputKey::kp_1, InputKey::kp_2, InputKey::kp_3, InputKey::kp_6, InputKey::kp_9, InputKey::kp_8, InputKey::kp_7, InputKey::kp_4 }; for(int n = 0; n < arraySize(actions); n++) if(state.isKeyDownAuto(actions[n])) m_view_pos += worldToScreen(TileGroup::Group::s_side_offsets[n] * m_cell_size); } if((state.isKeyPressed(InputKey::lctrl) && state.isMouseButtonPressed(InputButton::left)) || state.isMouseButtonPressed(InputButton::middle)) m_view_pos -= state.mouseMove(); IRect rect = worldToScreen(IBox(int3(0, 0, 0), asXZY(m_tile_map.dimensions(), 256))); m_view_pos = clamp(m_view_pos, rect.min, rect.max - m_view_size); }
void View::drawGrid(Renderer2D &out) const { if(!m_is_visible) return; const int2 tile_map_size = m_tile_map.dimensions(); int2 p[4] = { screenToWorld(m_view_pos + int2(0, 0)), screenToWorld(m_view_pos + int2(0, m_view_size.y)), screenToWorld(m_view_pos + int2(m_view_size.x, m_view_size.y)), screenToWorld(m_view_pos + int2(m_view_size.x, 0)) }; int2 offset = screenToWorld(worldToScreen(int3(0, m_height, 0))); for(int n = 0; n < 4; n++) p[n] -= offset; int2 tmin = min(min(p[0], p[1]), min(p[2], p[3])); int2 tmax = max(max(p[0], p[1]), max(p[2], p[3])); IRect box(max(tmin, int2(0, 0)), min(tmax, tile_map_size)); Color color(255, 255, 255, 64); for(int x = box.min.x - box.min.x % m_cell_size; x <= box.max.x; x += m_cell_size) drawLine(out, int3(x, m_height, box.min.y), int3(x, m_height, box.max.y), color); for(int y = box.min.y - box.min.y % m_cell_size; y <= box.max.y; y += m_cell_size) drawLine(out, int3(box.min.x, m_height, y), int3(box.max.x, m_height, y), color); }
/** * This draws the user's position. * * @param dc The drawing context. */ void ChunkWatchControl::drawArrow(CDC &dc) { // Draw the user's position: drawPos_ = WorldEditorCamera::instance().currentCamera().view(); drawPos_.invert(); Vector3 userPos = drawPos_.applyToOrigin(); Vector3 direction = drawPos_.applyToUnitAxisVector(2); float ux, uz; worldToScreen(&ux, &uz, userPos.x, userPos.z); float dx = direction.x; float dz = -direction.z; // invert y coord to match screen float len = std::sqrt(dx*dx + dz*dz); if (len != 0.0f) { dx /= len; dz /= len; } dx *= USER_POS_SIZE; dz *= USER_POS_SIZE; CPen pen(PS_SOLID, 1, CLR_USER_POS); CPen *oldPen = dc.SelectObject(&pen); dc.MoveTo((int)(ux - dx), (int)(uz - dz)); dc.LineTo((int)(ux + dx), (int)(uz + dz)); dc.MoveTo((int)(ux + dx), (int)(uz + dz)); dc.LineTo((int)(ux - dz), (int)(uz + dx)); dc.MoveTo((int)(ux + dx), (int)(uz + dz)); dc.LineTo((int)(ux + dz), (int)(uz - dx)); dc.SelectObject(oldPen); }
Vector SphericalCamera::worldToRaster(const Vector &wsP, const PTime time) const { Vector ssP = worldToScreen(wsP, time); Vector rsP; m_screenToRaster.multVecMatrix(ssP, rsP); return rsP; }
void Entity::addToRender(SceneRenderer &out, Color color) const { //PROFILE("Entity::addToRender"); IRect rect = m_sprite.getRect(m_seq_idx, m_frame_idx, m_dir_idx); if(!areOverlapping(out.targetRect(), rect + (int2)worldToScreen(m_pos))) return; FBox bbox = boundingBox() - pos(); if(shrinkRenderedBBox() && bbox.height() >= 2.0f) bbox = {float3(bbox.x(), min(bbox.y() + 1.0f, bbox.ey() - 0.5f), bbox.z()), bbox.max()}; bool as_overlay = renderAsOverlay(); FRect tex_rect; auto tex = m_sprite.getFrame(m_seq_idx, m_frame_idx, m_dir_idx, tex_rect); bool added = out.add(tex, rect, m_pos, bbox, color, tex_rect, as_overlay); if(added && m_oseq_idx != -1 && m_oframe_idx != -1) { //TODO: overlay may be visible, while normal sprite is not! rect = m_sprite.getRect(m_oseq_idx, m_oframe_idx, m_dir_idx); auto ov_tex = m_sprite.getFrame(m_oseq_idx, m_oframe_idx, m_dir_idx, tex_rect); out.add(ov_tex, rect, m_pos, bbox, color, tex_rect, true); } // if(findAny(boundingBox(), {Flags::all | Flags::colliding, ref()})) // out.addBox(bbox + pos(), ColorId::red); }
const IRect Entity::currentScreenRect() const { IRect rect = m_sprite.getRect(m_seq_idx, m_frame_idx, m_dir_idx); if(m_oseq_idx != -1 && m_oframe_idx != -1) rect = enclose(rect, m_sprite.getRect(m_oseq_idx, m_oframe_idx, m_dir_idx)); //TODO: float based results return rect + (int2)worldToScreen(pos()); }
SoccerPitchData(const Size &size) { pitchPoints.push_back(Point2f(0, 0)); pitchPoints.push_back(Point2f(13.85, 0)); pitchPoints.push_back(Point2f(24.85, 0)); pitchPoints.push_back(Point2f(43.15, 0)); pitchPoints.push_back(Point2f(54.15, 0)); pitchPoints.push_back(Point2f(68, 0)); pitchPoints.push_back(Point2f(24.85, 5.5)); pitchPoints.push_back(Point2f(43.15, 5.5)); pitchPoints.push_back(Point2f(13.85, 16.5)); pitchPoints.push_back(Point2f(26.69, 16.5)); pitchPoints.push_back(Point2f(41.31, 16.5)); pitchPoints.push_back(Point2f(54.15, 16.5)); pitchPoints.push_back(Point2f(0, 52.5)); pitchPoints.push_back(Point2f(24.85, 52.5)); pitchPoints.push_back(Point2f(43.15, 52.5)); pitchPoints.push_back(Point2f(68, 52.5)); pitchPoints.push_back(Point2f(13.85, 88.5)); pitchPoints.push_back(Point2f(26.69, 88.5)); pitchPoints.push_back(Point2f(41.31, 88.5)); pitchPoints.push_back(Point2f(54.15, 88.5)); pitchPoints.push_back(Point2f(24.85, 99.5)); pitchPoints.push_back(Point2f(43.15, 99.5)); pitchPoints.push_back(Point2f(0, 105)); pitchPoints.push_back(Point2f(13.85, 105)); pitchPoints.push_back(Point2f(24.85, 105)); pitchPoints.push_back(Point2f(43.15, 105)); pitchPoints.push_back(Point2f(54.15, 105)); pitchPoints.push_back(Point2f(68, 105)); pitchOuterPoints.push_back(Point2f(0, 0)); pitchOuterPoints.push_back(Point2f(0, 105)); pitchOuterPoints.push_back(Point2f(68, 105)); pitchOuterPoints.push_back(Point2f(68, 0)); worldToScreen(size, pitchPoints); worldToScreen(size, pitchOuterPoints); };
void Player::draw(sf::RenderWindow &render) const { View view(sf::FloatRect(0, 0, m_drawDim.x*(m_zooms[m_controller.getZoom()]), m_drawDim.y*m_zooms[m_controller.getZoom()])); view.setCenter(m_controller.getViewCenter()); view.setViewport(sf::FloatRect(m_drawPos.x/m_resolution.x, m_drawPos.y/m_resolution.y, m_drawDim.x/m_resolution.x, m_drawDim.y/m_resolution.y)); render.setView(view); std::vector<Entity*> toDraw = m_world.getEntitiesInRect(screenToWorld(Vec(0, 0)), screenToWorld(m_drawDim)); //m_world.draw(render); for(int i=0; i<toDraw.size(); i++) { toDraw[i]->draw(render); } for(int i=0; i<m_selection.size(); i++) { m_selection[i]->drawSelected(render); } draw::drawRect(render, Vec(0, 0), Vec(m_world.getDim()), sf::Color::White); for(int i=0; i<toDraw.size(); i++) { toDraw[i]->drawForeground(render, screenToWorld(mousePos())); } view.reset(sf::FloatRect(0, 0, m_drawDim.x, m_drawDim.y)); render.setView(view); if(m_selecting) { draw::drawRect(render, worldToScreen(m_A), worldToScreen(m_B)-worldToScreen(m_A), sf::Color(50, 100, 255, 100), 3); draw::drawRect(render, worldToScreen(m_A), worldToScreen(m_B)-worldToScreen(m_A), sf::Color(50, 100, 255, 100)); } m_gui->drawChildren(render, Vec(0, 0), m_drawDim); Displayer::instance.draw(render); draw::drawRect(render, Vec(1, 1), m_drawDim-Vec(1, 1)*2, sf::Color::White); }
void PlayerShip::cameraMove() { //Center the camera over the ship camera->x = (worldToScreen(body->GetPosition().x) + texture.getWidth() / 2) - SCREEN_WIDTH / 2; camera->y = (worldToScreen(body->GetPosition().y) + texture.getHeight() / 2) - SCREEN_HEIGHT / 2; //Keep the camera in bounds if (camera->x < 0) { camera->x = 0; } if (camera->y < 0) { camera->y = 0; } if (camera->x > LEVEL_WIDTH - camera->w) { camera->x = LEVEL_WIDTH - camera->w; } if (camera->y > LEVEL_HEIGHT - camera->h) { camera->y = LEVEL_HEIGHT - camera->h; } }
void Graph::draw(int x, int y) { ofPushMatrix(); ofPushStyle(); ofTranslate(x, y); drawPosition = worldToScreen(ofVec2f(0, 0)); ofFill(); ofSetColor(ofMap(ofGetElapsedTimef() - lastTrigger, 0, .5, 255, 0, true)); if(noData) { ofSetColor(128); } ofRect(0, 0, width, height); ofNoFill(); ofSetColor(255); ofPushStyle(); // if(hoverState) { // ofSetHexColor(0xffee00); // ofSetLineWidth(2); // } ofRect(0, 0, width, height); ofPopStyle(); ofRectangle region(1, height - 1, width - 2, -(height - 2)); ofSetHexColor(0xec008c); if(noData) { ofSetColor(200); } drawBuffer(derivativePolyline, threshold, derivativeBox, region); ofSetColor(255); drawBuffer(bufferPolyline, 0, bufferBox, region); ofSetColor(255); drawString(name, 5, 10); if(!buffer.empty() && !derivative.empty()) { ofPushMatrix(); ofTranslate(width, 0); drawString(ofToString(bufferBox.y, 2) + "<" + (buffer.empty() ? "empty" : ofToString(buffer.back(), 2)) + "<" + ofToString(bufferBox.y + bufferBox.height, 2), 5, 10); drawString(ofToString(derivativeBox.y, 2) + "<" + (derivative.empty() ? "empty" : ofToString(derivative.back(), 2)) + "<" + ofToString(derivativeBox.y + derivativeBox.height, 2), 5, 18); drawString(ofToString(threshold, 2) + ", " + ofToString(buffer.back(), 2) + " (" + ofToString(getNormalized(), 2) + ") " + ofToString(derivative.back(), 2), 5, 26); ofPopMatrix(); } ofPopStyle(); ofPopMatrix(); }
const IBox View::computeCursor(const int2 &start, const int2 &end, const int3 &bbox, int height, int offset) const { float2 height_off = worldToScreen(float3(0, height, 0)); int3 gbox(cellSize(), 1, cellSize()); int3 start_pos = asXZ((int2)( screenToWorld(float2(start + pos()) - height_off) + float2(0.5f, 0.5f))); int3 end_pos = asXZ((int2)( screenToWorld(float2(end + pos()) - height_off) + float2(0.5f, 0.5f))); start_pos.y = end_pos.y = height + offset; { int apos1 = start_pos.x % gbox.x; int apos2 = apos1 - gbox.x + bbox.x; start_pos.x -= apos1 < gbox.x - apos1 || bbox.x >= gbox.x? apos1 : apos2; } { int apos1 = start_pos.z % gbox.z; int apos2 = apos1 - gbox.z + bbox.z; start_pos.z -= apos1 < gbox.z - apos1 || bbox.z >= gbox.z? apos1 : apos2; } if(end == start) end_pos = start_pos; int3 dir(end_pos.x >= start_pos.x? 1 : -1, 1, end_pos.z >= start_pos.z? 1 : -1); int3 size(::abs(end_pos.x - start_pos.x), 1, ::abs(end_pos.z - start_pos.z)); size += bbox - int3(1, 1, 1); size.x -= size.x % bbox.x; size.z -= size.z % bbox.z; size = max(bbox, size); if(dir.x < 0) start_pos.x += bbox.x; if(dir.z < 0) start_pos.z += bbox.z; end_pos = start_pos + dir * size; if(start_pos.x > end_pos.x) swap(start_pos.x, end_pos.x); if(start_pos.z > end_pos.z) swap(start_pos.z, end_pos.z); int2 dims = m_tile_map.dimensions(); start_pos = asXZY(clamp(start_pos.xz(), int2(0, 0), dims), start_pos.y); end_pos = asXZY(clamp( end_pos.xz(), int2(0, 0), dims), end_pos.y); return IBox(start_pos, end_pos); }
Intersection WorldViewer::pixelIntersect(const int2 &screen_pos, const FindFilter &filter) const { Intersection out; FBox out_bbox; if(filter.flags() & Flags::tile) { const TileMap &tile_map = m_world->tileMap(); vector<int> inds; tile_map.findAll(inds, IRect(screen_pos, screen_pos + int2(1, 1)), filter.flags() | Flags::visible); for(int i = 0; i < (int)inds.size(); i++) { const auto &desc = tile_map[inds[i]]; FBox bbox = desc.bbox; if(out.empty() || drawingOrder(bbox, out_bbox) == 1) if(desc.ptr->testPixel(screen_pos - worldToScreen((int3)bbox.min))) { out = ObjectRef(inds[i], false); out_bbox = bbox; } } } if(filter.flags() & Flags::entity) { int ignore_index = m_world->filterIgnoreIndex(filter); for(int n = 0; n < (int)m_entities.size(); n++) { const Entity *entity = refEntity(n); if(!entity || !m_occluder_config.isVisible(m_entities[n].occluder_id) || !Flags::test(entity->flags(), filter.flags()) || n == ignore_index) continue; if(!entity->testPixel(screen_pos)) continue; FBox bbox = entity->boundingBox(); //TODO: check this if(out.empty() || drawingOrder(bbox, out_bbox) == 1) { out = ObjectRef(n, true); out_bbox = bbox; } } } if(out.empty()) return Intersection(); return Intersection(out, intersection(screenRay(screen_pos), out_bbox)); }
void EntitiesEditor::computeCursor(int2 start, int2 end, bool floor_mode) { float2 height_off = worldToScreen(int3(0, 0, 0)); start += m_view.pos(); end += m_view.pos(); Ray ray = screenRay(start); Flags::Type flags = Flags::all; if(floor_mode) flags = flags & ~(Flags::wall_tile | Flags::object_tile); auto isect = m_tile_map.trace(ray, -1, flags | Flags::visible); float3 pos = isect.first == -1? (float3)asXZ(screenToWorld(start)) : ray.at(isect.second); m_cursor_pos = (float3)round(pos); m_selection = IRect(min(start, end), max(start, end)); }
float PerspectiveCamera::evalWe(const Vector3& pCamera, const Vector3& pWorld) const { if (worldToScreen(pWorld, pCamera) == Camera::sInvalidPixel) { return 0.0f; } Vector4 pView = mView * Vector4(pWorld, 1.0f); Vector4 pLensLocal = mView * Vector4(pCamera, 1.0f); Vector4 dir(pView - pLensLocal); Vector4 pFocus = pLensLocal + (mFocalDistance / dir.z) * dir; Vector3 lensToFilm( pFocus.x - pLensLocal.x, pFocus.y - pLensLocal.y, pFocus.z - pLensLocal.z); float lensToFilmDistance2 = lensToFilm.squaredLength(); float cosTheta = normalize(lensToFilm).z; float G = cosTheta * cosTheta / lensToFilmDistance2; float lensArea = mLensRadius * mLensRadius * PI; float We = mLensRadius > 0.0f ? 1.0f / (mFilmArea * lensArea * G) : 1.0f / (mFilmArea * G); return We; }
void render(SDL_Renderer* renderer) { //draw draw space // if (input_draw_space) { // SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // // SDL_Rect rect; // rect.x = 0; // rect.y = 0; // mapToOrtho(worldMap.GetWidth(), worldMap.GetHeight(), rect.w, rect.h); // zoom(rect); // worldToScreen(rect.x, rect.y); // // SDL_RenderFillRect(renderer, &rect); // SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // } //draw map for (int y = 0; y < worldMap.GetHeight(); y++) { for (int x = 0; x < worldMap.GetWidth(); x++) { SDL_Rect rect; //in world coords rect.w = tileSizeX; rect.h = tileSizeY; mapToIso(x, y, rect.x, rect.y); zoom(rect); rect.y -= (tileSizeY*input_scale - tileWidth*input_scale); worldToScreen(rect.x, rect.y); SDL_Rect tileRect; //in tileset coords tileRect.w = tileSizeX; tileRect.h = tileSizeY; //layer terrain const int tileId = worldMap.Get(x,y).terrainId; if (tileId != -1) { int tileX; int tileY; getTileXY(tileId, &tileX, &tileY, TILESET_WIDTH); tileRect.x = tileX * tileSizeX; tileRect.y = tileY * tileSizeY; SDL_RenderCopy(renderer, tileset, &tileRect, &rect); } //layer object const int tileId2 = worldMap.Get(x, y).objectId; if (tileId2 != -1) { int tileObjX; int tileObjY; getTileXY(tileId2, &tileObjX, &tileObjY, TILESET_WIDTH); tileRect.x = tileObjX * tileSizeX; tileRect.y = tileObjY * tileSizeY; SDL_RenderCopy(renderer, tileset, &tileRect, &rect); } } } // //draw debug rect // if (input_show_debug_rect) { // SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); // for (int y = 0; y < worldMap.GetHeight(); y++) { // for (int x = 0; x < worldMap.GetWidth(); x++) { // SDL_Rect rect; // rect.w = tileSizeX; // rect.h = tileWidth; // // mapToOrtho(x,y,rect.x, rect.y); // zoom(rect); // worldToScreen(rect.x, rect.y); // // SDL_RenderDrawRect(renderer, &rect); // } // } // SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // } //show editor bar for (int i = 0; i < NB_TILES_EDITOR; i++) { SDL_Rect tileRect; //in tileset coords tileRect.w = tileSizeX; tileRect.h = tileSizeY; const int tileId = TILES_EDITOR[i]; int tileX; int tileY; getTileXY(tileId, &tileX, &tileY, TILESET_WIDTH); tileRect.x = tileX * tileSizeX; tileRect.y = tileY * tileSizeY; SDL_Rect rect; //in world coords rect.w = tileSizeX; rect.h = tileSizeY; rect.x = i * tileSizeX; rect.y = WIN_HEIGHT - tileSizeY; SDL_RenderCopy(renderer, tileset, &tileRect, &rect); } if (input_show_debug_rect) { SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); for (int x = 0; x < worldMap.GetWidth() + 1; x++) { int x1 = x; int y1 = 0; int x2 = x; int y2 = worldMap.GetHeight(); int tx1; int tx2; int ty1; int ty2; mapToIso(x1, y1, tx1, ty1); mapToIso(x2, y2, tx2, ty2); x1 = tx1; x2 = tx2; y1 = ty1; y2 = ty2; x1 += tileSizeX / 2; x2 += tileSizeX / 2; x1 *= input_scale; x2 *= input_scale; y1 *= input_scale; y2 *= input_scale; worldToScreen(x1, y1); worldToScreen(x2, y2); SDL_RenderDrawLine(renderer, x1, y1, x2, y2); } for (int y = 0; y < worldMap.GetHeight() + 1; y++) { int x1 = 0; int y1 = y; int x2 = worldMap.GetWidth(); int y2 = y; int tx1; int tx2; int ty1; int ty2; mapToIso(x1, y1, tx1, ty1); mapToIso(x2, y2, tx2, ty2); x1 = tx1; x2 = tx2; y1 = ty1; y2 = ty2; x1 += tileSizeX / 2; x2 += tileSizeX / 2; x1 *= input_scale; x2 *= input_scale; y1 *= input_scale; y2 *= input_scale; worldToScreen(x1, y1); worldToScreen(x2, y2); SDL_RenderDrawLine(renderer, x1, y1, x2, y2); } SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); } }
bool Entity::testPixel(const int2 &screen_pos) const { return m_sprite.testPixel(screen_pos - (int2)worldToScreen(pos()), m_seq_idx, m_frame_idx, m_dir_idx); }
//-------------------------------------------------------------- void HypercubeScene::update(){ if (ofGetFrameNum() % 60 == 0){ myShader.load("gradient"); } if(numPoly < NUM_POLY){ int newNumPoly = powf((ofGetElapsedTimef() - (float)resetMoment),2) * 2.0; if(newNumPoly > NUM_POLY) newNumPoly = NUM_POLY; if(numPoly != newNumPoly){ for(int i = numPoly; i < newNumPoly; i++){ brightnesses[i] = 1; } numPoly = newNumPoly; } } else numPoly = NUM_POLY; for(int i = 0; i < NUM_POLY; i++){ brightnesses[i] *= 0.8; } float SCALE = .002; for(int i = 0; i < NUM_POLY; i++){ polychron[i].rotate4DOnly(SCALE * sinf(ofGetElapsedTimef() * rotations[i].x), SCALE * sinf(ofGetElapsedTimef() * rotations[i].y), SCALE * sinf(ofGetElapsedTimef() * rotations[i].z) ); } for(int i = 0; i < NUM_POLY; i++) { // CALCULATE the highlighted vertices highlighted[i].clear(); for(int v = 0; v < polychron[i].getNumVertices(); v++){ Point4D vertex = polychron[i].vertices[v]; ofVec3f screenLocation = worldToScreen( ofVec3f(vertex.x, vertex.y, vertex.z), polyMatrix[i] ); if(pointInHotspot(hotSpots[0], screenLocation) || pointInHotspot(hotSpots[1], screenLocation) || pointInHotspot(hotSpots[2], screenLocation)){ highlighted[i].push_back(v); // vertex energy polychron[i].vertexEnergy[v] += 0.05; if(polychron[i].vertexEnergy[ v ] > 1) polychron[i].vertexEnergy[ v ] = 1; // edge energy vector<unsigned int> adjEdg = polychron[i].allEdgesAdjacentTo(v); for(int q = 0; q < adjEdg.size(); q++){ polychron[i].edgeEnergy[ adjEdg[q] ] += .05; if(polychron[i].edgeEnergy[ adjEdg[q] ] > 1) polychron[i].edgeEnergy[ adjEdg[q] ] = 1; } } } } lastFaceNose = faceNose; float closeness = 100; float xRot = faceCenterSmooth.x * .5; float yRot = faceCenterSmooth.y * .5; headTiltMatrix.makeIdentityMatrix(); headTiltMatrix.rotate(xRot, 0, 1, 0); headTiltMatrix.rotate(-yRot, 1, 0, 0); headTiltMatrix.translate(0, 0, closeness); }
ofVec3f CameraNode::worldToCameraScreen(const ofVec3f& p) { ofRectangle rect(0.0f, 0.0f, width, height); return worldToScreen(p, rect); }
bool OccluderConfig::update(const FBox &bbox) { //TODO: hiding when close to a door/window FBox test_box(bbox.min.x, bbox.min.y + 1.0f, bbox.min.z, bbox.max.x, 256, bbox.max.z); float3 mid_point = asXZY(test_box.center().xz(), bbox.min.y + 2.0f); bool vis_changed = update(); vector<int> temp; temp.reserve(256); IRect test_rect = (IRect)worldToScreen(bbox); const Grid &grid = m_map.m_grid; grid.findAll(temp, test_rect); vector<int> temp2; temp2.reserve(256); PodArray<int> overlaps(m_map.size()); memset(overlaps.data(), 0, m_map.size() * sizeof(int)); for(int i = 0; i < (int)temp.size(); i++) { const auto &object = grid[temp[i]]; if(object.occluder_id == -1) continue; const OccluderMap::Occluder &occluder = m_map[object.occluder_id]; int order = drawingOrder(object.bbox, bbox); if(order == 1) overlaps[object.occluder_id] = order; } for(int n = 0; n < (int)m_states.size(); n++) { bool is_overlapping = false; const OccluderMap::Occluder &occluder = m_map[n]; if(overlaps[n] == 1) { FBox bbox_around(bbox.min - float3(16, 0, 16), bbox.max + float3(16, 0, 16)); bbox_around.min.y = 0; bbox_around.max.y = Grid::max_height; temp2.clear(); grid.findAll(temp2, bbox_around); FBox local_box = FBox(); for(int i = 0; i < (int)temp2.size(); i++) { const auto &object = grid[temp2[i]]; if(object.occluder_id == n) local_box = local_box.empty()? object.bbox : sum(local_box, object.bbox); } is_overlapping = local_box.min.y > mid_point.y; } if(is_overlapping != m_states[n].is_overlapping) { m_states[n].is_overlapping = is_overlapping; vis_changed = true; } } if(!vis_changed) return false; for(int n= 0; n < (int)m_states.size(); n++) m_states[n].is_visible = !m_states[n].is_overlapping; //TODO: isUnder can be precomputed for(int n = 0; n < (int)m_states.size(); n++) { if(!m_states[n].is_visible) continue; for(int i = 0; i < (int)m_states.size(); i++) if(!m_states[i].is_visible && m_map.isUnder(i, n)) { m_states[n].is_visible = false; break; } } return true; }
void GroupEditor::drawContents(Renderer2D &out) const { int2 offset = innerOffset(); for(int n = 0; n < m_tile_group->entryCount(); n++) m_tile_group->entryTile(n)->m_temp = n; IRect clip_rect(int2(0, 0), clippedRect().size()); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; entry.is_selected = m_mode == mAddRemove? m_tile_group->isValidEntryId(entry.tile->m_temp, entry.tile) : entry.group_id == m_selected_group_id; IRect tile_rect = entry.tile->rect(); int2 pos = entry.pos - tile_rect.min - offset; if(areOverlapping(clip_rect, tile_rect + pos)) entry.tile->draw(out, pos); } DTexture::unbind(); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; if(!entry.is_selected) continue; Color col = m_tile_group->isEntryDirty(entry.tile->m_temp)? ColorId::red : ColorId::white; int2 pos = entry.pos - offset; out.addRect(IRect(pos, pos + entry.size), col); } if(m_mode == mModify && m_selected_group_id != -1) { IRect edit_rect(clippedRect().max - int2(280, 250), clippedRect().max - int2(5, 0)); int2 center = edit_rect.center(); out.setViewPos(-center); int2 half_size = edit_rect.size() / 2; out.addFilledRect(IRect(-half_size, half_size), FColor(0.3f, 0.3f, 0.3f)); drawBBox(out, IBox({-9, 0, -9}, {9, 1, 9}), ColorId::white); auto font = res::getFont(WindowStyle::fonts[0]); for(int n = 0; n < TileGroup::Group::side_count; n++) { out.setViewPos(-center - worldToScreen(TileGroup::Group::s_side_offsets[n] * 9)); font->draw(out, float2(0, 0), {ColorId::white}, format("%d", m_tile_group->groupSurface(m_selected_group_id, n))); } out.setViewPos(-center +edit_rect.size() / 2); font->draw(out, float2(0, 0), {ColorId::white}, format("setting surface: %d", m_selected_surface_id)); /* const char *names[] = { "", "snow", "gravel", "dirt", "grass", "mud", "mud_cracked", "sand", "green goo", }; out.setViewPos(-int2(bottom_rect.max.x - 200, bottom_rect.min.y)); for(int n = 0; n < arraySize(names); n++) font->draw(int2(0, 10), ColorId::white, m_selected_surface_id == n? "%d: [%s]\n" : "%d: %s\n", n, names[n]); */ out.setViewPos(-clippedRect().min); } if(m_current_entry) m_font->draw(out, float2(5, height() - 20), {ColorId::white, ColorId::black}, format("%s", m_current_entry->tile->resourceName().c_str())); }
const IRect Entity::screenRect() const { return m_sprite.getMaxRect() + (int2)worldToScreen(pos()); }
Vector3 Camera::worldToScreen(const Vector3& pWorld, const Vector3& pLens) const { return worldToScreen(pWorld); }