Issues with Obj Importing

overdhose

Active Member
Contributor
Design
World
GUI
funny, couldn't help quickly testing it out, same deal as with the plants : no errors, just empty space rendered. Wondering if I am missing something in defining the model
 

overdhose

Active Member
Contributor
Design
World
GUI
found the error :
Code:
SEVERE: Error reading asset mesh:engine:turtleminion
java.io.IOException: Failed to process line 8:"v -0.6384 -0.8412 -0.7434"
at org.terasology.asset.loaders.ObjMeshLoader.readMeshData(ObjMeshLoader.java:190)
at org.terasology.asset.loaders.ObjMeshLoader.load(ObjMeshLoader.java:43)
at org.terasology.asset.loaders.ObjMeshLoader.load(ObjMeshLoader.java:29)
at org.terasology.logic.manager.AssetManager.loadAsset(AssetManager.java:87)
at org.terasology.logic.manager.AssetManager.load(AssetManager.java:176)
at org.terasology.entitySystem.metadata.extension.AssetTypeHandler.deserialize(AssetTypeHandler.java:51)
at org.terasology.entitySystem.metadata.extension.AssetTypeHandler.deserialize(AssetTypeHandler.java:32)
at org.terasology.entitySystem.metadata.FieldMetadata.deserialize(FieldMetadata.java:31)
at org.terasology.entitySystem.persistence.EntityPersisterHelperImpl.deserializeOnto(EntityPersisterHelperImpl.java:433)
at org.terasology.entitySystem.persistence.EntityPersisterHelperImpl.deserializeComponent(EntityPersisterHelperImpl.java:238)
at org.terasology.entitySystem.persistence.EntityPersisterHelperImpl.deserializePrefab(EntityPersisterHelperImpl.java:203)
at org.terasology.game.modes.StateSinglePlayer.loadPrefabs(StateSinglePlayer.java:271)
at org.terasology.game.modes.StateSinglePlayer.init(StateSinglePlayer.java:220)
at org.terasology.game.TerasologyEngine.doPushState(TerasologyEngine.java:497)
at org.terasology.game.TerasologyEngine.access$200(TerasologyEngine.java:79)
at org.terasology.game.TerasologyEngine$ChangeState.enact(TerasologyEngine.java:515)
at org.terasology.game.TerasologyEngine.processStateChanges(TerasologyEngine.java:472)
at org.terasology.game.TerasologyEngine.mainLoop(TerasologyEngine.java:432)
at org.terasology.game.TerasologyEngine.run(TerasologyEngine.java:155)
at org.terasology.game.Terasology.main(Terasology.java:44)
Caused by: java.io.IOException: Bad statement
at org.terasology.asset.loaders.ObjMeshLoader.readMeshData(ObjMeshLoader.java:135)
... 19 more
to prevent unnecessary queries : yes I did rename the object file to turtleminion.obj, I used all lowercase notation in my test to exclude spelling / camelcase errors. So it seems this time around the problem is with the obj file.
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Suspect it is the double space between v and the first number, will modify the obj loader to handle white space better.
 

overdhose

Active Member
Contributor
Design
World
GUI
great might give my plant objects another try to who knows might have overlooked this at that point. I'll check your branch to get the update :D really want to test this heh
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Ok, the whitespace was an issue. There was also any issue with the use of UVW coords for textures (previously only supported UV, as per what Blender exports). I've "fixed" this by dropping the extra coordinate for the moment, will need to look into whether it is needed - initial impression is that the model looks fine without it, although my understanding is that it fixes some issues when the shape of the unwrapped faces doesn't match the actual face shapes.

Only other issue is the model is facing the wrong way - we'll need to sort out our conventions on that front. I believe I'm assuming models face the negative Y axis, as that is the standard direction used by Blender (unless I'm getting confused).

Very nice model though. :)
 

overdhose

Active Member
Contributor
Design
World
GUI
it also sinks into the ground, I suppose it's due to it's height / size, will fiddle a little with it, but yeah big sideways walking turtle is fun :p reminds me a bit of Dr Zoidberg atm heh
 

overdhose

Active Member
Contributor
Design
World
GUI
sigh some rotating and translating to set the right direction height etc resulted in :
Code:
SEVERE: Error reading asset mesh:engine:turtleminion2
java.io.IOException: Failed to process line 161:"usemtl"
    at org.terasology.asset.loaders.ObjMeshLoader.readMeshData(ObjMeshLoader.java:190)
    at org.terasology.asset.loaders.ObjMeshLoader.load(ObjMeshLoader.java:43)
    at org.terasology.asset.loaders.ObjMeshLoader.load(ObjMeshLoader.java:29)
    at org.terasology.logic.manager.AssetManager.loadAsset(AssetManager.java:87)
    at org.terasology.logic.manager.AssetManager.load(AssetManager.java:176)
    at org.terasology.entitySystem.metadata.extension.AssetTypeHandler.deserialize(AssetTypeHandler.java:51)
    at org.terasology.entitySystem.metadata.extension.AssetTypeHandler.deserialize(AssetTypeHandler.java:32)
    at org.terasology.entitySystem.metadata.FieldMetadata.deserialize(FieldMetadata.java:31)
    at org.terasology.entitySystem.persistence.EntityPersisterHelperImpl.deserializeOnto(EntityPersisterHelperImpl.java:433)
    at org.terasology.entitySystem.persistence.EntityPersisterHelperImpl.deserializeComponent(EntityPersisterHelperImpl.java:238)
    at org.terasology.entitySystem.persistence.EntityPersisterHelperImpl.deserializePrefab(EntityPersisterHelperImpl.java:203)
    at org.terasology.game.modes.StateSinglePlayer.loadPrefabs(StateSinglePlayer.java:271)
    at org.terasology.game.modes.StateSinglePlayer.init(StateSinglePlayer.java:220)
    at org.terasology.game.TerasologyEngine.doPushState(TerasologyEngine.java:497)
    at org.terasology.game.TerasologyEngine.access$200(TerasologyEngine.java:79)
    at org.terasology.game.TerasologyEngine$ChangeState.enact(TerasologyEngine.java:515)
    at org.terasology.game.TerasologyEngine.processStateChanges(TerasologyEngine.java:472)
    at org.terasology.game.TerasologyEngine.mainLoop(TerasologyEngine.java:432)
    at org.terasology.game.TerasologyEngine.run(TerasologyEngine.java:155)
    at org.terasology.game.Terasology.main(Terasology.java:44)
Caused by: java.io.IOException: Incomplete statement
    at org.terasology.asset.loaders.ObjMeshLoader.readMeshData(ObjMeshLoader.java:123)
    ... 19 more
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
More obj loader tweaks I guess - Immortius? :)

overdhose - you might want to attach the exact .obj that causes that issue, might be easier to replicate and fix
 

overdhose

Active Member
Contributor
Design
World
GUI
well I don't know what I do honestly. I import the obj in blender, it's 14kb, I translate and rotate it and export again, and it shrinks to 6kb file, so obviously I'm losing data there somewhere :D, although as far as I can see the uv mapping is there and that should be enough no? I tried adding a material etc and reexporting, the file is still 6kb and generates another error. So no doubt it's a blender pebcak problem given the fact the original renders just fine, so I'll let someone else optimize the model for now, while I'd love to expand blender skills, I know it's a painfull and slow process for someone like me.
 

Cervator

Org Co-Founder & Project Lead
Contributor
Design
Logistics
SpecOps
Ahh, okay. Then if you really want to make it easy to get help take exact screenshots of your steps or something then :twilightblush:
 

overdhose

Active Member
Contributor
Design
World
GUI
turtleminiion.png
here's the sunken turtle with a purple shell. Figured the shell would lend itself to differentiate them. Really getting the urge to start that minion roster now :ninja:
 

overdhose

Active Member
Contributor
Design
World
GUI
well no real need for screenshots : open blender, import obj, edit model, translate z and move up, rotate y and face right direction, export obj, the end.
 

overdhose

Active Member
Contributor
Design
World
GUI
grrr the wiki page looses the bb codes I added, while it showed them perfectly in the preview.
here is what the page should look like :

Creating a minion : a short tutorial.

This tutorial is intended to let people easily add a model to the world as a minion.

To start you need a wavefront .obj model with uv mapping and a .png image containing the textures.
the png files are located in
\Terasology\src\main\resources\org\terasology\data\textures
the obj files are located in
\Terasology\src\main\resources\org\terasology\data\mesh
so start by copying your files to the appropriate folder / dir.
*note : there probably should be different folders for mods, so the location might change in the future.

Lets say your model is called tuttest.obj, and your image is called tuttestimage.png, as an example used throughout this tutorial.

The first thing to create then is a material.
Materials are located in
\Terasology\src\main\resources\org\terasology\data\materials
A material is basically a json file which tells Terasology which image to load as a texture for your model.

Copy the file called monkeyHead.mat and paste it with the name tuttest.mat,
IMPORTANT! : notice that the name of the material needs to be different then the name of the image, else you will get an error if I remember correctly.
Now open the file tuttest.mat, it will look like this :
Code:
{
    "shader" : "engine:genericMesh",
    "params" : {
        "diffuse" : "engine:mhead",
        "colorOffset" : [1.0, 1.0, 1.0],
        "textured" : true
    }
}
The important part here is the params, namely the line
Code:
"diffuse" : "engine:mhead",
which refers to the monkeyhead image mhead.png, so you want to edit that line to look like this :
Code:
"diffuse" : "engine:tuttestimage",
notice you don't specify the extension .png, only the name of the file.
Save this file, you just created your first material, congratulations!

Now we need to create a prefab, which is another json file where we will bring pieces of the puzzle together.
As we will use the miniion mod in this tutorial to render the model, the files will be located in
\Terasology\mods\miniion\prefabs
If you'd like to create your own mod, you have create a new folder / dir in the mods folder, and a new subfolder / subdir prefabs.
I'll get into more detail in another tutorial or in an update for creating a new mod.
In the prefabs folder / dir of miniions you will find some prefabs.
Copy 1 of them, for example gelatinousMinion.prefab, and paste it as tuttest.prefab, similar to copying the material.
Then open the file, it will look like this :
Code:
{
  "name": "miniion:gelatinousMinion",
  "Minion" : {
    "icon" = "gelcube"
  },
  "Location" : {},
  "Mesh" : {
    "mesh" : "engine:testmonkey",
    "material" : "engine:monkeyHead"
  },
  "CharacterMovement" : {
    "faceMovementDirection" : true
  },
  "SimpleMinionAI" : {},
  "AABBCollision" : {
    "extents" : [0.5, 0.5, 0.5]
  },
  "CharacterSound" : {
    "footstepSounds" : ["Slime1", "Slime2", "Slime3", "Slime4", "Slime5"],
    "footstepVolume" : 0.7
  },
  "Inventory": {
      "itemSlots": [
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0
      ]
    },
    "AccessInventoryAction": {}
}
A couple lines are of intrest to us at this point :
first we want to give our model a name, you do this by modifying the line :
Code:
"name": "miniion:gelatinousMinion",
into :
Code:
"name": "miniion:tuttestMinion",
this is merely an example, tuttestMinion is a index / key we will use later in the factory to reference our model.
notice the prefix miniion: which specifies what mod the prefab belongs to. Change this if you created your own mod.

Now that we changed the name, we need to specify the mesh and material to use.
Modify the line :
Code:
"mesh" : "engine:testmonkey",
into :
Code:
"mesh" : "engine:tuttest",
to let Terasology know you want it to render the tuttest.obj file.
then modify the line under it :
Code:
"material" : "engine:monkeyHead"
into :
Code:
"material" : "engine:tuttestimage"
notice again that I didn't specify the extension .mat again,
this line will tell Terasology to use the tuttestimage.mat file to color our model.
ignore the prefix engine: for now, just let it be.

Congratulations, you just finished creating a model for the miniions mod (or your own mod).
Now what's left is actually telling Terasology where to render your model in the world.
That's where the miniion mod comes in handy, I created a factory located in
\Terasology\src\main\java\org\terasology\mods\miniions\componentsystem\entityfactory
called MiniionFactory.java
Open that file and you will see somthing like this :
Code:
package org.terasology.mods.miniions.componentsystem.entityfactory;
 
import org.terasology.components.LocationComponent;
import org.terasology.components.MeshComponent;
import org.terasology.entitySystem.EntityManager;
import org.terasology.entitySystem.EntityRef;
import org.terasology.utilities.FastRandom;
 
import javax.vecmath.Vector3f;
 
/**
* copied from @author Immortius
* modified by @author Overdhose
*/
public class MiniionFactory {
 
    private static final Vector3f[] COLORS = {new Vector3f(1.0f, 1.0f, 0.2f), new Vector3f(1.0f, 0.2f, 0.2f), new Vector3f(0.2f, 1.0f, 0.2f), new Vector3f(1.0f, 1.0f, 0.2f)};
 
    private FastRandom random;
    private EntityManager entityManager;
 
    // generates minion cubes for minion toolbar
    public EntityRef generateMiniion(Vector3f position, int index) {
        EntityRef entity = null;
        switch (index) {
            case 0: {
                entity = entityManager.create("miniion:monkeyMinion1");
                break;
            }
            case 1: {
                entity = entityManager.create("miniion:monkeyMinion2");
                break;
            }
            case 2: {
                entity = entityManager.create("miniion:monkeyMinion3");
                break;
            }
            case 3: {
                entity = entityManager.create("miniion:monkeyMinion4");
                break;
            }
            case 4: {
                entity = entityManager.create("miniion:monkeyMinion5");
                break;
            }
            case 5: {
                entity = entityManager.create("miniion:monkeyMinion6");
                break;
            }
            case 6: {
                entity = entityManager.create("miniion:monkeyMinion7");
                break;
            }
            case 7: {
                entity = entityManager.create("miniion:monkeyMinion8");
                break;
            }
            case 8: {
                entity = entityManager.create("miniion:monkeyMinion9");
                break;
            }
            default:
                entityManager.create("miniion:monkeyMinion1");
        }
        if (entity == null) {
            return null;
        }
        LocationComponent loc = entity.getComponent(LocationComponent.class);
        if (loc != null) {
            loc.setWorldPosition(position);
            loc.setLocalScale(((random.randomFloat() + 1.0f) / 2.0f) * 0.8f + 0.2f);
            entity.saveComponent(loc);
        }
 
        MeshComponent mesh = entity.getComponent(MeshComponent.class);
        if (mesh != null) {
            int colorId = Math.abs(random.randomInt()) % COLORS.length;
            mesh.color.set(COLORS[colorId].x, COLORS[colorId].y, COLORS[colorId].z, 1.0f);
            entity.saveComponent(mesh);
        }
 
        return entity;
    }
 
    public FastRandom getRandom() {
        return random;
    }
 
    public void setRandom(FastRandom random) {
        this.random = random;
    }
 
    public EntityManager getEntityManager() {
        return entityManager;
    }
 
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
}
Now all you have to do is modify a line in the switch statement to add your own model,
and you will be able to summon your creation using the miniion toolbar.
let's say you want to summon your model in position 1 on the toolbar,
just modify the line :
Code:
case 0: {
                entity = entityManager.create("miniion:monkeyMinion1");
                break;
            }
into
Code:
case 0: {
                entity = entityManager.create("miniion:tuttestMinion");
                break;
            }
and that's all you need to do.

If you now launch the game, and activate the minionbar by pressing the "x" key and left click on a block while the first slot is selected,
it should show you the model you just created in the game. If you see the toolbar shows an icon but you don't see a model, most likely the engine had a problem reading your obj file and generated an error in the log.
Please try to locate the error and let us know on the forums / irc what the error is.
If all went well you should be seeing your model in game, so take a screeny and let us see your creation.
The explanation might seem a bit long, but it's actually quite simple once you done it 1 time,
it takes max 5 minutes to create another model.
 

overdhose

Active Member
Contributor
Design
World
GUI
allright,
disabling the material file when exporting I get this error :
SEVERE: Error reading asset mesh:engine:turtleminion5
java.io.IOException: Mixed face format
at org.terasology.asset.loaders.ObjMeshLoader.load(ObjMeshLoader.java:59)
at org.terasology.asset.loaders.ObjMeshLoader.load(ObjMeshLoader.java:29)
at org.terasology.logic.manager.AssetManager.loadAsset(AssetManager.java:87)
at org.terasology.logic.manager.AssetManager.load(AssetManager.java:176)

which is triggered by :
if (normals.size() != vertices.size() || texCoord0.size() / 2 != vertices.size() / 3) {
throw new IOException("Mixed face format");
}
 

Immortius

Lead Software Architect
Contributor
Architecture
GUI
Make sure you enable normals for export too. Correct blender settings are materials off and normals on, basically.

I also think the model looks better with the shading set to flat rather than smooth - otherwise lighting looks messed up.

On the tutorial, tuttest.prefab, could also be done like

Code:
{
  "name": "miniion:tuttestMinion",
  "parent": "miniion:gelatinousMinion",
  "Mesh" : {
    "mesh" : "engine:tuttest",
    "material" : "engine:tuttestimage",
    "renderType" : "Normal"
  },
}
Taking advantage of prefab inheritance.
 

overdhose

Active Member
Contributor
Design
World
GUI
ach good to know will include that
 

overdhose

Active Member
Contributor
Design
World
GUI
Make sure you enable normals for export too
Well that did the trick, here's my floating mini turtle :p

miniturtle.png
I suppose plants will work to after applying the trick ;)
or maybe not
 

eleazzaar

Member
Contributor
Art
Split?
Useful information, but not having to do with "Unified Graphic Style"
 

woodspeople

Member
Contributor
Design
Overdhose, we found that the wiki throws away your formatting on the FIRST save of a wiki page but not afterward. So you write it without the formatting, then save it, then edit it again, set the formatting and save again, then it works. Also if you happen to press Tab while editing the page, it THROWS AWAY EVERYTHING YOU JUST PAINSTAKINGLY TYPED. At least on the Mac. So we switched to writing the whole wiki page in a text editor, then pasting it in and clicking Save.

Grrr is right. But it works, kinda.

LOVE the turtle. Can't wait to make our next let's play :)
 
Top