void HsvFeatures::UpdateFeatureVector(const Sample &s) { IntRect rect = s.GetROI(); cv::Rect roi(rect.XMin(), rect.YMin(), rect.Width(), rect.Height()); m_featVec.setZero(); cv::Mat hsv_img = s.GetImage().GetHsvImage()(roi); int height = rect.Height(); int width = rect.Width(); // continuous? if(hsv_img.isContinuous()) { width *= height; height = 1; } int ix, iy; uchar *p; for(iy=0; iy < height; ++iy) { p = hsv_img.ptr<uchar>(iy); for(ix=0; ix < width; ++ix) { cv::Vec3b pixel(p[3*ix+0], p[3*ix+1], p[3*ix+2]); auto bin_idx = compBinIdx(pixel); m_featVec[bin_idx]++; } } m_featVec /= rect.Area(); }
void D3D9Blit(const IntRect& dstRect, unsigned char* src, unsigned srcStride, bool discard = false) { RECT d3dRect; d3dRect.left = dstRect.left_; d3dRect.top = dstRect.top_; d3dRect.right = dstRect.right_; d3dRect.bottom = dstRect.bottom_; int level = 0; DWORD flags = discard ? D3DLOCK_DISCARD : 0; D3DLOCKED_RECT d3dLockedRect; IDirect3DTexture9* object = (IDirect3DTexture9*) webTexture2D_->GetTexture2D()->GetGPUObject(); if (FAILED(object->LockRect(level, &d3dLockedRect, (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags))) { LOGERROR("WebTexture2D - Could not lock texture"); return; } int width = dstRect.Width(); int height = dstRect.Height(); for (int j = 0; j < height; ++j) { unsigned char* dst = (unsigned char*) d3dLockedRect.pBits + j * d3dLockedRect.Pitch; memcpy(dst, src, width * 4); src += srcStride; } object->UnlockRect(level); }
BRegion& View::_ScreenClipping(BRegion* windowContentClipping, bool force) const { if (!fScreenClippingValid || force) { fScreenClipping = fLocalClipping; ConvertToScreen(&fScreenClipping); // see if parts of our bounds are hidden underneath // the parent, the local clipping does not account for this IntRect clippedBounds = Bounds(); ConvertToVisibleInTopView(&clippedBounds); if (clippedBounds.Width() < fScreenClipping.Frame().Width() || clippedBounds.Height() < fScreenClipping.Frame().Height()) { BRegion* temp = fWindow->GetRegion(); if (temp) { temp->Set((clipping_rect)clippedBounds); fScreenClipping.IntersectWith(temp); fWindow->RecycleRegion(temp); } } fScreenClipping.IntersectWith(windowContentClipping); fScreenClippingValid = true; } return fScreenClipping; }
Ray SceneView3D::GetCameraRay() { Ray camRay; Input* input = GetSubsystem<Input>(); IntVector2 cpos = input->GetMousePosition(); IntRect rect = GetRect(); if (!rect.Width() || !rect.Height()) return camRay; int x = rect.left_; int y = rect.top_; GetInternalWidget()->ConvertToRoot(x, y); return camera_->GetScreenRay(float(cpos.x_ - x) / rect.Width(), float(cpos.y_ - y) / rect.Height()); }
IntRect PreviewTab::UpdateViewRect() { IntRect tabRect = BaseClassName::UpdateViewRect(); if (viewRect_ != tabRect) { viewRect_ = tabRect; view_->SetSize(tabRect.Width(), tabRect.Height(), Graphics::GetRGBFormat(), TEXTURE_RENDERTARGET); view_->GetRenderSurface()->SetUpdateMode(SURFACE_UPDATEALWAYS); static_cast<RootUIElement*>(GetUI()->GetRoot())->SetOffset(tabRect.Min()); UpdateViewports(); } return tabRect; }
bool SpriteSheet2D::EndLoadFromPListFile() { ResourceCache* cache = GetSubsystem<ResourceCache>(); texture_ = cache->GetResource<Texture2D>(loadTextureName_); if (!texture_) { LOGERROR("Could not load texture " + loadTextureName_); loadXMLFile_.Reset(); loadTextureName_.Clear(); return false; } const PListValueMap& root = loadPListFile_->GetRoot(); const PListValueMap& frames = root["frames"].GetValueMap(); for (PListValueMap::ConstIterator i = frames.Begin(); i != frames.End(); ++i) { String name = i->first_.Split('.')[0]; const PListValueMap& frameInfo = i->second_.GetValueMap(); if (frameInfo["rotated"].GetBool()) { LOGWARNING("Rotated sprite is not support now"); continue; } IntRect rectangle = frameInfo["frame"].GetIntRect(); Vector2 hotSpot(0.5f, 0.5f); IntVector2 offset(0, 0); IntRect sourceColorRect = frameInfo["sourceColorRect"].GetIntRect(); if (sourceColorRect.left_ != 0 && sourceColorRect.top_ != 0) { offset.x_ = -sourceColorRect.left_; offset.y_ = -sourceColorRect.top_; IntVector2 sourceSize = frameInfo["sourceSize"].GetIntVector2(); hotSpot.x_ = ((float)offset.x_ + sourceSize.x_ / 2) / rectangle.Width(); hotSpot.y_ = 1.0f - ((float)offset.y_ + sourceSize.y_/ 2) / rectangle.Height(); } DefineSprite(name, rectangle, hotSpot, offset); } loadXMLFile_.Reset(); loadTextureName_.Clear(); return true; }
void RawFeatures::UpdateFeatureVector(const Sample& s) { IntRect rect = s.GetROI(); // note this truncates to integers cv::Rect roi(rect.XMin(), rect.YMin(), rect.Width(), rect.Height()); cv::resize(s.GetImage().GetImage(0)(roi), m_patchImage, m_patchImage.size()); //equalizeHist(m_patchImage, m_patchImage); int ind = 0; for (int i = 0; i < kPatchSize; ++i) { uchar* pixel = m_patchImage.ptr(i); for (int j = 0; j < kPatchSize; ++j, ++pixel, ++ind) { m_featVec[ind] = ((double)*pixel)/255; } } }
void IntRect::Merge(const IntRect& rect) { if (Width() <= 0 || Height() <= 0) { *this = rect; } else if (rect.Width() > 0 && rect.Height() > 0) { if (rect.left_ < left_) left_ = rect.left_; if (rect.top_ < top_) top_ = rect.top_; if (rect.right_ > right_) right_ = rect.right_; if (rect.bottom_ > bottom_) bottom_ = rect.bottom_; } }
void LaRank::Update(const MultiSample& sample, int y) { // add new support pattern SupportPattern* sp = new SupportPattern; const vector<FloatRect>& rects = sample.GetRects(); FloatRect centre = rects[y]; for (int i = 0; i < (int)rects.size(); ++i) { // express r in coord frame of centre sample FloatRect r = rects[i]; r.Translate(-centre.XMin(), -centre.YMin()); sp->yv.push_back(r); if (!m_config.quietMode && m_config.debugMode) { // store a thumbnail for each sample Mat im(kTileSize, kTileSize, CV_8UC1); IntRect rect = rects[i]; cv::Rect roi(rect.XMin(), rect.YMin(), rect.Width(), rect.Height()); cv::resize(sample.GetImage().GetImage(0)(roi), im, im.size()); sp->images.push_back(im); } } // evaluate features for each sample sp->x.resize(rects.size()); const_cast<Features&>(m_features).Eval(sample, sp->x); sp->y = y; sp->refCount = 0; m_sps.push_back(sp); ProcessNew((int)m_sps.size()-1); BudgetMaintenance(); for (int i = 0; i < 10; ++i) { Reprocess(); BudgetMaintenance(); } }
void View::ParentResized(int32 x, int32 y, BRegion* dirtyRegion) { IntRect newFrame = fFrame; resize_frame(newFrame, fResizeMode & 0x0000ffff, x, y); if (newFrame != fFrame) { // careful, MoveBy will change fFrame int32 widthDiff = (int32)(newFrame.Width() - fFrame.Width()); int32 heightDiff = (int32)(newFrame.Height() - fFrame.Height()); MoveBy(newFrame.left - fFrame.left, newFrame.top - fFrame.top, dirtyRegion); ResizeBy(widthDiff, heightDiff, dirtyRegion); } else { // TODO: this covers the fact that our screen clipping might change // when the parent changes its size, even though our frame stays // the same - there might be a way to test for this, but axeld doesn't // know, stippi should look into this when he's back :) InvalidateScreenClipping(); } }
void Batch::Prepare(View* view, bool setModelTransform) const { if (!vertexShader_ || !pixelShader_) return; Graphics* graphics = view->GetGraphics(); Renderer* renderer = view->GetRenderer(); Node* cameraNode = camera_ ? camera_->GetNode() : 0; Light* light = lightQueue_ ? lightQueue_->light_ : 0; Texture2D* shadowMap = lightQueue_ ? lightQueue_->shadowMap_ : 0; // Set pass / material-specific renderstates if (pass_ && material_) { bool isShadowPass = pass_->GetType() == PASS_SHADOW; BlendMode blend = pass_->GetBlendMode(); // Turn additive blending into subtract if the light is negative if (light && light->IsNegative()) { if (blend == BLEND_ADD) blend = BLEND_SUBTRACT; else if (blend == BLEND_ADDALPHA) blend = BLEND_SUBTRACTALPHA; } graphics->SetBlendMode(blend); renderer->SetCullMode(isShadowPass ? material_->GetShadowCullMode() : material_->GetCullMode(), camera_); if (!isShadowPass) { const BiasParameters& depthBias = material_->GetDepthBias(); graphics->SetDepthBias(depthBias.constantBias_, depthBias.slopeScaledBias_); } graphics->SetDepthTest(pass_->GetDepthTestMode()); graphics->SetDepthWrite(pass_->GetDepthWrite()); } // Set shaders first. The available shader parameters and their register/uniform positions depend on the currently set shaders graphics->SetShaders(vertexShader_, pixelShader_); // Set global (per-frame) shader parameters if (graphics->NeedParameterUpdate(SP_FRAME, (void*)0)) view->SetGlobalShaderParameters(); // Set camera shader parameters unsigned cameraHash = overrideView_ ? (unsigned)(size_t)camera_ + 4 : (unsigned)(size_t)camera_; if (graphics->NeedParameterUpdate(SP_CAMERA, reinterpret_cast<void*>(cameraHash))) view->SetCameraShaderParameters(camera_, true, overrideView_); // Set viewport shader parameters IntVector2 rtSize = graphics->GetRenderTargetDimensions(); IntRect viewport = graphics->GetViewport(); unsigned viewportHash = (viewport.left_) | (viewport.top_ << 8) | (viewport.right_ << 16) | (viewport.bottom_ << 24); if (graphics->NeedParameterUpdate(SP_VIEWPORT, reinterpret_cast<void*>(viewportHash))) { float rtWidth = (float)rtSize.x_; float rtHeight = (float)rtSize.y_; float widthRange = 0.5f * viewport.Width() / rtWidth; float heightRange = 0.5f * viewport.Height() / rtHeight; #ifdef URHO3D_OPENGL Vector4 bufferUVOffset(((float)viewport.left_) / rtWidth + widthRange, 1.0f - (((float)viewport.top_) / rtHeight + heightRange), widthRange, heightRange); #else Vector4 bufferUVOffset((0.5f + (float)viewport.left_) / rtWidth + widthRange, (0.5f + (float)viewport.top_) / rtHeight + heightRange, widthRange, heightRange); #endif graphics->SetShaderParameter(VSP_GBUFFEROFFSETS, bufferUVOffset); float sizeX = 1.0f / rtWidth; float sizeY = 1.0f / rtHeight; graphics->SetShaderParameter(PSP_GBUFFERINVSIZE, Vector4(sizeX, sizeY, 0.0f, 0.0f)); } // Set model or skinning transforms if (setModelTransform && graphics->NeedParameterUpdate(SP_OBJECTTRANSFORM, worldTransform_)) { if (geometryType_ == GEOM_SKINNED) { graphics->SetShaderParameter(VSP_SKINMATRICES, reinterpret_cast<const float*>(worldTransform_), 12 * numWorldTransforms_); } else graphics->SetShaderParameter(VSP_MODEL, *worldTransform_); // Set the orientation for billboards, either from the object itself or from the camera if (geometryType_ == GEOM_BILLBOARD) { if (numWorldTransforms_ > 1) graphics->SetShaderParameter(VSP_BILLBOARDROT, worldTransform_[1].RotationMatrix()); else graphics->SetShaderParameter(VSP_BILLBOARDROT, cameraNode->GetWorldRotation().RotationMatrix()); } } // Set zone-related shader parameters BlendMode blend = graphics->GetBlendMode(); // If the pass is additive, override fog color to black so that shaders do not need a separate additive path bool overrideFogColorToBlack = blend == BLEND_ADD || blend == BLEND_ADDALPHA; unsigned zoneHash = (unsigned)(size_t)zone_; if (overrideFogColorToBlack) zoneHash += 0x80000000; if (zone_ && graphics->NeedParameterUpdate(SP_ZONE, reinterpret_cast<void*>(zoneHash))) { graphics->SetShaderParameter(VSP_AMBIENTSTARTCOLOR, zone_->GetAmbientStartColor()); graphics->SetShaderParameter(VSP_AMBIENTENDCOLOR, zone_->GetAmbientEndColor().ToVector4() - zone_->GetAmbientStartColor().ToVector4()); const BoundingBox& box = zone_->GetBoundingBox(); Vector3 boxSize = box.Size(); Matrix3x4 adjust(Matrix3x4::IDENTITY); adjust.SetScale(Vector3(1.0f / boxSize.x_, 1.0f / boxSize.y_, 1.0f / boxSize.z_)); adjust.SetTranslation(Vector3(0.5f, 0.5f, 0.5f)); Matrix3x4 zoneTransform = adjust * zone_->GetInverseWorldTransform(); graphics->SetShaderParameter(VSP_ZONE, zoneTransform); graphics->SetShaderParameter(PSP_AMBIENTCOLOR, zone_->GetAmbientColor()); graphics->SetShaderParameter(PSP_FOGCOLOR, overrideFogColorToBlack ? Color::BLACK : zone_->GetFogColor()); float farClip = camera_->GetFarClip(); float fogStart = Min(zone_->GetFogStart(), farClip); float fogEnd = Min(zone_->GetFogEnd(), farClip); if (fogStart >= fogEnd * (1.0f - M_LARGE_EPSILON)) fogStart = fogEnd * (1.0f - M_LARGE_EPSILON); float fogRange = Max(fogEnd - fogStart, M_EPSILON); Vector4 fogParams(fogEnd / farClip, farClip / fogRange, 0.0f, 0.0f); Node* zoneNode = zone_->GetNode(); if (zone_->GetHeightFog() && zoneNode) { Vector3 worldFogHeightVec = zoneNode->GetWorldTransform() * Vector3(0.0f, zone_->GetFogHeight(), 0.0f); fogParams.z_ = worldFogHeightVec.y_; fogParams.w_ = zone_->GetFogHeightScale() / Max(zoneNode->GetWorldScale().y_, M_EPSILON); } graphics->SetShaderParameter(PSP_FOGPARAMS, fogParams); } // Set light-related shader parameters if (lightQueue_) { if (graphics->NeedParameterUpdate(SP_VERTEXLIGHTS, lightQueue_) && graphics->HasShaderParameter(VS, VSP_VERTEXLIGHTS)) { Vector4 vertexLights[MAX_VERTEX_LIGHTS * 3]; const PODVector<Light*>& lights = lightQueue_->vertexLights_; for (unsigned i = 0; i < lights.Size(); ++i) { Light* vertexLight = lights[i]; Node* vertexLightNode = vertexLight->GetNode(); LightType type = vertexLight->GetLightType(); // Attenuation float invRange, cutoff, invCutoff; if (type == LIGHT_DIRECTIONAL) invRange = 0.0f; else invRange = 1.0f / Max(vertexLight->GetRange(), M_EPSILON); if (type == LIGHT_SPOT) { cutoff = Cos(vertexLight->GetFov() * 0.5f); invCutoff = 1.0f / (1.0f - cutoff); } else { cutoff = -1.0f; invCutoff = 1.0f; } // Color float fade = 1.0f; float fadeEnd = vertexLight->GetDrawDistance(); float fadeStart = vertexLight->GetFadeDistance(); // Do fade calculation for light if both fade & draw distance defined if (vertexLight->GetLightType() != LIGHT_DIRECTIONAL && fadeEnd > 0.0f && fadeStart > 0.0f && fadeStart < fadeEnd) fade = Min(1.0f - (vertexLight->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 1.0f); Color color = vertexLight->GetEffectiveColor() * fade; vertexLights[i * 3] = Vector4(color.r_, color.g_, color.b_, invRange); // Direction vertexLights[i * 3 + 1] = Vector4(-(vertexLightNode->GetWorldDirection()), cutoff); // Position vertexLights[i * 3 + 2] = Vector4(vertexLightNode->GetWorldPosition(), invCutoff); } if (lights.Size()) graphics->SetShaderParameter(VSP_VERTEXLIGHTS, vertexLights[0].Data(), lights.Size() * 3 * 4); } } if (light && graphics->NeedParameterUpdate(SP_LIGHT, light)) { // Deferred light volume batches operate in a camera-centered space. Detect from material, zone & pass all being null bool isLightVolume = !material_ && !pass_ && !zone_; Matrix3x4 cameraEffectiveTransform = camera_->GetEffectiveWorldTransform(); Vector3 cameraEffectivePos = cameraEffectiveTransform.Translation(); Node* lightNode = light->GetNode(); Matrix3 lightWorldRotation = lightNode->GetWorldRotation().RotationMatrix(); graphics->SetShaderParameter(VSP_LIGHTDIR, lightWorldRotation * Vector3::BACK); float atten = 1.0f / Max(light->GetRange(), M_EPSILON); graphics->SetShaderParameter(VSP_LIGHTPOS, Vector4(lightNode->GetWorldPosition(), atten)); if (graphics->HasShaderParameter(VS, VSP_LIGHTMATRICES)) { switch (light->GetLightType()) { case LIGHT_DIRECTIONAL: { Matrix4 shadowMatrices[MAX_CASCADE_SPLITS]; unsigned numSplits = lightQueue_->shadowSplits_.Size(); for (unsigned i = 0; i < numSplits; ++i) CalculateShadowMatrix(shadowMatrices[i], lightQueue_, i, renderer, Vector3::ZERO); graphics->SetShaderParameter(VSP_LIGHTMATRICES, shadowMatrices[0].Data(), 16 * numSplits); } break; case LIGHT_SPOT: { Matrix4 shadowMatrices[2]; CalculateSpotMatrix(shadowMatrices[0], light, Vector3::ZERO); bool isShadowed = shadowMap && graphics->HasTextureUnit(TU_SHADOWMAP); if (isShadowed) CalculateShadowMatrix(shadowMatrices[1], lightQueue_, 0, renderer, Vector3::ZERO); graphics->SetShaderParameter(VSP_LIGHTMATRICES, shadowMatrices[0].Data(), isShadowed ? 32 : 16); } break; case LIGHT_POINT: { Matrix4 lightVecRot(lightNode->GetWorldRotation().RotationMatrix()); // HLSL compiler will pack the parameters as if the matrix is only 3x4, so must be careful to not overwrite // the next parameter #ifdef URHO3D_OPENGL graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 16); #else graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 12); #endif } break; } } float fade = 1.0f; float fadeEnd = light->GetDrawDistance(); float fadeStart = light->GetFadeDistance(); // Do fade calculation for light if both fade & draw distance defined if (light->GetLightType() != LIGHT_DIRECTIONAL && fadeEnd > 0.0f && fadeStart > 0.0f && fadeStart < fadeEnd) fade = Min(1.0f - (light->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 1.0f); // Negative lights will use subtract blending, so write absolute RGB values to the shader parameter graphics->SetShaderParameter(PSP_LIGHTCOLOR, Color(light->GetEffectiveColor().Abs(), light->GetEffectiveSpecularIntensity()) * fade); graphics->SetShaderParameter(PSP_LIGHTDIR, lightWorldRotation * Vector3::BACK); graphics->SetShaderParameter(PSP_LIGHTPOS, Vector4((isLightVolume ? (lightNode->GetWorldPosition() - cameraEffectivePos) : lightNode->GetWorldPosition()), atten)); if (graphics->HasShaderParameter(PS, PSP_LIGHTMATRICES)) { switch (light->GetLightType()) { case LIGHT_DIRECTIONAL: { Matrix4 shadowMatrices[MAX_CASCADE_SPLITS]; unsigned numSplits = lightQueue_->shadowSplits_.Size(); for (unsigned i = 0; i < numSplits; ++i) { CalculateShadowMatrix(shadowMatrices[i], lightQueue_, i, renderer, isLightVolume ? cameraEffectivePos : Vector3::ZERO); } graphics->SetShaderParameter(PSP_LIGHTMATRICES, shadowMatrices[0].Data(), 16 * numSplits); } break; case LIGHT_SPOT: { Matrix4 shadowMatrices[2]; CalculateSpotMatrix(shadowMatrices[0], light, cameraEffectivePos); bool isShadowed = lightQueue_->shadowMap_ != 0; if (isShadowed) { CalculateShadowMatrix(shadowMatrices[1], lightQueue_, 0, renderer, isLightVolume ? cameraEffectivePos : Vector3::ZERO); } graphics->SetShaderParameter(PSP_LIGHTMATRICES, shadowMatrices[0].Data(), isShadowed ? 32 : 16); } break; case LIGHT_POINT: { Matrix4 lightVecRot(lightNode->GetWorldRotation().RotationMatrix()); // HLSL compiler will pack the parameters as if the matrix is only 3x4, so must be careful to not overwrite // the next parameter #ifdef URHO3D_OPENGL graphics->SetShaderParameter(PSP_LIGHTMATRICES, lightVecRot.Data(), 16); #else graphics->SetShaderParameter(PSP_LIGHTMATRICES, lightVecRot.Data(), 12); #endif } break; } } // Set shadow mapping shader parameters if (shadowMap) { { // Calculate point light shadow sampling offsets (unrolled cube map) unsigned faceWidth = shadowMap->GetWidth() / 2; unsigned faceHeight = shadowMap->GetHeight() / 3; float width = (float)shadowMap->GetWidth(); float height = (float)shadowMap->GetHeight(); #ifdef URHO3D_OPENGL float mulX = (float)(faceWidth - 3) / width; float mulY = (float)(faceHeight - 3) / height; float addX = 1.5f / width; float addY = 1.5f / height; #else float mulX = (float)(faceWidth - 4) / width; float mulY = (float)(faceHeight - 4) / height; float addX = 2.5f / width; float addY = 2.5f / height; #endif // If using 4 shadow samples, offset the position diagonally by half pixel if (renderer->GetShadowQuality() & SHADOWQUALITY_HIGH_16BIT) { addX -= 0.5f / width; addY -= 0.5f / height; } graphics->SetShaderParameter(PSP_SHADOWCUBEADJUST, Vector4(mulX, mulY, addX, addY)); } { // Calculate shadow camera depth parameters for point light shadows and shadow fade parameters for // directional light shadows, stored in the same uniform Camera* shadowCamera = lightQueue_->shadowSplits_[0].shadowCamera_; float nearClip = shadowCamera->GetNearClip(); float farClip = shadowCamera->GetFarClip(); float q = farClip / (farClip - nearClip); float r = -q * nearClip; const CascadeParameters& parameters = light->GetShadowCascade(); float viewFarClip = camera_->GetFarClip(); float shadowRange = parameters.GetShadowRange(); float fadeStart = parameters.fadeStart_ * shadowRange / viewFarClip; float fadeEnd = shadowRange / viewFarClip; float fadeRange = fadeEnd - fadeStart; graphics->SetShaderParameter(PSP_SHADOWDEPTHFADE, Vector4(q, r, fadeStart, 1.0f / fadeRange)); } { float intensity = light->GetShadowIntensity(); float fadeStart = light->GetShadowFadeDistance(); float fadeEnd = light->GetShadowDistance(); if (fadeStart > 0.0f && fadeEnd > 0.0f && fadeEnd > fadeStart) intensity = Lerp(intensity, 1.0f, Clamp((light->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 0.0f, 1.0f)); float pcfValues = (1.0f - intensity); float samples = renderer->GetShadowQuality() >= SHADOWQUALITY_HIGH_16BIT ? 4.0f : 1.0f; graphics->SetShaderParameter(PSP_SHADOWINTENSITY, Vector4(pcfValues / samples, intensity, 0.0f, 0.0f)); } float sizeX = 1.0f / (float)shadowMap->GetWidth(); float sizeY = 1.0f / (float)shadowMap->GetHeight(); graphics->SetShaderParameter(PSP_SHADOWMAPINVSIZE, Vector4(sizeX, sizeY, 0.0f, 0.0f)); Vector4 lightSplits(M_LARGE_VALUE, M_LARGE_VALUE, M_LARGE_VALUE, M_LARGE_VALUE); if (lightQueue_->shadowSplits_.Size() > 1) lightSplits.x_ = lightQueue_->shadowSplits_[0].farSplit_ / camera_->GetFarClip(); if (lightQueue_->shadowSplits_.Size() > 2) lightSplits.y_ = lightQueue_->shadowSplits_[1].farSplit_ / camera_->GetFarClip(); if (lightQueue_->shadowSplits_.Size() > 3) lightSplits.z_ = lightQueue_->shadowSplits_[2].farSplit_ / camera_->GetFarClip(); graphics->SetShaderParameter(PSP_SHADOWSPLITS, lightSplits); } } // Set material-specific shader parameters and textures if (material_) { if (graphics->NeedParameterUpdate(SP_MATERIAL, material_)) { // Update shader parameter animations material_->UpdateShaderParameterAnimations(); const HashMap<StringHash, MaterialShaderParameter>& parameters = material_->GetShaderParameters(); for (HashMap<StringHash, MaterialShaderParameter>::ConstIterator i = parameters.Begin(); i != parameters.End(); ++i) graphics->SetShaderParameter(i->first_, i->second_.value_); } const SharedPtr<Texture>* textures = material_->GetTextures(); for (unsigned i = 0; i < MAX_MATERIAL_TEXTURE_UNITS; ++i) { TextureUnit unit = (TextureUnit)i; if (textures[i] && graphics->HasTextureUnit(unit)) graphics->SetTexture(i, textures[i]); } } // Set light-related textures if (light) { if (shadowMap && graphics->HasTextureUnit(TU_SHADOWMAP)) graphics->SetTexture(TU_SHADOWMAP, shadowMap); if (graphics->HasTextureUnit(TU_LIGHTRAMP)) { Texture* rampTexture = light->GetRampTexture(); if (!rampTexture) rampTexture = renderer->GetDefaultLightRamp(); graphics->SetTexture(TU_LIGHTRAMP, rampTexture); } if (graphics->HasTextureUnit(TU_LIGHTSHAPE)) { Texture* shapeTexture = light->GetShapeTexture(); if (!shapeTexture && light->GetLightType() == LIGHT_SPOT) shapeTexture = renderer->GetDefaultLightSpot(); graphics->SetTexture(TU_LIGHTSHAPE, shapeTexture); } } }
void Gizmo::SetScreenRect(const IntRect& rect) { displayPos_ = ToImGui(rect.Min()); displaySize_.x = rect.Width(); displaySize_.y = rect.Height(); }
bool PreviewTab::RenderWindowContent() { if (GetSubsystem<SceneManager>()->GetActiveScene() == nullptr) return true; IntRect rect = UpdateViewRect(); ui::Image(view_.Get(), ImVec2{static_cast<float>(rect.Width()), static_cast<float>(rect.Height())}); if (!inputGrabbed_ && simulationStatus_ == SCENE_SIMULATION_RUNNING && ui::IsItemHovered() && ui::IsAnyMouseDown() && GetInput()->IsMouseVisible()) GrabInput(); return true; }
void Batch::Prepare(View* view, Camera* camera, bool setModelTransform, bool allowDepthWrite) const { if (!vertexShader_ || !pixelShader_) return; Graphics* graphics = view->GetGraphics(); Renderer* renderer = view->GetRenderer(); Node* cameraNode = camera ? camera->GetNode() : 0; Light* light = lightQueue_ ? lightQueue_->light_ : 0; Texture2D* shadowMap = lightQueue_ ? lightQueue_->shadowMap_ : 0; // Set shaders first. The available shader parameters and their register/uniform positions depend on the currently set shaders graphics->SetShaders(vertexShader_, pixelShader_); // Set pass / material-specific renderstates if (pass_ && material_) { BlendMode blend = pass_->GetBlendMode(); // Turn additive blending into subtract if the light is negative if (light && light->IsNegative()) { if (blend == BLEND_ADD) blend = BLEND_SUBTRACT; else if (blend == BLEND_ADDALPHA) blend = BLEND_SUBTRACTALPHA; } graphics->SetBlendMode(blend); bool isShadowPass = pass_->GetIndex() == Technique::shadowPassIndex; CullMode effectiveCullMode = pass_->GetCullMode(); // Get cull mode from material if pass doesn't override it if (effectiveCullMode == MAX_CULLMODES) effectiveCullMode = isShadowPass ? material_->GetShadowCullMode() : material_->GetCullMode(); renderer->SetCullMode(effectiveCullMode, camera); if (!isShadowPass) { const BiasParameters& depthBias = material_->GetDepthBias(); graphics->SetDepthBias(depthBias.constantBias_, depthBias.slopeScaledBias_); } // Use the "least filled" fill mode combined from camera & material graphics->SetFillMode((FillMode)(Max(camera->GetFillMode(), material_->GetFillMode()))); graphics->SetDepthTest(pass_->GetDepthTestMode()); graphics->SetDepthWrite(pass_->GetDepthWrite() && allowDepthWrite); } // Set global (per-frame) shader parameters if (graphics->NeedParameterUpdate(SP_FRAME, (void*)0)) view->SetGlobalShaderParameters(); // Set camera & viewport shader parameters unsigned cameraHash = (unsigned)(size_t)camera; IntRect viewport = graphics->GetViewport(); IntVector2 viewSize = IntVector2(viewport.Width(), viewport.Height()); unsigned viewportHash = (unsigned)(viewSize.x_ | (viewSize.y_ << 16)); if (graphics->NeedParameterUpdate(SP_CAMERA, reinterpret_cast<const void*>(cameraHash + viewportHash))) { view->SetCameraShaderParameters(camera); // During renderpath commands the G-Buffer or viewport texture is assumed to always be viewport-sized view->SetGBufferShaderParameters(viewSize, IntRect(0, 0, viewSize.x_, viewSize.y_)); } // Set model or skinning transforms if (setModelTransform && graphics->NeedParameterUpdate(SP_OBJECT, worldTransform_)) { if (geometryType_ == GEOM_SKINNED) { graphics->SetShaderParameter(VSP_SKINMATRICES, reinterpret_cast<const float*>(worldTransform_), 12 * numWorldTransforms_); } else graphics->SetShaderParameter(VSP_MODEL, *worldTransform_); // Set the orientation for billboards, either from the object itself or from the camera if (geometryType_ == GEOM_BILLBOARD) { if (numWorldTransforms_ > 1) graphics->SetShaderParameter(VSP_BILLBOARDROT, worldTransform_[1].RotationMatrix()); else graphics->SetShaderParameter(VSP_BILLBOARDROT, cameraNode->GetWorldRotation().RotationMatrix()); } } // Set zone-related shader parameters BlendMode blend = graphics->GetBlendMode(); // If the pass is additive, override fog color to black so that shaders do not need a separate additive path bool overrideFogColorToBlack = blend == BLEND_ADD || blend == BLEND_ADDALPHA; unsigned zoneHash = (unsigned)(size_t)zone_; if (overrideFogColorToBlack) zoneHash += 0x80000000; if (zone_ && graphics->NeedParameterUpdate(SP_ZONE, reinterpret_cast<const void*>(zoneHash))) { graphics->SetShaderParameter(VSP_AMBIENTSTARTCOLOR, zone_->GetAmbientStartColor()); graphics->SetShaderParameter(VSP_AMBIENTENDCOLOR, zone_->GetAmbientEndColor().ToVector4() - zone_->GetAmbientStartColor().ToVector4()); const BoundingBox& box = zone_->GetBoundingBox(); Vector3 boxSize = box.Size(); Matrix3x4 adjust(Matrix3x4::IDENTITY); adjust.SetScale(Vector3(1.0f / boxSize.x_, 1.0f / boxSize.y_, 1.0f / boxSize.z_)); adjust.SetTranslation(Vector3(0.5f, 0.5f, 0.5f)); Matrix3x4 zoneTransform = adjust * zone_->GetInverseWorldTransform(); graphics->SetShaderParameter(VSP_ZONE, zoneTransform); graphics->SetShaderParameter(PSP_AMBIENTCOLOR, zone_->GetAmbientColor()); graphics->SetShaderParameter(PSP_FOGCOLOR, overrideFogColorToBlack ? Color::BLACK : zone_->GetFogColor()); float farClip = camera->GetFarClip(); float fogStart = Min(zone_->GetFogStart(), farClip); float fogEnd = Min(zone_->GetFogEnd(), farClip); if (fogStart >= fogEnd * (1.0f - M_LARGE_EPSILON)) fogStart = fogEnd * (1.0f - M_LARGE_EPSILON); float fogRange = Max(fogEnd - fogStart, M_EPSILON); Vector4 fogParams(fogEnd / farClip, farClip / fogRange, 0.0f, 0.0f); Node* zoneNode = zone_->GetNode(); if (zone_->GetHeightFog() && zoneNode) { Vector3 worldFogHeightVec = zoneNode->GetWorldTransform() * Vector3(0.0f, zone_->GetFogHeight(), 0.0f); fogParams.z_ = worldFogHeightVec.y_; fogParams.w_ = zone_->GetFogHeightScale() / Max(zoneNode->GetWorldScale().y_, M_EPSILON); } graphics->SetShaderParameter(PSP_FOGPARAMS, fogParams); } // Set light-related shader parameters if (lightQueue_) { if (light && graphics->NeedParameterUpdate(SP_LIGHT, lightQueue_)) { Node* lightNode = light->GetNode(); float atten = 1.0f / Max(light->GetRange(), M_EPSILON); Vector3 lightDir(lightNode->GetWorldRotation() * Vector3::BACK); Vector4 lightPos(lightNode->GetWorldPosition(), atten); graphics->SetShaderParameter(VSP_LIGHTDIR, lightDir); graphics->SetShaderParameter(VSP_LIGHTPOS, lightPos); if (graphics->HasShaderParameter(VSP_LIGHTMATRICES)) { switch (light->GetLightType()) { case LIGHT_DIRECTIONAL: { Matrix4 shadowMatrices[MAX_CASCADE_SPLITS]; unsigned numSplits = Min(MAX_CASCADE_SPLITS, lightQueue_->shadowSplits_.Size()); for (unsigned i = 0; i < numSplits; ++i) CalculateShadowMatrix(shadowMatrices[i], lightQueue_, i, renderer); graphics->SetShaderParameter(VSP_LIGHTMATRICES, shadowMatrices[0].Data(), 16 * numSplits); } break; case LIGHT_SPOT: { Matrix4 shadowMatrices[2]; CalculateSpotMatrix(shadowMatrices[0], light); bool isShadowed = shadowMap && graphics->HasTextureUnit(TU_SHADOWMAP); if (isShadowed) CalculateShadowMatrix(shadowMatrices[1], lightQueue_, 0, renderer); graphics->SetShaderParameter(VSP_LIGHTMATRICES, shadowMatrices[0].Data(), isShadowed ? 32 : 16); } break; case LIGHT_POINT: { Matrix4 lightVecRot(lightNode->GetWorldRotation().RotationMatrix()); // HLSL compiler will pack the parameters as if the matrix is only 3x4, so must be careful to not overwrite // the next parameter #ifdef ATOMIC_OPENGL graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 16); #else graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 12); #endif } break; } } float fade = 1.0f; float fadeEnd = light->GetDrawDistance(); float fadeStart = light->GetFadeDistance(); // Do fade calculation for light if both fade & draw distance defined if (light->GetLightType() != LIGHT_DIRECTIONAL && fadeEnd > 0.0f && fadeStart > 0.0f && fadeStart < fadeEnd) fade = Min(1.0f - (light->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 1.0f); // Negative lights will use subtract blending, so write absolute RGB values to the shader parameter graphics->SetShaderParameter(PSP_LIGHTCOLOR, Color(light->GetEffectiveColor().Abs(), light->GetEffectiveSpecularIntensity()) * fade); graphics->SetShaderParameter(PSP_LIGHTDIR, lightDir); graphics->SetShaderParameter(PSP_LIGHTPOS, lightPos); if (graphics->HasShaderParameter(PSP_LIGHTMATRICES)) { switch (light->GetLightType()) { case LIGHT_DIRECTIONAL: { Matrix4 shadowMatrices[MAX_CASCADE_SPLITS]; unsigned numSplits = Min(MAX_CASCADE_SPLITS, lightQueue_->shadowSplits_.Size()); for (unsigned i = 0; i < numSplits; ++i) CalculateShadowMatrix(shadowMatrices[i], lightQueue_, i, renderer); graphics->SetShaderParameter(PSP_LIGHTMATRICES, shadowMatrices[0].Data(), 16 * numSplits); } break; case LIGHT_SPOT: { Matrix4 shadowMatrices[2]; CalculateSpotMatrix(shadowMatrices[0], light); bool isShadowed = lightQueue_->shadowMap_ != 0; if (isShadowed) CalculateShadowMatrix(shadowMatrices[1], lightQueue_, 0, renderer); graphics->SetShaderParameter(PSP_LIGHTMATRICES, shadowMatrices[0].Data(), isShadowed ? 32 : 16); } break; case LIGHT_POINT: { Matrix4 lightVecRot(lightNode->GetWorldRotation().RotationMatrix()); // HLSL compiler will pack the parameters as if the matrix is only 3x4, so must be careful to not overwrite // the next parameter #ifdef ATOMIC_OPENGL graphics->SetShaderParameter(PSP_LIGHTMATRICES, lightVecRot.Data(), 16); #else graphics->SetShaderParameter(PSP_LIGHTMATRICES, lightVecRot.Data(), 12); #endif } break; } } // Set shadow mapping shader parameters if (shadowMap) { { // Calculate point light shadow sampling offsets (unrolled cube map) unsigned faceWidth = (unsigned)(shadowMap->GetWidth() / 2); unsigned faceHeight = (unsigned)(shadowMap->GetHeight() / 3); float width = (float)shadowMap->GetWidth(); float height = (float)shadowMap->GetHeight(); #ifdef ATOMIC_OPENGL float mulX = (float)(faceWidth - 3) / width; float mulY = (float)(faceHeight - 3) / height; float addX = 1.5f / width; float addY = 1.5f / height; #else float mulX = (float)(faceWidth - 4) / width; float mulY = (float)(faceHeight - 4) / height; float addX = 2.5f / width; float addY = 2.5f / height; #endif // If using 4 shadow samples, offset the position diagonally by half pixel if (renderer->GetShadowQuality() == SHADOWQUALITY_PCF_16BIT || renderer->GetShadowQuality() == SHADOWQUALITY_PCF_24BIT) { addX -= 0.5f / width; addY -= 0.5f / height; } graphics->SetShaderParameter(PSP_SHADOWCUBEADJUST, Vector4(mulX, mulY, addX, addY)); } { // Calculate shadow camera depth parameters for point light shadows and shadow fade parameters for // directional light shadows, stored in the same uniform Camera* shadowCamera = lightQueue_->shadowSplits_[0].shadowCamera_; float nearClip = shadowCamera->GetNearClip(); float farClip = shadowCamera->GetFarClip(); float q = farClip / (farClip - nearClip); float r = -q * nearClip; const CascadeParameters& parameters = light->GetShadowCascade(); float viewFarClip = camera->GetFarClip(); float shadowRange = parameters.GetShadowRange(); float fadeStart = parameters.fadeStart_ * shadowRange / viewFarClip; float fadeEnd = shadowRange / viewFarClip; float fadeRange = fadeEnd - fadeStart; graphics->SetShaderParameter(PSP_SHADOWDEPTHFADE, Vector4(q, r, fadeStart, 1.0f / fadeRange)); } { float intensity = light->GetShadowIntensity(); float fadeStart = light->GetShadowFadeDistance(); float fadeEnd = light->GetShadowDistance(); if (fadeStart > 0.0f && fadeEnd > 0.0f && fadeEnd > fadeStart) intensity = Lerp(intensity, 1.0f, Clamp((light->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 0.0f, 1.0f)); float pcfValues = (1.0f - intensity); float samples = 1.0f; if (renderer->GetShadowQuality() == SHADOWQUALITY_PCF_16BIT || renderer->GetShadowQuality() == SHADOWQUALITY_PCF_24BIT) samples = 4.0f; graphics->SetShaderParameter(PSP_SHADOWINTENSITY, Vector4(pcfValues / samples, intensity, 0.0f, 0.0f)); } float sizeX = 1.0f / (float)shadowMap->GetWidth(); float sizeY = 1.0f / (float)shadowMap->GetHeight(); graphics->SetShaderParameter(PSP_SHADOWMAPINVSIZE, Vector2(sizeX, sizeY)); Vector4 lightSplits(M_LARGE_VALUE, M_LARGE_VALUE, M_LARGE_VALUE, M_LARGE_VALUE); if (lightQueue_->shadowSplits_.Size() > 1) lightSplits.x_ = lightQueue_->shadowSplits_[0].farSplit_ / camera->GetFarClip(); if (lightQueue_->shadowSplits_.Size() > 2) lightSplits.y_ = lightQueue_->shadowSplits_[1].farSplit_ / camera->GetFarClip(); if (lightQueue_->shadowSplits_.Size() > 3) lightSplits.z_ = lightQueue_->shadowSplits_[2].farSplit_ / camera->GetFarClip(); graphics->SetShaderParameter(PSP_SHADOWSPLITS, lightSplits); if (graphics->HasShaderParameter(PSP_VSMSHADOWPARAMS)) graphics->SetShaderParameter(PSP_VSMSHADOWPARAMS, renderer->GetVSMShadowParameters()); if (light->GetShadowBias().normalOffset_ > 0.0f) { Vector4 normalOffsetScale(Vector4::ZERO); // Scale normal offset strength with the width of the shadow camera view if (light->GetLightType() != LIGHT_DIRECTIONAL) { Camera* shadowCamera = lightQueue_->shadowSplits_[0].shadowCamera_; normalOffsetScale.x_ = 2.0f * tanf(shadowCamera->GetFov() * M_DEGTORAD * 0.5f) * shadowCamera->GetFarClip(); } else { normalOffsetScale.x_ = lightQueue_->shadowSplits_[0].shadowCamera_->GetOrthoSize(); if (lightQueue_->shadowSplits_.Size() > 1) normalOffsetScale.y_ = lightQueue_->shadowSplits_[1].shadowCamera_->GetOrthoSize(); if (lightQueue_->shadowSplits_.Size() > 2) normalOffsetScale.z_ = lightQueue_->shadowSplits_[2].shadowCamera_->GetOrthoSize(); if (lightQueue_->shadowSplits_.Size() > 3) normalOffsetScale.w_ = lightQueue_->shadowSplits_[3].shadowCamera_->GetOrthoSize(); } normalOffsetScale *= light->GetShadowBias().normalOffset_; #ifdef GL_ES_VERSION_2_0 normalOffsetScale *= renderer->GetMobileNormalOffsetMul(); #endif graphics->SetShaderParameter(VSP_NORMALOFFSETSCALE, normalOffsetScale); graphics->SetShaderParameter(PSP_NORMALOFFSETSCALE, normalOffsetScale); } } } else if (lightQueue_->vertexLights_.Size() && graphics->HasShaderParameter(VSP_VERTEXLIGHTS) && graphics->NeedParameterUpdate(SP_LIGHT, lightQueue_)) { Vector4 vertexLights[MAX_VERTEX_LIGHTS * 3]; const PODVector<Light*>& lights = lightQueue_->vertexLights_; for (unsigned i = 0; i < lights.Size(); ++i) { Light* vertexLight = lights[i]; Node* vertexLightNode = vertexLight->GetNode(); LightType type = vertexLight->GetLightType(); // Attenuation float invRange, cutoff, invCutoff; if (type == LIGHT_DIRECTIONAL) invRange = 0.0f; else invRange = 1.0f / Max(vertexLight->GetRange(), M_EPSILON); if (type == LIGHT_SPOT) { cutoff = Cos(vertexLight->GetFov() * 0.5f); invCutoff = 1.0f / (1.0f - cutoff); } else { cutoff = -1.0f; invCutoff = 1.0f; } // Color float fade = 1.0f; float fadeEnd = vertexLight->GetDrawDistance(); float fadeStart = vertexLight->GetFadeDistance(); // Do fade calculation for light if both fade & draw distance defined if (vertexLight->GetLightType() != LIGHT_DIRECTIONAL && fadeEnd > 0.0f && fadeStart > 0.0f && fadeStart < fadeEnd) fade = Min(1.0f - (vertexLight->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 1.0f); Color color = vertexLight->GetEffectiveColor() * fade; vertexLights[i * 3] = Vector4(color.r_, color.g_, color.b_, invRange); // Direction vertexLights[i * 3 + 1] = Vector4(-(vertexLightNode->GetWorldDirection()), cutoff); // Position vertexLights[i * 3 + 2] = Vector4(vertexLightNode->GetWorldPosition(), invCutoff); } graphics->SetShaderParameter(VSP_VERTEXLIGHTS, vertexLights[0].Data(), lights.Size() * 3 * 4); } } // Set zone texture if necessary #ifndef GL_ES_VERSION_2_0 if (zone_ && graphics->HasTextureUnit(TU_ZONE)) graphics->SetTexture(TU_ZONE, zone_->GetZoneTexture()); #else // On OpenGL ES set the zone texture to the environment unit instead if (zone_ && zone_->GetZoneTexture() && graphics->HasTextureUnit(TU_ENVIRONMENT)) graphics->SetTexture(TU_ENVIRONMENT, zone_->GetZoneTexture()); #endif // Set material-specific shader parameters and textures if (material_) { if (graphics->NeedParameterUpdate(SP_MATERIAL, reinterpret_cast<const void*>(material_->GetShaderParameterHash()))) { const HashMap<StringHash, MaterialShaderParameter>& parameters = material_->GetShaderParameters(); for (HashMap<StringHash, MaterialShaderParameter>::ConstIterator i = parameters.Begin(); i != parameters.End(); ++i) graphics->SetShaderParameter(i->first_, i->second_.value_); } const HashMap<TextureUnit, SharedPtr<Texture> >& textures = material_->GetTextures(); for (HashMap<TextureUnit, SharedPtr<Texture> >::ConstIterator i = textures.Begin(); i != textures.End(); ++i) { if (graphics->HasTextureUnit(i->first_)) graphics->SetTexture(i->first_, i->second_.Get()); } } // Set light-related textures if (light) { if (shadowMap && graphics->HasTextureUnit(TU_SHADOWMAP)) graphics->SetTexture(TU_SHADOWMAP, shadowMap); if (graphics->HasTextureUnit(TU_LIGHTRAMP)) { Texture* rampTexture = light->GetRampTexture(); if (!rampTexture) rampTexture = renderer->GetDefaultLightRamp(); graphics->SetTexture(TU_LIGHTRAMP, rampTexture); } if (graphics->HasTextureUnit(TU_LIGHTSHAPE)) { Texture* shapeTexture = light->GetShapeTexture(); if (!shapeTexture && light->GetLightType() == LIGHT_SPOT) shapeTexture = renderer->GetDefaultLightSpot(); graphics->SetTexture(TU_LIGHTSHAPE, shapeTexture); } } }
void FilterNodeD2D1::SetAttribute(uint32_t aIndex, const IntRect &aValue) { if (mType == FilterType::TURBULENCE) { MOZ_ASSERT(aIndex == ATT_TURBULENCE_RECT); mEffect->SetValue(D2D1_TURBULENCE_PROP_OFFSET, D2D1::Vector2F(Float(aValue.X()), Float(aValue.Y()))); mEffect->SetValue(D2D1_TURBULENCE_PROP_SIZE, D2D1::Vector2F(Float(aValue.Width()), Float(aValue.Height()))); return; } UINT32 input = GetD2D1PropForAttribute(mType, aIndex); MOZ_ASSERT(input < mEffect->GetPropertyCount()); mEffect->SetValue(input, D2D1::RectF(Float(aValue.X()), Float(aValue.Y()), Float(aValue.XMost()), Float(aValue.YMost()))); }
void onMouse(int event, int x, int y, int, void*) { if (selectObject) { selectionRegion.SetXMin(MIN(x, originMouse.x)); selectionRegion.SetYMin(MIN(y, originMouse.y)); selectionRegion.SetWidth(std::abs(x - originMouse.x)); selectionRegion.SetHeight(std::abs(y - originMouse.y)); } switch (event) { case CV_EVENT_LBUTTONDOWN: printf("buttondown: x:%d,y:%d\n",x,y); originMouse = Point(x, y); selectionRegion = IntRect(x, y, 0, 0); selectObject = true; break; case CV_EVENT_LBUTTONUP: selectObject = false; newregion = true; trackObject = -1; printf("buttonup: x:%d,y:%d,width:%d,height:%d\n", selectionRegion.XMin(), selectionRegion.YMin(), selectionRegion.Height(), selectionRegion.Width()); break; } }
SceneEditor3D ::SceneEditor3D(Context* context, const String &fullpath, UITabContainer *container) : ResourceEditor(context, fullpath, container) { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); SharedPtr<File> xmlFile = cache->GetFile(fullpath); if (GetExtension(fullpath) == ".scene") scene_->LoadXML(*xmlFile); else scene_->Load(*xmlFile); scene_->SetUpdateEnabled(false); sceneView_ = new SceneView3D(context_, this); // EARLY ACCESS if (fullpath.Find(String("ToonTown")) != String::NPOS) { sceneView_->GetCameraNode()->SetWorldPosition(Vector3(-119.073f, 76.1121f, 16.47763f)); Quaternion q(0.55f, 0.14f, 0.8f, -0.2f); sceneView_->SetYaw(q.YawAngle()); sceneView_->SetPitch(q.PitchAngle()); sceneView_->GetCameraNode()->SetWorldRotation(q); } else { Node* playerSpawn = scene_->GetChild("PlayerInfoStart", true); if (playerSpawn) { sceneView_->GetCameraNode()->SetPosition(playerSpawn->GetPosition()); sceneView_->SetYaw(playerSpawn->GetRotation().EulerAngles().y_); } } sceneView_->SetGravity(UI_GRAVITY_ALL); rootContentWidget_->AddChild(sceneView_); gizmo3D_ = new Gizmo3D(context_); gizmo3D_->SetView(sceneView_); gizmo3D_->Show(); SubscribeToEvent(E_UPDATE, HANDLER(SceneEditor3D, HandleUpdate)); SubscribeToEvent(E_EDITORACTIVENODECHANGE, HANDLER(SceneEditor3D, HandleEditorActiveNodeChange)); SubscribeToEvent(E_GIZMOEDITMODECHANGED, HANDLER(SceneEditor3D, HandleGizmoEditModeChanged)); // FIXME: Set the size at the end of setup, so all children are updated accordingly // future size changes will be handled automatically IntRect rect = container_->GetContentRoot()->GetRect(); rootContentWidget_->SetSize(rect.Width(), rect.Height()); SubscribeToEvent(E_EDITORPLAYSTARTED, HANDLER(SceneEditor3D, HandlePlayStarted)); SubscribeToEvent(E_EDITORPLAYSTOPPED, HANDLER(SceneEditor3D, HandlePlayStopped)); SubscribeToEvent(scene_, E_NODEREMOVED, HANDLER(SceneEditor3D, HandleNodeRemoved)); }
/// Convert screen coordinates to element coordinates. IntVector2 ScreenToElement(const IntVector2& screenPos) override { IntVector2 result(-1, -1); if (node_.Expired()) return result; Scene* scene = node_->GetScene(); auto* model = node_->GetComponent<StaticModel>(); if (scene == nullptr || model == nullptr) return result; auto* renderer = GetSubsystem<Renderer>(); if (renderer == nullptr) return result; // \todo Always uses the first viewport, in case there are multiple auto* octree = scene->GetComponent<Octree>(); if (viewport_ == nullptr) viewport_ = renderer->GetViewportForScene(scene, 0); if (viewport_.Expired() || octree == nullptr) return result; if (viewport_->GetScene() != scene) { URHO3D_LOGERROR("UIComponent and Viewport set to component's root element belong to different scenes."); return result; } Camera* camera = viewport_->GetCamera(); if (camera == nullptr) return result; IntRect rect = viewport_->GetRect(); if (rect == IntRect::ZERO) { auto* graphics = GetSubsystem<Graphics>(); rect.right_ = graphics->GetWidth(); rect.bottom_ = graphics->GetHeight(); } Ray ray(camera->GetScreenRay((float)screenPos.x_ / rect.Width(), (float)screenPos.y_ / rect.Height())); PODVector<RayQueryResult> queryResultVector; RayOctreeQuery query(queryResultVector, ray, RAY_TRIANGLE_UV, M_INFINITY, DRAWABLE_GEOMETRY, DEFAULT_VIEWMASK); octree->Raycast(query); if (queryResultVector.Empty()) return result; for (unsigned i = 0; i < queryResultVector.Size(); i++) { RayQueryResult& queryResult = queryResultVector[i]; if (queryResult.drawable_ != model) { // ignore billboard sets by default if (queryResult.drawable_->GetTypeInfo()->IsTypeOf(BillboardSet::GetTypeStatic())) continue; return result; } Vector2& uv = queryResult.textureUV_; result = IntVector2(static_cast<int>(uv.x_ * GetWidth()), static_cast<int>(uv.y_ * GetHeight())); return result; } return result; }