Cette page contient des conseils courants pour créer un Scene
et interagir avec celui-ci.
Afficher une scène sans RA
La classe SceneView
vous permet d'afficher une scène 3D sans avoir à utiliser la caméra de l'appareil ni une session de RA. Cette fonctionnalité est utile pour prévisualiser des objets 3D dans votre application sans la RA, ou pour fournir des fonctionnalités alternatives sur des appareils non compatibles avec la RA.
Par défaut, SceneView
n'affiche pas l'image de la caméra de RA et utilise un arrière-plan noir. Pour modifier la couleur de l'arrière-plan, vous pouvez appeler view.setBackgroundColor()
ou définir une couleur d'arrière-plan dans la mise en page, comme indiqué ci-dessous:
<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"/>
Le nœud Camera
de la scène est placé à l'origine (position 0,0,0) et orienté vers l'avant (direction 0,0,-1). La position et la rotation de la caméra ne sont pas liées au suivi du mouvement en RA. Vous pouvez donc la repositionner ou l'animer comme n'importe quel autre nœud.
Camera camera = sceneView.getScene().getCamera();
camera.setLocalRotation(Quaternion.axisAngle(Vector3.right(), -30.0f));
Interactions
Gérer les commandes tactiles de l'utilisateur
Lorsque l'utilisateur touche l'écran, Sceneform propage l'événement tactile aux gestionnaires d'événements et aux écouteurs associés aux nœuds et à la scène. Ce comportement est semblable à la manière dont les événements tactiles se propagent dans les vues et les groupes de vues dans Android. Voici l'ordre de propagation:
L'événement est envoyé à tout écouteur ajouté dans
scene.addOnPeekTouchListener()
.Cette méthode est semblable à
viewGroup.intercept()
, si ce n'est que l'écouteur tactile de la scène n'est pas compatible avec l'événement.L'événement est transmis au premier nœud avec lequel le rayon se croise.
- Le nœud peut consommer l'événement en définissant un ensemble de méthodes
onTouchEvent()
qui renvoietrue
. - Si la méthode
onTouchEvent()
renvoiefalse
ou qu'aucun écouteur n'est défini, l'événement est propagé au parent du nœud. Ce processus se poursuit jusqu'à ce que l'événement soit consommé ou que la scène soit atteinte.
- Le nœud peut consommer l'événement en définissant un ensemble de méthodes
Enfin, si aucun écouteur n'a consommé l'événement, celui-ci est transmis à
scene.onTouchListener()
.
Détecter des gestes
ArFragment
est désormais compatible avec les gestes tactiles (sélection), déplacement (glissement), pincement (mise à l'échelle) et rotation (rotation).
Par exemple, consultez HelloSceneformActivity.java
dans l'exemple d'application HelloSceneform.
Créer des nœuds personnalisés
Comme pour la création de vues Android personnalisées, vous pouvez créer des nœuds personnalisés en définissant des sous-classes Node
. Vous pouvez être amené à créer un nœud personnalisé dans les cas suivants:
- Vous souhaitez accéder à des événements du cycle de vie du nœud, tels que
onUpdate()
,onActivate
etonDeactivate()
. - Vous souhaitez créer un nœud composé d'un groupe de nœuds.
- Vous dupliquez beaucoup de code et pouvez l'intégrer à une sous-classe.
Pour obtenir un exemple, consultez Planet.java
dans l'exemple d'application du système solaire.
Animer des nœuds
Il existe deux façons d'animer les nœuds:
- Utilisez
ObjectAnimator
de l'API standard Android Animation. - Créer une classe de nœud personnalisé et remplacer
onUpdate()
Animer des objets avec ObjectAnimator
Voici un exemple qui permet d'animer une intensité d'un effet de projecteur:
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();
Pour en savoir plus, consultez la page Animer avec ObjectAnimator.
Animer dans onUpdate
Remplacez l'élément onUpdate()
du nœud pour l'animer. L'exemple suivant, qui utilise Planet.java
dans l'exemple d'application Solar System, ajuste la carte d'informations à chaque image pour qu'elle fasse face à l'utilisateur, même lorsque la planète tourne.
@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);
}
Ajouter des lumières
Lights
peut être associé à n'importe quel nœud de la scène. Par défaut, chaque scène Sceneform comprend un nœud Sun
auquel une lumière directionnelle est associée.
Vous pouvez modifier le soleil ou ajouter vos propres lumières à une scène. L'exemple suivant ajoute un effet de projecteur:
Light spotLightYellow =
Light.builder(this, Light.Type.FOCUSED_SPOTLIGHT)
.setColor(new Color(android.graphics.Color.YELLOW))
.setShadowCastingEnabled(true)
.build();
Appelez ensuite setLight()
pour l'associer à un nœud.
Personnaliser la visualisation du plan
Par défaut, la scène dispose d'un PlaneRenderer
qui met en évidence Planes
lorsqu'il a été détecté par ARCore. Elle se présente comme suit :
Vous pouvez modifier la matière et la texture par défaut utilisées pour le rendu des surfaces planes détectées. Voici comment modifier 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));
});
Ombres
Les ombres donnent l'impression que le rendu s'ancre dans le monde et donne aux utilisateurs un peu de profondeur et d'espace.
Dans Sceneform, les objets peuvent caster des ombres et les objets qui peuvent recevoir des ombres.
Lights
etRenderables
peuvent caster des ombresPar défaut, la diffusion des ombres est activée sur le soleil, mais pas pour les lumières. Appelez
setShadowCastingEnabled()
pour l'activer.Renderables
etPlaneRenderer
peuvent recevoir des ombres.Par défaut, la réception en parallèle est activée. Appelez
setShadowReceiver()
pour la désactiver.
Si un rendu peut caster et recevoir des ombres, il peut projeter des ombres sur lui-même.