Questa pagina contiene suggerimenti comuni per creare una Scene e interagirvi.
Rendering di una scena senza AR
Il corso SceneView ti consente di eseguire il rendering di una scena 3D senza richiedere l'utilizzo della fotocamera del dispositivo o di una sessione AR. È utile per visualizzare l'anteprima degli oggetti 3D nell'app senza AR o per fornire funzionalità alternative sui dispositivi che non supportano l'AR.
Per impostazione predefinita, SceneView non mostra l'immagine dalla fotocamera AR e utilizza uno sfondo nero. Per cambiare il colore dello sfondo, puoi chiamare view.setBackgroundColor() o definire un colore di sfondo nel layout come mostrato di seguito:
<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"/>
Il nodo Camera della scena viene posizionato nell'origine (posizione 0,0,0) e rivolto in avanti (direzione 0,0,-1). Poiché la posizione e la rotazione della videocamera non sono collegate al rilevamento del movimento AR, puoi riposizionarla o animarla come qualsiasi altro nodo.
Camera camera = sceneView.getScene().getCamera();
camera.setLocalRotation(Quaternion.axisAngle(Vector3.right(), -30.0f));
Interazioni
Gestire il tocco degli utenti
Quando l'utente tocca lo schermo, Sceneform propaga l'evento touch ai gestori di eventi e ai listener collegati ai nodi e alla scena. Questo comportamento è simile alla propagazione degli eventi touch nelle visualizzazioni e nei gruppi di visualizzazioni in Android. Ecco l'ordine di propagazione:
L'evento viene inviato a qualsiasi ascoltatore aggiunto in
scene.addOnPeekTouchListener().È simile a
viewGroup.intercept(), ad eccezione del fatto che l'ascoltatore della scena in anteprima non può consumare l'evento.L'evento viene passato al primo nodo con cui si incrocia il raggio.
- Il nodo può consumare l'evento definendo un set di metodi
onTouchEvent()che restituiscetrue. - Se il metodo
onTouchEvent()restituiscefalseo non viene definito alcun listener, l'evento viene propagato al genitore del nodo. Questo processo continua fino al consumo dell'evento o fino al raggiungimento della scena.
- Il nodo può consumare l'evento definendo un set di metodi
Infine, se nessun listener ha utilizzato l'evento, questo viene trasmesso a
scene.onTouchListener().
Rilevamento dei gesti
ArFragment ha un supporto integrato per gesti di tocco (selezione), trascinamento (spostamento), pizzico (scala) e rotazione (rotazione).
Ad esempio, vedi HelloSceneformActivity.java nell'app di esempio HelloSceneform.
Crea nodi personalizzati
Analogamente alla creazione di viste Android personalizzate, puoi creare nodi personalizzati con la sottoclasse Node. Ecco alcune situazioni in cui potresti voler creare un nodo personalizzato:
- Vuoi accedere agli eventi nel ciclo di vita dei nodi, ad esempio
onUpdate(),onActivateeonDeactivate(). - Vuoi creare un nodo composto da un gruppo di nodi.
- Stai duplicando molto codice e puoi includerlo in una sottoclasse.
Per un esempio, vedi Planet.java nell'app di esempio Solar System.
Animazione dei nodi
Esistono due modi per animare i nodi:
- Utilizza
ObjectAnimatordall'API Android Animation standard. - Crea una classe di nodo personalizzato ed esegui l'override di
onUpdate()
Animazione con ObjectAnimator
Ecco un esempio che anima un'intensità di Spotlight:
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();
Per ulteriori informazioni, consulta la sezione Animazione con ObjectAnimator.
Animazione in onUpdate
Sostituisci l'onUpdate() del nodo per animarlo da un frame all'altro. L'esempio seguente, a partire da Planet.java nell'app di esempio Solar System, regola la scheda informativa ogni frame per inquadrare l'utente, anche quando il pianeta ruota.
@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);
}
Aggiungi luci
Lights può essere collegato a qualsiasi nodo nella scena. Per impostazione predefinita, ogni scena Sceneform include un nodo Sun, a cui è collegata una luce direzionale.
Puoi modificare il sole o aggiungere le tue luci a una scena. L'esempio seguente aggiunge un riflettore:
Light spotLightYellow =
Light.builder(this, Light.Type.FOCUSED_SPOTLIGHT)
.setColor(new Color(android.graphics.Color.YELLOW))
.setShadowCastingEnabled(true)
.build();
Quindi chiama setLight() per collegarlo a un nodo.
Personalizzare la visualizzazione del piano
Per impostazione predefinita, la scena contiene un elemento PlaneRenderer che evidenzia Planes quando sono stati rilevati da ARCore. Ha questo aspetto:
Puoi modificare il materiale e la texture predefiniti utilizzati per visualizzare i piani rilevati. Ecco come modificare la texture:
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));
});
Ombre
Le ombre fanno apparire i rendering di terra nel mondo e danno agli utenti un senso di profondità e di spazio.
In Sceneform, esistono oggetti che possono castare ombre e oggetti che possono ricevere ombreggiature.
LightseRenderablespossono proiettare ombrePer impostazione predefinita, la trasmissione delle ombre è attivata sul sole, ma non sulle luci. Chiama il numero
setShadowCastingEnabled()per attivarla.RenderablesePlaneRendererpossono ricevere ombre.Per impostazione predefinita, è attiva la ricezione shadow. Chiama
setShadowReceiver()per disattivarla.
Se un rendering può trasmettere e ricevere ombre, può trasmettere ombra su se stessa.


