I'm a newbie in Android Vuforia AR development. After google and vuforia forum has no results, I come here and need your suggestions. I successful replace a teapot by my own 3d object, now i need to add another teapots into "stones" target, like this image link? Have you ever work with this case? Please give me some traces to begin.
Thanks and best Regards!
Are you using Unity? Here are two suggestions:
You can programmatically instantiate prefabs on an image target following this code, just add additional transforms:
https://developer.vuforia.com/forum/faq/unity-how-can-i-dynamically-attach-my-3d-model-image-target
Alternatively, in your Scene Hierarchy, you can make additional GameObjects children of the ImageTarget prefab (probably the easiest way), and adjust their position using the Scene Editor.
First, grab a fresh copy of the modelview matrix before transforming it. Second, bind your modelViewProjectionMatrix before using it.
modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(trackable->getPose());
SampleUtils::rotatePoseMatrix(5.0f, 0.0f, 0.0f, 1.0f, &modelViewMatrix.data[0]);
SampleUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale,
&modelViewMatrix.data[0]);
SampleUtils::multiplyMatrix(&projectionMatrix.data[0],
&modelViewMatrix.data[0] ,
&modelViewProjection.data[0]);
glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE,
(GLfloat*)&modelViewProjection.data[0] );
SampleUtils::checkGlError("ImageTargets renderFrame");
glDrawElements(GL_TRIANGLES, NUM_TEAPOT_OBJECT_INDEX, GL_UNSIGNED_SHORT,
(const GLvoid*) &teapotIndices[0]);
Related
I want to create a static starfield in libgdx.
My first way was: create a Decal and a DecalBatch over it.
When I draw the Decal I use a Billboarding technic on the Decal
star.decal.setRotation(camera.direction, camera.up);
next: I wanted to animate the alphas on the decals, so I created on a random way some time:
star.decal.setColor(1, 1, 1, 0.6f+((float) Math.random()*0.4f) );
It is working, but my FPS went down from 55 FPS to 25 FPS (because of my 500-1000 stars)
Can I use only one batch call in any way? Maybe a particleMaterial with only one Vertex list and with a GL_POINT mode that is always face to front of my camera?
How can I do this in libgdx?
The Batch is way to complex than what you need , on every frame it needs to copy all the vertices of the sprites in another array and do calculations on them to find the scale rotation etc..
As you suspect GL_POINT sprites will be way faster and in a medium range device it should be able to render in 60 fps like 2000 points that have different position and color
here is some old code of mine ,its in c and it uses opengl es 1.1 and propably there will be a more simple way to do it in libgdx
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnable (GL_POINT_SPRITE_OES);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, TXTparticle);
glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
glPointSize(30);
glColorPointer(4, GL_FLOAT, 32, particlesC);//particlesC the vertices color
glVertexPointer(3, GL_FLOAT, 24, particlesV);//particlesV the vertices
glDrawArrays(GL_POINTS, 0, vertvitLenght/6);
glDisable( GL_POINT_SPRITE_OES );
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
I want to implement indoor navigation through image recognition using Vuforia tool which works collaboratively with Android SDK.
I have collected the images that I want to use and now I have succesfully replaced the default picture of ImageTargets appication so as to add my own pictures.
My problem is the step further, since when this application recognizes a museum exhibit diplays a teapot.I want to replace this teapot with arrows that will help museum users to navigate into the museum.
How can I do it?There is an article to the official website of Vuforia which partially clarifies what must have happened but it's far from comprehensive(https://developer.vuforia.com/resources/dev-guide/replacing-teapot).
Any help might be totally crucial for me
Thank you in advance
The first step is to create your arrow models in a program such as Blender or Autodesk Maya and export it as a Wavefront OBJ file. You may have to tweak some plugins/settings in your chosen modelling software to enable that option.
Then you need to convert that .obj file to a C/C++ include file (.h) to work with the native code in ImageTargets.cpp. There is a convenient Perl script that you can download to make this process easier - OBJ2OPENGL.
Then it is a matter of importing your new model in ImageTargets.cpp, e.g. #import "arrow.h" then replace the code to draw the teapot with the following:
// set input data to arrays
glVertexPointer(3, GL_FLOAT, 0, arrowVerts);
glNormalPointer(GL_FLOAT, 0, arrowNormals);
glTexCoordPointer(2, GL_FLOAT, 0, arrowTexCoords);
// draw data
glDrawArrays(GL_TRIANGLES, 0, arrowNumVerts);
Don't forget to rebuild the project using ndk-build when you're finished.
iOS Code:
I have working code on iOS which prepares a 3D transformation for a UIView's layer:
CATransform3D t = CATransform3DIdentity;
t.m34 = -1.0f/500.0f;
t = CATransform3DTranslate(t, 10.0f, 20.0f, 0.0f);
t = CATransform3DRotate(t, 0.25f * M_PI, -1.0f, 0.0f, 0.0f);
I'm trying to port the above code to Android. I'm trying to prepare an android.view.animation.Transformation t which will do the same thing. It will be executed by ViewGroup.getChildStaticTransformation(View v, Transformation t).
unfinished Android Code:
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
android.graphics.Camera camera = new android.graphics.Camera();
// set perspective (m34) here.. how??
camera.translate(10.0f, 20.0f, 0.0f);
camera.rotateX(-1.0f * Math.toDegrees(0.25 * Math.PI));
camera.getMatrix(t.getMatrix());
My main issue:
The main problem is that I'm not sure how set the perspective t.m34 = -1.0f/500.0f in Android. Reading the docs is rather cryptic and my best bet is using Camera.setLocation(). Also, the docs say nothing about units, so what would be an appropriate value?
Another issue is that setLocation() is only available from API 12, so I would really need to set it manually in the Matrix instead (or via some transformation). Any ideas how?
Final comment:
I'm aware that there are probably more issues.. like the translate() units, transformation order and generally the issue that we transform the camera in Android but the object in iOS. I will get to all of these later :)
I'm learning Open GL ES and would like to get a more intuitive interface with 3D objects than the one suggested by google in the TouchRotateActivity sample.
In order to do that, I would like to multiply my Modelview matrix by the ModelView matrix in the previous state.
But I encounter the following problem : getFloatv function returns 0 values in my float array, and I don't understand why (my ModelView matrix is not empty : if it was, I wouldn't get my cube on the screen).
Could someone help me to figure out what the problem is? Here are the changes in the code .
private float[] previous;
public CubeRenderer() {
mCube = new Cube();
previous = new float[16];
}
public void onDrawFrame(GL10 gl) {
GL11 gl11 = (GL11) gl;
gl11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
gl11.glMatrixMode(GL11.GL_MODELVIEW);
gl11.glLoadIdentity();
gl11.glTranslatef(0, 0, -3.0f);
gl11.glRotatef(mAngleX, 0, 1, 0);
gl11.glRotatef(mAngleY, 1, 0, 0);
gl11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
gl11.glEnableClientState(GL11.GL_COLOR_ARRAY);
/*if(!previous.equals(new float[16]))
gl11.glMultMatrixf(previous, 0);*/
gl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, previous, 0);
Log.d("taille matrice",Integer.toString(previous.length));
for(int i=0; i<previous.length;i++)
Log.d(Integer.toString(i),Float.toString(previous[i]));
mCube.draw(gl11);
}
Thank you in advance.
Depending on your device you might be using the PixelFlinger software GL renderer, which unfortunately does not implement glGetFloat, at least as of version 1.2. Checking the logcat output should reveal messages to this effect if this is the case.
The solution is to handle the matrices yourself so there's no need to retrieve them from OpenGL in the first place. Like so.
I don't program in Java, so for all I know, your problem could be in the way the memory is being passed to glGetFloatv. In any case, I found this page floating around out there, maybe it will help you.
How to load a Mesh (3dmax) in Android OpenGL into a ByteBuffer ?
example:
float triangleCoords[] = {
-0.5f, -0.25f , 0, // 0,
0.5f, -0.25f , 0, // 1,
0.0f, 0.559016994f, 0 // 2,
};
ByteBuffer vbb = ByteBuffer.allocateDirect(triangleCoords.length * _4_FLOAT_LENGTH);
vbb.order(ByteOrder.nativeOrder());
triangleVB = vbb.asFloatBuffer();
triangleVB.put(triangleCoords);
triangleVB.position(0);
how to load a mesh like an array or Coords or ineed a library for this job
It basically boils down to loading the data from the file into your data structures (like the vertex array from your code snippet) and providing these to OpenGL for rendering (in your case glDrawArrays, for example). This is generally the same procedure, no matter if working with Android, Windows, Plan9, OpenGL or Direct3D. Only the implementation details matter, therefore this question is a bit broad.
You can look at this description of the 3DS file format (hinted in your question), which also has links to tutorials for loading these files. Although the 3DS format is a quite easy to read binary format, for a start you might also look into the Wavefront OBJ format, a simple ASCII file format that nearly every modeling software can export to (but this should also hold for 3DS). Loading these formats into a bunch of simple vertex arrays should boil down to some few lines of code.
These should get you started. If you encounter any specific problems implementing these mesh loading functionalities on your particular platform, feel free to ask a more specific question.