檢視畫面、邊界和剪輯

簡介

此指南說明風景區的檢視邊界和裁剪方式。這個 本指南將說明如何設定檢視區塊邊界,以及如何解讀指令 進行的活動,以及檢視範圍對現有 View 子系統的影響。

概念

設定檢視範圍

嵌入程式必須為檢視區塊和檢視保留者建立一組符記,且必須 也會在檢視畫面內分配空間,供嵌入式檢視容器進行配置。 方法是設定內嵌檢視檢視畫面保留項上的邊界。目的地: 設定檢視區塊的邊界,您必須在其上呼叫 SetViewProperties 個別 ViewHolder。您可以在前面或之後呼叫 SetViewProperties 系統會建立檢視畫面,並連結至 ViewHolder,所以您不必為此 你只需擔心設定的順序邊界本身已設定 方法是指定 3D 空間的最小和最大點 (xyz)。

邊界和插邊

ViewProperties 結構體集的 bounding_box 屬性可用來設定 也就是檢視區塊的邊界。上下限代表下限和上限 軸對齊定界框的座標點上限。

insets_from_mininsets_from_max 屬性會提供提示 定界框和插邊之間的區域可能會被遮住 風景不會使用插邊值來判斷定界框, 只是在

{ bounding_box.min + inset_from_min, bounding_box.max - inset_from_max }

內容可能會遭到其祖系檢視遮蓋。遮蓋原因和規則 且每個產品相關。

範例

// Create a pair of tokens to register a view and view holder in
// the scene graph.
auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();

// Create the actual view and view holder.
scenic::View view(session, std::move(view_token), "View");
scenic::ViewHolder view_holder(session, std::move(view_holder_token),
                               "ViewHolder");
// Set the bounding box dimensions on the view holder.
view_holder.SetViewProperties({.bounding_box{.min{0, 0, -200}, .max{500, 500, 0}},
                               .inset_from_min{20, 30, 0},
                               .inset_from_max{20, 30, 0}});

上述程式碼會建立 View 和 ViewHolder 組合,其邊界從 (0, 0, -200) 開始,並延伸至 (500, 500, 0)。上下限本身 軸對齊。

座標系統

景觀 3D 系統是由多個座標空間組成。他們可以 大致分為:圖層空間、世界空間和當地空間空間 點的每個座標系統中都有獨立座標。轉型 矩陣說明如何對應兩個座標空間之間的空間點;這個 系統 A 中點的座標會乘以轉換矩陣, 取得系統 B 的座標 (或在系統 B 中,相反的 方向)。

所有景觀座標系統皆為右手採用。

協調空間圖表

圖層空間 (螢幕空間)

「圖層空間」是對應螢幕上區域的 2D 座標空間。 - 原點:左上角,X 軸指向右側,Y 軸指向下方。軸對齊 螢幕。 - 尺寸:通常等於顯示尺寸 (全螢幕圖層)。

相機轉換

相機轉換矩陣可將座標從 World Space 轉換為圖層 空白鍵。

這項轉換實際上包含幾個步驟。

首先,我們從「世界太空」轉換為「相機」中繼空間 空白鍵。這是經過正規化處理的三維座標系統,從 -1 到 1 無所不在這個座標系統靠右手,X 軸為右手 指向右方的 Y 軸、Z 軸和 Z 軸 螢幕」。攝影機在世界空間中的位置和方向會定義 轉型。

接下來,投影轉換矩陣會決定如何壓平相機 太空的二維空間。這項轉換 指定要執行的投影類型:正反射或透視 專案。最常見的選擇是擬真攝影,這個世界基本上就是世界 水平固定在 Z 方向上,同時維持 X 軸和 Y 軸。

最後,可能會套用裁剪空間轉換,藉此縮放、翻譯 啟用放大功能所需的 2D 空間1

世界太空

「世界空間」是場景圖的根檢視定位,而 。整個場景圖也已嵌入到這個空間 以及 Camera Space 與場景之間的關聯

轉換節點

場景圖中的每個節點都有相關聯的本機空間。這個聊天室是 並定義由該節點的轉換矩陣 節點的本機空間給其父項的本機空間。矩陣是 取決於節點定義的位置、旋轉和縮放比例 父項。

每個節點的當地空間只要乘以 轉換場景圖的上空矩陣,終止在場景圖的根層級 (其轉換矩陣是從根層級本機空間轉換到 。這個相乘矩陣稱為節點的「全域轉換」。

節點的轉換矩陣是平移、縮放 節點輪替應用程式順序為先調度資源,然後旋轉 翻譯工作因為每個值都可以 以及矩陣的乘法順序 然後,請將完整的轉換寫成:

parent_local_point = translation matrix * rotation_matrix * scale_matrix * local_point

範例

我們有一個場景圖,由兩個節點 (Node1 和 Node2) 組成。 Node1 是 Node2 的子項,而 P1 是 Node1 本機空間中的點。 Node1 和 Node2 提供旋轉、資源調度和轉譯功能。 如要取得 P1 的世界空間座標,請依序合併所有父項的轉換: p1_world_position = (translation_node2 * rotation_node2 * scale_node2) * (translation_node1 * rotation_node1 * scale_node1) * p1_local_position

當地空間 (Scenic View Space)2

不是每個講座都具備完整的場景圖的完整知識 全都在其 View 的本機座標空間中執行。這就是您要進行的 會定義節點的轉換作業、輸入座標 的包裹。

  • 來源:「返回角落」。檢視畫面的 Z 維度通常會設定 為 -1000 到 0 (這是由左手座標開始產生的副作用 後來才變成右手狀態),因此檢視畫面的原點就位於 Z 值,但至少為 X 和 Y 值。通常與 造福世界

查看範圍

檢視畫面邊界是以本機座標和其世界空間位置指定 取決於檢視表節點的全域轉換

來自圖層空間的輸入座標,通常對應至像素 畫面左上角與起點協調輸入系統 與合成器和相機搭配運作,根據輸入裝置座標 世界太空 Ray 轉換和命中測試

範例

// Create a view and view-holder token pair.
auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
scenic::View view(session, std::move(view_token), "View");
scenic::ViewHolder view_holder(session, std::move(view_holder_token),
                               "ViewHolder");

// Add the view holder as a child of the scene.
scene.AddChild(view_holder);

// Translate the view holder and set view bounds.
view_holder.SetTranslation(100, 100, 200);
view_holder.SetViewProperties({.bounding_box{.max{500, 500, 200}}});

在上述程式碼中,檢視範圍在本機空間的最小值和最大值 (0, 0, 0)(500, 500, 200),但因為父項節點會轉譯為 (100, 100, 200) 「世界空間」的檢視界限實際上會包含「世界」 聊天室範圍下限和上限:(100, 100, 200)(600, 600, 400) 。但是,檢視區塊本身不會看到這些世界空間邊界, 只能處理其當地空間的邊界。

置中幾何圖形

幾何圖形 (例如 RoundedRectangle) 的質心中心是 對檢視區塊而言,邊界的質心中心則是其最小的 座標。這表示若檢視畫面和圓角矩形為 兩個檢視的翻譯相同,也就是圓角矩形的中心 會以檢視畫面邊界的最小座標呈現。如要修正這個問題,請套用 將形狀節點上的另一個轉譯文字移到 上下限

置中幾何圖形圖表

偵錯線框轉譯

如要協助偵錯檢視畫面邊界,您可以將 連接線模式,即可查看您的視圖在 World Space 中的實際位置。這個 功能可透過 View 指令套用每個檢視區塊:

// This command turns on wireframe rendering of the specified
// view, which can aid in debugging.
struct SetEnableDebugViewBoundsCmd {
    uint32 view_id;
    bool display_bounds;
};

這個指令使用 view id,並使用 bool 切換 應會顯示檢視邊界。預設顯示色彩為白色,不過您可以 在SetViewHolderBoundsColorCmd 指定檢視保留項:

// This command determines the color to be set on a view holder’s debug
// wireframe bounding box.
struct SetViewHolderBoundsColorCmd {
    uint32 view_holder_id;
    ColorRgbValue color;
};

Ray 轉換和點擊測試

透過光線測試將地圖圖層空間座標轉換為場景幾何圖形, 座標。最後,輸入內容會傳送至具有「View-local」功能的檢視畫面 座標。如座標系統所述 區段和「檢視-本地」座標,是由 查看從 World Space 對應至當地空間的節點。

熱門光芒四射

插入觸控輸入事件時,我們需要瞭解以下兩件事:1.哪些客戶 我們要傳送輸入事件給嗎?2. 輸入事件的座標為何? 用戶端的本機座標系統?

將輸入座標從圖層空間轉換為世界空間,涉及將 以及輸入系統、合成器層和攝影機

輸入座標空格

系統會執行命中測試,找出要將事件傳送給哪個用戶端。這是 將光線投射到場景中 (在「世界太空」) 中,看看物體是什麼 交互交集,然後將輸入內容傳送至最接近的命中物件。當我們點擊 可以看出接著,我們會計算 將命中物件自主視角轉換成 2010 年世界空間,以及 使用這個字串,將輸入事件傳送到用戶端的本機座標。

原始輸入座標是螢幕像素中的 2D 座標。 輸入系統和合成器認同慣例,如上所示,如上所示: 裝置座標以 3 個維度 (藍色) 表示,檢視音量深度為 1 時, 附近的飛機為 z = 0,最遠的平面為 z = -1。瞭解這些之後 輸入系統會計算「世界太空座標」的座標,藉此建立命中射線 觸控座標 (藉由反轉相機轉換),請將這些座標設為 起點為 Z 點,方向為 (0, 0, 1),朝著場景前進。

在「World Space」中,上述命中匣的起點為 (x, y, -1000) 方向為 (0, 0, 1000)

規則

執行命中測試時,檢視畫面會針對 ViewNode 的邊界進行測試 然後再判斷是否應繼續檢查 節點。

  • 如果灰色完全遺漏檢視區塊的定界框,就不會出現 就能達到這個目標

  • 如果某一個光的定界框與定界框相交,則只有 從邊界框內即可離開 才會計入命中資料舉例來說,裁剪的幾何圖形不可點擊。

如果您忘記設定檢視畫面的邊界,則任何以子項為主體的幾何圖形 就無法命中這是因為邊界為空值 因此無限小,這也表示沒有幾何圖形 。

在偵錯模式中,空值定界框會觸發 FXL_DCHECK escher::BoundingBox 類別,表示需要 大於或等於 2。

特殊情況

雨天在定界框的一側垂直對齊 縮減其邊緣無法視為命中。由 6 個飛機構成 定界框本身就是剪裁 直接出現在夾扣上 也會被裁切

碰撞

光柵轉換在相同動作中偵測到兩個以上的命中時,就會產生衝突 距離。如出現衝突,就代表命中目標發生重疊, 就在場景中佔有相同位置我們認為這是不正確的行為 即使發生衝突,View 也不會提供命中測試保證。 用戶端必須避免衝突。

發生衝突的方式有兩種:

  • 同一個檢視畫面中節點間的衝突。擁有的檢視表必須確保 將元素正確放置在檢視畫面中。

  • 不同檢視畫面中節點間的衝突。上層檢視畫面必須防止任何 即子項裁剪邊界之間的交集。

我們也建議您遵循這些規則,避免在視覺上產生多面向衝突 內容。

偵測到衝突時,系統會按照 工作階段 ID 和資源 ID。


  1. 想要處理放大功能,更好的方法是在圖表中插入比例節點,然後直接操控。這種做法會導致一些問題,在應用程式大小及應分配的記憶體方面感到困惑 (因為指標事件是透過縮放功能發出),而我們也導入剪輯空間轉換做為解決方法。另外,由於相機空間目前會處理輸入作業,因此加上了令人難忘的副作用,放大手勢在放大時可能會顯得更小。 

  2. 請別與 3D 圖形的一般 Model-View-Projection 標記法 (此處稱為「相機空間」) 和 View Space 混淆。