تتيح لك حزمة تطوير البرامج (SDK) لمنصة Jetpack XR استخدام Jetpack SceneCore لإنشاء مثيلات Entity
والتحكّم فيها وإدارتها، مثل التصاميم الثلاثية الأبعاد والفيديوهات المجسمة وPanelEntity
باستخدام Jetpack SceneCore.
تستخدم Jetpack SceneCore نمطَين شائعَين من أنماط البنية لدعم تطوير التطبيقات الثلاثية الأبعاد، وهما مخطط المشهد ونظام الكيانات والمكوّنات (ECS).
استخدام الرسم البياني للمشهد لإنشاء الكيانات والتحكّم فيها
لإنشاء عناصر والتحكّم فيها في مساحة ثلاثية الأبعاد، يمكنك استخدام واجهة برمجة التطبيقات Session في Jetpack SceneCore للوصول إلى الرسم البياني للمشهد. يتوافق الرسم البياني للمشهد مع العالم الحقيقي للمستخدم، ويتيح لك تنظيم العناصر الثلاثية الأبعاد، مثل اللوحات والنماذج الثلاثية الأبعاد، في بنية هرمية، والاحتفاظ بحالة هذه العناصر.
بعد الحصول على إذن الوصول إلى الرسم البياني للمشهد، يمكنك استخدام واجهات برمجة التطبيقات في Jetpack Compose for XR لإنشاء واجهة مستخدم مكانية (على سبيل المثال، مثيلات SpatialPanel
وOrbiter
) ضمن الرسم البياني للمشهد. بالنسبة إلى المحتوى الثلاثي الأبعاد، مثل التصاميم الثلاثية الأبعاد، يمكنك الوصول إلى الجلسة مباشرةً. لمزيد من المعلومات، يُرجى الاطّلاع على لمحة عن
ActivitySpace في هذه الصفحة.
نظام مكونات الكيانات
يتبع نظام الكيان والمكوّن مبدأ التركيب بدلاً من الوراثة. يمكنك توسيع نطاق سلوك الكيانات من خلال إرفاق مكونات تحدد السلوك، ما يتيح لك تطبيق السلوك نفسه على أنواع مختلفة من الكيانات. لمزيد من المعلومات، يُرجى الاطّلاع على إضافة سلوك مشترك إلى الكيانات في هذه الصفحة.
لمحة عن ActivitySpace
يحتوي كل Session
على ActivitySpace
يتم إنشاؤه تلقائيًا باستخدام Session
. ActivitySpace
هو Entity
المستوى الأعلى في الرسم البياني للمشهد.
يمثّل ActivitySpace مساحة ثلاثية الأبعاد بنظام إحداثيات أيمن (يشير المحور x إلى اليمين، ويشير المحور y إلى الأعلى، ويشير المحور z إلى الخلف بالنسبة إلى نقطة الأصل) ووحدات قياس بالمتر تتطابق مع العالم الحقيقي. إنّ نقطة الأصل في ActivitySpace
اختيارية إلى حد ما (إذ يمكن للمستخدمين إعادة ضبط موضع ActivitySpace
في العالم الحقيقي)، لذا يُنصح بوضع المحتوى بالنسبة إلى بعضه البعض بدلاً من وضعه بالنسبة إلى نقطة الأصل.
التعامل مع الكيانات
تُعد الكيانات عنصرًا أساسيًا في SceneCore. معظم العناصر التي يراها المستخدم ويتفاعل معها هي كيانات تمثّل لوحات ونماذج ثلاثية الأبعاد وغير ذلك.
بما أنّ ActivitySpace
هي العقدة ذات المستوى الأعلى في الرسم البياني للمشهد، يتم تلقائيًا وضع جميع الكيانات الجديدة مباشرةً في ActivitySpace
. يمكنك نقل العناصر
على طول الرسم البياني للمشهد من خلال استدعاء setParent()
أو
addChild()
.
تتضمّن الكيانات بعض السلوكيات التلقائية للأشياء التي تنطبق على جميع الكيانات، مثل تغيير الموضع أو الدوران أو مستوى الظهور. تتضمّن بعض الفئات الفرعية، مثل GltfModelEntity
، سلوكيات إضافية تتوافق مع الفئة الفرعية.Entity
تعديل الكيانات
عند إجراء تغيير على سمة Entity
تنتمي إلى فئة Entity
الأساسية، سيتم تطبيق هذا التغيير على جميع العناصر التابعة لها. على سبيل المثال، سيؤدي تعديل Pose
لعنصر رئيسي Entity
إلى تطبيق التعديل نفسه على جميع العناصر الفرعية. لا يؤثر إجراء تغيير في 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
، استخدِم setHidden()
.
// Hide the entity entity.setHidden(true)
لتغيير حجم Entity
مع الحفاظ على شكله العام، استخدِم setScale()
.
// Double the size of the entity entity.setScale(2f)
إضافة سلوك مشترك إلى الكيانات
يمكنك استخدام المكوّنات التالية لإضافة سلوك شائع إلى الكيانات:
MovableComponent
: يسمح للمستخدم بنقل الكياناتResizableComponent
: يسمح للمستخدم بتغيير حجم العناصر باستخدام أنماط متسقة لواجهة المستخدمInteractableComponent
: تتيح لك تسجيل أحداث الإدخال للتفاعلات المخصّصة
يجب إنشاء مثيل للمكوّنات من خلال طريقة الإنشاء المناسبة في الفئة Session
. على سبيل المثال، لإنشاء ResizableComponent
، استخدِم الأمر
ResizableComponent.create()
.
لإضافة سلوك المكوّن المحدّد إلى Entity
، استخدِم الطريقة addComponent()
.
استخدام MovableComponent
لجعل الكائن قابلاً للنقل من قِبل المستخدم
تسمح MovableComponent
للمستخدم بتحريك Entity
. يمكنك أيضًا تحديد ما إذا كان يمكن تثبيت الكيان على نوع سطح معيّن، مثل الأسطح الأفقية أو الرأسية، أو الأسطح الدلالية المحدّدة، مثل الطاولة أو الجدار أو السقف. لتحديد خيارات التثبيت، حدِّد مجموعة من AnchorPlacement
عند إنشاء MovableComponent
.
في ما يلي مثال على عنصر يمكن نقله وتثبيته على أي سطح عمودي وعلى الأسطح الأفقية للأرضية والسقف فقط.
val anchorPlacement = AnchorPlacement.createForPlanes( planeTypeFilter = setOf(PlaneSemantic.FLOOR, PlaneSemantic.TABLE), planeSemanticFilter = setOf(PlaneType.VERTICAL) ) val movableComponent = MovableComponent.create( session = session, systemMovable = false, scaleInZ = false, anchorPlacement = setOf(anchorPlacement) ) entity.addComponent(movableComponent)
عندما يحرك المستخدم العنصر، تعدّل المَعلمة scaleInZ
تلقائيًا مقياس العنصر أثناء ابتعاده عن المستخدم بطريقة مشابهة لطريقة تعديل النظام لمقاييس اللوحات في المساحة الرئيسية. بسبب طبيعة "التتالي" لنظام مكونات الكيانات، سيؤثر مقياس العنصر الأصل في جميع العناصر التابعة له.
استخدِم ResizableComponent
لجعل حجم Entity قابلاً للتغيير من قِبل المستخدم
تتيح ResizableComponent
للمستخدمين تغيير حجم Entity
. يتضمّن
ResizableComponent
إشارات مرئية للتفاعل تدعو المستخدم إلى
تغيير حجم Entity
. عند إنشاء ResizableComponent
، يمكنك تحديد حد أدنى أو أقصى للحجم (بالمتر). يمكنك أيضًا تحديد نسبة عرض إلى ارتفاع ثابتة عند تغيير الحجم، وذلك لكي يتم تغيير حجم العرض والارتفاع بشكل متناسب مع بعضهما البعض.
عند استخدام ResizableComponent
، يجب تحديد ResizeListener
للاستجابة لأحداث تغيير الحجم المحدّدة، مثل onResizeUpdate
أو
onResizeEnd
.
في ما يلي مثال على استخدام السمة ResizableComponent
مع نسبة عرض إلى ارتفاع ثابتة على SurfaceEntity
:
val resizableComponent = ResizableComponent.create(session) resizableComponent.minimumSize = Dimensions(177f, 100f, 1f) resizableComponent.fixedAspectRatio = 16f / 9f // Specify a 16:9 aspect ratio resizableComponent.addResizeListener( executor, object : ResizeListener { override fun onResizeEnd(entity: Entity, finalSize: Dimensions) { // update the size in the component resizableComponent.size = finalSize // update the Entity to reflect the new size (entity as SurfaceEntity).canvasShape = SurfaceEntity.CanvasShape.Quad(finalSize.width, finalSize.height) } }, ) entity.addComponent(resizableComponent)
استخدِم InteractableComponent
لتسجيل أحداث إدخال المستخدم
تتيح لك السمة InteractableComponent
تسجيل أحداث الإدخال من المستخدم،
مثل عندما يتفاعل المستخدم مع Entity
أو يمرّر مؤشر الماوس فوقه. عند إنشاء
InteractableComponent
، يجب تحديد InputEventListener
لتلقّي أحداث الإدخال. عندما ينفّذ المستخدم أي إجراء إدخال، سيتم استدعاء الطريقة
onInputEvent
مع معلومات الإدخال المحدّدة
المقدَّمة في المَعلمة 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_TYPE_RIGHT) { entity.setScale(1.5f) } else if (it.pointerType == InputEvent.POINTER_TYPE_LEFT) { entity.setScale(0.5f) } } } entity.addComponent(interactableComponent)