JurassicParkTrespasser/jp2_pc/Source/Tools/GroffExp/Export.cpp
2018-01-01 23:07:24 +01:00

605 lines
18 KiB
C++

#include "StandardTypes.hpp"
#include "ObjectDef.hpp"
//**********************************************************************************************
// Must undefine GetMessage as it gets defined inside of the Max.h include hierarchy, most
// likely it is a windows entry point.
//
#undef GetMessage
#include "Lib/Sys/SysLog.hpp"
#include "Lib/Groff/FileIO.hpp"
#include "Lib/Groff/Groff.hpp"
#include "Tools/GroffExp/Export.hpp"
#include "Tools/GroffExp/GUIInterface.hpp"
extern CGUIInterface guiInterface;
bool CGroffExport::bWriteToSection(CObjectDef* pod_node, TSectionHandle seh_handle, void* data, uint u_size, const char* str_error_message)
{
int i_actual_size;
// Write out the file header.
i_actual_size = fioFile.iWrite(seh_handle, data, u_size);
if (i_actual_size != (int) u_size)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("%s\n\nbWriteToSection: File IO error message: %s\n", str_error_message, fioFile.GetMessage());
slLogfile.Printf("bWriteToSection: Node address: 0x%X, Handle: 0x%X, Buffer: 0x%X, Requested size %d, Actual size: %d\n",
pod_node, seh_handle, data, u_size, i_actual_size);
// Do we have a valid object node?
if (pod_node != 0)
{
slLogfile.Printf("bWriteToSection: Node ID %d, Object name: %s\n", pod_node->iID, pod_node->estrObjectName.strData());
}
// Write out the file header.
fioFile.iWrite(seh_handle, data, u_size);
// Return an error.
return false;
}
// Return a successful result.
return true;
}
bool CGroffExport::bSaveMaterial(CObjectDef* pod_node, TSectionHandle& seh_handle)
{
// Is there a material definition?
if (pod_node->uMaterialCount == 0)
{
// No! Return a zero handle and a successful result.
seh_handle = 0;
return true;
}
// Attempt to setup a material object.
CGroffMaterial gmat_material;
gmat_material.uTextureCount = pod_node->uMaterialCount;
// Attempt to configure this object.
if (!gmat_material.bConfigure())
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveMaterial: Unable to configure material object for object:%s:\n", pod_node->estrObjectName.strData());
}
// Attempt to create an object section.
seh_handle = fioFile.sehCreate(".material", gMATERIAL);
// Were we successful?
if (seh_handle == 0)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveMaterial: Unable to create material section for :%s:\n", pod_node->estrObjectName.strData());
// Return an error.
return false;
}
// Loop through all the materials and convert them from symbols to handles.
for (uint u_i = 0; u_i < pod_node->uMaterialCount; u_i++)
{
// Are there any texture maps?
if (pod_node->astrTextureMap != 0)
{
// First attempt to add the name to the symbol table.
if (pod_node->astrTextureMap[u_i] != 0)
{
gmat_material.asyhTextureHandle[u_i] = fioFile.syhInsert(pod_node->astrTextureMap[u_i]);
// Were we successful?
if (gmat_material.asyhTextureHandle[u_i] == 0)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveMaterial: Unable to register symbol :%s: to symbol table.\n", pod_node->astrTextureMap[u_i]);
// No! Return an error.
return false;
}
}
else
{
// Set the symbol handle to 0.
gmat_material.asyhTextureHandle[u_i] = 0;
}
}
// Are there any opacity maps?
if (pod_node->astrOpacityMap != 0)
{
// First attempt to add the name to the symbol table.
if (pod_node->astrOpacityMap[u_i] != 0)
{
gmat_material.asyhOpacityHandle[u_i] = fioFile.syhInsert(pod_node->astrOpacityMap[u_i]);
// Were we successful?
if (gmat_material.asyhOpacityHandle[u_i] == 0)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveMaterial: Unable to register symbol :%s: to symbol table.\n", pod_node->astrOpacityMap[u_i]);
// No! Return an error.
return false;
}
}
else
{
// Set the symbol handle to 0.
gmat_material.asyhOpacityHandle[u_i] = 0;
}
}
// Are there any bump maps?
if (pod_node->astrBumpMap != 0)
{
// First attempt to add the name to the symbol table.
if (pod_node->astrBumpMap[u_i] != 0)
{
gmat_material.asyhBumpHandle[u_i] = fioFile.syhInsert(pod_node->astrBumpMap[u_i]);
// Were we successful?
if (gmat_material.asyhBumpHandle[u_i] == 0)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveMaterial: Unable to register symbol :%s: to symbol table.\n", pod_node->astrBumpMap[u_i]);
// No! Return an error.
return false;
}
}
else
{
// Set the symbol handle to 0.
gmat_material.asyhBumpHandle[u_i] = 0;
}
}
}
// Attempt to write the material definition to the image.
if (!bWriteToSection(pod_node, seh_handle, &gmat_material.uTextureCount, sizeof(uint),
"bSaveMaterial: Unable to write the material count."))
return false;
if (!bWriteToSection(pod_node, seh_handle, gmat_material.asyhTextureHandle, sizeof(uint) * gmat_material.uTextureCount,
"bSaveMaterial: Unable to write the texture map handle list."))
return false;
if (!bWriteToSection(pod_node, seh_handle, gmat_material.asyhOpacityHandle, sizeof(uint) * gmat_material.uTextureCount,
"bSaveMaterial: Unable to write the opacity map handle list."))
return false;
if (!bWriteToSection(pod_node, seh_handle, gmat_material.asyhBumpHandle, sizeof(uint) * gmat_material.uTextureCount,
"bSaveMaterial: Unable to write the bumpmap handle list."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &gmat_material.fAmbient, sizeof(float),
"bSaveMaterial: Unable to write the ambient lighting term."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &gmat_material.fDiffuse, sizeof(float),
"bSaveMaterial: Unable to write the diffuse lighting term."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &gmat_material.fSpecular, sizeof(float),
"bSaveMaterial: Unable to write the specular lighting term."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &gmat_material.fOpacity, sizeof(float),
"bSaveMaterial: Unable to write the opacity value."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &gmat_material.fBumpiness, sizeof(float),
"bSaveMaterial: Unable to write the bumpiness value."))
return false;
// Return a successful result.
return true;
}
bool CGroffExport::bSaveMapping(CObjectDef* pod_node, TSectionHandle& seh_handle)
{
// Is there a mapping definition?
if (pod_node->uTextureFaceCount == 0 && pod_node->uTextureVertexCount == 0)
{
// No! Return a zero handle and a successful result.
seh_handle = 0;
return true;
}
CGroffMapping gmap_mapping;
// Attempt to create an object section.
seh_handle = fioFile.sehCreate(".mapping", gMAPPING);
// Were we successful?
if (seh_handle == 0)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveMapping: Unable to create mapping section for :%s:\n", pod_node->estrObjectName.strData());
// Return an error.
return false;
}
// Attempt to add the material section. Were we successful?
if (!bSaveMaterial(pod_node, gmap_mapping.sehMaterial))
{
// No! Return an error;
return false;
}
// Attempt to write the class info to the image.
if (!bWriteToSection(pod_node, seh_handle, &gmap_mapping.sehMaterial, sizeof(TSectionHandle),
"bSaveMapping: Unable to write the material handle."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &pod_node->uTextureVertexCount, sizeof(uint),
"bSaveMapping: Unable to write the texture vertex count."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &pod_node->uTextureFaceCount, sizeof(uint),
"bSaveMapping: Unable to write the texture face count."))
return false;
if (!bWriteToSection(pod_node, seh_handle, pod_node->afv2TextureVertex, sizeof(fvector2) * pod_node->uTextureVertexCount,
"bSaveMapping: Unable to write the texture vertices."))
return false;
if (!bWriteToSection(pod_node, seh_handle, pod_node->auv3TextureFace, sizeof(uvector3) * pod_node->uTextureFaceCount,
"bSaveMapping: Unable to write the texture faces."))
return false;
if (!bWriteToSection(pod_node, seh_handle, pod_node->auFaceMaterialIndex, sizeof(uint) * pod_node->uTextureFaceCount,
"bSaveMapping: Unable to write the face material indices."))
return false;
// Return a successful result.
return true;
}
bool CGroffExport::bSaveGeometry(CObjectDef* pod_node, TSectionHandle& seh_handle)
{
// Is there a valid geometry definition?
if (pod_node->uVertexCount == 0 && pod_node->uFaceCount == 0 && pod_node->uVertexNormalCount == 0)
{
// No! Return a zero handle and a successful result.
seh_handle = 0;
return true;
}
CGroffGeometry gg_geometry;
// Attempt to create an object section.
seh_handle = fioFile.sehCreate(".geometry", gGEOMETRY);
// Were we successful?
if (seh_handle == 0)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveGeometry: Unable to create geometry section for :%s:\n", pod_node->estrObjectName.strData());
// No! Return an error;
return false;
}
// Attempt to write the data to the image.
if (!bWriteToSection(pod_node, seh_handle, &pod_node->uVertexCount, sizeof(uint),
"bSaveGeometry: Unable to write vertex count."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &pod_node->uFaceCount, sizeof(uint),
"bSaveGeometry: Unable to write face count."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &pod_node->uVertexNormalCount, sizeof(uint),
"bSaveGeometry: Unable to write vertex normal count."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &pod_node->uv3DefaultColor.X, sizeof(uvector3),
"bSaveGeometry: Unable to write the default color."))
return false;
if (!bWriteToSection(pod_node, seh_handle, pod_node->afv3Vertex, sizeof(fvector3) * pod_node->uVertexCount,
"bSaveGeometry: Unable to write vertices."))
return false;
if (!bWriteToSection(pod_node, seh_handle, pod_node->auv3Face, sizeof(uvector3) * pod_node->uFaceCount,
"bSaveGeometry: Unable to write faces."))
return false;
if (!bWriteToSection(pod_node, seh_handle, pod_node->afv3FaceNormal, sizeof(fvector3) * pod_node->uFaceCount,
"bSaveGeometry: Unable to write face normals."))
return false;
if (!bWriteToSection(pod_node, seh_handle, pod_node->afv3VertexNormal, sizeof(fvector3) * pod_node->uVertexNormalCount,
"bSaveGeometry: Unable to write vertex normals."))
return false;
// Return a successful result.
return true;
}
bool CGroffExport::bSaveObject(CObjectDef* pod_node, TSectionHandle& seh_handle, TSymbolHandle& syh_name)
{
CGroffObject go_object;
// First attempt to add the object name to the symbol table.
go_object.syhObjectName = fioFile.syhInsert(pod_node->estrObjectName.strData());
// Were we successful?
if (go_object.syhObjectName == 0)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveObject: Unable to register symbol :%s: to symbol table.\n", pod_node->estrObjectName.strData());
// No! Return an error.
return false;
}
// Return the symbol handle for convenience.
syh_name = go_object.syhObjectName;
// Attempt to create an object section.
seh_handle = fioFile.sehCreate(pod_node->estrObjectName.strData(), gOBJECT);
// Were we successful?
if (seh_handle == 0)
{
// Something went wrong so report the error and return an error.
slLogfile.Printf("bSaveObject: Unable to create object section for :%s:\n", pod_node->estrObjectName.strData());
// No! Return an error;
return false;
}
// Attempt to add a geometry section to the file.
if (!bSaveGeometry(pod_node, go_object.sehGeometry))
{
slLogfile.Printf("bSaveObject: Unable to construct geometry section for :%s:\n", pod_node->estrObjectName.strData());
// No! Return an error.
return false;
}
// Yes! Then attempt to write this information to the file image. Were we succesful?
if (!bSaveMapping(pod_node, go_object.sehMapping))
{
slLogfile.Printf("bSaveObject: Unable to construct mapping section for :%s:\n", pod_node->estrObjectName.strData());
// Return an error.
return false;
}
//
// Add code to write physics, AI, sound, trigger, design daemon and special information.
//
// Attempt to write the class info to the image.
if (!bWriteToSection(pod_node, seh_handle, &go_object.syhObjectName, sizeof(TSymbolHandle),
"bSaveObject: Unable to write object symbol handle."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &go_object.sehGeometry, sizeof(TSectionHandle),
"bSaveObject: Unable to write geometry section handle."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &go_object.sehMapping, sizeof(TSectionHandle),
"bSaveObject: Unable to write mapping section handle."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &go_object.sehPhysics, sizeof(TSectionHandle),
"bSaveObject: Unable to write physics section handle."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &go_object.sehAI, sizeof(TSectionHandle),
"bSaveObject: Unable to write AI section handle."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &go_object.sehSound, sizeof(TSectionHandle),
"bSaveObject: Unable to write sound section handle."))
return false;
if (!bWriteToSection(pod_node, seh_handle, &go_object.sehSpecial, sizeof(TSectionHandle),
"bSaveObject: Unable to write special section handle."))
return false;
// Return a successful result.
return true;
}
bool CGroffExport::bSaveRegion(CObjectDefList* podl_scene, TSectionHandle& seh_region)
{
// Allocate the region section and fill it in as we go along.
CGroffRegion gr_region(podl_scene->uObjectCount());
// Were we successful?
if (gr_region.agocObjectList == 0)
{
// Something went wrong so flush the image and return an error.
slLogfile.Printf("bSaveRegion: Unable to build region with %d objects.\n", podl_scene->uObjectCount());
// No! Return an error.
return false;
}
// Create a section for the region descriptor.
seh_region = fioFile.sehCreate(".region", gREGION);
// Were we successful?
if (seh_region == 0)
{
// No! Return an error;
return false;
}
// Setup a pointer to the object at the from of the list.
CObjectDef* pod_node = podl_scene->podHead;
// Process the scene list one object at a time.
uint u_object_index = 0;
while (pod_node != 0)
{
// Setup the positional information.
CGroffObjectConfig& goc_config = gr_region.agocObjectList[u_object_index];
// Convert the object list format to representation format.
goc_config.fScale = pod_node->fGetScale();
// Convert the position.
Point3 p3_pos = pod_node->p3GetPosition();
fvector3 fv3_pos;
fv3_pos.X = p3_pos[0];
fv3_pos.Y = p3_pos[1];
fv3_pos.Z = p3_pos[2];
goc_config.fv3Position = fv3_pos;
// Convert the rotation.
Point3 p3_rot = pod_node->p3GetRotation();
fvector3 fv3_rot;
fv3_rot.X = p3_rot[0];
fv3_rot.Y = p3_rot[1];
fv3_rot.Z = p3_rot[2];
goc_config.fv3Rotation = fv3_rot;
// Attempt to add the objects to the scene.
if (!bSaveObject(pod_node, goc_config.sehObject, goc_config.syhObjectName))
{
// Something went wrong so flush the image and return an error.
slLogfile.Printf("bAddRegion: Unable to add object :%s: to region.\n", pod_node->estrObjectName.strData());
// Return an error.
return false;
}
// Advance to the next node in the list.
pod_node = pod_node->podNext;
// Increment the index pointer.
u_object_index++;
};
// Attempt to write the object to the image.
if (!bWriteToSection(pod_node, seh_region, &gr_region.uObjectCount, sizeof(uint),
"bSaveRegion: Unable to write object count."))
return false;
if (!bWriteToSection(pod_node, seh_region, gr_region.agocObjectList, sizeof(CGroffObjectConfig) * gr_region.uObjectCount,
"bSaveRegion: Unable to write object handles."))
return false;
// Return a successful result.
return true;
}
bool CGroffExport::bSaveHeader()
{
// Write out the file header.
CGroffHeader gh_header;
// Attempt to create the section header.
TSectionHandle seh_handle = fioFile.sehCreate(".header", gHEADER);
// Were we successful?
if (seh_handle == 0)
{
// Something went wrong so flush the image and return an error.
slLogfile.Printf("bExportScene: Unable to create file header section.\n");
// No! Return an error.
return false;
}
// Write out the file header.
if (!bWriteToSection(0, seh_handle, &gh_header, sizeof(CGroffHeader), "bAddHeader: Unable to write file header."))
{
// Return an error.
return false;
}
// Return a successful result.
return true;
}
bool CGroffExport::bSaveScene(CObjectDefList* podl_scene, const char* str_export_filename)
{
// Determine whether the file should be active or not.
if (guiInterface.bGenerateLogfiles())
{
// Open the log file.
char str_logfile[256];
// Construct the proper path for the logfile.
guiInterface.BuildPath(str_logfile, guiInterface.strGetLogfileDirPath(), "GroffGen.log");
slLogfile.Open(str_logfile);
// Activate the logfile.
slLogfile.Enable();
}
else
{
// Deactivate the logfile.
slLogfile.Disable();
}
// Place a startup message in the logfile.
slLogfile.Printf("***** Generating GROFF Image: %s *****\n", str_export_filename);
// Open the Groff output file. Were we successful?
if (!fioFile.bOpen(str_export_filename, eWrite))
{
// We were not able to open the file. Return an error.
return false;
}
// Attempt to generate the object file header.
if (!bSaveHeader())
{
// Return an error.
return false;
}
TSectionHandle sh_region;
// Attempt to generate a region file. Were we successful?
if (!bSaveRegion(podl_scene, sh_region))
{
// No! Return an error.
return false;
}
// Write the image to disk.
fioFile.bWriteImage();
// Close the export file.
fioFile.bClose();
// Report that the file export is complete.
slLogfile.Printf("\n***** GROFF File generation complete. *****\n");
// Close the logfile.
slLogfile.Close();
// Return a successful result
return true;
}