All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.daxie.xops.bd1.BD1OBJWriter Maven / Gradle / Ivy

Go to download

XOPSManipulator is a Java library that offers several functions to manipulate matters relating to X operations.

The newest version!
package com.daxie.xops.bd1;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.daxie.basis.vector.Vector;
import com.daxie.basis.vector.VectorFunctions;
import com.daxie.log.LogFile;
import com.daxie.tool.ExceptionFunctions;
import com.daxie.tool.FilenameFunctions;

import de.javagl.obj.Mtl;
import de.javagl.obj.MtlWriter;
import de.javagl.obj.Mtls;
import de.javagl.obj.Obj;
import de.javagl.obj.ObjWriter;
import de.javagl.obj.Objs;

/**
 * Writes out BD1 blocks into an OBJ file.
 * @author Daba
 *
 */
class BD1OBJWriter {
	private boolean data_prepared_flag;
	
	private Map texture_filenames_map;
	private Map> faces_map;
	
	public BD1OBJWriter(Map texture_filenames_map,List blocks) {
		data_prepared_flag=false;
		if(texture_filenames_map==null||blocks==null) {
			LogFile.WriteWarn("[BD1OBJWriter-] Null argument(s) where non-null required.",true);
			return;
		}
		
		this.texture_filenames_map=texture_filenames_map;
		faces_map=new HashMap<>();
		
		for(BD1Block block:blocks) {
			int[] texture_ids=block.GetTextureIDs();
			
			Vector[] vertex_positions=block.GetVertexPositions();
			float[] us=block.GetUs();
			float[] vs=block.GetVs();
			
			//Calculate normals.
			Vector[] normals=new Vector[6];
			Vector v1,v2;
			for(int i=0;i<6;i++) {
				int[] vertex_indices=BD1Functions.GetFaceCorrespondingVertexIndices(i);
				
				v1=VectorFunctions.VSub(vertex_positions[vertex_indices[3]], vertex_positions[vertex_indices[0]]);
				v2=VectorFunctions.VSub(vertex_positions[vertex_indices[1]], vertex_positions[vertex_indices[0]]);
				
				normals[i]=VectorFunctions.VCross(v1, v2);
				normals[i]=VectorFunctions.VNorm(normals[i]);
			}
			
			BD1Face[] faces=new BD1Face[6];
			for(int i=0;i<6;i++)faces[i]=new BD1Face();
			
			for(int i=0;i<6;i++) {
				int[] vertex_indices=BD1Functions.GetFaceCorrespondingVertexIndices(i);
				int[] uv_indices=BD1Functions.GetFaceCorrespondingUVIndices(i);
				
				for(int j=0;j<4;j++) {
					faces[i].SetVertexPosition(j, vertex_positions[vertex_indices[j]]);
					faces[i].SetUV(j, us[uv_indices[j]], vs[uv_indices[j]]);
				}
				faces[i].SetNormal(normals[i]);
			}
			
			for(int i=0;i<6;i++) {
				int texture_id=texture_ids[i];
				
				if(faces_map.containsKey(texture_id)==false) {
					List list_temp=new ArrayList<>();
					faces_map.put(texture_id, list_temp);
				}
				List faces_list=faces_map.get(texture_id);
				faces_list.add(faces[i]);
			}
		}
		
		data_prepared_flag=true;
	}
	
	/**
	 * Writes out data into an OBJ file.
	 * @param obj_filename Filename
	 * @return -1 on error and 0 on success
	 */
	public int Write(String obj_filename) {
		if(data_prepared_flag==false) {
			LogFile.WriteWarn("[BD1OBJWriter-Write] Data not prepared.",true);
			return -1;
		}
		
		String mtllib_str;
		mtllib_str=FilenameFunctions.GetFilenameWithoutDirectory(obj_filename);
		mtllib_str=FilenameFunctions.GetFilenameWithoutExtension(mtllib_str)+".mtl";
		String mtl_filename;
		mtl_filename=FilenameFunctions.GetFilenameWithoutExtension(obj_filename);
		mtl_filename=mtl_filename+".mtl";
		
		Obj obj=Objs.create();
		List mtls=new ArrayList<>();
		
		obj.setMtlFileNames(Arrays.asList(mtllib_str));
		obj.setActiveGroupNames(Arrays.asList("map"));
		
		int count=0;
		for(Map.Entry> entry:faces_map.entrySet()) {
			int texture_id=entry.getKey();
			String texture_filename=texture_filenames_map.get(texture_id);
			if(texture_filename==null) {
				LogFile.WriteWarn("[BD1OBJWriter-Write] Detected a discrepancy between two maps. texture_id:"+texture_id,true);
				texture_filename="unknown_"+texture_id;
			}
			
			String material_name;
			material_name=FilenameFunctions.GetFilenameWithoutDirectory(texture_filename);
			material_name=FilenameFunctions.GetFilenameWithoutExtension(material_name);
			material_name+="_"+texture_id;
			
			Mtl mtl=Mtls.create(material_name);
			mtl.setNs(0.0f);
			mtl.setKa(1.0f,1.0f,1.0f);
			mtl.setKd(1.0f, 1.0f, 1.0f);
			mtl.setKs(0.0f, 0.0f, 0.0f);
			mtl.setD(1.0f);
			mtl.setNs(0.0f);
			mtl.setMapKd(texture_filename);
			mtls.add(mtl);
			
			obj.setActiveMaterialGroupName(material_name);
			
			List faces=entry.getValue();
			
			for(BD1Face face:faces) {
				Vector[] vertex_positions=face.GetVertexPositions();
				Vector normal=face.GetNormal();
				float[] us=face.GetUs();
				float[] vs=face.GetVs();
				
				for(int i=3;i>=0;i--) {
					obj.addVertex(vertex_positions[i].GetX(), vertex_positions[i].GetY(), vertex_positions[i].GetZ());
					obj.addNormal(normal.GetX(), normal.GetY(), normal.GetZ());
					obj.addTexCoord(us[i], -vs[i]);
				}
				
				int[] indices=new int[] {count,count+1,count+2,count+3};
				obj.addFace(indices,indices,indices);
				
				count+=4;
			}
		}
		
		OutputStream os_obj=null;
		OutputStream os_mtl=null;
		try {
			os_obj=new FileOutputStream(obj_filename);
			os_mtl=new FileOutputStream(mtl_filename);
		}
		catch(IOException e) {
			String str=ExceptionFunctions.GetPrintStackTraceString(e);
			
			LogFile.WriteWarn("[BD1OBJWriter-Write] Below is the stack trace.",true);
			LogFile.WriteWarn(str,false);
			
			return -1;
		}
		
		try {
			ObjWriter.write(obj, os_obj);
			MtlWriter.write(mtls, os_mtl);
		}
		catch(IOException e) {
			String str=ExceptionFunctions.GetPrintStackTraceString(e);
			
			LogFile.WriteWarn("[BD1OBJWriter-Write] Below is the stack trace.",true);
			LogFile.WriteWarn(str,false);
			
			return -1;
		}
		
		return 0;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy