Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding preliminary Quake1 MDL plugin. #1441

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/native/module/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set(classes
vtkF3DSplatReader
vtkQuakeMDLReader
)

set(_no_install "")
Expand Down
135 changes: 135 additions & 0 deletions plugins/native/module/vtkQuakeMDLReader.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#include "vtkQuakeMDLReader.h"

#include <vtkCellArray.h>
#include <vtkCellData.h>
#include <vtkCommand.h>
#include <vtkDemandDrivenPipeline.h>
#include <vtkFloatArray.h>
#include <vtkIdTypeArray.h>
#include <vtkInformation.h>
#include <vtkInformationVector.h>
#include <vtkNew.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkUnsignedCharArray.h>

//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkQuakeMDLReader);

//----------------------------------------------------------------------------
vtkQuakeMDLReader::vtkQuakeMDLReader()
{
this->SetNumberOfInputPorts(0);
}

//----------------------------------------------------------------------------
int vtkQuakeMDLReader::RequestData(
vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector)
{
vtkPolyData* output = vtkPolyData::GetData(outputVector);

std::ifstream inputStream(this->FileName, std::ios::binary);

// identity ("IDPO"): 4 chars (4 bytes)
vtkNew<vtkUnsignedCharArray> IDPOArray;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you don't really need to create VTK arrays for internal data, it's only useful for data that will be outputted down the pipeline.
I suggest we start by supporting a small subset for now (i.e. geometry only without texturing nor animation)
For now, you can just use the code in the section "Reading a MDL file" of this page: http://tfc.duke.free.fr/coding/mdl-specs-en.html
Later it would be better to clean that up to modern C++ style for readability.
When this is read, you can take a look at the section "Rendering the model", the idea is just to take the frame index 0 (we'll extend it later to support animation), and just transform vertices to a vtkFloatArray (3 components, num_verts tuples) and a vtkIdTypeArray for triangles (1 component, 4*num_tris tuples)
If you're wondering about why "4*num_tris", that's because the buffer is containing the size of the cell before the indices to support quads or polygons with more vertices. Take a look at this code, you should do something similar.

IDPOArray->SetNumberOfComponents(4);
IDPOArray->SetName("identity");

// version: 1 int (4 bytes)
vtkNew<vtkIntArray> version;
version->SetNumberOfComponents(1);
version->SetName("version");

//====================================

// scaling factor: 3 floats (12 bytes)
vtkNew<vtkFloatArray> scalingFactor;
scalingFactor->SetNumberOfComponents(3);
scalingFactor->SetName("scaling factor");

// translation vector: 3 floats (12 bytes)
vtkNew<vtkFloatArray> translationVector;
translationVector->SetNumberOfComponents(3);
translationVector->SetName("translation vector");

// bounding radius: 1 float (4 bytes)
vtkNew<vtkFloatArray> boundingRadius;
boundingRadius->SetNumberOfComponents(1);
boundingRadius->SetName("bounding radius");

// eye position: 3 floats (12 bytes)
vtkNew<vtkFloatArray> eyePosition;
eyePosition->SetNumberOfComponents(3);
eyePosition->SetName("eye position");

//====================================

// number of textures: 1 int (4 bytes)
vtkNew<vtkIntArray> texturesNum;
texturesNum->SetNumberOfComponents(1);
texturesNum->SetName("number of textures");

// texture width: 1 int (4 bytes)
vtkNew<vtkIntArray> textureWidth;
textureWidth->SetNumberOfComponents(1);
textureWidth->SetName("texture width");

// texture height: 1 int (4 bytes)
vtkNew<vtkIntArray> textureHeight;
textureHeight->SetNumberOfComponents(1);
textureHeight->SetName("texture height");

//====================================

// number of vertices: 1 int (4 bytes)
vtkNew<vtkIntArray> verticesNum;
verticesNum->SetNumberOfComponents(1);
verticesNum->SetName("number of vertices");

// number of triangles: 1 int (4 bytes)
vtkNew<vtkIntArray> trianglesNum;
trianglesNum->SetNumberOfComponents(1);
trianglesNum->SetName("number of triangles");

// number of frames: 1 int (4 bytes)
vtkNew<vtkIntArray> framesNum;
framesNum->SetNumberOfComponents(1);
framesNum->SetName("number of frames");

//====================================

// sync type (0: synchron, 1: random): 1 int (4 bytes)
vtkNew<vtkIntArray> syncType;
syncType->SetNumberOfComponents(1);
syncType->SetName("sync type");

// state flags: 1 int (4 bytes)
vtkNew<vtkIntArray> stateFlags;
stateFlags->SetNumberOfComponents(1);
stateFlags->SetName("state flags");

//====================================

// position: 3 floats (12 bytes)
vtkNew<vtkFloatArray> position;
position->SetNumberOfComponents(3);
position->SetName("position");

// scale: 3 floats (12 bytes)
vtkNew<vtkFloatArray> scale;
scale->SetNumberOfComponents(3);
scale->SetName("scale");

// rotation: 4 chars (4 bytes)
vtkNew<vtkUnsignedCharArray> rotation;
rotation->SetNumberOfComponents(4);
rotation->SetName("rotation");

// color+opacity: 4 chars (4 bytes)
vtkNew<vtkUnsignedCharArray> colorAndOpacity;
colorAndOpacity->SetNumberOfComponents(4);
colorAndOpacity->SetName("color and opacity");

return 1;
}
35 changes: 35 additions & 0 deletions plugins/native/module/vtkQuakeMDLReader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @class vtkQuakeMDLReader
* @brief VTK Reader for Quake 1 models in binary .mdl file format
*/

#ifndef vtkQuakeMDLReader_h
#define vtkQuakeMDLReader_h

#include <vtkPolyDataAlgorithm.h>

class vtkQuakeMDLReader : public vtkPolyDataAlgorithm
{
public:
static vtkQuakeMDLReader* New();
vtkTypeMacro(vtkQuakeMDLReader, vtkPolyDataAlgorithm);

/**
* Set the file name.
*/
vtkSetMacro(FileName, std::string);

protected:
vtkQuakeMDLReader();
~vtkQuakeMDLReader() override = default;

int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;

private:
vtkQuakeMDLReader(const vtkQuakeMDLReader&) = delete;
void operator=(const vtkQuakeMDLReader&) = delete;

std::string FileName;
};

#endif