Search in sources :

Example 6 with ParsingException

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);
}
Also used : HashMap(java.util.HashMap) NotParsableException(org.rajawali3d.loader.awd.exceptions.NotParsableException) Material(org.rajawali3d.materials.Material) NormalMapTexture(org.rajawali3d.materials.textures.NormalMapTexture) AwdProperties(org.rajawali3d.loader.LoaderAWD.AwdProperties) SpecularMapTexture(org.rajawali3d.materials.textures.SpecularMapTexture) SpecularMapTexture(org.rajawali3d.materials.textures.SpecularMapTexture) Texture(org.rajawali3d.materials.textures.Texture) NormalMapTexture(org.rajawali3d.materials.textures.NormalMapTexture) SpecularMethod(org.rajawali3d.materials.methods.SpecularMethod) ParsingException(org.rajawali3d.loader.ParsingException)

Example 7 with ParsingException

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);
}
Also used : SkeletalAnimationChildObject3D(org.rajawali3d.animation.mesh.SkeletalAnimationChildObject3D) ArrayList(java.util.ArrayList) Object3D(org.rajawali3d.Object3D) SkeletalAnimationObject3D(org.rajawali3d.animation.mesh.SkeletalAnimationObject3D) SkeletalAnimationChildObject3D(org.rajawali3d.animation.mesh.SkeletalAnimationChildObject3D) SparseArray(android.util.SparseArray) BoneWeight(org.rajawali3d.animation.mesh.SkeletalAnimationChildObject3D.BoneWeight) ParsingException(org.rajawali3d.loader.ParsingException) BoneVertex(org.rajawali3d.animation.mesh.SkeletalAnimationChildObject3D.BoneVertex)

Example 8 with ParsingException

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;
}
Also used : InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) FileNotFoundException(java.io.FileNotFoundException) Vector3(org.rajawali3d.math.vector.Vector3) TextureException(org.rajawali3d.materials.textures.ATexture.TextureException) ParsingException(org.rajawali3d.loader.ParsingException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) InvocationTargetException(java.lang.reflect.InvocationTargetException) Stack(java.util.Stack) TextureException(org.rajawali3d.materials.textures.ATexture.TextureException) ParsingException(org.rajawali3d.loader.ParsingException) DirectionalLight(org.rajawali3d.lights.DirectionalLight) BufferedReader(java.io.BufferedReader) Model(org.rajawali3d.loader.fbx.FBXValues.Objects.Model) FileReader(java.io.FileReader) Camera(org.rajawali3d.cameras.Camera) ALight(org.rajawali3d.lights.ALight)

Example 9 with ParsingException

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;
    }
}
Also used : SkeletalAnimationChildObject3D(org.rajawali3d.animation.mesh.SkeletalAnimationChildObject3D) ParsingException(org.rajawali3d.loader.ParsingException) SkeletalAnimationMaterialPlugin(org.rajawali3d.materials.plugins.SkeletalAnimationMaterialPlugin) DiffuseMethod(org.rajawali3d.materials.methods.DiffuseMethod) SkeletalAnimationObject3D(org.rajawali3d.animation.mesh.SkeletalAnimationObject3D) Material(org.rajawali3d.materials.Material) Texture(org.rajawali3d.materials.textures.Texture) SkeletonJoint(org.rajawali3d.animation.mesh.SkeletalAnimationFrame.SkeletonJoint)

Aggregations

ParsingException (org.rajawali3d.loader.ParsingException)9 FileNotFoundException (java.io.FileNotFoundException)4 BufferedReader (java.io.BufferedReader)3 FileReader (java.io.FileReader)3 InputStream (java.io.InputStream)3 InputStreamReader (java.io.InputStreamReader)3 SkeletonJoint (org.rajawali3d.animation.mesh.SkeletalAnimationFrame.SkeletonJoint)3 Material (org.rajawali3d.materials.Material)3 TextureException (org.rajawali3d.materials.textures.ATexture.TextureException)3 Texture (org.rajawali3d.materials.textures.Texture)3 IOException (java.io.IOException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 StringTokenizer (java.util.StringTokenizer)2 Object3D (org.rajawali3d.Object3D)2 SkeletalAnimationChildObject3D (org.rajawali3d.animation.mesh.SkeletalAnimationChildObject3D)2 SkeletalAnimationObject3D (org.rajawali3d.animation.mesh.SkeletalAnimationObject3D)2 AwdProperties (org.rajawali3d.loader.LoaderAWD.AwdProperties)2 Vector3 (org.rajawali3d.math.vector.Vector3)2 Bitmap (android.graphics.Bitmap)1 SparseArray (android.util.SparseArray)1