Jetpack XR SDK מאפשר לכם להשתמש ב-Jetpack SceneCore כדי ליצור, לשלוט ולנהל מופעים של Entity
כמו מודלים תלת-ממדיים, סרטונים סטריאוסקופיים וPanelEntity
באמצעות Jetpack SceneCore.
ב-Jetpack SceneCore נעשה שימוש בשני דפוסי ארכיטקטורה נפוצים כדי לתמוך בפיתוח תלת-ממד: גרף סצנה ומערכת רכיבי ישויות (ECS).
שימוש בגרף הסצנה כדי ליצור ולשלוט בישויות
כדי ליצור אובייקטים במרחב תלת-ממדי ולשלוט בהם, אפשר להשתמש ב-Session API של Jetpack SceneCore כדי לקבל גישה לגרף הסצנה. גרף הסצנה מותאם לעולם האמיתי של המשתמש ומאפשר לארגן ישויות תלת-ממדיות כמו חלוניות ומודלים תלת-ממדיים במבנה היררכי, ולשמור את המצב של הישויות האלה.
אחרי שמקבלים גישה לגרף הסצנה, אפשר להשתמש בממשקי ה-API ב-Jetpack Compose for XR כדי ליצור ממשק משתמש מרחבי (לדוגמה, מופעים של SpatialPanel
ושל Orbiter
) בתוך גרף הסצנה. כדי לגשת לתוכן תלת-ממדי כמו מודלים תלת-ממדיים, אפשר להיכנס ישירות לסשן. מידע נוסף זמין בקטע מידע על ActivitySpace בדף הזה.
מערכת רכיבים של ישות
מערכת רכיבי ישויות פועלת לפי העיקרון של הרכבה על פני ירושה. אפשר להרחיב את ההתנהגות של ישויות על ידי צירוף רכיבים שמגדירים את ההתנהגות, וכך להחיל את אותה התנהגות על סוגים שונים של ישויות. מידע נוסף זמין במאמר בנושא הוספת התנהגות נפוצה לישויות בדף הזה.
מידע על ActivitySpace
לכל Session
יש ActivitySpace
שנוצר באופן אוטומטי עם Session
. ActivitySpace
הוא Entity
ברמה העליונה בתרשים של הסצנה.
המרחב ActivitySpace מייצג מרחב תלת-ממדי עם מערכת צירים ימנית (ציר ה-x מצביע ימינה, ציר ה-y מצביע למעלה וציר ה-z מצביע אחורה ביחס לנקודת המוצא) ועם יחידות של מטרים שתואמות לעולם האמיתי. המיקום של ActivitySpace
הוא שרירותי במידה מסוימת (כי המשתמשים יכולים לאפס את המיקום של ActivitySpace
בעולם האמיתי), ולכן מומלץ למקם את התוכן ביחס אחד לשני ולא ביחס ל-ActivitySpace
.
עבודה עם ישויות
הישויות הן מרכזיות ב-SceneCore. כמעט כל מה שהמשתמש רואה ומקיים איתו אינטראקציה הם ישויות שמייצגות חלוניות, מודלים תלת-ממדיים ועוד.
מכיוון ש-ActivitySpace
הוא הצומת ברמה העליונה בתרשים הסצנה, כברירת מחדל,
כל הישויות החדשות ממוקמות ישירות ב-ActivitySpace
. אפשר להעביר מיקומי ישויות לאורך גרף הסצנה על ידי הגדרת parent
או באמצעות addChild()
.
לישויות יש כמה התנהגויות שמוגדרות כברירת מחדל, שמשותפות לכל הישויות, כמו שינוי המיקום, הסיבוב או הנראות. למחלקות משנה ספציפיות, כמו GltfModelEntity
, יש התנהגויות נוספות שתומכות במחלקת המשנה.Entity
שינוי ישויות
כשמבצעים שינוי בנכס Entity
ששייך למחלקת הבסיס Entity
השינוי יועבר לכל הצאצאים שלו. לדוגמה, אם משנים את Pose
של Entity
אב, כל הצאצאים שלו יקבלו את אותו שינוי. שינוי ביחידה ארגונית ברמת הצאצא Entity
לא משפיע על היחידה הארגונית ברמה העליונה שלה.
Pose
מייצג את המיקום והסיבוב של הישות במרחב תלת-ממדי. המיקום הוא Vector3
שכולל את המיקומים המספריים x, y ו-z. הסיבוב מיוצג על ידי Quaternion
. המיקום של Entity
תמיד יחסי לישות ההורה שלו. במילים אחרות, Entity
שמיקומו הוא (0, 0, 0) יוצב בנקודת האפס של ישות האב שלו.
// Place the entity forward 2 meters val newPosition = Vector3(0f, 0f, -2f) // Rotate the entity by 180 degrees on the up axis (upside-down) val newOrientation = Quaternion.fromEulerAngles(0f, 0f, 180f) // Update the position and rotation on the entity entity.setPose(Pose(newPosition, newOrientation))
כדי להשבית Entity
, משתמשים ב-setEnabled()
. הפעולה הזו תגרום לכך שהגיליון יהיה בלתי נראה ותפסיק את כל העיבוד שמתבצע בו.
// Disable the entity. entity.setEnabled(false)
כדי לשנות את הגודל של Entity
בלי לשנות את הצורה הכללית שלו, משתמשים ב-setScale()
.
// Double the size of the entity entity.setScale(2f)
הוספת התנהגות נפוצה לישויות
אפשר להשתמש ברכיבים הבאים כדי להוסיף התנהגות נפוצה לישויות:
-
MovableComponent
: מאפשר למשתמש להעביר ישויות -
ResizableComponent
: מאפשר למשתמש לשנות את הגודל של ישויות באמצעות דפוסי ממשק משתמש עקביים -
InteractableComponent
: מאפשרת לכם לתעד אירועי קלט לאינטראקציות מותאמות אישית
צריך ליצור מופעים של רכיבים באמצעות שיטת היצירה המתאימה במחלקה Session
. לדוגמה, כדי ליצור ResizableComponent
, קוראים ל-ResizableComponent.create()
.
כדי להוסיף את ההתנהגות הספציפית של הרכיב ל-Entity
, משתמשים בשיטה addComponent()
.
איך משתמשים ב-MovableComponent
כדי לאפשר למשתמשים להזיז ישות
ההרשאה MovableComponent
מאפשרת למשתמש להזיז את Entity
.
אירועי תנועה נשלחים לרכיב כשמתבצעת אינטראקציה עם הרכיבים המוספים. ההתנהגות של המערכת כברירת מחדל, שנוצרה באמצעות MovableComponent.createSystemMovable()
, גורמת להזזת Entity
כשגוררים את הקישוטים:
val movableComponent = MovableComponent.createSystemMovable(session) entity.addComponent(movableComponent)
הפרמטר האופציונלי scaleInZ
(שמוגדר כברירת מחדל ל-true
) גורם לישות להתאים את הגודל שלה באופן אוטומטי כשהיא מתרחקת מהמשתמש, בדומה לאופן שבו המערכת משנה את הגודל של חלוניות במרחב הביתי.
בגלל האופי ההיררכי של מערכת רכיבי הישות, קנה המידה של רכיב ההורה ישפיע על כל רכיבי הצאצא.
אפשר גם לציין אם הישות יכולה להיות מעוגנת לסוג משטח כמו משטחים אופקיים או אנכיים, או למשטחים סמנטיים ספציפיים כמו שולחן, קיר או תקרה. כדי לציין אפשרויות של עוגן, מציינים קבוצה של AnchorPlacement
כשיוצרים את MovableComponent
. בדוגמה הזו, הישות שאפשר להזיז ולעגן לכל משטח אופקי של רצפה או שולחן:
val anchorPlacement = AnchorPlacement.createForPlanes( anchorablePlaneOrientations = setOf(PlaneOrientation.VERTICAL), anchorablePlaneSemanticTypes = setOf(PlaneSemanticType.FLOOR, PlaneSemanticType.TABLE) ) val movableComponent = MovableComponent.createAnchorable( session = session, anchorPlacement = setOf(anchorPlacement) ) entity.addComponent(movableComponent)
שימוש ב-ResizableComponent
כדי לשנות את הגודל של רכיב Entity
התכונה ResizableComponent
מאפשרת למשתמשים לשנות את הגודל של Entity
. האזור ResizableComponent
כולל רמזים חזותיים לאינטראקציה שמזמינים את המשתמש לשנות את הגודל של Entity
. כשיוצרים את ResizableComponent
, אפשר לציין גודל מינימלי או מקסימלי (במטרים). יש לכם גם אפשרות לציין יחס גובה-רוחב קבוע כשמשנים את הגודל, כך שהרוחב והגובה ישתנו באופן יחסי זה לזה.
כשיוצרים ResizableComponent
, מציינים resizeEventListener
שמטפל באירועי העדכון. אפשר להגיב לאירועים שונים של ResizeState
, כמו RESIZE_STATE_ONGOING
או RESIZE_STATE_END
.
דוגמה לשימוש בתג ResizableComponent
עם יחס רוחב-גובה קבוע בתג SurfaceEntity
:
val resizableComponent = ResizableComponent.create(session) { event -> if (event.resizeState == ResizeEvent.ResizeState.RESIZE_STATE_END) { // update the Entity to reflect the new size surfaceEntity.canvasShape = SurfaceEntity.CanvasShape.Quad(event.newSize.width, event.newSize.height) } } resizableComponent.minimumEntitySize = FloatSize3d(177f, 100f, 1f) resizableComponent.fixedAspectRatio = 16f / 9f // Specify a 16:9 aspect ratio surfaceEntity.addComponent(resizableComponent)
שימוש ב-InteractableComponent
כדי לתעד אירועי קלט של משתמשים
התג InteractableComponent
מאפשר לכם לתעד אירועי קלט מהמשתמש, כמו כשמשתמש יוצר אינטראקציה עם Entity
או מעביר מעליו את העכבר. כשיוצרים InteractableComponent
, צריך לציין listener שמקבל את אירועי הקלט.
כשמשתמש מבצע פעולת קלט כלשהי, מתבצעת קריאה ל-listener עם פרטי הקלט שמופיעים בפרמטר InputEvent
.
-
InputEvent.action
מציין את סוג הקלט, כמו העברת העכבר או הקשה על ישות -
InputEvent.source
מציין מאיפה הגיע הקלט, למשל קלט של יד או של בקר -
InputEvent.pointerType
מציין אם הקלט הגיע מיד ימין או מיד שמאל
רשימה מלאה של כל הקבועים של InputEvent
זמינה במסמכי העזר.
בקטע הקוד הבא מוצגת דוגמה לשימוש ב-InteractableComponent
כדי להגדיל את הגודל של ישות באמצעות יד ימין ולהקטין אותו באמצעות יד שמאל.
val executor = Executors.newSingleThreadExecutor() val interactableComponent = InteractableComponent.create(session, executor) { // when the user disengages with the entity with their hands if (it.source == InputEvent.Source.SOURCE_HANDS && it.action == InputEvent.Action.ACTION_UP) { // increase size with right hand and decrease with left if (it.pointerType == InputEvent.Pointer.POINTER_TYPE_RIGHT) { entity.setScale(1.5f) } else if (it.pointerType == InputEvent.Pointer.POINTER_TYPE_LEFT) { entity.setScale(0.5f) } } } entity.addComponent(interactableComponent)