Table des matières

Shape specifications

A Shape in the code

Following notes are only a draft and work in progress! — Sit Melai 2016/12/05 19:37

How a shape is optimally created

To fill a shape, you have to fill the CMesh::CMeshBuild (structure explained below). Then you can call build on a CMesh object with your CMesh::CMeshBuild object as parameter. The CMesh object generated from this can be written into a file by opening a COFile stream and calling the serial method on the CMesh with your stream as paremeter.

How it is serialized in the code (using serial())

Cliquez pour afficher ⇲

Cliquez pour masquer ⇱

CShapeStream::serial(NLMISC::IStream &f) // called by NLMISC::IStream.serial(CShapeStream)
	f.serialCheck( NELID( "PAHS" ) ) // NELID converts the string to a uint32
	f.serialPolyPtr( _Shape ) // _Shape is a property of the CShapeStream object

	// both functions above can be found in stream.h


serialCheck(const T &value) // in stream.h
	read and compare to value
	or
	write value

serialPolyPtr(T* &ptr) // in stream.h
	create IStreamable pointer p from ptr
	serialIStreamable(p) // in stream.h
	static_cast p back to type T and assign to ptr

IStream::serialIStreamable(IStreamable* &ptr) // in stream.cpp
     if reading
	serial a uint64
	result is 0 -> set ptr to NULL and end
	else
	Check if object already created or read
	if not
	serial a string className
	set ptr to CClassRegistry::create(className) dynamic_cast to IStreamable*
	if ptr is null
	throw error
	else
	check ptr is valid object with CClassREgistry::checkObject
	Insert into the _IdMap
	ptr->serial(*this) // Should call IStreamable::serial which is equal to class of this::serial(IStream &f)

How CMeshBuild struct looks like

Cliquez pour afficher ⇲

Cliquez pour masquer ⇱

CMesh::CMeshBuild structure (mesh.h)
	sint32 VertexFlags
	uint8 NumCoords[CVertexBuffer::MaxStage] // how many coordinates each uvw uses (2 or 3)
	uint8 UVRouting[CVertexBuffer::MaxStage] // uv routing table, each uv channel can be routed to any vertex uv
	std::vector<NLMISC::CVector> Vertices
	std::vector<CMesh::CSkinWeight> SkinWeights // same size as Vertices, NULL if no skinning (Palette Skinning Vertices array?)
	std::vector<std::string> BonesNames // each matrix id in SkinWeights must have a corresponding entry in bone name entry
	std::vector<CMesh::CFace> Faces
	std::vector<CMesh::CBlendShape> BlendShapes
	std::vector<CMesh::CVertLink> VertLink // Link between VB and max vertex index, will be filled by build
	NLMISC::CSmartPtr<IMeshVertexProgram> MeshVertexProgram // MeshVertexProgram to be copied to meshGeom
	std::vector<CMesh::CInterface> Interfaces // Mesh Interface System for MRM building
	std::vector<CMesh::CInterfaceLink> InterfaceLinks // Same size as Vertices, or Mesh Interface system disabled
	NLMISC::CBitSet InterfaceVertexFlag // each bit indicates if vertex belongs to an interface

	CMeshBuild() // build a CMesh


NLMISC::CVector (vector.h)
	float x
	float y
	float z

	CVector(x, y, z)

	// all mathematic standard operations and more


NL3D_MESH_SKINNING_MAX_MATRIX = 4 (mesh.h)

CMesh::CSkinWeight (mesh.h) // if you don't use all matrix set 0 on weights you don't use
	uint32 MatrixId[NL3D_MESH_SKINNING_MAX_MATRIX] // which matrix of skeleton shape this vertexuses
	float Weights[NL3D_MESH_SKINNING_MAX_MATRIX] // sum of all entries should be 1


CMesh::CFace (mesh.h)
	NLMISC::CCorner Corner[3]
	sint32 MaterialId
	sint32 SmoothGroup


CMesh::CCorner (mesh.h)
	sint32 Vertex // id of the vertex
	NLMISC::CVector Normal
	NLMISC::CUVW Uvws[CVertexBuffer::MaxStage]
	NLMISC::CRGBA Color
	NLMISC::CRGBA Specular


NLMISC::CUVW (uv.h)
	float u
	float v
	float w

	CUVW(u, v, w)

	// all mathematic standard operations and more


NLMISC::CRGBA (rgba.h)
	uint8 R
	uint8 G
	uint8 B
	uint8 A

	CRGBA(R, G, B, A = 255)


NL3D::CBlendShape (mesh_morpher.h)
	std::string Name
	std::vector<NLMISC::CVector> deltaPos
	std::vector<NLMISC::CVector> deltaNorm
	std::vector<NLMISC::CVector> deltaTgSpace
	std::vector<NLMISC::CUV> deltaUV
	std::vector<NLMISC::CRGBAF> deltaCol
	std::vector<uint32> VertRefs // Array of vertices references


NLMISC::CUV


NLMISC::RGBAF


CMesh::CVertLink (mesh.h)
	uint32 nFace
	uint32 nCorner
	uint32 VertVB

	CVertLink(nFace, nCorner, VertVB)


CMesh::CInterface (mesh.h)
	std::vector<CInterfaceVertex> Vertices // polygon of interface between 2 meshs


CMesh::CInterfaceVertex (mesh.h)
	CVector Pos
	CVector Normal


CMesh::CInterfaceLink (mesh.h)
	sint InterfaceId // id of the interface this vertex is welded to
	uint InterfaceVertexId // id of the vertex this vertex is welded to

The .shape format

You want to make your own importer/exporter for .shape files? Take a look at the structure of the .shape format.

Not finished yet, missing some parts that can be parsed as PolyPtr! WIP!

Sit Melai 2016/12/11 16:48

Check Nel Files Documentation for how to serialize each class:

Base class for start is CShapeStream. You need all classes that are called from this class, and following classes (or child classes) for PolyPtr: