use of org.rajawali3d.loader.ParsingException in project Rajawali by Rajawali.
the class BlockSimpleMaterial method parseBlock.
public void parseBlock(AWDLittleEndianDataInputStream dis, BlockHeader blockHeader) throws Exception {
// Lookup name
mLookupName = dis.readVarString();
// Material type
mMaterialType = dis.readByte();
// Shading method count
mShadingMethodCount = dis.readByte();
// Read properties
final AwdProperties properties = dis.readProperties(EXPECTED_PROPS);
mSpezialType = (Integer) properties.get((short) 4, 0);
// Spezial type 2 or higher is not supported in the specification
if (mSpezialType >= 2)
throw new NotParsableException("Spezial type " + mSpezialType + " is not currently supported.");
// Debug
if (RajLog.isDebugEnabled()) {
RajLog.d(" Lookup Name: " + mLookupName);
RajLog.d(" Material Type: " + mMaterialType);
RajLog.d(" Shading Methods: " + mShadingMethodCount);
RajLog.d(" Spezial Type: " + mSpezialType);
}
// Parse the methods
for (int i = 0; i < mShadingMethodCount; ++i) {
// TODO Looking at the AWD source, this appears to be completely unused?
dis.readUnsignedShort();
dis.readProperties();
dis.readUserAttributes(null);
}
final HashMap<String, Object> attributes = new HashMap<String, Object>();
dis.readUserAttributes(attributes);
mMaterial = new Material();
long diffuseTexture = 0, ambientTexture = 0, diffuseColor = 0;
// remove any chars that will break shader compile
String cleanName = cleanName(mLookupName);
switch(mMaterialType) {
case TYPE_COLOR:
// default to 0xcccccc per AWD implementation
diffuseColor = (Long) properties.get((short) 1, 0xccccccL);
final float[] colorFloat = new float[4];
colorFloat[0] = ((diffuseColor >> 16) & 0xff) / 255.0f;
colorFloat[1] = ((diffuseColor >> 8) & 0xff) / 255.0f;
colorFloat[2] = (diffuseColor & 0xff) / 255.0f;
colorFloat[3] = (((int) ((Double) properties.get(PROP_ALPHA, 1.0d) * 0xff)) & 0xff) / 255.0f;
mMaterial.setColor(colorFloat);
break;
case TYPE_TEXTURE:
diffuseTexture = (Long) properties.get(PROP_TEXTURE, 0L);
ambientTexture = (Long) properties.get(PROP_AMBIENT_TEXTURE, 0L);
if (diffuseTexture == 0 && ambientTexture == 0)
throw new ParsingException("Texture ID can not be 0, document corrupt or unsupported version.");
if (diffuseTexture > 0)
mMaterial.addTexture(new Texture(cleanName + diffuseTexture, lookup(blockHeader, diffuseTexture)));
if (ambientTexture > 0)
mMaterial.addTexture(new Texture(cleanName + ambientTexture, lookup(blockHeader, ambientTexture)));
mMaterial.setColorInfluence(0);
break;
}
// either material type can have specular and/or normal maps
long specularTexture = (Long) properties.get(PROP_SPECULAR_TEXTURE, 0L);
long normalTexture = (Long) properties.get(PROP_NORMAL_TEXTURE, 0L);
// either material type can have settings for diffuse, ambient, specular lighting
double diffuseLevel = (Double) properties.get(PROP_DIFFUSE_LEVEL, 1.0d);
long ambientColor = (Long) properties.get(PROP_AMBIENT_COLOR, (long) Color.WHITE);
double ambientLevel = (Double) properties.get(PROP_AMBIENT_LEVEL, 1.0d);
long specularColor = (Long) properties.get(PROP_SPECULAR_COLOR, (long) Color.WHITE);
double specularGloss = (Double) properties.get(PROP_SPECULAR_GLOSS, 50.0D);
double specularLevel = (Double) properties.get(PROP_SPECULAR_LEVEL, 1.0d);
if (specularTexture > 0)
mMaterial.addTexture(new SpecularMapTexture(cleanName + specularTexture, lookup(blockHeader, specularTexture)));
if (normalTexture > 0)
mMaterial.addTexture(new NormalMapTexture(cleanName + normalTexture, lookup(blockHeader, normalTexture)));
// ambient 1.0 is default, washes-out object; assume < 1 is intended
ambientLevel = (ambientLevel < 1.0 ? ambientLevel : 0.0);
mMaterial.setAmbientIntensity(ambientLevel, ambientLevel, ambientLevel);
mMaterial.setAmbientColor((int) ambientColor);
if (// always 1.0 in current AWD implementation
diffuseLevel > 0)
mMaterial.setDiffuseMethod(new DiffuseMethod.Lambert());
if (specularLevel > 0) {
SpecularMethod.Phong phong = new SpecularMethod.Phong();
phong.setSpecularColor((int) specularColor);
phong.setShininess((float) specularGloss);
phong.setIntensity((float) specularLevel);
mMaterial.setSpecularMethod(phong);
}
// don't enable lighting if specular and diffuse are absent, otherwise enable
if (diffuseLevel > 0 || specularLevel > 0)
mMaterial.enableLighting(true);
}
use of org.rajawali3d.loader.ParsingException in project Rajawali by Rajawali.
the class BlockTriangleGeometry method parseBlock.
public void parseBlock(AWDLittleEndianDataInputStream dis, BlockHeader blockHeader) throws Exception {
// Lookup name
mLookupName = dis.readVarString();
// Count of sub geometries
mSubGeometryCount = dis.readUnsignedShort();
// TODO Meshes need to be joined in some fashion. This might work. Need to test it I suppose.
// One object for each sub geometry
mBaseObjects = new Object3D[mSubGeometryCount];
// Debug
if (RajLog.isDebugEnabled()) {
RajLog.d(" Lookup Name: " + mLookupName);
RajLog.d(" Sub Geometry Count: " + mSubGeometryCount);
}
// Determine the precision for the block
final boolean geoAccuracy = (blockHeader.flags & BlockHeader.FLAG_ACCURACY_GEO) == BlockHeader.FLAG_ACCURACY_GEO;
final short geoNr = geoAccuracy ? AWDLittleEndianDataInputStream.TYPE_FLOAT64 : AWDLittleEndianDataInputStream.TYPE_FLOAT32;
// Read the properties
SparseArray<Short> properties = new SparseArray<Short>();
// Scale Texture U
properties.put(1, geoNr);
// Scale Texture V
properties.put(2, geoNr);
// TODO Apply texture scales, need example of this working.
dis.readProperties(properties);
// Calculate the sizes
final int geoPrecisionSize = blockHeader.globalPrecisionGeo ? 8 : 4;
// Read each sub mesh data
for (int parsedSub = 0; parsedSub < mSubGeometryCount; ++parsedSub) {
long subMeshEnd = dis.getPosition() + dis.readUnsignedInt();
// Geometry
float[] vertices = null;
int[] indices = null;
float[] uvs = null;
float[] normals = null;
int[] joints = null;
float[] weights = null;
// Skip reading of mesh properties for now (per AWD implementation)
dis.readProperties();
// Read each data type from the mesh
while (dis.getPosition() < subMeshEnd) {
int idx = 0;
int type = dis.readUnsignedByte();
int typeF = dis.readUnsignedByte();
long subLength = dis.readUnsignedInt();
long subEnd = dis.getPosition() + subLength;
if (RajLog.isDebugEnabled())
RajLog.d(" Mesh Data: t:" + type + " tf:" + typeF + " l:" + subLength + " ls:" + dis.getPosition() + " le:" + subEnd);
// Process the mesh data by type
switch((int) type) {
case // Vertex positions
1:
vertices = new float[(int) (subLength / geoPrecisionSize)];
while (idx < vertices.length) {
// X, Y, Z
vertices[idx++] = (float) dis.readPrecisionNumber(blockHeader.globalPrecisionGeo);
vertices[idx++] = (float) dis.readPrecisionNumber(blockHeader.globalPrecisionGeo);
vertices[idx++] = (float) -dis.readPrecisionNumber(blockHeader.globalPrecisionGeo);
}
break;
case // Face indices
2:
indices = new int[(int) (subLength / 2)];
while (idx < indices.length) {
indices[idx + 2] = dis.readUnsignedShort();
indices[idx + 1] = dis.readUnsignedShort();
indices[idx] = dis.readUnsignedShort();
idx += 3;
}
break;
case // UV coordinates
3:
uvs = new float[(int) (subLength / geoPrecisionSize)];
while (idx < uvs.length) uvs[idx++] = (float) dis.readPrecisionNumber(blockHeader.globalPrecisionGeo);
break;
case // Vertex normals
4:
normals = new float[(int) (subLength / geoPrecisionSize)];
while (idx < normals.length) {
normals[idx++] = (float) dis.readPrecisionNumber(blockHeader.globalPrecisionGeo);
normals[idx++] = (float) dis.readPrecisionNumber(blockHeader.globalPrecisionGeo);
normals[idx++] = (float) dis.readPrecisionNumber(blockHeader.globalPrecisionGeo);
}
break;
case // Joint index
6:
joints = new int[(int) (subLength / 2)];
while (idx < joints.length) joints[idx++] = dis.readUnsignedShort();
break;
case // Joint weight
7:
weights = new float[(int) (subLength / geoPrecisionSize)];
while (idx < weights.length) weights[idx++] = (float) dis.readPrecisionNumber(blockHeader.globalPrecisionGeo);
break;
// Vertex tangents
case 5:
default:
// Unknown mesh data, skipping
dis.skip(subLength);
}
// Validate each mesh data ending. This is a sanity check against precision flags.
if (dis.getPosition() != subEnd)
throw new ParsingException("Unexpected ending. Expected " + subEnd + ". Got " + dis.getPosition());
}
dis.readUserAttributes(null);
// Verify the arrays
if (vertices == null)
vertices = new float[0];
if (normals == null)
normals = new float[0];
if (uvs == null)
uvs = new float[0];
if (indices == null)
indices = new int[0];
// FIXME This should be combining sub geometry not creating objects
if (joints != null && joints.length > 0) {
/*
* Prepares skeletal animation object as far as possible; setting mesh
* and skeletal weight data. The object will not yet have an actual
* skeleton applied to it.
*/
SkeletalAnimationChildObject3D obj = new SkeletalAnimationChildObject3D();
obj.setData(vertices, normals, uvs, null, indices, false);
int numVertices = vertices.length / 3;
// AWD stipulates all vertices have same # bindings, possibly 0 weighted
int weightsPerVertex = weights.length / numVertices;
// true WPV may be out of range, so clamp
int clampWeightsPerVertex = Math.min(weightsPerVertex, SkeletalAnimationChildObject3D.MAX_WEIGHTS_PER_VERTEX);
// one BoneVertex per actual vertex, maps to N weights & joint indices
BoneVertex[] bvertices = new BoneVertex[numVertices];
ArrayList<BoneWeight> bweights = new ArrayList<BoneWeight>();
int maxWeightsPerVertex = 0;
int vertexWeightIndex = 0;
for (int vert = 0; vert < numVertices; vert++) {
BoneVertex bone = new BoneVertex();
bvertices[vert] = bone;
// we may ignore weights, so map to our custom list
bone.weightIndex = bweights.size();
// true position in raw weight array
vertexWeightIndex = vert * weightsPerVertex;
// only add first [clamp] non-zero weights
for (int wgt = 0; wgt < clampWeightsPerVertex; wgt++) {
if (weights[vertexWeightIndex + wgt] == 0)
continue;
BoneWeight weight = new BoneWeight();
// joints and weights are indexed together
weight.jointIndex = joints[vertexWeightIndex + wgt];
weight.weightValue = weights[vertexWeightIndex + wgt];
bone.numWeights++;
bweights.add(weight);
}
maxWeightsPerVertex = Math.max(maxWeightsPerVertex, bone.numWeights);
}
// extract the clean BoneWeight array
BoneWeight[] boneweights = bweights.toArray(new BoneWeight[bweights.size()]);
obj.setMaxBoneWeightsPerVertex(maxWeightsPerVertex);
obj.setSkeletonMeshData(bvertices, boneweights);
//obj.setInverseZScale(true);
mBaseObjects[parsedSub] = obj;
} else {
mBaseObjects[parsedSub] = new Object3D();
mBaseObjects[parsedSub].setData(vertices, normals, uvs, null, indices, false);
}
}
dis.readUserAttributes(null);
}
use of org.rajawali3d.loader.ParsingException in project Rajawali by Rajawali.
the class LoaderFBX method parse.
@Override
public LoaderFBX parse() throws ParsingException {
super.parse();
BufferedReader buffer = null;
if (mFile == null) {
InputStream fileIn = mResources.openRawResource(mResourceId);
buffer = new BufferedReader(new InputStreamReader(fileIn));
} else {
try {
buffer = new BufferedReader(new FileReader(mFile));
} catch (FileNotFoundException e) {
RajLog.e("[" + getClass().getCanonicalName() + "] Could not find file.");
throw new ParsingException(e);
}
}
String line;
try {
while ((line = buffer.readLine()) != null) {
String repl = line.replaceAll(REGEX_CLEAN, REPLACE_EMPTY);
if (repl.length() == 0 || repl.charAt(0) == COMMENT)
continue;
readLine(buffer, line);
}
buffer.close();
} catch (Exception e) {
throw new ParsingException(e);
}
// -- get lights
Stack<Model> lights = mFbx.objects.getModelsByType(FBXValues.MODELTYPE_LIGHT);
int numLights = lights.size();
Renderer.setMaxLights(numLights == 0 ? 1 : numLights);
Stack<ALight> sceneLights = new Stack<ALight>();
for (int i = 0; i < numLights; ++i) {
Model l = lights.get(i);
// -- really need to add more light types
sceneLights.add(buildLight(l));
}
if (numLights == 0) {
ALight light = new DirectionalLight();
light.setPosition(2, 0, -5);
light.setPower(1);
sceneLights.add(light);
}
// -- check fog
//TODO: add fog support
/*if(mFbx.version5.fogOptions.fogEnable != null && mFbx.version5.fogOptions.fogEnable == 1) {
FogOptions fogOptions = mFbx.version5.fogOptions;
mRenderer.setFogEnabled(true);
Camera cam = mRenderer.getCamera();
cam.setFogEnabled(true);
cam.setFogNear(fogOptions.fogStart);
cam.setFogColor(fogOptions.fogColor.color);
mRenderer.setBackgroundColor(fogOptions.fogColor.color);
}*/
// -- get meshes
Stack<Model> models = mFbx.objects.getModelsByType(FBXValues.MODELTYPE_MESH);
try {
for (int i = 0; i < models.size(); ++i) {
buildMesh(models.get(i), sceneLights);
}
} catch (TextureException tme) {
throw new ParsingException(tme);
}
// -- get cameras
Stack<Model> cameras = mFbx.objects.getModelsByType(FBXValues.MODELTYPE_CAMERA);
Model camera = null;
for (int i = 0; i < cameras.size(); ++i) {
if (cameras.get(i).hidden == null || !cameras.get(i).hidden.equals("True")) {
camera = cameras.get(i);
break;
}
}
if (camera != null) {
//TODO: FIX
Camera cam = mRenderer.getCurrentCamera();
cam.setPosition(camera.position);
cam.setX(mRenderer.getCurrentCamera().getX() * -1);
cam.setRotation(camera.properties.lclRotation);
Vector3 lookAt = camera.lookAt;
// lookAt.x = -lookAt.x;
cam.setLookAt(lookAt);
cam.setNearPlane(camera.properties.nearPlane);
cam.setFarPlane(camera.properties.farPlane);
cam.setFieldOfView(camera.properties.fieldOfView);
}
return this;
}
use of org.rajawali3d.loader.ParsingException in project Rajawali by Rajawali.
the class LoaderMD5Mesh method createObjects.
private void createObjects() throws TextureException, ParsingException, SkeletalAnimationException {
SkeletalAnimationObject3D root = new SkeletalAnimationObject3D();
root.uBoneMatrix = mBindPoseMatrix;
root.mInverseBindPoseMatrix = mInverseBindPoseMatrix;
root.setJoints(mJoints);
mRootObject = root;
for (int i = 0; i < mNumMeshes; ++i) {
SkeletonMeshData mesh = mMeshes[i];
SkeletalAnimationChildObject3D o = new SkeletalAnimationChildObject3D();
o.setData(mesh.vertices, GLES20.GL_STREAM_DRAW, mesh.normals, GLES20.GL_STREAM_DRAW, mesh.textureCoordinates, GLES20.GL_STATIC_DRAW, null, GLES20.GL_STATIC_DRAW, mesh.indices, GLES20.GL_STATIC_DRAW, false);
o.setMaxBoneWeightsPerVertex(mesh.maxBoneWeightsPerVertex);
o.setSkeletonMeshData(mesh.numVertices, mesh.boneVertices, mesh.numWeights, mesh.boneWeights);
o.setName("MD5Mesh_" + i);
o.setSkeleton(mRootObject);
o.setInverseZScale(true);
boolean hasTexture = mesh.textureName != null && mesh.textureName.length() > 0;
Material mat = new Material();
mat.addPlugin(new SkeletalAnimationMaterialPlugin(mNumJoints, mesh.maxBoneWeightsPerVertex));
mat.enableLighting(true);
mat.setDiffuseMethod(new DiffuseMethod.Lambert());
o.setMaterial(mat);
if (!hasTexture) {
o.setColor(0xff000000 + (int) (Math.random() * 0xffffff));
} else {
int identifier = mResources.getIdentifier(mesh.textureName, "drawable", mResources.getResourcePackageName(mResourceId));
if (identifier == 0) {
throw new ParsingException("Couldn't find texture " + mesh.textureName);
}
mat.setColorInfluence(0);
mat.addTexture(new Texture("md5tex" + i, identifier));
}
mRootObject.addChild(o);
mesh.destroy();
mesh = null;
}
}
Aggregations