באמצעות Jetpack XR SDK תוכלו להשתמש ב-Jetpack SceneCore כדי ליצור, לשלוט ולנהל מכונות Entity
, כמו מודלים תלת-ממדיים, וידאו סטריאופוליסקופי ו-PanelEntity
.
ב-Jetpack SceneCore נעשה שימוש בשני דפוסי ארכיטקטורה נפוצים כדי לתמוך בפיתוח תלת-ממד: תרשים סצנה ומערכת ישות-רכיב (ECS).
שימוש בתרשים הסצינה כדי ליצור ישויות ולשלוט בהן
כדי ליצור אובייקטים במרחב תלת-ממדי ולשלוט בהם, צריך להשתמש ב-API של Session ב-Jetpack SceneCore כדי לקבל גישה לתרשים הסצינה. תרשים הסצינה תואם לעולם האמיתי של המשתמש ומאפשר לארגן ישויות תלת-ממדיות כמו לוחות ומודלים תלת-ממדיים במבנה היררכי, ולשמור את המצב של הישויות האלה.
אחרי שתקבלו גישה לתרשים הסצנה, תוכלו להשתמש בממשקי ה-API ב-Jetpack Compose for XR כדי ליצור ממשק משתמש מרחבי (לדוגמה, SpatialPanel
ו-Orbiter
) בתרשים הסצנה. לגבי תוכן תלת-ממדי, כמו מודלים תלת-ממדיים, אפשר לגשת ישירות לסשן. מידע נוסף זמין בקטע מידע על ActivitySpace שבדף הזה.
מערכת רכיבים של ישות
מערכת של ישויות ורכיבים פועלת לפי העיקרון של הרכבה במקום בירושה. אפשר להרחיב את ההתנהגות של ישויות על ידי צירוף רכיבים שמגדירים את ההתנהגות, וכך להחיל את אותה התנהגות על סוגים שונים של ישויות. מידע נוסף זמין בקטע הוספת התנהגות נפוצה לישויות שבדף הזה.
מידע על ActivitySpace
לכל Session
יש ActivitySpace
שנוצר באופן אוטומטי עם ה-Session
. ה-ActivitySpace
הוא ה-Entity
ברמת העליונה בתרשים הסצינה.
מרחב הפעילות מייצג מרחב תלת-ממדי עם מערכת קואורדינטות ימנית (ציר ה-X מצביע ימינה, ציר ה-Y מצביע למעלה וציר ה-Z מצביע לאחור ביחס למקור) ועם יחידות של מטרים שתואמות לעולם האמיתי. המקור של ActivitySpace
הוא שרירותי במידה מסוימת (כי המשתמשים יכולים לאפס את המיקום של ActivitySpace
בעולם האמיתי), לכן מומלץ למקם את התוכן ביחס זה לזה במקום ביחס למקור.
עבודה עם ישויות
ישויות הן רכיב מרכזי ב-SceneCore. רוב מה שהמשתמש רואה ומקיים איתו אינטראקציה הוא ישויות שמייצגות לוחות, מודלים תלת-ממדיים ועוד.
מכיוון ש-ActivitySpace
הוא הצומת ברמה העליונה של תרשים הסצנה, כברירת מחדל כל הישויות החדשות ממוקמות ישירות ב-ActivitySpace
. כדי להעביר ישויות לאורך תרשים הסצנה, אפשר להפעיל את הפונקציה setParent
או את הפונקציה addChild
.
יש לישות התנהגויות ברירת מחדל מסוימות לדברים שתקפים לכל הישות, כמו שינוי המיקום, הסיבוב או החשיפה. למחלקות משנה ספציפיות של Entity
, כמו GltfEntity
, יש התנהגויות נוספות שתומכות במחלקת המשנה.
מניפולציה של ישויות
כשמשנים נכס Entity
ששייך לכיתה הבסיסית Entity
, השינוי יועבר אל כל הצאצאים שלו. לדוגמה, שינוי הערך של Pose
של הורה Entity
גורם לכל הצאצאים שלו לקבל את אותה התאמה. שינוי ב-Entity
ברמת הצאצא לא משפיע על ההורה.
Pose
מייצג את המיקום והסיבוב של הישות במרחב תלת-ממדי. המיקום הוא Vector3
שמורכב מהמיקומים המספריים x, y ו-z. הסיבוב מיוצג על ידי Quaternion
. המיקום של Entity
הוא תמיד ביחס לישות ההורה שלו. במילים אחרות, Entity
שהמיקום שלו הוא (0, 0, 0) יוצב במקור של הישות ההורה שלו.
//place the entity forward 2 meters
val modelPosition = 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
, משתמשים ב-setHidden
.
//hide the entity
entity.setHidden(true)
כדי לשנות את הגודל של Entity
תוך שמירה על הצורה הכוללת שלו, משתמשים ב-setScale
.
//double the size of the entity
entity.setScale(2f)
הוספת התנהגות משותפת לישויות
אפשר להשתמש ברכיבים הבאים כדי להוסיף התנהגות משותפת לישויות:
MovableComponent
: מאפשרת למשתמש להעביר ישויותResizableComponent
: מאפשרת למשתמש לשנות את הגודל של ישויות באמצעות דפוסים עקביים של ממשק המשתמשInteractableComponent
: מאפשרת לתעד אירועי קלט של אינטראקציות בהתאמה אישית
יצירת רכיבים צריכה להתבצע באמצעות שיטת היצירה המתאימה בכיתה Session
. לדוגמה, כדי ליצור ResizableComponent
, צריך להפעיל את הפונקציה session.createResizableComponent()
.
כדי להוסיף את התנהגות הרכיב הספציפית ל-Entity
, משתמשים ב-method addComponent()
.
שימוש ב-MovableComponent כדי לאפשר למשתמש להזיז ישות
האפשרות MovableComponent
מאפשרת למשתמש להזיז את Entity
. אפשר גם לציין אם הישות יכולה להיות מוצמדת לסוג משטח, כמו משטחים אופקיים או אנכיים, או למשטחים סמנטיים ספציפיים כמו שולחן, קיר או תקרה. כדי לציין אפשרויות של עוגנים, מציינים קבוצה של AnchorPlacement
כשיוצרים את MovableComponent
.
דוגמה לישות שאפשר להזיז ולעגן לכל משטח אנכי, ורק למשטחים אופקיים של רצפה ותקרה.
val anchorPlacement = AnchorPlacement.createForPlanes(
planeTypeFilter = setOf(PlaneSemantic.FLOOR, PlaneSemantic.TABLE),
planeSemanticFilter = setOf(PlaneType.VERTICAL))
val movableComponent = xrSession.createMovableComponent(
systemMovable = false,
scaleInZ = false,
anchorPlacement = setOf(anchorPlacement)
)
entity.addComponent(movableComponent)
שימוש ב-ResizableComponent כדי לאפשר למשתמשים לשנות את הגודל של ישות
הלחצן ResizableComponent
מאפשר למשתמשים לשנות את הגודל של Entity
. ה-ResizableComponent
כולל סימני אינטראקציה חזותיים שמזמינים את המשתמש לשנות את הגודל של Entity
. כשיוצרים את ResizeableComponent
, אפשר לציין את הגודל המינימלי או המקסימלי (במטרים). אפשר גם לציין יחס גובה-רוחב קבוע כשמשנים את הגודל, כדי שהרוחב והגובה ישתנו באופן יחסי זה לזה.
דוגמה לשימוש ב-ResizableComponent
עם יחס גובה-רוחב קבוע:
val resizableComponent = xrSession.createResizableComponent()
resizableComponent.minimumSize = Dimensions(177f, 100f, 1f )
resizableComponent.fixedAspectRatio = 16f / 9f //Specify a 16:9 aspect ratio
entity.addComponent(resizableComponent)
שימוש ב-InteractableComponent כדי לתעד אירועי קלט של משתמשים
האירוע InteractableComponent
מאפשר לתעד אירועי קלט מהמשתמש, למשל כשהמשתמש יוצר אינטראקציה עם Entity
או מעביר את העכבר מעליו.
כשיוצרים InteractableComponent
, צריך לציין InputEventListener
כדי לקבל את אירועי הקלט. כשהמשתמש מבצע פעולת קלט כלשהי, תתבצע קריאה ל-method onInputEvent
עם פרטי הקלט הספציפיים שסופקו בפרמטר InputEvent
.
InputEvent.action
מציין את סוג הקלט, למשל החזקה או הקשה(ACTION_DOWN) על ישותInputEvent.source
מציין מאיפה הגיע הקלט, למשל קלט מיד או מבקרInputEvent.pointerType
מציין אם הקלט הגיע מהיד הימנית או מהיד השמאלית
רשימה מלאה של כל הקבועים של InputEvent
מופיעה בחומר העזר.
קטע הקוד הבא מציג דוגמה לשימוש ב-InteractableComponent
כדי להגדיל את הגודל של ישות באמצעות היד הימנית ולהקטין אותו באמצעות היד השמאלית.
private val executor by lazy { Executors.newSingleThreadExecutor() }
val interactableComponent = xrSession.createInteractableComponent(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_TYPE_RIGHT){
entity.setScale(1.5f)
} else if (it.pointerType == InputEvent.POINTER_TYPE_LEFT){
entity.setScale(0.5f)
}
}
}
entity.addComponent(interactableComponent)