arcore the displaying image is perpendicular to the plane - arcore

This is what I want ->
Here some importants part of code, I want to display the author of the book on top of the book but as you see displaying image perpendicular to the book. Help me, this is what I got ->
private void OnUpdateFrame(FrameTime frameTime){
Frame frame=arFragment.getArSceneView().getArFrame();
Collection<AugmentedImage> augmentedImages=frame.getUpdatedTrackables(AugmentedImage.class);
for(AugmentedImage augmentedImage: augmentedImages){
if(augmentedImage.getTrackingState()== TrackingState.TRACKING ){
if(augmentedImage.getName().equals("arimage") && shouldAddModel){
placeObject(arFragment,
augmentedImage.createAnchor(augmentedImage.getCenterPose()),
Uri.parse("author.jpg"));
shouldAddModel=false;
}
}}
}
private void placeObject(ArFragment fragment, Anchor anchor, Uri model){
ViewRenderable.builder().
setView(this,R.layout.lol)
.setVerticalAlignment(ViewRenderable.VerticalAlignment.BOTTOM)
.build()
.thenAccept(viewRenderable -> addNodeToScene(fragment,anchor,viewRenderable))
.exceptionally(throwable -> {
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setMessage(throwable.getMessage())
.setTitle("Error!");
AlertDialog dialog=builder.create();
dialog.show();
return null;
});
}
private void addNodeToScene(ArFragment fragment, Anchor anchor, ViewRenderable viewRenderable) {
AnchorNode anchorNode=new AnchorNode(anchor);
anchorNode.setLocalScale(new Vector3(0.5f, 0.5f, 0.5f));
TransformableNode node=new TransformableNode(fragment.getTransformationSystem());
node.setRenderable(viewRenderable);
node.setParent(anchorNode);
fragment.getArSceneView().getScene().addChild(anchorNode);
node.select();
}

A simple local rotation of the node should do the trick.Once you have set the parent of the node as this.
node.setParent(anchorNode);
node.setLocalRotation(Quaternion.axisAngle(new Vector3(0, 0, 1f), 180));
fragment.getArSceneView().getScene().addChild(anchorNode);
Play around with the values of the Quaternion. You should get it.

Related

how to display first two objects in loop of anchor in sceneform ARcCore

if (frame.getCamera().getTrackingState() == TrackingState.TRACKING && anchorsts && !placed) {
Session session = arFragment.getArSceneView().getSession();
String type = "fwd";
int distance = 0;
int nextPoint = 1;
String[] positions = {"u", "u","r", "r","r", "r", "r", "r", "r", "r"};
if (turnStatus == null){
turnStatus = positions[distance];
Log.i("turnStatus", "pos " + positions[distance]);
}
float[] rotation = {0, 0, 0, 0};
do {
if (positions[distance].equals("u")) {
turnStatus = "u";
placeNav(session, new float[]{dx, dy, dz}, rotation, positions[distance]);
if (!turnStatus.equals(positions[nextPoint])) {
if (positions[nextPoint].equals("r")) {
turnDistance = distance;
}
}
} else if (positions[distance].equals("r")){
turnDistance ++;
turnStatus = "r";
placeNav(session, new float[]{turnDistance, -1.5f, -turnDistance}, rotation, positions[distance]);
if (!turnStatus.equals(positions[nextPoint])) {
if (positions[nextPoint].equals("u")) {
}
}
}
distance++;
nextPoint ++;
} while (distance <9);
placed = true; //to place the arrow just once.
}
private void placeNav(Session session, float[] pos, float[] rotation, String type) {
AnchorNode anchorNode = new AnchorNode(anchor);
currentAnchorNode = anchorNode;
anchorNode.setParent(arFragment.getArSceneView().getScene());
Node arrow = new Node();
arrow.setParent(anchorNode);
if (type.equals("u"))
arrow.setRenderable(andyRenderable);
else if (type.equals("r"))
arrow.setRenderable(andyRenderable);
}
the above code is used to render a loop of renderables into scene. I need to display only first two renderables and display next renderables while user is moving forward. here the positions array isnused to render objects into scene. Please to help me to implement this
Just create the first two renderable in onCreate method. For creating the other renderable, when the person is moving forward, you should check if the new position of the camera is in front of the previous position of the camera.
Vector3 newCameraPosition = getScene().getCamera().getWorldPosition();
Vector3 direction = Vector3.subtract(newCameraPosition, oldCameraPosition);
Quaternion lookRotation = Quaternion.lookRotation(direction, Vector3.up());
double product =
(newCameraPosition.x - oldCameraPosition.x) * direction.x + (newCameraPosition.y - oldCameraPosition.y) * direction.y + (newCameraPosition.z - oldCameraPosition.z) * direction.z;
if (product > 0.0) {
// means camera moved forward
}

How do we use sceneform along with ARCloud anchors?

Every time I try to host an anchor "session.hostCloudAnchor(anchor);" it shows up NotTrackingException.
How can we host and resolve the Anchor that we get from arFragment.setOnTapArPlaneListener ?
This is the snippet of the code I was using,
arFragment.setOnTapArPlaneListener(
(HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
Camera camera = arFragment.getArSceneView().getArFrame().getCamera();
TrackingState cameraTrackingState = camera.getTrackingState();
if (andyRenderable == null) {
return;
}
if (plane.getType() != Type.HORIZONTAL_UPWARD_FACING) {
return;
}
if (cameraTrackingState == TrackingState.TRACKING && session!= null) {
// Create the Anchor.
anchor = hitResult.createAnchor();
try{
session.hostCloudAnchor(anchor);
}
catch (NotTrackingException e)
{
e.printStackTrace();
}
setNewAnchor(anchor);
appAnchorState = AppAnchorState.HOSTING;
Toast.makeText(HelloSceneformActivity.this, "Now, hosting anchor", Toast.LENGTH_SHORT)
.show();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(arFragment.getArSceneView().getScene());
// Create the transformable andy and add it to the anchor.
TransformableNode andy = new TransformableNode(arFragment.getTransformationSystem());
andy.setParent(anchorNode);
andy.setRenderable(andyRenderable);
andy.select();
checkUpdatedAnchor();
}
});
You need to check the anchor tracking state & proceed with hosting.
override fun onTapPlane(hitResult: HitResult, plane: Plane, motionEvent: MotionEvent?) {
if (plane.type == Plane.Type.HORIZONTAL_UPWARD_FACING) {
val anchor = hitResult.createAnchor()
val anchorNode = AnchorNode(anchor)
anchorNode.setParent(arFragment.arSceneView.scene)
if (anchor.trackingState == TrackingState.TRACKING) {
viewModel.hostAnchorToCloud(anchor)
}
}
}
Before hosting an anchor:
Try to look at the anchor from different angles.
Move around the anchor for at least a few seconds.
Make sure you are not too far away from the anchor.
Refer : https://developers.google.com/ar/develop/java/cloud-anchors/cloud-anchors-developer-guide-android

Android Attach Image between text with SpannableStringBuilder

Sory for my english. I want attach image from gallery and show in edit text with SpannableStringBuilder. I have success for get Image Path from Gallery. After picture selected, Picture Show. But, for the second attach image picture not show and first image attach became a text. any one give me solution ? big thanks.
this is my code:
private void IntentPict() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select File"),MY_INTENT_CLICK);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode == MY_INTENT_CLICK){
if (null == data) return;
String selectedImagePath;
Uri selectedImageUri = data.getData();
//there is no problem with get path
selectedImagePath = ImageFilePath.getPath(getApplicationContext(), selectedImageUri);
//pathImag is ListArray<String>
pathImg.add(selectedImagePath);
addImageBetweentext(pathImg);
}
}
}
private void addImageBetweentext(ArrayList<String> listPath) {
SpannableStringBuilder ssb = new SpannableStringBuilder();
for(int i=0;i<listPath.size();i++){
String path = listPath.get(i);
Drawable drawable = Drawable.createFromPath(path);
drawable.setBounds(0, 0, 400, 400);
ssb.append(mBodyText+"\n");
ssb.setSpan(new ImageSpan(drawable), ssb.length()-(path.length()+1),
ssb.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
mBodyText.setText(ssb);
}
Here's something that should work. I am loading resource drawables instead, just because it was quicker for me to validate, but I tried to keep as mich as possible for your original flow and variable names:
Drawable[] drawables = new Drawable[2];
drawables[0] = getResources().getDrawable(R.drawable.img1);
drawables[1] = getResources().getDrawable(R.drawable.img2);
SpannableStringBuilder ssb = new SpannableStringBuilder();
for (int i = 0; i < drawables.length; i++) {
Drawable drawable = drawables[i];
drawable.setBounds(0, 0, 400, 400);
String newStr = drawable.toString() + "\n";
ssb.append(newStr);
ssb.setSpan(
new ImageSpan(drawable),
ssb.length() - newStr.length(),
ssb.length() - "\n".length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
mBodyText.setText(ssb);
Long story short: the start position for the incremental builder needs to be set to the current length of it, minus what you just added.

No head tracking in demo scene

I have downloaded the sdk and tried to load up the demo scene but there is no head tracking when I export an apk, any suggestions?
on installing the apk, i get the stereo scene and the cube is rotating, but no head tracking. I can turn on and off the distortion but have not found where I can enable head tracking.
Any help would be much appreciated.
1.) Create a new c# script in Unity3D with this content:
using UnityEngine;
using System.Collections;
public class VROneRotateAround : MonoBehaviour {
public Transform target;
public float distance = 5f;
public Vector3 offset = Vector3.zero;
public bool useAngleX = true;
public bool useAngleY = true;
public bool useAngleZ = true;
public bool useRealHorizontalAngle = true;
public bool resetViewOnTouch = true;
private Quaternion initialRotation = Quaternion.identity;
private Quaternion currentRotation;
private static Vector3 gyroAngles; // original angles from gyro
private static Vector3 usedAngles; // converted into unity world coordinates
private int userSleepTimeOut; // original device SleepTimeOut setting
private bool gyroAvail = false;
void Start() {
Input.compensateSensors = true;
transform.position = (target.position + offset) - transform.forward * distance;
}
void FixedUpdate() {
if (gyroAvail == false) {
if (Input.gyro.attitude.eulerAngles != Vector3.zero && Time.frameCount > 30) {
gyroAvail = true;
initialRotation = Input.gyro.attitude;
target.gameObject.SendMessage("StartFlight");
}
return; // early out
}
// reset origin on touch or not yet set origin
if(resetViewOnTouch && (Input.touchCount > 0))
initialRotation = Input.gyro.attitude;
// new rotation
currentRotation = Quaternion.Inverse(initialRotation)*Input.gyro.attitude;
gyroAngles = currentRotation.eulerAngles;
//usedAngles = Quaternion.Inverse (currentRotation).eulerAngles;
usedAngles = gyroAngles;
// reset single angle values
if (useAngleX == false)
usedAngles.x = 0f;
if (useAngleY == false)
usedAngles.y = 0f;
if (useAngleZ == false)
usedAngles.z = 0f;
if (useRealHorizontalAngle)
usedAngles.y *= -1;
transform.localRotation = Quaternion.Euler (new Vector3(-usedAngles.x, usedAngles.y, usedAngles.z));
transform.position = (target.position + offset) - transform.forward * distance;
}
public static Vector3 GetUsedAngles() {
return usedAngles;
}
public static Vector3 GetGyroAngles() {
return gyroAngles;
}
public void ResetView() {
initialRotation = Input.gyro.attitude;
}
void OnEnable() {
// sensor on
Input.gyro.enabled = true;
initialRotation = Quaternion.identity;
gyroAvail = false;
// store device sleep timeout setting
userSleepTimeOut = Screen.sleepTimeout;
// disable sleep timeout when app is running
Screen.sleepTimeout = SleepTimeout.NeverSleep;
}
void OnDisable() {
// restore original sleep timeout
Screen.sleepTimeout = userSleepTimeOut;
//sensor off
Input.gyro.enabled = false;
}
}
Open the demo scene and attach this script to the VROneSDK prefab.
In the property editor select Cube as Target and enter 6 for distance.
Build the app and test it on a device or use UnityRemote to test the behaviour in the editor.
the SDK seems to run only on the supported deviced you need to get a S5 to get it working. You also need to get the Android Pro Plugin for Unity.
We actually did get the distotion going but the screen is cropped for like 10 pxels on either side. That can't be right.
Same here: I see the demo scene (rotating cube on a grid backdrop and three light sources) in a left/right split-screen, but there is no head tracking. No pre-distortion either.
This is on a Samsung Galaxy S3 (Android 4.3) with Unity 4.5.3f3.

How to write to file (encode) modified camera frames in Windows Phone 8

I have custom an camera app in Windows Phone 8. I need add a watermark image to each frame from camera capture and then record to a video.
I can customise each frame from the preview using the following code:
int[] pixelData = new int[(int)(camera.PreviewResolution.Width * camera.PreviewResolution.Height)];
camera.GetPreviewBufferArgb32(pixelData);
return pixelData;
and write it back to the preview.
my problem is that while I can show the frames on the screen while the user is recording a movie using the camera I cant find a working solution for WP8 to encode the frames and audio to save to a file.
I already tried opencv,libav and others without success,
if anyone can point me to the right direction it would be greatly appreciated.
You can do it like this.
private void GetCameraPicture_Click(object sender, RoutedEventArgs e)
{
Microsoft.Phone.Tasks.CameraCaptureTask cameraCaptureTask = new Microsoft.Phone.Tasks.CameraCaptureTask();
cameraCaptureTask.Completed += cct_Completed;
cameraCaptureTask.Show();
}
try
{
if (e.TaskResult == Microsoft.Phone.Tasks.TaskResult.OK)
{
var imageStream = e.ChosenPhoto;
var name = e.OriginalFileName;
using (MemoryStream mem = new MemoryStream())
{
TextBlock tb = new TextBlock() { Text = DateTime.Now.ToString("dd MMM yyyy, HH:mm"), Foreground = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0)), FontSize = 40 };
BitmapImage finalImage = new BitmapImage();
finalImage.SetSource(imageStream);
WriteableBitmap wbFinal = new WriteableBitmap(finalImage);
wbFinal.Render(tb, null);
wbFinal.Invalidate();
wbFinal.SaveJpeg(mem, wbFinal.PixelWidth, wbFinal.PixelHeight, 0, 100);
mem.Seek(0, System.IO.SeekOrigin.Begin);
MediaLibrary lib = new MediaLibrary();
lib.SavePictureToCameraRoll("Copy" + name, mem.ToArray());
}
}
}
catch (Exception exp) { MessageBox.Show(exp.Message); }
Hope it may help you.

Resources