jmc2obj / j-mc-2-obj

Java-based Minecraft-to-OBJ exporter.
http://www.jmc2obj.net
356 stars 59 forks source link

Custom Export Advanced #36

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hey just a question and a possible request. For objects that have multiple 
states (ie. fences) if I wanted to use a custom model it would be very handy 
and nice to have if we could model multiple states in the master object.OBJ 
file like for our fences example if the fence has no other fence posts beside 
it use #thismodel if it has a fence attached to it use #thismodel.  Or even for 
rails if the rail is turning right use this model, if it's turning left use 
this model, ect. 

obviously it would be a bit more advanced then that, but this would give a lot 
of power to custom models and I don't mind the more advanced setup needed 
(modeling for certain states) but really it isn't that complicated to model 
multiple states, some of the states for certain models would just be a state of 
rotating a certain model to fit the proper orientation.

also would be fun if this is implemented I would be able to line up vertices 
and delete faces so that when the model is built and I import it as separate 
objects, it's just a simple matter of selecting the object, selecting all 
vertices and hitting weld to clean up the mesh

anyways let me know if this is possible, 

Original issue reported on code.google.com by jgora...@gmail.com on 4 May 2012 at 10:08

GoogleCodeExporter commented 9 years ago
I'm not sure if that is what you mean, but it is possible to use different 
models depending on block data. For example:

 <block id="XX" name="Fence">
    <model>Mesh</model>
    <mesh data=1>object.obj#Fence-1</mesh>
    <mesh data=2>object.obj#Fence-2</mesh>
    <mesh data=3>object.obj#Fence-3</mesh>
    <mesh data=4>object.obj#Fence-4</mesh>
    <occlusion>none</occlusion>
  </block>

I also wanted to implement the simple transformations such as rotation, but 
this requires expanding the "language" used in the configuration files. While 
it's simple for things like fences, it's much more complicated for other stuff 
like liquids, doors and redstone.

Original comment by danijel....@gmail.com on 5 May 2012 at 7:40

GoogleCodeExporter commented 9 years ago
that's exactly what I was thinking, does it already support this? and anyway to 
reference what the mesh data=1-ect means?

Original comment by jgora...@gmail.com on 5 May 2012 at 2:54

GoogleCodeExporter commented 9 years ago
Yes it does support. To know what "data" means, you will need to refer to the 
following page:
http://www.minecraftwiki.net/wiki/Data_values

For example, for wheat the values form 0-7 represent the different stages of 
growth.

Original comment by danijel....@gmail.com on 5 May 2012 at 3:33

GoogleCodeExporter commented 9 years ago
ah okay so it does correlated with the minecraft block data, I'll have to try 
this out when I get home.  

For stuff like fences, I tried checking the wiki for data values of 
north-west-east-south and other states for a fence but there doesn't seem to be 
anything on that.

Original comment by jgora...@gmail.com on 5 May 2012 at 3:48

GoogleCodeExporter commented 9 years ago
Yea, fences don't really work that way. It actually looks for surrounding 
blocks and tries to connect to them. This is how Paol did it:
http://code.google.com/p/j-mc-2-obj/source/browse/trunk/src/org/jmc/models/Fence
.java

To enable that power of expressiveness in a configuration file is quite the 
challenge.

Original comment by danijel....@gmail.com on 5 May 2012 at 4:08

GoogleCodeExporter commented 9 years ago
hmmmm ya that is a challenge, I feel like I'm demanding too much lol.  The 
current configuration should work for almost everything anyways, just fences I 
guess won't work.

Original comment by jgora...@gmail.com on 5 May 2012 at 4:10

GoogleCodeExporter commented 9 years ago
Nah, we wanted to do it anyway. It's just a matter of sitting down and actually 
doing it right.

Original comment by danijel....@gmail.com on 5 May 2012 at 4:13

GoogleCodeExporter commented 9 years ago
just tested the import functions for custom objects, it works perfectly.  I 
need to test further but I was about to get all four cauldron models to load in 
no problems though it took some figuring out how to set it up.

I've been meaning to do some video tutorials, I think I'll do one up on custom 
models as well.

Original comment by jgora...@gmail.com on 5 May 2012 at 4:31

GoogleCodeExporter commented 9 years ago
for something like this

Redstone Repeater
Low (1st & 2nd) bits:
0x0: Facing north
0x1: Facing east
0x2: Facing south
0x3: Facing west
High (3rd & 4th) bits:
0x0: 1 tick delay
0x1: 2 tick delay
0x2: 3 tick delay
0x3: 4 tick delay

how would you setup the mesh values?

Original comment by jgora...@gmail.com on 5 May 2012 at 4:35

GoogleCodeExporter commented 9 years ago
Well, as it is now, you would need to create 16 different models and map each 
combination of the two values to one of the models :)

Of course, in code it's much easier: low=data&0x04; high=(data-low)>>2;

Thanks for pointing out this example. We'll think about how to work this out in 
config if possible.

Also, if you make some nice custom models, feel free to share them with us. We 
can add them to the project as examples for others.

Original comment by danijel....@gmail.com on 5 May 2012 at 6:47

GoogleCodeExporter commented 9 years ago
I'll probably release a model pack once I get a few models together and working 
properly, and I still wanna do those tutorial videos, might try and put a 
couple together tonight

Original comment by jgora...@gmail.com on 5 May 2012 at 7:34

GoogleCodeExporter commented 9 years ago
Super! Tutorial videos are always welcome! :)

Original comment by danijel....@gmail.com on 5 May 2012 at 7:38

GoogleCodeExporter commented 9 years ago
I keep getting this error

java.lang.ArrayIndexOutOfBoundsException: -7
    at org.jmc.models.Mesh.addModel(Mesh.java:88)
    at org.jmc.OBJOutputFile.addChunkBuffer(OBJOutputFile.java:368)
    at org.jmc.OBJExportPanel.run(OBJExportPanel.java:390)
    at java.lang.Thread.run(Unknown Source)

I had it working just fine, then I started it up again changing pretty much 
nothing, then tried exporting again and now this message keeps popping up every 
time I export with the new models.  It was JUST working so I have no clue what 
I changed, though I did change the map it was generating from, is there an 
issue with chunks and custom models?

Original comment by jgora...@gmail.com on 5 May 2012 at 10:19

GoogleCodeExporter commented 9 years ago
Can you try out the newest download (r174). I made a fix and wanted to see if 
it helps.

Java is weak when it comes to primitive data types (signed/unsigned) so it 
interpreted the data value from your save file as negative, even though data 
values are 0-15. I made a workaround for this problem, but I'm not sure if it 
works.

I'm going to sleep now, so I won't be able to reply until morning ;)

Original comment by danijel....@gmail.com on 5 May 2012 at 10:36

GoogleCodeExporter commented 9 years ago
yup that seems to have fixed it, have a good night!

Original comment by jgora...@gmail.com on 5 May 2012 at 10:49

GoogleCodeExporter commented 9 years ago
getting this error on "Dead Bush"

java.lang.ArrayIndexOutOfBoundsException: 3
    at org.jmc.OBJOutputFile.addFace(OBJOutputFile.java:270)
    at org.jmc.OBJInputFile.addObject(OBJInputFile.java:261)
    at org.jmc.models.Mesh.addModel(Mesh.java:97)
    at org.jmc.OBJOutputFile.addChunkBuffer(OBJOutputFile.java:372)
    at org.jmc.ObjExporter.export(ObjExporter.java:140)
    at org.jmc.gui.OBJExportPanel$2$1.run(OBJExportPanel.java:200)
    at java.lang.Thread.run(Unknown Source)

this is the config file

<block id="32" name="Dead Bush">
    <model>Mesh</model>
    <mesh>object.obj#Shrub</mesh>
    <occlusion>none</occlusion>
    <materials>dead_shrub</materials>
  </block>

Original comment by jgora...@gmail.com on 6 May 2012 at 9:58

GoogleCodeExporter commented 9 years ago
It seems to me, the problem is that your model has a triangle. Unfortunately, 
we don't support triangles at the moment :( That is because we would need to 
change most of the program to support them. We intend to do so, but for now you 
can modify the model slightly to get rid of the triangle.

Also, materials in mesh models are ignored. They are simply copied from the 
imported OBJ and aren't necessary here. I suggest you use the same MTL in your 
imported OBJ as you use for the final export.

Original comment by danijel....@gmail.com on 7 May 2012 at 4:54

GoogleCodeExporter commented 9 years ago
okay that's fine, I guess I missed a triangle, need to look over the model 
again, can you customize the error message to tell me that it's a triangle 
support issue?

okay so I can just delete the materials tag?

Original comment by jgora...@gmail.com on 7 May 2012 at 4:58

GoogleCodeExporter commented 9 years ago
Yea, the message is there, but something must have gone wrong. I'll test it out.

Yes, you can remove the materials tag.

Original comment by danijel....@gmail.com on 7 May 2012 at 4:59

GoogleCodeExporter commented 9 years ago
working with the custom model stuff for a bit now I have a suggestion.

Ability to select what OBJ file to use or what block.conf to use, haven't 
worked out how to do this in my head yet.  I just think it would be nice to 
switch between default models and custom models without having to overwrite the 
block.conf and object.obj every time

Original comment by jgora...@gmail.com on 7 May 2012 at 5:04

GoogleCodeExporter commented 9 years ago
I just double checked my model, I don't see any triangles, so I'm not sure 
what's going on

Original comment by jgora...@gmail.com on 7 May 2012 at 5:47

GoogleCodeExporter commented 9 years ago
FOUND IT! sneaky bugger lol

Original comment by jgora...@gmail.com on 7 May 2012 at 6:03

GoogleCodeExporter commented 9 years ago
Okay, I fixed the unreported triangles in the newest SVN. BTW, are triangles 
important, from your point of view? I'm trying to prioritize tasks a little.

The blocks.conf file is read only at program start for now. We would have to 
create a way to reload configuration while the program is running and maybe we 
could define which files to use there. The OBJ file is only referenced in the 
blocks.conf file so we don't need to deal with that one explicitly. 

Btw, you can use several OBJ files if you want. You can even put them in a 
subfolder (should work AFAIK). I thought that would be useful while doing the 
modeling (keep each modeled object in a separate file) and you can easily merge 
them later to one file if you are releasing a "pack".

Original comment by danijel....@gmail.com on 7 May 2012 at 8:45

GoogleCodeExporter commented 9 years ago
Triangles aren't important per-say.  Most modelers with any kind of training 
are taught to always keep their models in quads, it makes for a cleaner mesh 
down the line.  It's just good practice to always use quads.

The only thing I wanted to do with triangles was for a process of using a 
single triangle as a placeholder and then scattering objects on the center of 
the placeholder. It's a bit complicated to explain but I think I have a work 
around I gotta try that works with quads, just requires some scripting.

I think I tried using different OBJ files and referenced them in the block.conf 
but it didn't load for some reason, I'll have to try again.  Separate files 
would be nice for organization sake, but it's easy enough to work with all the 
models in one file and in the center of the world, just gotta hide the models 
you aren't working on.

Original comment by jgora...@gmail.com on 7 May 2012 at 3:40

GoogleCodeExporter commented 9 years ago
I can try and do a hack for triangles where I would add a 4th vertex to it that 
would be the same as the 3rd. So a triangle

f v1 v2 v3

Would become:

f v1 v2 v3 v3

And our program would work without any extensive changes. You think that would 
be a good idea, or are there some potential problems with doing it that way?

I'll test loading multiple files as well.

Original comment by danijel....@gmail.com on 7 May 2012 at 3:45

GoogleCodeExporter commented 9 years ago
I can see a lot of issues with the polys if you do it that way, I wouldn't 
recommend it.  It can also potentially damage the UV mapping

Original comment by jgora...@gmail.com on 7 May 2012 at 3:55

GoogleCodeExporter commented 9 years ago
Ok, just a thougth. I think I'll try and put a NaN value for the 4th vertex in 
triangles and then check for that values everywhere in the code.

Original comment by danijel....@gmail.com on 7 May 2012 at 3:57

GoogleCodeExporter commented 9 years ago
I checked the multiple files and it works. Remember, if you have named objects 
in the files you need to reference them explicitly. You can also give only the 
file name, but that only works if there are no named objects (lines beginning 
with "o") in the file.

Original comment by danijel....@gmail.com on 7 May 2012 at 4:09

GoogleCodeExporter commented 9 years ago
I added bit-masks to mesh configuration in r177. Now it's possible to do 
something like this:

  <block id="93" name="Redstone Repeater (off)">
    <model>Mesh</model>
    <mesh data="0" mask="3">delay.obj#BaseN</mesh>
    <mesh data="1" mask="3">delay.obj#BaseE</mesh>
    <mesh data="2" mask="3">delay.obj#BaseS</mesh>
    <mesh data="3" mask="3">delay.obj#BaseW</mesh>
    <mesh data="0" mask="12">delay.obj#Pointer0</mesh>
    <mesh data="4" mask="12">delay.obj#Pointer1</mesh>
    <mesh data="8" mask="12">delay.obj#Pointer2</mesh>
    <mesh data="12" mask="12">delay.obj#Pointer3</mesh>
    <occlusion>none</occlusion>
  </block>

Attatched is a file I used in this example. This doesn't yet completely solve 
the issue of repeaters, because we can't orient the delay markers according to 
the data value (without making 16 different meshes), but it's a good start...

Here's a quick render of a simple test: http://i.imgur.com/uKdZm.png

Original comment by danijel....@gmail.com on 7 May 2012 at 5:35

Attachments:

GoogleCodeExporter commented 9 years ago
okay so you just separated the two components? basically two sub models for a 
single model? what is the mask value in relation to?

Original comment by jgora...@gmail.com on 7 May 2012 at 6:06

GoogleCodeExporter commented 9 years ago
Yea. The way it works is it goes through each "mesh" and checks if the 
currently drawn block "matches" the data/mask combination and if it's true then 
adds it to the model. You could theoretically add several identical data/mask 
combinations in different mesh blocks and it would add all of them.

To solve the whole problem I intend to add a "transform" tag and add the 
ability to freely nest mesh and transform tags. For example:

 <block id="93" name="Redstone Repeater (off)">
    <model>Mesh</model>
    <mesh data="0" mask="3">
      <transform type="rotate" const="Y" value="90">
        <mesh>delay.obj#Base</mesh>
      </transform>
    </mesh>
        ...

Original comment by danijel....@gmail.com on 7 May 2012 at 6:17

GoogleCodeExporter commented 9 years ago
Issue 34 has been merged into this issue.

Original comment by danijel....@gmail.com on 7 May 2012 at 8:58

GoogleCodeExporter commented 9 years ago
I like the transform idea, that would help a lot.

not sure if this is possible but to build on the transform idea it would be 
awesome if you could do something like 

<transform type="rotate" const="Y" value="random">

or something to that effect.  It would be nice to have for certain objects to 
break up the uniformity of some objects.

Original comment by jgora...@gmail.com on 7 May 2012 at 9:13

GoogleCodeExporter commented 9 years ago
Cool idea. I'll keep it in mind.

Original comment by danijel....@gmail.com on 7 May 2012 at 9:16

GoogleCodeExporter commented 9 years ago
I made a cool new change in r181. Click on the revision to read the details.

I did a quick test using a configuration like this and it worked:

  <block id="92" name="Cake">
    <model>Mesh</model>
    <mesh>
        object.obj#Cake
        <transform type="scale" const="xyz" value="0.25">
            <transform type="translate" const="y" value="1">            
                <mesh>object.obj#Cake</mesh>
            </transform>
        </transform>
    </mesh>
    <occlusion>none</occlusion>
  </block>

I uploaded the program with that revision on the download section. It is 
backward compatible, but it should make your work a bit simpler, I think. Let 
me know if you find any problems.

Following that, we should add some kind of mechanism to read different values 
apart from "data" and "mask". Things like neighbor blocks and their data. Then 
we should figure out how to address the materials and other minor changes 
within the models.

Original comment by danijel....@gmail.com on 8 May 2012 at 6:37

GoogleCodeExporter commented 9 years ago

Original comment by danijel....@gmail.com on 8 May 2012 at 6:47

GoogleCodeExporter commented 9 years ago
I'm just trying to understand your formatting, so you first define the mesh, 
then apply the transform scale at 0.25 all axis, then move it 1 on the y axis 
then create a new mesh object again?

Original comment by jgora...@gmail.com on 8 May 2012 at 11:09

GoogleCodeExporter commented 9 years ago
tried this:

<block id="26" name="Bed">
    <model>Mesh</model>
    <mesh data="0">
        <transform type="rotate" const="y" value="90">
            object.obj#Bed_South
        </transform>
    </mesh>
    <mesh data="1">object.obj#Bed_West</mesh>
    <mesh data="2">object.obj#Bed_North</mesh>
    <mesh data="3">object.obj#Bed_East</mesh>
    <occlusion>none</occlusion>
    <materials>bed_head_top, bed_head_side, bed_head_front, bed_foot_top, bed_foot_side, bed_foot_front</materials>
  </block>

and the bed just doesn't generate and gets "Block 26 has invalid mesh 
definition. Ignoring."

I don't understand the formatting

Original comment by jgora...@gmail.com on 8 May 2012 at 11:54

GoogleCodeExporter commented 9 years ago
First, the error is my fault. It's fixed in the newest version (r182).

Second, that was what something I wasn't sure about how to do. The way I 
decided to do it is to allow the name of the OBJ (so object.obj#Bed_South) only 
within <mesh> tags and not <transform>. In other words, you'd need to do:
   <mesh data="0">
        <transform type="rotate" const="y" value="90">
            <mesh>object.obj#Bed_South</mesh>
        </transform>
    </mesh>

But now I'm not sure if that is the best way to do it. Any suggestions?

Original comment by danijel....@gmail.com on 9 May 2012 at 6:39

GoogleCodeExporter commented 9 years ago
okay that makes sense, I'm just trying to think of this logically, kind of talk 
it out.

so basically you say hey for this data point rotate this mesh.  It seems to 
make sense, can't really think of how else you could do it other then

<mesh data="0" transform="type,const,value or randval(0,10)">blah.obj</mesh>

but that might be too complicated to setup in code? that's the only other way I 
can think of doing it but I'm not a programmer so I wouldn't know if that is 
even possible and the current way of doing it with embedded statements seems 
okay, at least I understand the format now

Original comment by jgora...@gmail.com on 9 May 2012 at 4:42

GoogleCodeExporter commented 9 years ago
Paol also suggested to scrap the <transform> tag and simply use individual 
<rotate> <translate> and <scale> tags.

Your idea is also possible, but that makes it less obvious how to embed several 
transformations in a row, I think.

I suggest we allow object names directly within transform nodes (so no need to 
have a mesh node specifically for that) and use Paol's suggestion with the tag 
names. You think that makes sense?

Original comment by danijel....@gmail.com on 9 May 2012 at 5:43

GoogleCodeExporter commented 9 years ago
Ok, I did those changes in r185 available for download. Let me know if that 
works for you...

Original comment by danijel....@gmail.com on 9 May 2012 at 7:55

GoogleCodeExporter commented 9 years ago
Sorry haven't gotten back to you, been really busy with the tutorial series, 
but getting back to the custom blocks now so should get back to you either 
tonight or sometime next week.

Original comment by jgora...@gmail.com on 14 May 2012 at 2:12

GoogleCodeExporter commented 9 years ago
okay the rotate works great, took me a while to figure out but it seems the 
program resets the rotation of the object to 0? then applies the value you 
enter or if you don't use a rotate modifier it just still sets it to zero

this is fine, just kind of caught me off guard but I got it figured out. Gotta 
check if it also does this for the translate.

can't wait to get my model pack done and see what it looks like with a real map.

Original comment by jgora...@gmail.com on 14 May 2012 at 5:07

GoogleCodeExporter commented 9 years ago
Not sure what you mean exactly. If you don't use rotation, it shouldn't apply 
the matrix to the object. When you choose to use rotation it creates a rotation 
matrix and adds it to the transformations that are applied to the object. Of 
course, the order of these operations matters and they should be applied in the 
order you decide. If you find anything that doesn't work how you expect, just 
paste it here.

Original comment by danijel....@gmail.com on 14 May 2012 at 5:53

GoogleCodeExporter commented 9 years ago
Okay, let me explain what's going on, I could be misinterpreting what's going 
on.

I've been trying to figure out the coordinates to minecraft correlation. From 
what I can tell:

+z = S
-z = N
+x = E
-x = W

so when I was dealing with the corner rails, it took a long time to figure out 
what goes with what. Since corner rails deal with two coordinates (by that I 
mean it starts from one direction and goes another) knowing the compass is 
really important.

I had a corner rail in 3dsmax that had a -90 on y (I'm flipping the z/y for you 
so this doesn't get confusing) So I figured the -90 y + the <rotate> adds onto 
the rotation of the object.

When I set the rotations to what I THOUGHT pointed in the proper direction, it 
was way off, it took a lot of back and forth trying to figure out where my 
miscalculation was coming from, and for what ever reason when I assumed your 
tool was resetting the rotate to 0 (either that or the export is resetting it) 
everything matched up perfectly.

not sure where the miscalculation is coming from, I could still have my compass 
confused, or something, no clue.

Original comment by jgora...@gmail.com on 14 May 2012 at 6:10

GoogleCodeExporter commented 9 years ago
Here's a little example I created. I made 4 letters in Blender: N,S,W,E and 
exported it to sides.obj (attached). Then I created this configuration:
 <block id="92" name="Cake">
    <model>Mesh</model>
    <mesh>
    <scale const="XYZ" value="0.2">
        <translate const="Z" value="-0.5">
            sides.obj#N
            <rotate const="Y" value="90">sides.obj#E</rotate>
            <rotate const="Y" value="180">sides.obj#S</rotate>
            <rotate const="Y" value="270">sides.obj#W</rotate>              
        </translate>
    </scale>
    </mesh>
    <occlusion>none</occlusion>
  </block>

The result is this image: http://imgur.com/AO9K6

Original comment by danijel....@gmail.com on 14 May 2012 at 6:34

Attachments:

GoogleCodeExporter commented 9 years ago
oh so you changed the formatting again as well.

your north and south are backwards compared to mine, the east and west are 
correct though.

if I set the rotate on my corner track it works to that setup, if I leave the 
-90 on the y the rotates that I do in the <rotate> don't match the directions, 
but if I set my track to 0 on y (but the export hasn't changed, it's still -90) 
then it matches the <rotate>

I'm really confused now lol

Original comment by jgora...@gmail.com on 14 May 2012 at 6:52

GoogleCodeExporter commented 9 years ago
    <mesh data="6">object.obj#Corner_Track_NW</mesh>
#based on the -90 on y in max by my compass the track would be pointing NE when 
for this data point it should be pointing SE, if I put my Y to 0 in max then it 
is pointing SE properly though the export obj version is still pointing NE, if 
I change my N and S to copy your compass it will be pointing the right 
direction of SE, but watch what happens on the next data point

    <mesh data="7">
        <rotate const="y" value="90">
            <mesh>object.obj#Corner_Track_NW</mesh>
        </rotate>
    </mesh>
#This one should be pointing SW, with the -90 y in max (-90 y + 90 y rotate = 0 
y) it actually points SE, if I flip my N and S like your compass it will be 
pointing NE, both those directions are wrong, but if I set my track again to 0 
y then + 90 y then it is facing SW

    <mesh data="8">
        <rotate const="y" value="180">
            <mesh>object.obj#Corner_Track_NW</mesh>
        </rotate>
    </mesh>
#This one is NW, again as stated above, with -90 in max the +180 will put it 
facing SW, flip the compass to yours and it is correct, set the max to 0 first 
then +180 and it faces the right direction of NW

    <mesh data="9">
        <rotate const="y" value="-90">
            <mesh>object.obj#Corner_Track_NW</mesh>
        </rotate>
    </mesh>
#This one should be NE, starting from -90 in max the additional -90 puts it 
facing NW, your compass, SW, set to 0 first then -90, proper direction

so in all these cases, setting the rotate of my object in max to 0 matches 
minecraft, but yet it's exported -90 so all of this should be wrong, when I 
import the track OBJ into max it has the -90 direction (facing NE) but the 
rotate is reset 0,0,0 

actually, looking at it now, if you reverse the positives and negatives (-90, 
-180, 90) and switch the compass to yours (swapping N and S) then it matches... 
but why does the negative rotates reverse? maybe negative rotates aren't 
supported... that would explain the issue maybe

Original comment by jgora...@gmail.com on 14 May 2012 at 7:19

GoogleCodeExporter commented 9 years ago
I just put a negative value in my conf and it worked (put -90 instead of 270).

What do you mean by "setting -90 in max"? Do you mean that is how you rotate it 
before exporting it to objects.obj?

Would it be possible to get a sample of your blocks.conf and object.obj that 
gives you problems so I could take a look at it? Maybe there is a nasty bug 
somewhere in the code, but I'm not sure what it could be.

Original comment by danijel....@gmail.com on 14 May 2012 at 7:31