یک صحنه را بسازید و با آن تعامل کنید

این صفحه حاوی نکات رایج برای ساخت یک 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));

فعل و انفعالات

لمس کاربر را کنترل کنید

هنگامی که کاربر صفحه را لمس می کند، Sceneform رویداد لمسی را به کنترل کننده رویداد و شنوندگان متصل به گره ها و صحنه منتشر می کند. این رفتار شبیه نحوه انتشار رویدادهای لمسی به نماها و مشاهده گروه‌ها در Android است. ترتیب انتشار به شرح زیر است:

  1. رویداد برای هر شنونده ای که در scene.addOnPeekTouchListener() اضافه شده است ارسال می شود.

    این شبیه به viewGroup.intercept() است، با این تفاوت که شنونده لمسی صحنه نمی تواند رویداد را مصرف کند.

  2. رویداد به اولین گره ای که پرتو با آن تقاطع پیدا می کند ارسال می شود.

    • گره می‌تواند رویداد را با تعریف یک مجموعه متد onTouchEvent() که true را برمی‌گرداند مصرف کند.
    • اگر onTouchEvent() false را برگرداند، یا شنونده ای تعریف نشده باشد، رویداد به والد گره منتشر می شود. این روند تا زمانی که رویداد مصرف شود یا به صحنه برسد ادامه می یابد.
  3. در نهایت، اگر هیچ شنونده ای رویداد را مصرف نکرده باشد، رویداد به scene.onTouchListener() می شود.

تشخیص حرکات

ArFragment پشتیبانی از حرکات ضربه (انتخاب)، کشیدن (حرکت)، نیشگون گرفتن (مقیاس)، و چرخش (چرخش) را دارد.

به عنوان مثال، HelloSceneformActivity.java را در برنامه نمونه HelloSceneform ببینید .

گره های سفارشی ایجاد کنید

مشابه ایجاد نماهای سفارشی اندروید، می توانید گره های سفارشی را با زیر کلاس بندی Node ایجاد کنید. در اینجا چند موقعیت وجود دارد که ممکن است بخواهید یک گره سفارشی ایجاد کنید:

  • می‌خواهید به رویدادهایی در چرخه عمر گره دسترسی داشته باشید، مانند onUpdate 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 ها را می توان به هر گره ای در صحنه وصل کرد. به‌طور پیش‌فرض، هر صحنه Sceneform شامل یک گره 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));
        });

سایه ها

سایه‌ها باعث می‌شوند که رندربل‌ها در دنیا زمینی به نظر برسند و به کاربران حس عمق و فضا را می‌دهند.

در Sceneform، اشیائی هستند که می توانند سایه ایجاد کنند و اشیایی هستند که می توانند سایه دریافت کنند .

  • Lights و Renderables ها می توانند سایه ایجاد کنند

    به‌طور پیش‌فرض، سایه‌زنی روی خورشید فعال است، اما برای نورها نه. برای روشن کردن setShadowCastingEnabled() فراخوانی کنید.

  • Renderables و PlaneRenderer می توانند سایه ها را دریافت کنند.

    به طور پیش فرض، دریافت سایه فعال است. برای خاموش کردن setShadowReceiver() فراخوانی کنید.

اگر یک renderable هم سایه می اندازد و هم سایه می گیرد، می تواند روی خودش سایه بیاندازد.