این صفحه حاوی نکات رایج برای ساخت یک 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 است. ترتیب انتشار به شرح زیر است:
رویداد برای هر شنونده ای که در
scene.addOnPeekTouchListener()
اضافه شده است ارسال می شود.این شبیه به
viewGroup.intercept()
است، با این تفاوت که شنونده لمسی صحنه نمی تواند رویداد را مصرف کند.رویداد به اولین گره ای که پرتو با آن تقاطع پیدا می کند ارسال می شود.
- گره میتواند رویداد را با تعریف یک مجموعه متد
onTouchEvent()
کهtrue
را برمیگرداند مصرف کند. - اگر
onTouchEvent()
false
را برگرداند، یا شنونده ای تعریف نشده باشد، رویداد به والد گره منتشر می شود. این روند تا زمانی که رویداد مصرف شود یا به صحنه برسد ادامه می یابد.
- گره میتواند رویداد را با تعریف یک مجموعه متد
در نهایت، اگر هیچ شنونده ای رویداد را مصرف نکرده باشد، رویداد به
scene.onTouchListener()
می شود.
تشخیص حرکات
ArFragment
پشتیبانی از حرکات ضربه (انتخاب)، کشیدن (حرکت)، نیشگون گرفتن (مقیاس)، و چرخش (چرخش) را دارد.
به عنوان مثال، HelloSceneformActivity.java
را در برنامه نمونه HelloSceneform ببینید .
گره های سفارشی ایجاد کنید
مشابه ایجاد نماهای سفارشی اندروید، می توانید گره های سفارشی را با زیر کلاس بندی Node
ایجاد کنید. در اینجا چند موقعیت وجود دارد که ممکن است بخواهید یک گره سفارشی ایجاد کنید:
- میخواهید به رویدادهایی در چرخه عمر گره دسترسی داشته باشید، مانند onUpdate
onUpdate()
،onActivate
وonDeactivate()
. - شما می خواهید یک گره ایجاد کنید که از گروهی از گره ها تشکیل شده باشد.
- شما کدهای زیادی را کپی می کنید و می توانید آن را به یک زیر کلاس تبدیل کنید.
برای مثال، Planet.java
را در برنامه نمونه منظومه شمسی ببینید.
گره ها را متحرک کنید
دو راه برای متحرک سازی گره ها وجود دارد:
- از
ObjectAnimator
از API استاندارد Android Animation استفاده کنید. - یک کلاس node سفارشی ایجاد کنید و
onUpdate()
را لغو کنید
با 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 هم سایه می اندازد و هم سایه می گیرد، می تواند روی خودش سایه بیاندازد.