Ejemplo n.º 1
0
void C3DOParser::GetPrimitives(S3DOPiece* obj, int pos, int num, int excludePrim, const std::vector<unsigned char>& fileBuf)
{
	std::map<int,int> prevHashes;

	for (int a=0; a<num; a++) {
		if (a == excludePrim) {
			continue;
		}

		_Primitive p;
		int curOffset = pos + a * sizeof(_Primitive);
		READ_PRIMITIVE(p, fileBuf, curOffset);

		if (p.NumberOfVertexIndexes < 3)
			continue;

		S3DOPrimitive sp;
		sp.indices.resize(p.NumberOfVertexIndexes);
		sp.vnormals.resize(p.NumberOfVertexIndexes);

		// load vertex indices list
		curOffset = p.OffsetToVertexIndexArray;
		for (int b=0; b<p.NumberOfVertexIndexes; b++) {
			boost::uint16_t w;
			STREAM_READ(&w,2, fileBuf, curOffset);
			swabWordInPlace(w);
			sp.indices[b] = w;
		}

		// find texture
		sp.texture = GetTexture(obj, &p, fileBuf);

		// set the primitive-normal
		const float3 v0v1 = (obj->vertexPos[sp.indices[1]] - obj->vertexPos[sp.indices[0]]);
		const float3 v0v2 = (obj->vertexPos[sp.indices[2]] - obj->vertexPos[sp.indices[0]]);
		sp.primNormal = (-v0v1.cross(v0v2)).SafeANormalize();

		// some 3dos got multiple baseplates a.k.a. `selection primitive`
		// it's not meant to be rendered, so hide it
		if (IsBasePlate(obj, &sp))
			continue;

		// 3do has often duplicated faces (with equal geometry)
		// with different textures (e.g. for animations and other effects)
		// we don't support those, only render the last one
		std::vector<int> orderVert = sp.indices;
		std::sort(orderVert.begin(), orderVert.end());
		const int vertHash = HsiehHash(&orderVert[0], orderVert.size() * sizeof(orderVert[0]), 0x123456);

		auto phi = prevHashes.find(vertHash);
		if (phi != prevHashes.end()) {
			obj->prims[phi->second] = sp;
			continue;
		}
		prevHashes[vertHash] = obj->prims.size();
		obj->prims.push_back(sp);
	}
}
Ejemplo n.º 2
0
// used only by ReadInfoMap (for unitsync)
void CSMFMapFile::ReadHeightmap(unsigned short* heightmap)
{
	const int hmx = header.mapx + 1;
	const int hmy = header.mapy + 1;

	ifs.Seek(header.heightmapPtr);
	ifs.Read(heightmap, hmx * hmy * sizeof(short));

	for (int y = 0; y < hmx * hmy; ++y) {
		swabWordInPlace(heightmap[y]);
	}
}