Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - maggie

#1
Support / Re: Does jPCT-AE support shadow?
June 10, 2016, 08:58:13 PM
Hi again, just have time now to follow up this one ;D
So I modified my code a bit, by adding sh.setCullingMode(true) as suggested, and set the sun+projector position 400 unit above the ground, while (x,y) remains (0,0). Having this value, I think the shadow should be exactly below the teapot. But here is what I got on Xperia M:


Also, with the same code, I'm not sure why I got different shadow behaviour when I run my code on Nexus 9 tablet:


any idea why?  :-\
#2
Support / Re: Does jPCT-AE support shadow?
May 17, 2016, 08:48:05 PM
So I tried to integrate the shadow with vuforia, without any advanced customization. Just like how the example does it, I put the projector in the sun's location and look at to the ground.


public Constructor() {
   sun = new Light(world);
   sun.setIntensity(250, 250, 250);
   
   ...
   ...

   object = Object3D.mergeAll(Loader.loadOBJ(
mActivity.getAssets().open("teapot.obj"), null, 250f));
   object.build();

   world.addObject(object);
   
   // Shadow receiver
   ground = ExtendedPrimitives.createPlane(100, 10);
   ground.setAdditionalColor(new RGBColor(255, 255, 255));
   ground.setTransparency(20);
   ground.build();
   ground.rotateX( (float) Math.PI/2f );
   
   world.addObject(ground);
   cam = world.getCamera();

   SimpleVector sv = new SimpleVector();
   sv.set(ground.getTransformedCenter());
   sv.x += 50;
   sv.z += 400;
   sun.setPosition(sv);
   
}

public void onDrawFrame(GL10 gl) {
   ...
   sh.updateShadowMap(fb, world);
   ...
}

public void onSurfaceChanged(GL10 gl, int width, int height) {
        ...   
       
     // set projector and shadow
    Projector projector = new Projector();
projector.setClippingPlanes(0.75f, 3000f);
float fov = projector.convertDEGAngleIntoFOV(90);
projector.setFOV(fov);
projector.setYFOV(fov);

projector.setPosition( sun.getPosition() );
projector.lookAt(ground.getTransformedCenter());

sh = new ShadowHelper(fb, projector, 1024);
sh.setAmbientLight(new RGBColor(50, 50, 50));
sh.addCaster(object);
sh.addReceiver(ground);

    ...
}


Here is the screen capture:


It looks like not mapped correctly.. any idea what possibly went wrong?
#3
Support / Re: Does jPCT-AE support shadow?
May 14, 2016, 12:42:25 AM
I mean in this particular example, projector orientation is not set explicitly. Perhaps because it's already set by the lib?
Quote from: EgonOlsen on May 05, 2016, 09:37:36 PM
This should help: http://www.jpct.net/forum2/index.php/topic,4333.msg32272.html#msg32272

So generally, how the projector should be treated to make the shadow works with vuforia marker/image target?
#4
Support / Re: Does jPCT-AE support shadow?
May 13, 2016, 05:13:12 PM
Quote from: EgonOlsen on April 27, 2016, 12:47:27 PM
About the table...yes, in theory. But it would require that you model the table in the scene. You can't project a shadow on nothing and a table in a 2D camera image is actually nothing to a 3D engine.

In vuforia case, is it necessary to set the orientation of the projector for the shadow?
#5
ah ok... Got it.
Cool, now it works. Thank you!  ;D
#6
Here is the full code:


import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Light;
import com.threed.jpct.Loader;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Projector;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.ExtendedPrimitives;
import com.threed.jpct.util.MemoryHelper;
import com.threed.jpct.util.ShadowHelper;

public class ShadowExample extends Activity {

private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer buffer = null;
private World world = null;
private RGBColor back = new RGBColor(50, 50, 100);

private float touchTurn = 0;
private float touchTurnUp = 0;

private float xpos = -1;
private float ypos = -1;

private Object3D myObject = null;
private Object3D plane = null;
private int fps = 0;

private Light sun = null;
private ShadowHelper sh;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(getApplication());
mGLView.setEGLContextClientVersion(2);
renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
}

@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}

@Override
protected void onStop() {
super.onStop();
System.exit(0);
}

public boolean onTouchEvent(MotionEvent me) {

if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
return true;
}

if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}

if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;

xpos = me.getX();
ypos = me.getY();

touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
return true;
}

try {
Thread.sleep(15);
} catch (Exception e) {
// No need for this...
}

return super.onTouchEvent(me);
}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();

public MyRenderer() {
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
try {
Config.farPlane = 5000;
buffer = new FrameBuffer(w, h);

world = new World();
world.setAmbientLight(100, 100, 100);

TextureManager tm = TextureManager.getInstance();
tm.addTexture("floor", new Texture(ShadowExample.this.getBaseContext().getAssets().open("floor.jpg")));

myObject = Object3D.mergeAll(Loader.loadOBJ(
getApplicationContext().getAssets().open("teapot.obj"), null, 12));
myObject.build();
myObject.translate(0, 10, 0);
world.addObject(myObject);

plane = ExtendedPrimitives.createPlane(100, 2);
plane.setTexture("floor");
plane.setTransparency(20);
plane.build();
plane.translate(0, 40, 10);
world.addObject(plane);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(plane.getTransformedCenter());

SimpleVector sv = new SimpleVector(myObject.getTransformedCenter());
sv.y -= 100;
sv.z += 30;

sun = new Light(world);
sun.setIntensity(250, 250, 250);
sun.setPosition(sv);

Projector projector = new Projector();
projector.setClippingPlanes(0.001f, 100f);
projector.setFOVLimits(0, 999);
float fov = projector.convertDEGAngleIntoFOV(90);
projector.setFOV(fov);
projector.setYFOV(fov);

sh = new ShadowHelper(buffer, projector, 1024);
sh.setLightMode(true);
sh.setLightSource(projector);

sh.addCaster(myObject);
sh.addReceiver(plane);

MemoryHelper.compact();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
myObject.rotateY(touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
myObject.rotateX(touchTurnUp);
touchTurnUp = 0;
}

sh.updateShadowMap(buffer, world);

buffer.clear(back);

world.renderScene(buffer);
world.draw(buffer);

// sh.blit(buffer);

buffer.display();

if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
}
}


Apart from the shadow color, why there's no shadow at all when I set the projector's position in the sun's position ( projector.setPosition(sun.getPosition) ) ?
Isn't projection's position supposed to control the position of the shadow on the receiver? Just like what sun does with the ShadowHelper in your zip example?
#7
Sorry, it was a mistake. Just ignore that line.
Yup, I'm sure that I use ShadowHelper from the jar  :(
#8
The shadow still makes the receiver looks like have a "hole"... :(
Plus, the shadow is not mapped correctly. Probably because of my Projector, not so sure if I set all needed parameters correctly.
Here is my code:


public void onSurfaceChanged(GL10 gl, int w, int h) {
try {
Config.farPlane = 5000;
buffer = new FrameBuffer(w, h);

world = new World();
world.setAmbientLight(100, 100, 100);

TextureManager tm = TextureManager.getInstance();
tm.addTexture("floor", new Texture(ShadowExample.this.getBaseContext().getAssets().open("floor.jpg")));

myObject = Object3D.mergeAll(Loader.loadOBJ(
getApplicationContext().getAssets().open("teapot.obj"), null, 10));
myObject.build();
myObject.translate(5, 10, -10);
world.addObject(myObject);

plane = ExtendedPrimitives.createPlane(100, 2);
plane.setTexture("floor");
plane.setTransparency(20);
plane.build();
plane.translate(0, 20, 10);
world.addObject(plane);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(plane.getTransformedCenter());

SimpleVector sv = new SimpleVector(myObject.getTransformedCenter());
sv.y -= 70;
sv.z = 30;

                                sun = new Light(world);
sun.setIntensity(250, 250, 250);
sun.setPosition(sv);

Projector projector = new Projector();
projector.setFOVLimits(0, 999);
float fov = projector.convertDEGAngleIntoFOV(90);
projector.setFOV(fov);
projector.setYFOV(fov);
projector.setPosition(myObject.getTransformedCenter());

sh = new ShadowHelper(buffer, projector, 512);
sh.setLightSource(projector);
sh.addCaster(myObject);
sh.addReceiver(plane);

MemoryHelper.compact();
} catch (Exception e) {
throw new RuntimeException(e);
}
}




public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
myObject.rotateY(touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
myObject.rotateX(touchTurnUp);
touchTurnUp = 0;
}

sh.updateShadowMap(buffer, world);

buffer.clear(back);

world.renderScene(buffer);
world.draw(buffer);

buffer.display();

if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
#9
Quote from: EgonOlsen on February 27, 2015, 11:11:29 PM
Ok, here you go: http://jpct.de/download/example/ShadowExample.zip

And you'll need a slightly updated version of jPCT-AE for this to work correctly in portrait mode. You can grab this here: http://jpct.de/download/beta/jpct_ae.jar

It's based on Thomas.' work but simplified to one ShadowHelper class (a little similar to what desktop jPCT already offers). That's not saying that Thomas.' source code is too complicated, but it has a much larger scope than this small example, so i decided to cut some stuff and modify some parts. Anyway, without his great work, i couldn't have done this in just 2 hours.

Image:


I hope this helps somehow. This example uses a single shader for all receiver objects. It's based on the most complex default shader that jPCT-AE offers. So performance might not be optimal in all cases. In addition, it assumes that the depthmap is in texture unit 1, which might not be the case for multitextured objects. Anyway. it's just an example to get you started. I hope it helps.

If i find the time, i'll add it to the wiki in some modified form and if i find even more time, i'll add an even more modified version to the actual release... ;)

Based on this example, I'm trying to have a transparent receiver by simply adding: plane.setTransparency(20)
And here is the result:


Is it possible to have a dark color shadow with a transparent receiver? Could you please give me a hint how to do that in jpct-ae?
Basically what I want to achieve is exactly the same with this post: http://www.jpct.net/forum2/index.php/topic,2626.msg19433.html. The only different thing is I'm using jpct-ae.
#10
I switch everything to Java, and it works pretty well.
Here's the main part of my integration: https://github.com/TheMaggieSimpson/Vuforia559_jPCT-AE

I hope it'll be useful for some people  ;)
#11
Yes, it has getClassType(). Here is the complete content of ObjectTracker.h :


/*===============================================================================
Copyright (c) 2014 Qualcomm Connected Experiences, Inc. All Rights Reserved.

Vuforia is a trademark of QUALCOMM Incorporated, registered in the United States
and other countries. Trademarks of QUALCOMM Incorporated are used with permission.

@file
    ObjectTracker.h

@brief
    Header file for ObjectTracker class.
===============================================================================*/
#ifndef _QCAR_OBJECT_TRACKER_H_
#define _QCAR_OBJECT_TRACKER_H_

// Include files
#include <QCAR/Tracker.h>

namespace QCAR
{

// Forward Declaration
class Trackable;
class DataSet;
class ImageTargetBuilder;
class TargetFinder;

/// ObjectTracker class.
/**
*  The ObjectTracker tracks ObjectTargets, ImageTargets, CylinderTargets
*  or MultiTargets contained in a DataSet.
*  The ObjectTracker class provides methods for creating, activating and
*  deactivating datasets. Note that methods for activating and deactivating
*  datasets should not be called while the ObjectTracker is working at the
*  same time. Doing so will make these methods block and wait until the
*  tracker has finished.
*  The suggested way of swapping datasets is during the execution of
*  UpdateCallback, which guarantees that the ObjectTracker is not working
*  concurrently. Alternatively the ObjectTracker can be stopped explicitly.
*  However, this is a very expensive operation.
*/
class QCAR_API ObjectTracker : public Tracker
{
public:

    /// Returns the Tracker class' type
    static Type getClassType();

    /// Factory function for creating an empty dataset.
    /**
     *  Returns the new instance on success, NULL otherwise. Use
     *  DataSet::destroyDataSet() to destroy a DataSet that is no longer needed.
     */     
    virtual DataSet* createDataSet() = 0;

    /// Destroys the given dataset and releases allocated resources.
    /// Returns false if the given dataset is currently active.
    virtual bool destroyDataSet(DataSet* dataset) = 0;

    /// Activates the given dataset.
    /**
     *  This function will return true if the DataSet was successfully
     *  activated and false otherwise.
     *  The recommended way to activate datasets is during the execution of the
     *  UpdateCallback, which guarantees that the ObjectTracker is not working
     *  concurrently.
     */   
    virtual bool activateDataSet(DataSet* dataset) = 0;
   
    /// Deactivates the given dataset.
    /**
     *  This function will return true if the DataSet was successfully
     *  deactivated and false otherwise (E.g. because this dataset is not
     *  currently active).
     *  The recommended way to deactivate datasets is during the execution of
     *  the UpdateCallback, which guarantees that the ObjectTracker is not
     *  working concurrently.
     */   
    virtual bool deactivateDataSet(DataSet* dataset) = 0;

    /// Returns the idx-th active dataset. Returns NULL if no DataSet has
    /// been activated or if idx is out of range.
    virtual DataSet* getActiveDataSet(const int idx = 0) = 0;

    /// Returns the number of currently activated dataset.
    virtual int getActiveDataSetCount() const = 0;

    /// Returns instance of ImageTargetBuilder to be used for generated
    /// target image from current scene.
    virtual ImageTargetBuilder* getImageTargetBuilder() = 0;
   
    /// Returns instance of TargetFinder to be used for retrieving
    /// targets by cloud-based recognition.
    virtual TargetFinder* getTargetFinder() = 0;

    ///  Persist/Reset Extended Tracking
    /**
     *  In persistent Extended Tracking mode, the environment map will only
     *  ever be reset when the developer calls resetExtendedTracking().
     *  This function will return true if persistent Extended Tracking
     *  was set successfully (or was already set to the specified value)
     *  and false otherwise.
     */
    virtual bool persistExtendedTracking(bool on) = 0;

    /// Resets environment map for Extended Tracking
    /**
     *  Environment map can only be reset by the developer if persistent
     *  extended tracking is enabled.
     *  This function will return true if environment map was reset
     *  successfully and false otherwise.
     */
    virtual bool resetExtendedTracking() = 0;

};

} // namespace QCAR

#endif //_QCAR_OBJECT_TRACKER_H_
#12
Yes, it has been included...
Now I suspect that I need to compile ObjectTracker.h file, which I'm not really sure how to do it on this case.
#13
Hi all, I'm using https://github.com/sidneibjunior/vuforia-jpct as my base, and have successfully migrated to Vuforia 3.0.9 without major problem.
Now I'm trying to migrate to Vuforia 5.0.5, but I got this error while building my codes:

[armeabi-v7a] Compile++ arm  : ImageTargetsNative <= ImageTargets.cpp
[armeabi-v7a] SharedLibrary  : libImageTargetsNative.so
jni/ImageTargets.cpp:92: error: undefined reference to 'QCAR::ObjectTracker::getClassType()'
jni/ImageTargets.cpp:159: error: undefined reference to 'QCAR::ObjectTracker::getClassType()'
jni/ImageTargets.cpp:178: error: undefined reference to 'QCAR::ObjectTracker::getClassType()'
jni/ImageTargets.cpp:190: error: undefined reference to 'QCAR::ObjectTracker::getClassType()'
collect2: error: ld returned 1 exit status
make: *** [obj/local/armeabi-v7a/libImageTargetsNative.so] Error 1

---

Has anyone ever face the same problem? Or have successfully migrate to Vuforia 5? Please help... I really need to migrate.
I have tried to follow this instruction: https://developer.vuforia.com/library/articles/Solution/How-to-Migrate-an-Android-Project
But somehow still end up in "undefined reference" error... I don't know much about C++, but I need to use the native code for my project.

Thanks in advance.