יצירת סצנה ואינטראקציה איתה

הדף הזה מכיל טיפים נפוצים ליצירה של Scene ולאינטראקציה איתו.

רינדור סצנה ללא AR

הכיתה SceneView מאפשרת לעבד סצנה בתלת-ממד ללא צורך בשימוש במצלמה של המכשיר או בסשן AR. זו שימושית לתצוגה מקדימה של אובייקטים בתלת-ממד באפליקציה ללא AR, או כדי לספק פונקציונליות חלופית במכשירים שאינם תומכים ב-AR.

כברירת מחדל, SceneView לא מציגה את התמונה ממצלמת ה-AR ומשתמשת ברקע שחור. כדי לשנות את צבע הרקע, אפשר להתקשר לפונקציה view.setBackgroundColor() או להגדיר צבע רקע בפריסה כפי שמוצג למטה:

<com.google.ar.sceneform.SceneView
    android:id="@+id/scene_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/deep_teal"/>

הצומת Camera של הסצנה מוקם במקור (מיקום 0,0,0) ופונה קדימה (כיוון 0,0,-1). מאחר שהמיקום והסיבוב של המצלמה לא קשורים למעקב אחר התנועה ב-AR, אפשר למקם אותה מחדש או להגדיר לה אנימציה, כמו כל צומת אחר.

Camera camera = sceneView.getScene().getCamera();
camera.setLocalRotation(Quaternion.axisAngle(Vector3.right(), -30.0f));

אינטראקציות

ניהול מגע של משתמשים

כשהמשתמש נוגע במסך, התכונה schemapena מרחיבה את אירוע המגע למטפלים ולמאזינים של האירועים המחוברים לצמתים ולסצנה. התנהגות זו דומה לאופן שבו מתרחשים אירועי מגע בצפיות ובתצוגות המפורטות ב-Android. זהו סדר ההפצה:

  1. האירוע יישלח לכל המאזינים שיתווספו באמצעות scene.addOnPeekTouchListener().

    הפעולה הזו דומה ל-viewGroup.intercept(), אבל היא לא יכולה לצרוך את האירוע בהאזנה מהירה.

  2. האירוע מועבר לצומת הראשון שהקרן חוצה אותו.

    • הצומת יכול לצרוך את האירוע על ידי הגדרת שיטת onTouchEvent() המחזירה true.
    • אם השיטה onTouchEvent() מחזירה את הערך false, או שלא מוגדר מאזינים, האירוע מופץ להורים של הצומת. התהליך הזה נמשך עד לצריכה של האירוע או עד שמגיעים לסצנה.
  3. לסיום, אם אף מאזינים לא צרכו את האירוע, האירוע מועבר אל scene.onTouchListener().

זיהוי תנועות

ב-ArFragment יש תמיכה מובנית בתנועות של הקשה (בחירה), גרירה (העברה), צביטה (קנה מידה) ופיתול (סיבוב).

לדוגמה, אפשר לראות את HelloSceneformActivity.java באפליקציה לדוגמה HelloSceneform.

יצירת צמתים בהתאמה אישית

בדומה ליצירת תצוגות מותאמות אישית של Android, ניתן ליצור צמתים מותאמים אישית על ידי סיווג משנה Node. הנה כמה מצבים שבהם כדאי ליצור צומת מותאם אישית:

  • רוצים לגשת לאירועים במחזור החיים של הצומת, כמו onUpdate(), onActivate ו-onDeactivate().
  • אתם רוצים ליצור צומת שמורכב מקבוצה של צמתים.
  • מתבצע שכפול של הרבה קוד, ואפשר לשייך אותו לסיווג משנה.

לדוגמה, אפשר לראות את Planet.java באפליקציה לדוגמה של מערכת השמש.

אנימציה של צמתים

יש שתי דרכים ליצור אנימציה של צמתים:

אנימציה עם ObjectAnimator

דוגמה לאנימציה של התמקדות בזרקור:

final int durationInMilliseconds = 1000;
final float minimumIntensity = 1000.0f;
final float maximumIntensity = 3000.0f;
ValueAnimator intensityAnimator =
    ObjectAnimator.ofFloat(
        spotlightNode.getLight(), "intensity", minimumIntensity, maximumIntensity);
intensityAnimator.setDuration(durationInMilliseconds);
intensityAnimator.setRepeatCount(ValueAnimator.INFINITE);
intensityAnimator.setRepeatMode(ValueAnimator.REVERSE);
intensityAnimator.start();

מידע נוסף זמין במאמר אנימציה עם ObjectAnimator.

אנימציה ב-onUpdate

מבטלים את הצומת של onUpdate() כדי להוסיף אנימציה למסגרת. הדוגמה הבאה, מ-Planet.java באפליקציה לדוגמה מערכת סולארית, מתאימה את כרטיס המידע לכל פריים כדי לפנות אל המשתמש, גם אם כדור הארץ מסתובב.

@Override
public void onUpdate(FrameTime frameTime) {
  Vector3 cameraPosition = getScene().getCamera().getWorldPosition();
  Vector3 cardPosition = infoCard.getWorldPosition();
  Vector3 direction = Vector3.subtract(cameraPosition, cardPosition);
  Quaternion lookRotation = Quaternion.lookRotation(direction, Vector3.up());
  infoCard.setWorldRotation(lookRotation);
}

הוספת אורות

ניתן לצרף את Lights לכל צומת בסצנה. כברירת מחדל, כל סצנה ב-סביבת התצוגה כוללת צומת Sun, עם תאורת כיוון.

אתם יכולים לשנות את השמש או להוסיף תאורה משלכם לסצנה. הדוגמה הבאה מוסיפה באור הזרקורים:

Light spotLightYellow =
    Light.builder(this, Light.Type.FOCUSED_SPOTLIGHT)
        .setColor(new Color(android.graphics.Color.YELLOW))
        .setShadowCastingEnabled(true)
        .build();

לאחר מכן יש להתקשר אל setLight() כדי לצרף אותו לצומת.

התאמה אישית של הצגת המטוס

כברירת מחדל, לסצנה יש PlaneRenderer שמדגיש את Planes כשהם מזוהים על ידי ARCore. כך זה נראה:

ניתן לשנות את חומר ברירת המחדל ואת המרקם המשמש לעיבוד המטוסים שזוהו. כך משנים את המרקם:

Texture.Sampler sampler =
        Texture.Sampler.builder()
                .setMinFilter(Texture.Sampler.MinFilter.LINEAR)
                .setWrapMode(Texture.Sampler.WrapMode.REPEAT)
                .build();

// R.drawable.custom_texture is a .png file in src/main/res/drawable
Texture.builder()
        .setSource(this, R.drawable.custom_texture)
        .setSampler(sampler)
        .build()
        .thenAccept(texture -> {
          arSceneView.getPlaneRenderer()
                  .getMaterial().thenAccept(material ->
                  material.setTexture(PlaneRenderer.MATERIAL_TEXTURE, texture));
        });

צלליות

צלליות גורמות לרינדור של יצירות מלוטשות בעולם ומשאירות למשתמשים תחושת עומק ושטח.

ב- הרשאה של עיצוב צורה, יש אובייקטים שיכולים להטיל צלליות ואובייקטים שיכולים לקבל צלליות.

  • Lights ו-Renderables יכולים להעביר צלליות

    כברירת מחדל, העברה (cast) באמצעות צללית מופעלת בשמש, אבל לא בתאורה. צריך להתקשר אל setShadowCastingEnabled() כדי להפעיל אותו.

  • Renderables ו-PlaneRenderer יכולים לקבל צלליות.

    קבלת צלליות מופעלת כברירת מחדל. יש להתקשר אל setShadowReceiver() כדי להשבית אותה.

אם אפשרות עיבוד ניתנת להעברה (cast) וגם מקבלת צלליות, היא יכולה להטיל צלליות על עצמה.