Jetpack XR SDK מאפשר לכם להשתמש ב-Jetpack SceneCore כדי ליצור, לשלוט ולנהל מופעים של Entity כמו מודלים תלת-ממדיים, סרטונים סטריאוסקופיים וPanelEntity באמצעות Jetpack SceneCore.
ב-Jetpack SceneCore נעשה שימוש בשתי תבניות ארכיטקטוניות נפוצות לתמיכה בפיתוח תלת-ממד: גרף סצנה ומערכת רכיבים של ישויות (ECS).
שימוש בתרשים הסצנה ליצירה ולשליטה בישויות
כדי ליצור אובייקטים ולשלוט בהם במרחב תלת-ממדי, אפשר להשתמש ב-API של Session ב-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().
לישויות יש כמה התנהגויות שמוגדרות כברירת מחדל, שמשותפות לכל הישויות, כמו שינוי המיקום, הסיבוב או הנראות. לEntity
תת-מחלקות ספציפיות, כמו GltfModelEntity, יש התנהגויות נוספות שתומכות בתת-המחלקות.
שינוי ישויות
כשמבצעים שינוי בנכס 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.END) { // update the Entity to reflect the new size surfaceEntity.shape = SurfaceEntity.Shape.Quad(FloatSize2d(event.newSize.width, event.newSize.height)) } } resizableComponent.minimumEntitySize = FloatSize3d(177f, 100f, 1f) resizableComponent.isFixedAspectRatioEnabled = true // Maintain a fixed aspect ratio when resizing 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.HANDS && it.action == InputEvent.Action.UP) { // increase size with right hand and decrease with left if (it.pointerType == InputEvent.Pointer.RIGHT) { entity.setScale(1.5f) } else if (it.pointerType == InputEvent.Pointer.LEFT) { entity.setScale(0.5f) } } } entity.addComponent(interactableComponent)