تتيح لك حزمة تطوير البرامج (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
. يمكنك نقل المواقع الجغرافية
للكيانات على طول الرسم البياني للمشهد من خلال ضبط parent
أو باستخدام
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
، استخدِم 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
لجعل حجم مستخدم الكائن قابلاً للتغيير
تتيح 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
، حدِّد أداة معالجة تتلقّى أحداث الإدخال.
عندما ينفّذ المستخدم أي إجراء إدخال، سيتم استدعاء أداة معالجة الأحداث مع معلومات الإدخال المقدَّمة في المَعلمة 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)