Client/Server Networking in JPCT-AE

Started by arianaa30, May 01, 2012, 02:59:48 AM

Previous topic - Next topic

arianaa30

Hi everybody,
It seems there is no specific networking API predefined in JPCT-AE. I want to transfer the objects from a server to a client, then try to render them and run the game. The simple method is using Android's API, creating a connection and simply transfer the items. Does it work? Is there any alternatives for that? Thanks

EgonOlsen

It highly depends on what exactly you want to do. If you just want to load models from a server, i would simply load them via http.

...and why not include the models in the APK?

Darkflame

I have successfully got 3ds (created by 3dsmax) objects loaded from a sever, with textures, provided the textures are in a known location on the server so yes, it does work. Or, at least, can work :)

The following is code taken straight from my app. Its VERY messy, and uses a few things specific too my app.
However, it should give you some keywords too look for.

//its a 3ds file , so a mesh
object3dtype = ARBlipObject.ObjectType.MESH_OBJECT;

HashSet<String> Namesbefore = TextureManager.getInstance()
.getNames();
int SizeBefore = Namesbefore.size();

// load 3d model
URL downloadfrom = new URL(newblip.ObjectData);
URLConnection conn = downloadfrom.openConnection();
conn.connect();
BufferedInputStream bis = new BufferedInputStream(conn
.getInputStream());
Log.i("3ds", "got stream");
Object3D[] newobjects = Loader.load3DS(bis, 1);

for (int x = 0; x < newobjects.length; x++) {
newobjects[x].rotateX((float) Math.PI / 2);
newobjects[x].rotateZ((float) Math.PI);
newobjects[x].rotateY(-((float) Math.PI / 2));

newobjects[x].rotateMesh();
newobjects[x].setRotationMatrix(new Matrix());
}

Log.i("3ds", "now merging...");
newmarker = Object3D.mergeAll(newobjects);

// This scale is wrong...no idea what the correct scale to use
// is :(
// newmarker.scale(2f);

// clear memory first
System.gc(); // no idea if this is a good place, but I was
// getting some out of memory errors without it

// ok, if occlusion is set, then we simply dont specify a
// texture
if (newblip.isOcculisionMask) {

newmarker.setTexture("occlusion");

return newmarker;
}

HashSet<String> newNames = TextureManager.getInstance()
.getNames();

newNames.removeAll(Namesbefore);

// now get the texture names
Iterator<String> it = newNames.iterator();

// get path
String URLPath = newblip.ObjectData.substring(0,
newblip.ObjectData.lastIndexOf('/') + 1);

try {
ARWaveView.fetchAndSwapTexturesFromURL(it, URLPath);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Log.i("3ds", "created 3ds");


static void fetchAndSwapTexturesFromURL(Iterator<String> it, String URLPath)
throws MalformedURLException, IOException {
while (it.hasNext()) {

String textureNameToLoad = (String) it.next();
Log.i("3ds", "Loading Texture:-" + textureNameToLoad);

// get the url
// NOTE; filename must be lower case
// In future we might want to check for uppercase too.
// Unfortunately, 3dsmax stores all its filenames uppercase
// internally, so we cant have mixed cases
// in filenames, as they wont be recognised.
String TextureURL = URLPath + textureNameToLoad.toLowerCase();

Log.i("3d", "getting texture at " + TextureURL);

// make the texture
URL texturedownloadfrom = new URL(TextureURL);
URLConnection textureconnection = texturedownloadfrom
.openConnection();

textureconnection.connect();
BufferedInputStream texturebis = new BufferedInputStream(
textureconnection.getInputStream());

Bitmap maxtexture1 = BitmapFactory.decodeStream(texturebis);
TextureManager tm = TextureManager.getInstance();
Texture newmaxtexture = new Texture(maxtexture1);

// swap it in
// Note; This automatically assigns the correct textures onto the
// model, because when the model was loaded, it was assigned the file names in the
// 3ds file for its texture names.
// neat eh?
tm.replaceTexture(textureNameToLoad, newmaxtexture);

}
}



Now, the tricker thing is sending a mesh from the client app to the server....

arianaa30

Quote from: EgonOlsen on May 01, 2012, 09:16:21 PM
It highly depends on what exactly you want to do. If you just want to load models from a server, i would simply load them via http.

...and why not include the models in the APK?

Well Egon, I need to test the streaming using a client/server connection. So can not include them in the code...

arianaa30

Quote from: Darkflame on May 02, 2012, 01:49:37 PM
I have successfully got 3ds (created by 3dsmax) objects loaded from a sever, with textures, provided the textures are in a known location on the server so yes, it does work. Or, at least, can work :)

The following is code taken straight from my app. Its VERY messy, and uses a few things specific too my app.
However, it should give you some keywords too look for.

Now, the tricker thing is sending a mesh from the client app to the server....

ummm, seems it would work...let me try it. Thanks buddy :)

arianaa30

I tested the approach, and it works, as expected. But a problem is that when the app is trying to receive the texture, everything freezes during transmission. Do you have any idea for that?
To Egon: I'm using jpct-AE Demo code, and in order to test, when number of passed frames equals 100 in the onDrawFrame(), I try receiving a texture to replace an older one.

Thomas.

You have to use another thread for downloading new textures to avoid freeze during transmission.