Esempio n. 1
0
bool NzDirectory::NextResult(bool skipDots)
{
	NazaraLock(m_mutex);

	#if NAZARA_CORE_SAFE
	if (!m_impl)
	{
		NazaraError("Directory not opened");
		return false;
	}
	#endif

	NzString name;
	do
	{
		if (!m_impl->NextResult())
			return false;

		name = m_impl->GetResultName();

		if (skipDots && (name == '.' || name == ".."))
			continue;

		if (name.Match(m_pattern))
			break;
	}
	while (true);

	return true;
}
Esempio n. 2
0
NzString NzStringStream::ToString() const
{
	NzString string;
	string.Reserve(m_bufferSize);

	for (const NzString& str : m_strings)
		string += str;

	return string;
}
Esempio n. 3
0
NzString NzInputStream::ReadLine(unsigned int lineSize)
{
	NzString line;
	if (lineSize == 0) // Taille maximale indéterminée
	{
		const unsigned int bufferSize = 64;

		char buffer[bufferSize+1];
		buffer[bufferSize] = '\0';

		unsigned int readSize;
		do
		{
			readSize = Read(buffer, bufferSize);

			const char* ptr = std::strchr(buffer, '\n');
			if (ptr)
			{
				unsigned int pos = ptr-buffer;

				if (m_streamOptions & nzStreamOption_Text && pos > 0 && buffer[pos-1] == '\r')
					line.Append(buffer, pos-1);
				else
					line.Append(buffer, pos);

				if (!SetCursorPos(GetCursorPos() - readSize + pos + 1))
					NazaraWarning("Failed to reset cursos pos");

				break;
			}
			else
				line.Append(buffer, readSize);
		}
		while (readSize == bufferSize);
	}
	else
	{
		line.Set(lineSize, '\0');
		unsigned int readSize = Read(&line[0], lineSize);
		unsigned int pos = line.Find('\n');
		if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier)
		{
			if (m_streamOptions & nzStreamOption_Text && pos > 0 && line[pos-1] == '\r')
				line.Resize(pos);
			else
				line.Resize(pos+1);

			if (!SetCursorPos(GetCursorPos() - readSize + pos + 1))
				NazaraWarning("Failed to reset cursos pos");
		}
		else
			line.Resize(readSize);
	}

	return line;
}
Esempio n. 4
0
void NzShaderStage::SetSource(const NzString& source)
{
	#if NAZARA_RENDERER_SAFE
	if (!m_id)
	{
		NazaraError("Shader stage is not initialized");
		return;
	}
	#endif

	const char* tmp = source.GetConstBuffer();
	GLint length = source.GetSize();
	glShaderSource(m_id, 1, &tmp, &length);
}
Esempio n. 5
0
bool NzLuaInstance::Execute(const NzString& code)
{
	if (code.IsEmpty())
		return true;

	if (luaL_loadstring(m_state, code.GetConstBuffer()) != 0)
	{
		m_lastError = lua_tostring(m_state, -1);
		lua_pop(m_state, 1);

		return false;
	}

	return Run(0, 0);
}
Esempio n. 6
0
bool NzShader::Create()
{
	NzContext::EnsureContext();

	m_program = glCreateProgram();
	if (!m_program)
	{
		NazaraError("Failed to create program");
		return false;
	}

	m_linked = false;

	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData0], "InstanceData0");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData1], "InstanceData1");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData2], "InstanceData2");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData3], "InstanceData3");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData4], "InstanceData4");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData5], "InstanceData5");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Color],         "VertexColor");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Normal],        "VertexNormal");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Position],      "VertexPosition");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Tangent],       "VertexTangent");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_TexCoord],      "VertexTexCoord");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata0],     "VertexUserdata0");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata1],     "VertexUserdata1");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata2],     "VertexUserdata2");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata3],     "VertexUserdata3");
	glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata4],     "VertexUserdata4");

	if (NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets))
	{
		NzString uniform;
		uniform = "RenderTarget";

		unsigned int maxRenderTargets = NzRenderer::GetMaxRenderTargets();
		for (unsigned int i = 0; i < maxRenderTargets; ++i)
		{
			NzString uniformName = uniform + NzString::Number(i);
			glBindFragDataLocation(m_program, i, uniformName.GetConstBuffer());
		}
	}

	if (NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary))
		glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);

	return true;
}
Esempio n. 7
0
bool NzDirectory::Exists(const NzString& dirPath)
{
	if (dirPath.IsEmpty())
		return false;

	return NzDirectoryImpl::Exists(NzFile::NormalizePath(dirPath));
}
Esempio n. 8
0
bool NzDirectory::Remove(const NzString& dirPath, bool emptyDirectory)
{
	if (dirPath.IsEmpty())
		return false;

	if (emptyDirectory)
	{
		NzDirectory dir(dirPath);
		if (!dir.Open())
			return NzDirectoryImpl::Remove(dirPath); // Si on n'arrive pas à ouvrir le dossier, on tente de le supprimer

		while (dir.NextResult(true))
		{
			if (dir.IsResultDirectory())
			{
				if (!Remove(dir.GetResultPath(), true))
					return false;
			}
			else if (!NzFile::Delete(dir.GetResultPath()))
			{
				NazaraError(dir.GetResultPath());
				return false;
			}
		}

		dir.Close();
	}

	return NzDirectoryImpl::Remove(NzFile::NormalizePath(dirPath));
}
void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags)
{
    Shader& shader = m_shaders[stage];
    shader.present = true;
    shader.source = source;

    // On extrait les flags de la chaîne
    std::vector<NzString> flags;
    shaderFlags.Split(flags, ' ');

    for (NzString& flag : flags)
	{
		auto it = m_flags.find(flag);
		if (it == m_flags.end())
			m_flags[flag] = 1U << m_flags.size();

		auto it2 = shader.flags.find(flag);
		if (it2 == shader.flags.end())
			shader.flags[flag] = 1U << shader.flags.size();
	}

	// On construit les flags requis pour l'activation du shader
	shader.requiredFlags = 0;

	flags.clear();
	requiredFlags.Split(flags, ' ');

    for (NzString& flag : flags)
	{
		nzUInt32 flagVal;

		auto it = m_flags.find(flag);
		if (it == m_flags.end())
		{
			flagVal = 1U << m_flags.size();
			m_flags[flag] = flagVal;
		}
		else
			flagVal = it->second;

		shader.requiredFlags |= flagVal;
	}
}
Esempio n. 10
0
bool NzDirectory::Copy(const NzString& sourcePath, const NzString& destPath)
{
	if (sourcePath.IsEmpty() || destPath.IsEmpty())
		return false;

	NzString dirPath(sourcePath);
	NzString dest(NzFile::NormalizePath(destPath));

	if (!Create(destPath, true))
	{
		NazaraError("Unable to create \"" + destPath + '"');
		return false;
	}

	NzDirectory dir(dirPath);
	if (!dir.Open())
	{
		NazaraError("Unable to open \"" + destPath + '"');
		return false;
	}

	while (dir.NextResult(true))
	{
		if (dir.IsResultDirectory())
		{
			if (!Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName()))
				return false;
		}
		else if (!NzFile::Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName()))
		{
			NazaraError("Failed to copy \"" + dir.GetResultPath() + "\" to \"" + dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName() + '"');
			return false;
		}
	}

	dir.Close();

	return true;
}
Esempio n. 11
0
NzString NzShaderStage::GetSource() const
{
	#if NAZARA_RENDERER_SAFE
	if (!m_id)
	{
		NazaraError("Shader stage is not initialized");
		return NzString();
	}
	#endif

	NzString source;

	GLint length = 0;
	glGetShaderiv(m_id, GL_SHADER_SOURCE_LENGTH, &length);
	if (length > 1) // Le caractère de fin compte
	{
		source.Set(length - 1, '\0'); // La taille retournée est celle du buffer (Avec caractère de fin)
		glGetShaderSource(m_id, length, nullptr, &source[0]);
	}

	return source;
}
Esempio n. 12
0
NzString NzShaderStage::GetLog() const
{
	#if NAZARA_RENDERER_SAFE
	if (!m_id)
	{
		NazaraError("Shader stage is not initialized");
		return NzString();
	}
	#endif

	NzString log;

	GLint length = 0;
	glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &length);
	if (length > 1) // Le caractère de fin faisant partie du compte
	{
		log.Set(length - 1, '\0'); // La taille retournée est celle du buffer (Avec caractère de fin)
		glGetShaderInfoLog(m_id, length, nullptr, &log[0]);
	}
	else
		log = "No log.";

	return log;
}
Esempio n. 13
0
void NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh)
{
	#if NAZARA_UTILITY_SAFE
	if (!m_impl)
	{
		NazaraError("Mesh not created");
		return;
	}

	if (identifier.IsEmpty())
	{
		NazaraError("Identifier is empty");
		return;
	}

	auto it = m_impl->subMeshMap.find(identifier);
	if (it != m_impl->subMeshMap.end())
	{
		NazaraError("SubMesh identifier \"" + identifier + "\" is already used");
		return;
	}

	if (!subMesh)
	{
		NazaraError("Invalid submesh");
		return;
	}

	if (m_impl->animationType != subMesh->GetAnimationType())
	{
		NazaraError("Submesh animation type must match mesh animation type");
		return;
	}
	#endif

	int index = m_impl->subMeshes.size();

	subMesh->AddResourceListener(this, index);
	subMesh->AddResourceReference();

	m_impl->aabbUpdated = false; // On invalide l'AABB
	m_impl->subMeshes.push_back(subMesh);
	m_impl->subMeshMap[identifier] = index;
}
Esempio n. 14
0
bool NzWindowImpl::Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style)
{
	bool fullscreen = (style & nzWindowStyle_Fullscreen) != 0;
	DWORD win32Style, win32StyleEx;
	unsigned int x, y;
	unsigned int width = mode.width;
	unsigned int height = mode.height;
	if (fullscreen)
	{
		DEVMODE win32Mode;
		std::memset(&win32Mode, 0, sizeof(DEVMODE));
		win32Mode.dmBitsPerPel = mode.bitsPerPixel;
		win32Mode.dmPelsHeight = mode.height;
		win32Mode.dmPelsWidth  = mode.width;
		win32Mode.dmFields	   = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
		win32Mode.dmSize	   = sizeof(DEVMODE);

		if (ChangeDisplaySettings(&win32Mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
		{
			// Situation extrêmement rare grâce à NzVideoMode::IsValid appelé par NzWindow
			NazaraError("Failed to change display settings for fullscreen, this video mode is not supported by your computer");
			fullscreen = false;
		}
	}

	// Testé une seconde fois car sa valeur peut changer
	if (fullscreen)
	{
		x = 0;
		y = 0;
		win32Style = WS_CLIPCHILDREN | WS_POPUP;

		// Pour cacher la barre des tâches
		// http://msdn.microsoft.com/en-us/library/windows/desktop/ff700543(v=vs.85).aspx
		win32StyleEx = WS_EX_APPWINDOW;

		fullscreenWindow = this;
	}
	else
	{
		win32Style = WS_VISIBLE;
		if (style & nzWindowStyle_Titlebar)
		{
			win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
			if (style & nzWindowStyle_Closable)
				win32Style |= WS_SYSMENU;

			if (style & nzWindowStyle_Resizable)
				win32Style |= WS_MAXIMIZEBOX | WS_SIZEBOX;
		}
		else
			win32Style |= WS_POPUP;

		win32StyleEx = 0;

		RECT rect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
		AdjustWindowRect(&rect, win32Style, false);
		width = rect.right-rect.left;
		height = rect.bottom-rect.top;

		x = (GetSystemMetrics(SM_CXSCREEN) - width)/2;
		y = (GetSystemMetrics(SM_CYSCREEN) - height)/2;
	}

	m_callback = 0;

	#if NAZARA_UTILITY_THREADED_WINDOW
	NzMutex mutex;
	NzConditionVariable condition;
	m_threadActive = true;

	// On attend que la fenêtre soit créée
	mutex.Lock();
	m_thread = NzThread(WindowThread, &m_handle, win32StyleEx, title.GetWideString().data(), win32Style, x, y, width, height, this, &mutex, &condition);
	condition.Wait(&mutex);
	mutex.Unlock();
	#else
	m_handle = CreateWindowExW(win32StyleEx, className, title.GetWideString().data(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this);
	#endif

	if (!m_handle)
	{
		NazaraError("Failed to create window: " + NzError::GetLastSystemError());
		return false;
	}

	if (fullscreen)
	{
		SetForegroundWindow(m_handle);
		ShowWindow(m_handle, SW_SHOW);
	}

	m_eventListener = true;
	m_ownsWindow = true;
	#if !NAZARA_UTILITY_THREADED_WINDOW
	m_sizemove = false;
	#endif
	m_style = style;

	// Récupération de la position/taille de la fenêtre (Après sa création)
	RECT clientRect, windowRect;
	GetClientRect(m_handle, &clientRect);
	GetWindowRect(m_handle, &windowRect);

	m_position.Set(windowRect.left, windowRect.top);
	m_size.Set(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);

	return true;
}
Esempio n. 15
0
nzLuaType NzLuaInstance::GetGlobal(const NzString& name) const
{
	return FromLuaType(lua_getglobal(m_state, name.GetConstBuffer()));
}
Esempio n. 16
0
bool NzPluginManager::Mount(const NzString& pluginPath, bool appendExtension)
{
	if (!Initialize())
	{
		NazaraError("Failed to initialize PluginManager");
		return false;
	}

	NzString path = pluginPath;
	if (appendExtension && !path.EndsWith(NAZARA_DYNLIB_EXTENSION))
		path += NAZARA_DYNLIB_EXTENSION;

	bool exists = false;
	if (!NzFile::IsAbsolute(path))
	{
		for (const NzString& dir : s_directories)
		{
			NzString testPath;
			testPath.Reserve(dir.GetSize() + path.GetSize() + 10);

			testPath = dir;
			testPath += NAZARA_DIRECTORY_SEPARATOR;
			testPath += path;

			if (NzFile::Exists(testPath))
			{
				path = testPath;
				exists = true;
				break;
			}
		}
	}
	else if (NzFile::Exists(path))
		exists = true;

	if (!exists)
	{
		NazaraError("Failed to find plugin file");
		return false;
	}

	std::unique_ptr<NzDynLib> library(new NzDynLib);
	if (!library->Load(path))
	{
		NazaraError("Failed to load plugin");
		return false;
	}

	PluginLoad func = reinterpret_cast<PluginLoad>(library->GetSymbol("NzPluginLoad"));
	if (!func)
	{
		NazaraError("Failed to get symbol NzPluginLoad");
		return false;
	}

	if (!func())
	{
		NazaraError("Plugin failed to load");
		return false;
	}

	s_plugins[pluginPath] = library.release();

	return true;
}
Esempio n. 17
0
nzLuaType NzLuaInstance::GetMetatable(const NzString& tname) const
{
	return FromLuaType(luaL_getmetatable(m_state, tname.GetConstBuffer()));
}
Esempio n. 18
0
bool NzLuaInstance::IsOfType(int index, const NzString& tname) const
{
	return IsOfType(index, tname.GetConstBuffer());
}
Esempio n. 19
0
void NzLuaInstance::PushMetatable(const NzString& str)
{
	luaL_getmetatable(m_state, str.GetConstBuffer());
}
Esempio n. 20
0
void NzLuaInstance::Error(const NzString& message)
{
	luaL_error(m_state, message.GetConstBuffer());
}
Esempio n. 21
0
bool NzDirectory::Create(const NzString& dirPath, bool recursive)
{
	if (dirPath.IsEmpty())
		return false;

	if (recursive)
	{
		NzString path = NzFile::NormalizePath(dirPath);
		unsigned int foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR);
		if (foundPos == NzString::npos)
			return false;

		#ifdef NAZARA_PLATFORM_WINDOWS
		// Contrairement au disque (Ex: "C:"), le chemin réseau n'est pas considéré comme un dossier (Ex: "\\Laptop")
		if (path.Match("\\\\*"))
		{
			foundPos = path.Find('\\', 2);
			if (foundPos == NzString::npos)
				return false;

			foundPos = path.Find('\\', foundPos+1);
			if (foundPos == NzString::npos)
				return false;
		}
		#endif

		do
		{
			NzString p = path.SubString(0, foundPos);
			if (p.EndsWith(NAZARA_DIRECTORY_SEPARATOR))
				p = p.SubString(0, -2);

			if (!NzDirectoryImpl::Exists(p) && !NzDirectoryImpl::Create(p))
				return false;

			if (foundPos == NzString::npos)
				break;

			foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR, foundPos+1);
		}
		while (true);

		return true;
	}
	else
		return NzDirectoryImpl::Create(NzFile::NormalizePath(dirPath));
}
Esempio n. 22
0
void NzWindowImpl::SetTitle(const NzString& title)
{
	SetWindowTextW(m_handle, title.GetWideString().data());
}
Esempio n. 23
0
void NzLuaInstance::SetMetatable(const NzString& tname)
{
	luaL_setmetatable(m_state, tname.GetConstBuffer());
}
Esempio n. 24
0
void NzLuaInstance::SetGlobal(const NzString& name)
{
	lua_setglobal(m_state, name.GetConstBuffer());
}
Esempio n. 25
0
void NzLuaInstance::SetField(const NzString& name, int index)
{
	lua_setfield(m_state, index, name.GetConstBuffer());
}
Esempio n. 26
0
void NzLuaInstance::PushString(const NzString& str)
{
	lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize());
}
Esempio n. 27
0
nzLuaType NzLuaInstance::GetField(const NzString& fieldName, int index) const
{
	return FromLuaType(lua_getfield(m_state, index, fieldName.GetConstBuffer()));
}
Esempio n. 28
0
bool NzMTLParser::Parse()
{
	m_keepLastLine = false;
	m_lineCount = 0;
	m_materials.clear();

	Material* currentMaterial = nullptr;

	while (Advance(false))
	{
		NzString keyword = m_currentLine.GetWord(0).ToLower();
		if (keyword == "ka")
		{
			float r, g, b;
			if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
			{
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->ambient = NzColor(r*255.f, g*255.f, b*255.f);
			}
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			else
				UnrecognizedLine();
			#endif
		}
		else if (keyword == "kd")
		{
			float r, g, b;
			if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
			{
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->diffuse = NzColor(r*255.f, g*255.f, b*255.f);
			}
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			else
				UnrecognizedLine();
			#endif
		}
		else if (keyword == "ks")
		{
			float r, g, b;
			if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3)
			{
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->specular = NzColor(r*255.f, g*255.f, b*255.f);
			}
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			else
				UnrecognizedLine();
			#endif
		}
		else if (keyword == "ni")
		{
			float density;
			if (std::sscanf(&m_currentLine[3], "%f", &density) == 1)
			{
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->refractionIndex = density;
			}
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			else
				UnrecognizedLine();
			#endif
		}
		else if (keyword == "ns")
		{
			float coef;
			if (std::sscanf(&m_currentLine[3], "%f", &coef) == 1)
			{
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->shininess = coef;
			}
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			else
				UnrecognizedLine();
			#endif
		}
		else if (keyword == 'd' || keyword == "tr")
		{
			float alpha;
			if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1)
			{
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->alpha = alpha;
			}
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			else
				UnrecognizedLine();
			#endif
		}
		else if (keyword == "illum")
		{
			unsigned int model;
			if (std::sscanf(&m_currentLine[6], "%u", &model) == 1)
			{
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->illumModel = model;
			}
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			else
				UnrecognizedLine();
			#endif
		}
		else if (keyword == "map_ka")
		{
			unsigned int mapPos = m_currentLine.GetWordPosition(1);
			if (mapPos != NzString::npos)
			{
				NzString map = m_currentLine.SubString(mapPos);
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->ambientMap = map;
			}
		}
		else if (keyword == "map_kd")
		{
			unsigned int mapPos = m_currentLine.GetWordPosition(1);
			if (mapPos != NzString::npos)
			{
				NzString map = m_currentLine.SubString(mapPos);
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->diffuseMap = map;
			}
		}
		else if (keyword == "map_ks")
		{
			unsigned int mapPos = m_currentLine.GetWordPosition(1);
			if (mapPos != NzString::npos)
			{
				NzString map = m_currentLine.SubString(mapPos);
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->specularMap = map;
			}
		}
		else if (keyword == "map_bump" || keyword == "bump")
		{
			unsigned int mapPos = m_currentLine.GetWordPosition(1);
			if (mapPos != NzString::npos)
			{
				NzString map = m_currentLine.SubString(mapPos);
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->bumpMap = map;
			}
		}
		else if (keyword == "map_d")
		{
			unsigned int mapPos = m_currentLine.GetWordPosition(1);
			if (mapPos != NzString::npos)
			{
				NzString map = m_currentLine.SubString(mapPos);
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->alphaMap = map;
			}
		}
		else if (keyword == "map_decal" || keyword == "decal")
		{
			unsigned int mapPos = m_currentLine.GetWordPosition(1);
			if (mapPos != NzString::npos)
			{
				NzString map = m_currentLine.SubString(mapPos);
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->decalMap = map;
			}
		}
		else if (keyword == "map_disp" || keyword == "disp")
		{
			unsigned int mapPos = m_currentLine.GetWordPosition(1);
			if (mapPos != NzString::npos)
			{
				NzString map = m_currentLine.SubString(mapPos);
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->displacementMap = map;
			}
		}
		else if (keyword == "map_refl" || keyword == "refl")
		{
			unsigned int mapPos = m_currentLine.GetWordPosition(1);
			if (mapPos != NzString::npos)
			{
				NzString map = m_currentLine.SubString(mapPos);
				if (!currentMaterial)
					currentMaterial = &m_materials["default"];

				currentMaterial->reflectionMap = map;
			}
		}
		else if (keyword == "newmtl")
		{
			NzString materialName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
			if (!materialName.IsEmpty())
				currentMaterial = &m_materials[materialName];
			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			else
				UnrecognizedLine();
			#endif
		}
		#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
		else
			UnrecognizedLine();
		#endif
	}

	return true;
}
Esempio n. 29
0
bool NzOBJParser::Parse()
{
	NzString matName, meshName;
	matName = meshName = "default";
	m_keepLastLine = false;
	m_lineCount = 0;
	m_meshes.clear();
	m_mtlLib.Clear();

	m_normals.clear();
	m_positions.clear();
	m_texCoords.clear();

	// Beaucoup de meshs font plus de 100 sommets, préparons le terrain
	m_normals.reserve(100);
	m_positions.reserve(100);
	m_texCoords.reserve(100);

	// On va regrouper les meshs par nom et par matériau
	std::unordered_map<NzString, std::unordered_map<NzString, std::vector<Face>>> meshes;

	// On prépare le mesh par défaut
	std::vector<Face>* currentMesh = &meshes[meshName][matName];

	while (Advance(false))
	{
		switch (std::tolower(m_currentLine[0]))
		{
			case 'f': // Une face
			{
				if (m_currentLine.GetSize() < 7) // Le minimum syndical pour définir une face de trois sommets (f 1 2 3)
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					UnrecognizedLine();
					#endif
					break;
				}

				unsigned int vertexCount = m_currentLine.Count(' ');
				if (vertexCount < 3)
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					UnrecognizedLine();
					#endif
					break;
				}

				Face face;
				face.vertices.resize(vertexCount);

				bool error = false;
				unsigned int pos = 2;
				for (unsigned int i = 0; i < vertexCount; ++i)
				{
					int offset;
					int& n = face.vertices[i].normal;
					int& p = face.vertices[i].position;
					int& t = face.vertices[i].texCoord;

					if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3)
					{
						if (std::sscanf(&m_currentLine[pos], "%d//%d%n", &p, &n, &offset) != 2)
						{
							if (std::sscanf(&m_currentLine[pos], "%d/%d%n", &p, &t, &offset) != 2)
							{
								if (std::sscanf(&m_currentLine[pos], "%d%n", &p, &offset) != 1)
								{
									#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
									UnrecognizedLine();
									#endif
									error = true;
									break;
								}
								else
								{
									n = 0;
									t = 0;
								}
							}
							else
								n = 0;
						}
						else
							t = 0;
					}

					if (p < 0)
					{
						p += m_positions.size();
						if (p < 0)
						{
							Error("Vertex index out of range (" + NzString::Number(p) + " < 0");
							error = true;
							break;
						}
					}
					else
						p--;

					if (n < 0)
					{
						n += m_normals.size();
						if (n < 0)
						{
							Error("Vertex index out of range (" + NzString::Number(n) + " < 0");
							error = true;
							break;
						}
					}
					else
						n--;

					if (t < 0)
					{
						t += m_texCoords.size();
						if (t < 0)
						{
							Error("Vertex index out of range (" + NzString::Number(t) + " < 0");
							error = true;
							break;
						}
					}
					else
						t--;

					if (static_cast<unsigned int>(p) >= m_positions.size())
					{
						Error("Vertex index out of range (" + NzString::Number(p) + " >= " + NzString::Number(m_positions.size()) + ')');
						error = true;
						break;
					}
					else if (n >= 0 && static_cast<unsigned int>(n) >= m_normals.size())
					{
						Error("Normal index out of range (" + NzString::Number(n) + " >= " + NzString::Number(m_normals.size()) + ')');
						error = true;
						break;
					}
					else if (t >= 0 && static_cast<unsigned int>(t) >= m_texCoords.size())
					{
						Error("TexCoord index out of range (" + NzString::Number(t) + " >= " + NzString::Number(m_texCoords.size()) + ')');
						error = true;
						break;
					}

					pos += offset;
				}

				if (!error)
					currentMesh->push_back(std::move(face));

				break;
			}

			case 'm':
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				if (m_currentLine.GetWord(0).ToLower() != "mtllib")
					UnrecognizedLine();
				#endif

				m_mtlLib = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
				break;

			case 'g':
			case 'o':
			{
				if (m_currentLine.GetSize() <= 2 || m_currentLine[1] != ' ')
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					UnrecognizedLine();
					#endif
					break;
				}

				NzString objectName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
				if (objectName.IsEmpty())
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					UnrecognizedLine();
					#endif
					break;
				}

				meshName = objectName;
				currentMesh = &meshes[meshName][matName];
				break;
			}

			#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
			case 's':
				if (m_currentLine.GetSize() <= 2 || m_currentLine[1] == ' ')
				{
					NzString param = m_currentLine.SubString(2);
					if (param != "all" && param != "on" && param != "off" && !param.IsNumber())
						UnrecognizedLine();
				}
				else
					UnrecognizedLine();
				break;
			#endif

			case 'u':
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				if (m_currentLine.GetWord(0) != "usemtl")
					UnrecognizedLine();
				#endif

				matName = m_currentLine.SubString(m_currentLine.GetWordPosition(1));
				if (matName.IsEmpty())
				{
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					UnrecognizedLine();
					#endif
					break;
				}

				currentMesh = &meshes[meshName][matName];
				break;

			case 'v':
			{
				NzString word = m_currentLine.GetWord(0).ToLower();
				if (word == 'v')
				{
					NzVector4f vertex(NzVector3f::Zero(), 1.f);
					unsigned int paramCount = std::sscanf(&m_currentLine[2], "%f %f %f %f", &vertex.x, &vertex.y, &vertex.z, &vertex.w);
					if (paramCount >= 3)
						m_positions.push_back(vertex);
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					else
						UnrecognizedLine();
					#endif
				}
				else if (word == "vn")
				{
					NzVector3f normal(NzVector3f::Zero());
					unsigned int paramCount = std::sscanf(&m_currentLine[3], "%f %f %f", &normal.x, &normal.y, &normal.z);
					if (paramCount == 3)
						m_normals.push_back(normal);
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					else
						UnrecognizedLine();
					#endif
				}
				else if (word == "vt")
				{
					NzVector3f uvw(NzVector3f::Zero());
					unsigned int paramCount = std::sscanf(&m_currentLine[3], "%f %f %f", &uvw.x, &uvw.y, &uvw.z);
					if (paramCount >= 2)
						m_texCoords.push_back(uvw);
					#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
					else
						UnrecognizedLine();
					#endif
				}
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				else
					UnrecognizedLine();
				#endif

				break;
			}

			default:
				#if NAZARA_UTILITY_STRICT_RESOURCE_PARSING
				UnrecognizedLine();
				#endif
				break;
		}
	}

	std::unordered_map<NzString, unsigned int> materials;
	unsigned int matCount = 0;

	for (auto& meshIt : meshes)
	{
		for (auto& matIt : meshIt.second)
		{
			if (!matIt.second.empty())
			{
				Mesh mesh;
				mesh.faces = std::move(matIt.second);
				mesh.name = meshIt.first;

				auto it = materials.find(matIt.first);
				if (it == materials.end())
				{
					mesh.material = matCount;
					materials[matIt.first] = matCount++;
				}
				else
					mesh.material = it->second;

				m_meshes.push_back(std::move(mesh));
			}
		}
	}

	if (m_meshes.empty())
	{
		NazaraError("No meshes");
		return false;
	}

	m_materials.resize(matCount);
	for (const std::pair<NzString, unsigned int>& pair : materials)
		m_materials[pair.second] = pair.first;

	return true;
}
Esempio n. 30
0
bool NzLuaInstance::NewMetatable(const NzString& str)
{
	return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0;
}