I'm creating a game that will mainly run on browser thanks to GWT HTML5 deployment. I have quite a few MB of assets between images and sounds. Obviously I don't need them all at all times. I'd like to load them depending on the screen that's coming next and other parameters. That is specially critical because my main deployment will be on web (can't load all 50MB when starting just in case they will be used).
I don't really know how asset loading works on LibGDX on HTML5 really. I'd like to use the AssetManager or something similar to load my TextureAtlases and Sounds but I think HTML5 deployment just loads everything in the beginning regardless if I later use the AssetManager in the core project.
What would be a correct asset loading pipeline with libGDX and GWT. It would be awesome to load all from the core project because that way would be multiplatform for the future but it is not critical now so the important part is to load assets wisely on the web.
Thanks in advance.
My recommended way of managing assets:
// load texture atlas
final String spriteSheet = "images/spritesheet.pack";
assetManager.load(spriteSheet, TextureAtlas.class);
// blocks until all assets are loaded
assetManager.finishedLoading();
// all assets are loaded, we can now create our TextureAtlas object
TextureAtlas atlas = assetManager.get(spriteSheet);
// (optional) enable texture filtering for pixel smoothing
for (Texture t: atlas.getTextures())
t.setFilter(TextureFilter.Linear, TextureFilter.Linear);
Now to load a sprite you do:
// Create AtlasRegion instance according the given <atlasRegionName>
final String atlasRegionName = "regionName";
AtlasRegion atlasRegion = atlas.findRegion(atlasRegionName);
// adjust your sprite position and dimensions here
final float xPos = 0;
final float yPos = 0;
final float w = asset.getWidth();
final float h = asset.getHeight();
// create sprite from given <atlasRegion>, with given dimensions <w> and <h>
// on the position of the given coordinates <xPos> and <yPos>
Sprite spr = new Sprite(atlasRegion, w, h, xPos, yPos);
Related
I have a slider component which I want to have a handle as png image pass as a prop. Now, I want that png image to pass through react native to native modules(android and ios both). The component is written at native side for both ios(Objective C) and android(Java).
How can I pass png image as a prop to native modules?
How can I use them at native Java part?(I am using Canvas to draw my
slider as shown below).
How can I use them at native Objective C?(I am using CGContext to
draw my slider).
What I have tried:
I resolved path of png image by following code at React Native side.
const myImage = require('../assets/slider-handle.png');
const resolveAssetSource = require('react-native/Libraries/Image/resolveAssetSource');
const resolvedImage = resolveAssetSource(myImage);
Then pass the path of image as a prop imagePath={resolvedImage.uri}.
Then at Java part I do following:
public void drawImage(String imagePath, Canvas canvas, int x, int y) {
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
canvas.drawBitmap(bitmap, y, x, somePaintValue);
}
I am getting the path of image(the path is something like this: (http:/10.0.2.2:8081/assets/app/components/slider/assets/slider.png), I have verified that at native side by consoling the path.
Not sure if I need to pass only path of image or maybe there is a way to pass whole png.
This is my first time working with Java and Objective C.
This is the slider I am developing.
Any help will be really appreciated.
I have an absolute positioned image whose parent container I need to set a height on, but now I can't find a method in magnolia API that allows me to get the width or height of an asset/item.
Is there a way to get Image Dimensions (height, width) of an Asset/Item in Magnolia CMS using only the native API?
If not, how would you do it?
I would write it somehow like
import info.magnolia.dam.api.metadata.MagnoliaAssetMetadata;
// ...
if (asset.supports(MagnoliaAssetMetadata.class)) {
MagnoliaAssetMetadata metadata = asset.getMetadata(MagnoliaAssetMetadata.class);
long width = metadata.getWidth();
long height = metadata.getHeight();
// do whatever you need with the image dimensions
} else {
// handle non-image asset
}
See MagnoliaAssetMetadata javadoc and/or sources (and related classes) for more info.
I have done something like this, base on what you have suggested. I am using damTemplatingFunctions to get the asset using the JCR id.
Node node = nodes.nextNode();
String imageJcrId = node.getProperty("image").getValue().getString();
Asset asset = damTemplatingFunctions.getAsset(imageJcrId);
MagnoliaAssetMetadata metadata1 = asset.getMetadata(MagnoliaAssetMetadata.class);
System.out.println(metadata1.getHeight());
System.out.println(metadata1.getWidth());
i want to render model via JPCT-AE and use the ARToolkit to realizing AR Application.
so , i inject the code as below into the ARToolkit Project:
Matrix projMatrix = new Matrix();
projMatrix.setDump(ARNativeActivity.getProjectM());
projMatrix.transformToGL();
SimpleVector translation = projMatrix.getTranslation();
SimpleVector dir = projMatrix.getZAxis();
SimpleVector up = projMatrix.getYAxis();
cameraController.setPosition(translation);
cameraController.setOrientation(dir, up);
Matrix transformM = new Matrix();
transformM .setDump(ARNativeActivity.getTransformationM());
transformM .transformToGL();
model.clearTranslation();
model.translate(transformM .getTranslation());
dump.setRow(3,0.0f,0.0f,0.0f,1.0f);
model.clearRotation();
model.setRotationMatrix(transformM );
And then , the model can be render on the screen but always lie on the mark in the screen, ever i using model.rotateX/Y/Z( (float)Math.PI/2 );
Actually, the matrix output from the ARToolkit::ARNativeActivity.getTransformationMatrix() is correct, and then i split this 4*4Matrix into translation Matrix and Rotation Matrix and set into the model like this:
model.translate(transformM .getTranslation());
model.setRotationMatrix(transformM );
But still no work.
I would suggest to organize better your code, and work with matrices to separate the transformations to make to your model and the transformations to place the model in the marker.
What I suggest is:
First, use an additional matrix. It may be called modelMatrix, as it will store the transformation done to the model (scale, rotation and translation).
Then, declare all matrices outside this method (it is for performance reasons only, but is recommended), and on each frame simply setIdentity to them:
projMatrix.setIdentity();
transformM.setIdentity();
modelM.setIdentity();
later, make the model transformations on the modelM matrix. This transformations will apply to the model, after placed on the marker.
modelM.rotateZ((float) Math.toRadians(-angle+180));
modelM.translate(movementX, movementY, 0);
then, multiply the modelM matrix by the trasnformM (this means you get all the transformations done, and move and rotate them as the transformM describes, which in our case means that all the transformations done to the model are moved on top of the marker).
//now multiply trasnformationMat * modelMat
modelM.matMul(trasnformM);
And finally, apply the rotation and translation to your model:
model.setRotationMatrix(modelM);
model.setTranslationMatrix(modelM);
so the whole code would look as:
projMatrix.setIdentity();
projMatrix.setDump(ARNativeActivity.getProjectM());
projMatrix.transformToGL();
SimpleVector translation = projMatrix.getTranslation();
SimpleVector dir = projMatrix.getZAxis();
SimpleVector up = projMatrix.getYAxis();
cameraController.setPosition(translation);
cameraController.setOrientation(dir, up);
model.clearTranslation();
model.clearRotation();
transformM.setIdentity();
transformM .setDump(ARNativeActivity.getTransformationM());
transformM .transformToGL();
modelM.setIdentity()
//do whatever you want to your model
modelM.rotateZ((float)Math.toRadians(180));
modelM.matMul(transformM);
model.setRotationMatrix(modelM );
model.setTranslationMatrix(modelM);
I strongly reccomend to look at this tutorial about matrices and OpenGL, it is not about JPCT, but all concepts may apply also to there, and it is what I've used to place correctly models in markers with the ARSimple example as you may see in this blog entry I made.
Hope this helps!
I'm developing a game and use batcher.drawSprite method to draw all images in the game (background and all characters)
in assets.java :
charAtlas = new Texture(game, "charAtlas.png");
charEnemy = new TextureRegion(charAtlas, 0,0,250,300);
in worldGame.java :
batcher.beginBatch(Assets.charAtlas); // set atlas
batcher.drawSprite(130, 628, 120,140, Assets.charEnemy);
//assets.charEnemy
is it right to use this method in all condition ?
I have 3 atlas in game , i even use 2048x2048 atlas size so i can include all my images in there..
However, the image looks blurry in game (Tested in galaxy note, tab, and galaxy young). looks at the code above, i even have the enemy char take size in my atlas as much as 250x300 , it's not make sense that it'll look blurry as i only draw it in 120x140.
note : i use no layout (i mean no layout file in res folder) .. i use drawsprite to draw all image (Character,menu, button, etc)..
update :
I tried to use character image files from other game that i unzipped, when i run the app, it also looks blurry and jagged. while in the original game, it's so smooth and sharp. why is that ?
check your code, you might use scaledbitmap , see if you can set like this.
Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap source = BitmapFactory.decodeResource(a.getResources(), path, options);
I'm getting mixed results trying to render a basic alien that was done in Blender:
I export in to Ogre 3D and load it in Eclipse:
Then when I load it in my code and try to render it the material won't render:
Could you tell me what I must do to achieve the full alien in my scene? The code I use in Jmonkeyengine is
Spatial model3 = assetManager
.loadModel("objects/creatures/alien/alien.mesh.xml");
model3.scale(0.3f, 0.3f, 0.3f);
model3.setLocalTranslation(-40.0f, 3.5f, -20.0f);
rootNode.attachChild(model3);
Update
I've got material files like these from the export:
dev#dev-OptiPlex-745:~$ ls workspace/DungeonWorld2/assets/objects/creatures/alien/
alien.mesh Material.002.material Material.005.material
alien.mesh.xml Material.003.material
alien.skeleton.xml Material.004.material
dev#dev-OptiPlex-745:~$
This material code actually produces a material in the scene but it's not the one from blender:
model3.setMaterial( new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md") );
Result:
However, loading a 3D model of an alephant without defining the material does work:
Spatial elephant = (Spatial) assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
float scale = 0.05f;
elephant.scale(scale,scale,scale);
elephant.setLocalTranslation(-50.0f, 3.5f, -20.0f);
control = elephant.getControl(AnimControl.class);
control.addListener(this);
channel = control.createChannel();
for (String anim : control.getAnimationNames())
System.out.println("elephant can:"+anim);
The above code correctly renders the elephant so why can't I export a mesh like that for the alien? I tried to explcitly load the material but it's not working for me:
Spatial model3 = assetManager
.loadModel("objects/creatures/alien/alien.mesh.xml");
model3.scale(0.3f, 0.3f, 0.3f);
model3.setLocalTranslation(-40.0f, 3.5f, -20.0f);
model3.setMaterial( new Material(assetManager,
"objects/creatures/alien/alien.material") );
rootNode.attachChild(model3);
The above generates an exception and I don't really know what material file it is that I'm loading and what do to with the two or three other material files that the export generated:
java.lang.ClassCastException: com.jme3.material.MaterialList cannot be cast to com.jme3.material.MaterialDef
at com.jme3.material.Material.<init>(Material.java:116)
at adventure.Main.simpleInitApp(Main.java:309)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:225)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)
at java.lang.Thread.run(Thread.java:679)
Update
Loading other models this way is working:
BlenderKey blenderKey = new BlenderKey(
"objects/creatures/troll/troll.mesh.xml");
Spatial troll = (Spatial) assetManager.loadModel(blenderKey);
troll.setLocalTranslation(new Vector3f(-145, 15, -10));
rootNode.attachChild(troll);
BlenderKey blenderKey2 = new BlenderKey(
"objects/creatures/spaceman/man.mesh.xml");
Spatial man = (Spatial) assetManager.loadModel(blenderKey2);
man.setLocalTranslation(new Vector3f(-140, 15, -10));
rootNode.attachChild(man);
I get the models inside my game and they look alreight, both the troll and the spaceman that both originally were .blend files.
Now it's much better when I did it over and it is loading the material. The only problem with the alien left now is the holes in the head that was also answered here.
BlenderKey blenderKey = new BlenderKey(
"objects/creatures/alien/alien.mesh.xml");
Spatial alien = (Spatial) assetManager.loadModel(blenderKey);
alien.setLocalTranslation(new Vector3f(-145, 15, -10));
rootNode.attachChild(alien);
You didn't write anything about your material - did you write one and used it correctly? The problem you get seems to be the lack of material to me.
In general you'll need some *.material file and probably some textures (if you used them in Blender). For the beginning you can use one of the materials that come with Ogre, you'll just need to add:
model3.setMaterialName( "Examples/Rockwall" );
Then look if it changes anything. If you still get the problem you can look into 'Ogre.log' file - it's always worth checking because all the errors goes there.
I also see the second problem here - you render the object as 'one sided' while blender probably render is as two-sided mesh, so you get the holes on the head. You can select in the material to be two sided, but it's better (and faster during rendering) to just create your models without the holes :).