Merge branch 'next' into weather

Conflicts:
	apps/openmw/mwrender/renderingmanager.cpp
actorid
scrawl 13 years ago
commit 8b5da06fce

@ -1,11 +1,13 @@
project(OpenMW)
IF (APPLE)
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/OpenMW.app")
if (APPLE)
set(APP_BUNDLE_NAME "${CMAKE_PROJECT_NAME}.app")
set(APP_BUNDLE_DIR "${OpenMW_BINARY_DIR}/${APP_BUNDLE_NAME}")
# using 10.6 sdk
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.6.sdk")
ENDIF (APPLE)
endif (APPLE)
# Macros
@ -201,6 +203,13 @@ include_directories("."
link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR})
if(APPLE)
# List used Ogre plugins
SET(USED_OGRE_PLUGINS "RenderSystem_GL"
"Plugin_OctreeSceneManager"
"Plugin_ParticleFX")
endif(APPLE)
add_subdirectory( extern/caelum )
add_subdirectory( extern/mygui_3.0.1 )
@ -244,22 +253,17 @@ if (APPLE)
"${OpenMW_BINARY_DIR}/plugins.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
"${APP_BUNDLE_DIR}/Contents/Info.plist" COPYONLY)
"${APP_BUNDLE_DIR}/Contents/Info.plist")
configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns
"${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY)
# prepare plugins
configure_file(${OGRE_PLUGIN_DIR}/RenderSystem_GL.dylib
"${APP_BUNDLE_DIR}/Contents/Plugins/RenderSystem_GL.dylib" COPYONLY)
configure_file(${OGRE_PLUGIN_DIR}/Plugin_OctreeSceneManager.dylib
"${APP_BUNDLE_DIR}/Contents/Plugins/Plugin_OctreeSceneManager.dylib" COPYONLY)
configure_file(${OGRE_PLUGIN_DIR}/Plugin_ParticleFX.dylib
"${APP_BUNDLE_DIR}/Contents/Plugins/Plugin_ParticleFX.dylib" COPYONLY)
foreach(plugin ${USED_OGRE_PLUGINS})
configure_file("${OGRE_PLUGIN_DIR}/${plugin}.dylib"
"${APP_BUNDLE_DIR}/Contents/Plugins/${plugin}.dylib"
COPYONLY)
endforeach()
endif (APPLE)
@ -269,36 +273,6 @@ if (CMAKE_COMPILER_IS_GNUCC)
add_definitions (-Wall)
endif (CMAKE_COMPILER_IS_GNUCC)
# Apple bundling
# TODO REWRITE!
if (APPLE)
set(MISC_FILES
${APP_BUNDLE_DIR}/Contents/MacOS/openmw.cfg
${APP_BUNDLE_DIR}/Contents/MacOS/plugins.cfg)
set(OGRE_PLUGINS
${APP_BUNDLE_DIR}/Contents/Plugins/*)
install(FILES ${MISC_FILES} DESTINATION ../MacOS)
install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Plugins" DESTINATION ..)
install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Resources/resources" DESTINATION ../Resources)
set(CPACK_GENERATOR "Bundle")
set(CPACK_BUNDLE_PLIST "${CMAKE_SOURCE_DIR}/files/mac/Info.plist")
set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/files/mac/openmw.icns")
set(CPACK_BUNDLE_NAME "OpenMW")
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
set(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
include(CPack)
set(CMAKE_EXE_LINKER_FLAGS "-arch i386")
set(CMAKE_CXX_FLAGS "-arch i386")
endif (APPLE)
if(DPKG_PROGRAM)
SET(CMAKE_INSTALL_PREFIX "/usr")
@ -352,6 +326,45 @@ if(DPKG_PROGRAM)
include(CPack)
endif(DPKG_PROGRAM)
if(WIN32)
FILE(GLOB files "${OpenMW_BINARY_DIR}/Release/*.*")
INSTALL(FILES ${files} DESTINATION ".")
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
INSTALL(FILES "${OpenMW_BINARY_DIR}/launcher.cfg" "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION ".")
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".")
SET(CPACK_GENERATOR "NSIS")
SET(CPACK_PACKAGE_NAME "OpenMW")
SET(CPACK_PACKAGE_VENDOR "OpenMW.org")
SET(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
SET(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
SET(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW;esmtool;Esmtool;omwlauncher;OpenMW Launcher")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${OpenMW_SOURCE_DIR}/readme.txt")
SET(CPACK_RESOURCE_FILE_LICENSE "${OpenMW_SOURCE_DIR}/GPL3.txt")
SET(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
SET(CPACK_NSIS_DISPLAY_NAME "OpenMW")
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.openmw.org")
SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\www.openmw.org")
SET(CPACK_NSIS_INSTALLED_ICON_NAME "omwlauncher.exe")
SET(VCREDIST "${OpenMW_BINARY_DIR}/vcredist_x86.exe")
if(EXISTS ${VCREDIST})
INSTALL(FILES ${VCREDIST} DESTINATION "redist")
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\redist\\\\vcredist_x86.exe\\\" /q'" )
endif(EXISTS ${VCREDIST})
SET(OALREDIST "${OpenMW_BINARY_DIR}/oalinst.exe")
if(EXISTS ${OALREDIST})
INSTALL(FILES ${OALREDIST} DESTINATION "redist")
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}
ExecWait '\\\"$INSTDIR\\\\redist\\\\oalinst.exe\\\" /s'" )
endif(EXISTS ${OALREDIST})
include(CPack)
endif(WIN32)
# Components
add_subdirectory (components)
@ -406,3 +419,86 @@ if (WIN32)
#set_target_properties(openmw PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
#set_target_properties(openmw PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
endif()
# Apple bundling
if (APPLE)
set(INSTALL_SUBDIR OpenMW)
#install(FILES ${MISC_FILES} DESTINATION ../MacOS)
#install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Plugins" DESTINATION ..)
#install(DIRECTORY "${APP_BUNDLE_DIR}/Contents/Resources/resources" DESTINATION ../Resources)
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
set(CPACK_GENERATOR "DragNDrop")
# set(CPACK_BUNDLE_PLIST "${CMAKE_SOURCE_DIR}/files/mac/Info.plist")
# set(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/files/mac/openmw.icns")
# set(CPACK_BUNDLE_NAME "OpenMW")
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})
set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${OPENMW_VERSION_MINO})
set(CPACK_PACKAGE_VERSION_PATCH ${OPENMW_VERSION_RELEASE})
set(APPS "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}")
set(PLUGINS "")
# Scan Plugins dir for *.dylibs
file(GLOB ALL_PLUGINS "${APP_BUNDLE_DIR}/Contents/Plugins/*.dylib")
foreach(PLUGIN ${ALL_PLUGINS})
get_filename_component(PLUGIN_FILENAME ${PLUGIN} NAME)
set(PLUGINS ${PLUGINS} "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins/${PLUGIN_FILENAME}")
endforeach()
#For now, search unresolved dependencies only in default system paths, so if you put unresolveable (i.e. with @executable_path in id name) lib or framework somewhere else, it would fail
set(DIRS "")
# Overriding item resolving during installation, it needed if
# some library already has be "fixed up", i.e. its id name contains @executable_path,
# but library is not embedded in bundle. For example, it's Ogre.framework from Ogre SDK.
# Current implementation of GetPrerequsities/BundleUtilities doesn't handle that case.
#
# Current limitations:
# 1. Handles only frameworks, not simple libs
INSTALL(CODE "
set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_SYSTEM_FRAMEWORK_PATH ${CMAKE_SYSTEM_FRAMEWORK_PATH})
set(OPENMW_RESOLVED_ITEMS \"\")
function(gp_resolve_item_override context item exepath dirs resolved_item_var resolved_var)
if(item MATCHES \"@executable_path\" AND NOT \${\${resolved_var}})
if (item MATCHES \"Frameworks\") # if it is a framework
# get last segment of path
get_filename_component(fname \"\${item}\" NAME_WE)
find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} /Library/Frameworks)
if (ri)
message(STATUS \"found \${ri} for \${item}\")
string(REGEX REPLACE \"^.*/Frameworks/.*\\\\.framework\" \"\" item_part \${item})
set(ri \"\${ri}\${item_part}\")
set(\${resolved_item_var} \${ri} PARENT_SCOPE)
set(\${resolved_var} 1 PARENT_SCOPE)
set(OPENMW_RESOLVED_ITEMS \${_OPENMW_RESOLVED_ITEMS} \${ri})
endif()
else()
# code path for standard (non-framework) libs (ogre & qt pugins)
endif()
endif()
endfunction(gp_resolve_item_override)
cmake_policy(SET CMP0009 OLD)
set(BU_CHMOD_BUNDLE_ITEMS ON)
include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"${PLUGINS}\" \"${DIRS}\")
" COMPONENT Runtime)
include(CPack)
set(CMAKE_EXE_LINKER_FLAGS "-arch i386")
set(CMAKE_CXX_FLAGS "-arch i386")
endif (APPLE)

@ -926,13 +926,13 @@ int update_arg(void *field, char **orig_field,
const char *long_opt, char short_opt,
const char *additional_error)
{
char *stop_char = 0;
const char *val = value;
int found;
//char *stop_char = 0;
//const char *val = value;
//int found;
FIX_UNUSED (field);
stop_char = 0;
found = 0;
//stop_char = 0;
//found = 0;
if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
{
@ -955,8 +955,8 @@ int update_arg(void *field, char **orig_field,
(*prev_given)++;
if (field_given)
(*field_given)++;
if (possible_values)
val = possible_values[found];
//if (possible_values)
//val = possible_values[found];
switch(arg_type) {
default:
@ -996,7 +996,7 @@ cmdline_parser_internal (
int override;
int initialize;
int check_required;
//int check_required;
int check_ambiguity;
char *optarg;
@ -1008,7 +1008,7 @@ cmdline_parser_internal (
override = params->override;
initialize = params->initialize;
check_required = params->check_required;
//check_required = params->check_required;
check_ambiguity = params->check_ambiguity;
if (initialize)

@ -41,14 +41,25 @@ source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC
find_package(Qt4 REQUIRED)
set(QT_USE_QTGUI 1)
find_package(PNG REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
#find_package(PNG REQUIRED)
#include_directories(${PNG_INCLUDE_DIR})
QT4_ADD_RESOURCES(RCC_SRCS resources.qrc)
QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC})
include(${QT_USE_FILE})
# list here plugins that can't be detected statically, but loaded in runtime
# it needed for packaging automatisation
#set(USED_QT_PLUGINS imageformats/libqgif
# imageformats/libqico
# imageformats/libqjpeg
# imageformats/libqmng
# imageformats/libqsvg
# imageformats/libqtga
# imageformats/libqtiff)
# It seems that launcher works without this plugins, but it loads them into memory if they exists
# Main executable
add_executable(omwlauncher
${LAUNCHER}
@ -60,7 +71,7 @@ target_link_libraries(omwlauncher
${Boost_LIBRARIES}
${OGRE_LIBRARIES}
${QT_LIBRARIES}
${PNG_LIBRARY}
# ${PNG_LIBRARY}
components
)
@ -73,6 +84,13 @@ if (APPLE)
"${APP_BUNDLE_DIR}/../launcher.qss")
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
"${APP_BUNDLE_DIR}/../launcher.cfg")
# copy used QT plugins into ${APP_BUNDLE_DIR}/Contents/Plugins
#foreach(PLUGIN ${USED_QT_PLUGINS})
# get_filename_component(PLUGIN_FILENAME ${PLUGIN} NAME)
# configure_file("${QT_PLUGINS_DIR}/${PLUGIN}.dylib" "${APP_BUNDLE_DIR}/Contents/Plugins/${PLUGIN_FILENAME}.dylib" COPYONLY)
#endforeach()
else()
configure_file(${CMAKE_SOURCE_DIR}/files/launcher.qss
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launcher.qss")

@ -86,10 +86,6 @@ target_link_libraries(openmw
if(APPLE)
find_library(CARBON_FRAMEWORK Carbon)
target_link_libraries(openmw ${CARBON_FRAMEWORK})
install(TARGETS openmw
BUNDLE DESTINATION .
RUNTIME DESTINATION ../MacOS
COMPONENT Runtime)
endif(APPLE)
if(DPKG_PROGRAM)

@ -445,6 +445,28 @@ void OMW::Engine::activate()
}
}
void OMW::Engine::screenshot()
{
// Count screenshots.
int shotCount = 0;
const std::string screenshotPath = mCfgMgr.getLocalConfigPath().string();
// Find the first unused filename with a do-while
std::ostringstream stream;
do
{
// Reset the stream
stream.str("");
stream.clear();
stream << screenshotPath << "screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << ".png";
} while (boost::filesystem::exists(stream.str()));
mOgre->screenshot(stream.str());
}
void OMW::Engine::setCompileAll (bool all)
{
mCompileAll = all;

@ -149,6 +149,9 @@ namespace OMW
/// Activate the focussed object.
void activate();
/// Write screenshot to file.
void screenshot();
/// Compile all scripts (excludign dialogue scripts) at startup?
void setCompileAll (bool all);

@ -26,11 +26,12 @@ namespace MWClass
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
if (!model.empty())
objects.insertMesh(ptr, "meshes\\" + model);
const int color = ref->base->data.color;
const float r = ((color >> 0) & 0xFF) / 255.0f;
const float g = ((color >> 8) & 0xFF) / 255.0f;
@ -38,20 +39,18 @@ namespace MWClass
const float radius = float (ref->base->data.radius);
objects.insertLight (ptr, r, g, b, radius);
}
}
void Light::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
{
ESMS::LiveCellRef<ESM::Light, MWWorld::RefData> *ref =
ptr.get<ESM::Light>();
const std::string &model = ref->base->model;
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if(!model.empty()){
physics.insertObjectPhysics(ptr, "meshes\\" + model);
}
}
void Light::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const

@ -20,7 +20,7 @@ namespace MWClass
if (!model.empty())
{
MWRender::Objects& objects = renderingInterface.getObjects();
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false);
objects.insertBegin(ptr, ptr.getRefData().isEnabled(), true);
objects.insertMesh(ptr, "meshes\\" + model);
}
}
@ -30,13 +30,12 @@ namespace MWClass
ESMS::LiveCellRef<ESM::Static, MWWorld::RefData> *ref =
ptr.get<ESM::Static>();
const std::string &model = ref->base->model;
assert (ref->base != NULL);
const std::string &model = ref->base->model;
if(!model.empty()){
physics.insertObjectPhysics(ptr, "meshes\\" + model);
}
}
std::string Static::getName (const MWWorld::Ptr& ptr) const

@ -32,8 +32,8 @@ book formatText(std::string text,book mBook,int maxLine, int lineSize)
mBook.pages.pop_back();
}
std::string::iterator wordBegin = text.begin();
std::string::iterator wordEnd;
//std::string::iterator wordBegin = text.begin();
//std::string::iterator wordEnd;
std::string cText = text;

@ -83,27 +83,14 @@ namespace MWInput
MWGui::WindowManager &windows;
OMW::Engine& mEngine;
// Count screenshots.
int shotCount;
/* InputImpl Methods */
// Write screenshot to file.
void screenshot()
{
// Find the first unused filename with a do-while
char buf[50];
do
{
snprintf(buf, 50, "screenshot%03d.png", shotCount++);
} while (boost::filesystem::exists(buf));
ogre.screenshot(buf);
mEngine.screenshot();
}
/* toggleInventory() is called when the user presses the button to toggle the inventory screen. */
void toggleInventory()
{
@ -183,8 +170,7 @@ namespace MWInput
poller(input),
player(_player),
windows(_windows),
mEngine (engine),
shotCount(0)
mEngine (engine)
{
using namespace OEngine::Input;
using namespace OEngine::Render;

@ -101,7 +101,6 @@ namespace MWRender{
}
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){
bool useHandles = skel == creaturemodel->getSkeleton();
shapeNumber = 0;
std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
@ -112,6 +111,9 @@ namespace MWRender{
Nif::NiTriShapeCopy& copy = *allshapesiter;
std::vector<Ogre::Vector3>* allvertices = &copy.vertices;
std::vector<Ogre::Vector3>* allnormals = &copy.normals;
//std::set<unsigned int> vertices;
//std::set<unsigned int> normals;
@ -121,8 +123,7 @@ namespace MWRender{
//std::cout << "Name " << copy.sname << "\n";
Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0);
Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
//Ogre::HardwareVertexBufferSharedPtr vbufNormal = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(1);
// Ogre::Real* pRealNormal = static_cast<Ogre::Real*>(vbufNormal->lock(Ogre::HardwareBuffer::HBL_NORMAL));
std::vector<Ogre::Vector3> initialVertices = copy.morph.getInitialVertices();
//Each shape has multiple indices
@ -181,146 +182,76 @@ namespace MWRender{
std::vector<Nif::NiSkinData::IndividualWeight> inds = iter->second;
int verIndex = iter->first;
Ogre::Vector3 currentVertex = (*allvertices)[verIndex];
Ogre::Vector3 currentNormal = (*allnormals)[verIndex];
Nif::NiSkinData::BoneInfoCopy* boneinfocopy = &(allshapesiter->boneinfo[inds[0].boneinfocopyindex]);
Ogre::Bone *bonePtr = 0;
if(useHandles)
{
bonePtr = skel->getBone(boneinfocopy->bonehandle);
}
else
bonePtr = skel->getBone(boneinfocopy->bonename);
Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
/*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){
Ogre::Vector3 vecPos;
Ogre::Quaternion vecRot;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot>::iterator result = vecRotPos.find(boneinfocopy);
if(result == vecRotPos.end()){
bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
if(useHandles){
PosAndRot both;
both.vecPos = vecPos;
both.vecRot = vecRot;
vecPosRot[boneinfocopy->bonehandle] = both;
}
vecRotPos[boneinfocopy] = both;
}
else{
PosAndRot both = vecPosRot[boneinfocopy->bonehandle];
PosAndRot both = result->second;
vecPos = both.vecPos;
vecRot = both.vecRot;
}*/
}
Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight;
for(std::size_t i = 1; i < inds.size(); i++){
boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]);
if(useHandles)
bonePtr = skel->getBone(boneinfocopy->bonehandle);
else
bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
result = vecRotPos.find(boneinfocopy);
/*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){
if(result == vecRotPos.end()){
bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
if(useHandles){
PosAndRot both;
both.vecPos = vecPos;
both.vecRot = vecRot;
vecPosRot[boneinfocopy->bonehandle] = both;
}
vecRotPos[boneinfocopy] = both;
}
else{
PosAndRot both = vecPosRot[boneinfocopy->bonehandle];
PosAndRot both = result->second;
vecPos = both.vecPos;
vecRot = both.vecRot;
}*/
absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;
}
Ogre::Real* addr = (pReal + 3 * verIndex);
*addr = absVertPos.x;
*(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z;
}
#if 0
for (unsigned int i = 0; i < boneinfovector.size(); i++)
{
Nif::NiSkinData::BoneInfoCopy boneinfo = boneinfovector[i];
if(skel->hasBone(boneinfo.bonename)){
Ogre::Bone *bonePtr = skel->getBone(boneinfo.bonename);
Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfo.trafo.trans;
Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfo.trafo.rotation;
for (unsigned int j=0; j < boneinfo.weights.size(); j++)
{
unsigned int verIndex = boneinfo.weights[j].vertex;
if(vertices.find(verIndex) == vertices.end())
{
Ogre::Vector3 absVertPos = vecPos + vecRot * allvertices[verIndex];
absVertPos = absVertPos * boneinfo.weights[j].weight;
vertices.insert(verIndex);
Ogre::Real* addr = (pReal + 3 * verIndex);
*addr = absVertPos.x;
*(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z;
absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;
}
else
{
Ogre::Vector3 absVertPos = vecPos + vecRot * allvertices[verIndex];
absVertPos = absVertPos * boneinfo.weights[j].weight;
Ogre::Vector3 old = Ogre::Vector3(pReal + 3 * verIndex);
absVertPos = absVertPos + old;
Ogre::Real* addr = (pReal + 3 * verIndex);
*addr = absVertPos.x;
*(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z;
//std::cout << "Vertex" << verIndex << "Weight: " << boneinfo.weights[i].weight << "was seen twice\n";
}
if(normals.find(verIndex) == normals.end())
{
Ogre::Vector3 absNormalsPos = vecRot * allnormals[verIndex];
absNormalsPos = absNormalsPos * boneinfo.weights[j].weight;
normals.insert(verIndex);
Ogre::Real* addr = (pRealNormal + 3 * verIndex);
*addr = absNormalsPos.x;
*(addr+1) = absNormalsPos.y;
*(addr+2) = absNormalsPos.z;
}
else
{
Ogre::Vector3 absNormalsPos = vecRot * allnormals[verIndex];
absNormalsPos = absNormalsPos * boneinfo.weights[j].weight;
Ogre::Vector3 old = Ogre::Vector3(pRealNormal + 3 * verIndex);
absNormalsPos = absNormalsPos + old;
Ogre::Real* addr = (pRealNormal + 3 * verIndex);
*addr = absNormalsPos.x;
*(addr+1) = absNormalsPos.y;
*(addr+2) = absNormalsPos.z;
}
#endif
//}
//}
//} //Comment out
;
}
else
{
@ -329,10 +260,12 @@ namespace MWRender{
Ogre::Vector3 shapetrans = copy.trafo.trans;
float shapescale = copy.trafo.scale;
std::vector<std::string> boneSequence = copy.boneSequence;
std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
Ogre::Vector3 transmult;
Ogre::Quaternion rotmult;
float scale;
if(boneSequence.size() > 0){
std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
@ -360,6 +293,7 @@ namespace MWRender{
//std::cout << "Position: " << transmult << "Rotation: " << rotmult << "\n";
}
}
else
{
transmult = shapetrans;
@ -392,7 +326,7 @@ namespace MWRender{
}
vbuf->unlock();
//vbufNormal->unlock();
}
}
@ -465,22 +399,18 @@ namespace MWRender{
base->getAllAnimationStates()->_notifyDirty();
//base->_updateAnimation();
base->_notifyMoved();
//base->_notifyMoved();
for(unsigned int i = 0; i < entityparts.size(); i++){
Ogre::SkeletonInstance* skel = entityparts[i]->getSkeleton();
//Ogre::SkeletonInstance* skel = entityparts[i]->getSkeleton();
Ogre::Bone* b = skel->getRootBone();
b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3));//This is a trick
skel->_updateTransforms();
// skel->_notifyManualBonesDirty();
entityparts[i]->getAllAnimationStates()->_notifyDirty();
//entityparts[i]->_updateAnimation();
entityparts[i]->_notifyMoved();
}
std::vector<Nif::NiKeyframeData>::iterator iter;
int slot = 0;
if(transformations){
@ -488,9 +418,7 @@ namespace MWRender{
if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime())
{
slot++;
//iter++;
continue;
}
float x;
@ -511,7 +439,6 @@ namespace MWRender{
timeIndex(time, ttime, tindexI[slot], tindexJ, x);
//std::cout << "X: " << x << " X2: " << x2 << "\n";
Ogre::Vector3 t;
Ogre::Quaternion r;
@ -526,7 +453,6 @@ namespace MWRender{
bool bQuats = quats.size() > 0;
if(bQuats){
r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true);
//bone->setOrientation(r);
}
skel = base->getSkeleton();
if(skel->hasBone(iter->getBonename())){
@ -539,27 +465,10 @@ namespace MWRender{
skel->_updateTransforms();
//skel->_notifyManualBonesDirty();
base->getAllAnimationStates()->_notifyDirty();
//base->_updateAnimation();
base->_notifyMoved();
}
for(std::size_t i = 0; i < entityparts.size(); i++){
skel = entityparts[i]->getSkeleton();
if(skel->hasBone(iter->getBonename())){
Ogre::Bone* bone = skel->getBone(iter->getBonename());
if(bTrans)
bone->setPosition(t);
if(bQuats)
bone->setOrientation(r);
skel->_updateTransforms();
//skel->_notifyManualBonesDirty();
entityparts[i]->getAllAnimationStates()->_notifyDirty();
// entityparts[i]->_updateAnimation();
entityparts[i]->_notifyMoved();
}
}
slot++;
}
}

@ -26,6 +26,7 @@ class Animation{
Ogre::SceneNode* insert;
OEngine::Render::OgreRenderer &mRend;
MWWorld::Environment& mEnvironment;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot> vecRotPos;
static std::map<std::string, int> mUniqueIDs;

@ -38,6 +38,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme
}
void CreatureAnimation::runAnimation(float timepassed){
vecRotPos.clear();
if(animate > 0){
//Add the amount of time passed to time

@ -43,6 +43,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2);
bool female = tolower(secondtolast) == 'f';
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
/*std::cout << "Race: " << ref->base->race ;
if(female){
std::cout << " Sex: Female" << " Height: " << race->data.height.female << "\n";
@ -67,6 +68,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
//stay in the same place when we skipanim, or open a gui window
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(smodel))){
for(unsigned int init = 0; init < transformations->size(); init++){
@ -177,7 +179,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
if(clavicler)
insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/
if(neck)
{
insertBoundedPart("meshes\\" + neck->model, "Neck");
@ -213,6 +214,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
}
Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){
NIFLoader::load(mesh);
Entity* ent = mRend.getScene()->createEntity(mesh);
@ -225,15 +227,7 @@ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suf
Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered);
/*MaterialPtr material = ent->getSubEntity(0)->getMaterial();
material->removeAllTechniques();
Ogre::Technique* tech = material->createTechnique();
Pass* pass2 = tech->createPass();
pass2->setVertexProgram("Ogre/HardwareSkinningTwoWeights");
pass2->setColourWriteEnabled(false);
//tech->setSchemeName("blahblah");*/
insert->attachObject(ent);
@ -249,6 +243,7 @@ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suf
void NpcAnimation::runAnimation(float timepassed){
//1. Add the amount of time passed to time
//2. Handle the animation transforms dependent on time
@ -267,22 +262,17 @@ void NpcAnimation::runAnimation(float timepassed){
}
handleAnimationTransforms();
Ogre::Vector3 current = insert->_getWorldAABB().getCenter();
std::vector<std::vector<Nif::NiTriShapeCopy>*>::iterator shapepartsiter = shapeparts.begin();
std::vector<Ogre::Entity*>::iterator entitypartsiter = entityparts.begin();
while(shapepartsiter != shapeparts.end())
{
vecRotPos.clear();
std::vector<Nif::NiTriShapeCopy>* shapes = *shapepartsiter;
Ogre::Entity* theentity = *entitypartsiter;
/*
Pass* pass = theentity->getSubEntity(0)->getMaterial()->getBestTechnique()->getPass(0);
if (pass->hasVertexProgram() && pass->getVertexProgram()->isSkeletalAnimationIncluded())
std::cout << "It's hardware\n";
else
std::cout << "It's software\n";*/
handleShapes(shapes, theentity, theentity->getSkeleton());
handleShapes(shapes, theentity, base->getSkeleton());
shapepartsiter++;
entitypartsiter++;
}

@ -1,11 +1,11 @@
#include "objects.hpp"
#include <OgreSceneNode.h>
#include <components/nifogre/ogre_nif_loader.hpp>
using namespace Ogre;
using namespace MWRender;
bool Objects::lightConst = false;
float Objects::lightConstValue = 0.0f;
@ -23,10 +23,24 @@ bool Objects::lightOutQuadInLin = false;
int Objects::uniqueID = 0;
void Objects::setMwRoot(Ogre::SceneNode* root){
void Objects::clearSceneNode (Ogre::SceneNode *node)
{
/// \todo This should probably be moved into OpenEngine at some point.
for (int i=node->numAttachedObjects()-1; i>=0; --i)
{
Ogre::MovableObject *object = node->getAttachedObject (i);
node->detachObject (object);
mRenderer.getScene()->destroyMovableObject (object);
}
}
void Objects::setMwRoot(Ogre::SceneNode* root)
{
mMwRoot = root;
}
void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_)
{
Ogre::SceneNode* root = mMwRoot;
Ogre::SceneNode* cellnode;
if(mCellSceneNodes.find(ptr.getCell()) == mCellSceneNodes.end())
@ -49,68 +63,69 @@ void Objects::insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_){
f = ptr.getCellRef().pos.rot;
// Rotate around X axis
Quaternion xr(Radian(-f[0]), Vector3::UNIT_X);
Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X);
// Rotate around Y axis
Quaternion yr(Radian(-f[1]), Vector3::UNIT_Y);
Ogre::Quaternion yr(Ogre::Radian(-f[1]), Ogre::Vector3::UNIT_Y);
// Rotate around Z axis
Quaternion zr(Radian(-f[2]), Vector3::UNIT_Z);
Ogre::Quaternion zr(Ogre::Radian(-f[2]), Ogre::Vector3::UNIT_Z);
// Rotates first around z, then y, then x
insert->setOrientation(xr*yr*zr);
if (!enabled)
insert->setVisible (false);
ptr.getRefData().setBaseNode(insert);
isStatic = static_;
mIsStatic = static_;
}
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh){
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
{
Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
assert(insert);
NifOgre::NIFLoader::load(mesh);
Entity *ent = mRend.getScene()->createEntity(mesh);
Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);
if(!isStatic)
if(!mIsStatic)
{
insert->attachObject(ent);
}
else
{
Ogre::StaticGeometry* sg = 0;
if(mSG.find(ptr.getCell()) == mSG.end())
if(mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end())
{
uniqueID = uniqueID +1;
sg = mRend.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
//Create the scenenode and put it in the map
mSG[ptr.getCell()] = sg;
mStaticGeometry[ptr.getCell()] = sg;
}
else
{
sg = mSG[ptr.getCell()];
sg = mStaticGeometry[ptr.getCell()];
}
sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale());
sg->setRegionDimensions(Ogre::Vector3(100000,10000,100000));
mRend.getScene()->destroyEntity(ent);
mRenderer.getScene()->destroyEntity(ent);
}
}
void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius){
Ogre::SceneNode* insert = mRend.getScene()->getSceneNode(ptr.getRefData().getHandle());
void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, float radius)
{
Ogre::SceneNode* insert = mRenderer.getScene()->getSceneNode(ptr.getRefData().getHandle());
assert(insert);
Ogre::Light *light = mRend.getScene()->createLight();
Ogre::Light *light = mRenderer.getScene()->createLight();
light->setDiffuseColour (r, g, b);
float cval=0.0f, lval=0.0f, qval=0.0f;
if(lightConst)
cval = lightConstValue;
if(!lightOutQuadInLin)
{
if(lightLinear)
@ -145,8 +160,9 @@ bool Objects::deleteObject (const MWWorld::Ptr& ptr)
mCellSceneNodes.begin()); iter!=mCellSceneNodes.end(); ++iter)
if (iter->second==parent)
{
clearSceneNode (base);
base->removeAndDestroyAllChildren();
mRend.getScene()->destroySceneNode (base);
mRenderer.getScene()->destroySceneNode (base);
ptr.getRefData().setBaseNode (0);
return true;
}
@ -157,29 +173,35 @@ bool Objects::deleteObject (const MWWorld::Ptr& ptr)
return true;
}
void Objects::removeCell(MWWorld::Ptr::CellStore* store){
void Objects::removeCell(MWWorld::Ptr::CellStore* store)
{
if(mCellSceneNodes.find(store) != mCellSceneNodes.end())
{
Ogre::SceneNode* base = mCellSceneNodes[store];
for (int i=0; i<base->numChildren(); ++i)
clearSceneNode (static_cast<Ogre::SceneNode *> (base->getChild (i)));
base->removeAndDestroyAllChildren();
mCellSceneNodes.erase(store);
mRend.getScene()->destroySceneNode(base);
mRenderer.getScene()->destroySceneNode(base);
base = 0;
}
if(mSG.find(store) != mSG.end())
if(mStaticGeometry.find(store) != mStaticGeometry.end())
{
Ogre::StaticGeometry* sg = mSG[store];
mSG.erase(store);
mRend.getScene()->destroyStaticGeometry (sg);
Ogre::StaticGeometry* sg = mStaticGeometry[store];
mStaticGeometry.erase(store);
mRenderer.getScene()->destroyStaticGeometry (sg);
sg = 0;
}
}
void Objects::buildStaticGeometry(ESMS::CellStore<MWWorld::RefData>& cell){
if(mSG.find(&cell) != mSG.end())
void Objects::buildStaticGeometry(ESMS::CellStore<MWWorld::RefData>& cell)
{
if(mStaticGeometry.find(&cell) != mStaticGeometry.end())
{
Ogre::StaticGeometry* sg = mSG[&cell];
Ogre::StaticGeometry* sg = mStaticGeometry[&cell];
sg->build();
}
}

@ -1,20 +1,21 @@
#ifndef _GAME_RENDER_OBJECTS_H
#define _GAME_RENDER_OBJECTS_H
#include "components/esm_store/cell_store.hpp"
#include <openengine/ogre/renderer.hpp>
#include <components/esm_store/cell_store.hpp>
#include "../mwworld/refdata.hpp"
#include "../mwworld/ptr.hpp"
#include <openengine/ogre/renderer.hpp>
namespace MWRender{
class Objects{
OEngine::Render::OgreRenderer &mRend;
OEngine::Render::OgreRenderer &mRenderer;
std::map<MWWorld::Ptr::CellStore *, Ogre::SceneNode *> mCellSceneNodes;
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mSG;
std::map<MWWorld::Ptr::CellStore *, Ogre::StaticGeometry*> mStaticGeometry;
Ogre::SceneNode* mMwRoot;
bool isStatic;
bool mIsStatic;
static int uniqueID;
static bool lightConst;
static float lightConstValue;
@ -30,8 +31,12 @@ class Objects{
static float lightQuadraticRadiusMult;
static bool lightOutQuadInLin;
void clearSceneNode (Ogre::SceneNode *node);
///< Remove all movable objects from \a node.
public:
Objects(OEngine::Render::OgreRenderer& _rend): mRend(_rend){}
Objects(OEngine::Render::OgreRenderer& renderer): mRenderer (renderer){}
~Objects(){}
void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_);
void insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh);

@ -41,6 +41,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
mObjects.setMwRoot(mMwRoot);
mActors.setMwRoot(mMwRoot);
//mSkyManager = 0;
mSkyManager = MWRender::SkyManager::create(mRendering.getWindow(), mRendering.getCamera(), mMwRoot, resDir);
//used to obtain ingame information of ogre objects (which are faced or selected)
@ -53,10 +54,12 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
cameraPitchNode->attachObject(mRendering.getCamera());
mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode);
mSun = 0;
}
RenderingManager::~RenderingManager ()
{
//TODO: destroy mSun?
delete mPlayer;
delete mSkyManager;
}
@ -134,27 +137,32 @@ void RenderingManager::update (float duration){
void RenderingManager::skyEnable ()
{
if(mSkyManager)
mSkyManager->enable();
}
void RenderingManager::skyDisable ()
{
if(mSkyManager)
mSkyManager->disable();
}
void RenderingManager::skySetHour (double hour)
{
if(mSkyManager)
mSkyManager->setHour(hour);
}
void RenderingManager::skySetDate (int day, int month)
{
if(mSkyManager)
mSkyManager->setDate(day, month);
}
int RenderingManager::skyGetMasserPhase() const
{
return mSkyManager->getMasserPhase();
}
@ -163,8 +171,8 @@ int RenderingManager::skyGetSecundaPhase() const
return mSkyManager->getSecundaPhase();
}
void RenderingManager::skySetMoonColour (bool red)
{
void RenderingManager::skySetMoonColour (bool red){
if(mSkyManager)
mSkyManager->setMoonColour(red);
}
@ -228,12 +236,15 @@ void RenderingManager::configureAmbient(ESMS::CellStore<MWWorld::RefData> &mCell
// Create a "sun" that shines light downwards. It doesn't look
// completely right, but leave it for now.
Ogre::Light *light = mRendering.getScene()->createLight();
if(!mSun)
{
mSun = mRendering.getScene()->createLight();
}
Ogre::ColourValue colour;
colour.setAsABGR (mCell.cell->ambi.sunlight);
light->setDiffuseColour (colour);
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(0,-1,0);
mSun->setDiffuseColour (colour);
mSun->setType(Ogre::Light::LT_DIRECTIONAL);
mSun->setDirection(0,-1,0);
}
// Switch through lighting modes.

@ -121,6 +121,7 @@ class RenderingManager: private RenderingInterface {
int mAmbientMode;
Ogre::ColourValue mAmbientColor;
Ogre::Light* mSun;
/// Root node for all objects added to the scene. This is rotated so
/// that the OGRE coordinate system matches that used internally in

@ -5,6 +5,8 @@
#include <OgreSceneNode.h>
#include <OgreSceneManager.h>
#include <OgreCamera.h>
#include <OgreHardwareVertexBuffer.h>
#include <OgreHighLevelGpuProgramManager.h>
#include <components/nifogre/ogre_nif_loader.hpp>
@ -42,26 +44,124 @@ namespace MWRender
private:
Camera* mCamera;
Viewport* mViewport;
SceneNode* mRootNode;
SceneManager* mSceneMgr;
MaterialPtr mCloudMaterial;
MaterialPtr mAtmosphereMaterial;
HighLevelGpuProgramPtr mCloudFragmentShader;
void ModVertexAlpha(Entity* ent, unsigned int meshType);
};
void MWSkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
{
// Get the vertex colour buffer of this mesh
VertexDeclaration* dec = ent->getMesh()->getSubMesh(0)->vertexData->vertexDeclaration;
const Ogre::VertexElement* ves_diffuse = ent->getMesh()->getSubMesh(0)->vertexData->vertexDeclaration->findElementBySemantic( Ogre::VES_DIFFUSE );
HardwareVertexBufferSharedPtr colourBuffer = ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource());
// Lock
void* pData = colourBuffer->lock(HardwareBuffer::HBL_NORMAL);
// Iterate over all vertices
int vertex_size = colourBuffer->getVertexSize();
float * currentVertex = NULL;
for (int i=0; i<colourBuffer->getNumVertices(); ++i)
{
// Get a pointer to the vertex colour
ves_diffuse->baseVertexPointerToElement( pData, &currentVertex );
unsigned char alpha;
if (meshType == 0) alpha = i%2 ? 0 : 255; // this is a cylinder, so every second vertex belongs to the bottom-most row
else if (meshType == 1)
{
if (i>= 49 && i <= 64) alpha = 0; // bottom-most row
else if (i>= 33 && i <= 48) alpha = 64; // second bottom-most row
else alpha = 255;
}
uint8 tmpR = static_cast<uint8>(255);
uint8 tmpG = static_cast<uint8>(255);
uint8 tmpB = static_cast<uint8>(255);
uint8 tmpA = static_cast<uint8>(alpha);
// This does not matter since R and B are always 1.
/*VertexElementType format = Root::getSingleton().getRenderSystem()->getColourVertexElementType();
switch (format)
{
case VET_COLOUR_ARGB:
std::swap(tmpR, tmpB);
break;
case VET_COLOUR_ABGR:
break;
default:
break;
}*/
// Modify
*((uint32*)currentVertex) = tmpR | (tmpG << 8) | (tmpB << 16) | (tmpA << 24);
// Move to the next vertex
pData+=vertex_size;
}
// Unlock
ent->getMesh()->getSubMesh(0)->vertexData->vertexBufferBinding->getBuffer(ves_diffuse->getSource())->unlock();
}
MWSkyManager::MWSkyManager (SceneNode* pMwRoot, Camera* pCamera)
{
mViewport = pCamera->getViewport();
mSceneMgr = pMwRoot->getCreator();
mRootNode = pMwRoot->createChildSceneNode();
mRootNode->setScale(100.f, 100.f, 100.f);
mViewport->setBackgroundColour(ColourValue(0.87, 0.87, 0.87));
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
// Atmosphere
NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif");
ModVertexAlpha(atmosphere_ent, 0);
atmosphere_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY);
Ogre::SceneNode* atmosphere_node = mRootNode->createChildSceneNode();
atmosphere_node->attachObject(atmosphere_ent);
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
// Atmosphere shader
HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM);
vshader->setParameter("profiles", "vs_2_x arbvp1");
vshader->setParameter("entry_point", "main_vp");
StringUtil::StrStreamType outStream;
outStream <<
"void main_vp( \n"
" float4 position : POSITION, \n"
" in float4 color : COLOR, \n"
" out float4 oPosition : POSITION, \n"
" out float4 oColor : COLOR, \n"
" uniform float4 emissive, \n"
" uniform float4x4 worldViewProj \n"
") \n"
"{ \n"
" oPosition = mul( worldViewProj, position ); \n"
" oColor = color * emissive; \n"
"}";
vshader->setSource(outStream.str());
vshader->load();
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
vshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
// Clouds
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif");
@ -70,6 +170,60 @@ namespace MWRender
clouds_node->attachObject(clouds_ent);
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
// Clouds vertex shader
HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM);
vshader2->setParameter("profiles", "vs_2_x arbvp1");
vshader2->setParameter("entry_point", "main_vp");
StringUtil::StrStreamType outStream3;
outStream3 <<
"void main_vp( \n"
" float4 position : POSITION, \n"
" in float4 color : COLOR, \n"
" out float4 oColor : TEXCOORD1, \n"
" in float2 uv : TEXCOORD0, \n"
" out float2 oUV : TEXCOORD0, \n"
" out float4 oPosition : POSITION, \n"
" uniform float4x4 worldViewProj \n"
") \n"
"{ \n"
" oUV = uv; \n"
" oColor = color; \n"
" oPosition = mul( worldViewProj, position ); \n"
"}";
vshader2->setSource(outStream3.str());
vshader2->load();
vshader2->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
mCloudMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader2->getName());
// Clouds fragment shader
mCloudFragmentShader = mgr.createProgram("Clouds_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_FRAGMENT_PROGRAM);
mCloudFragmentShader->setParameter("profiles", "ps_2_x arbfp1");
mCloudFragmentShader->setParameter("entry_point", "main_fp");
StringUtil::StrStreamType outStream2;
outStream2 <<
"void main_fp( \n"
" in float2 uv : TEXCOORD0, \n"
" out float4 oColor : COLOR, \n"
" in float4 color : TEXCOORD1, \n"
" uniform sampler2D texture : TEXUNIT0, \n"
" uniform float time, \n"
" uniform float4 emissive \n"
") \n"
"{ \n"
" uv += float2(1,1) * time * 0.01; \n" // Scroll in x,y direction
" float4 tex = tex2D(texture, uv); \n"
" clip(tex.a<0.5); \n"
" oColor = color * float4(emissive.xyz,1) * tex2D(texture, uv); \n"
"}";
mCloudFragmentShader->setSource(outStream2.str());
mCloudFragmentShader->load();
mCloudFragmentShader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
mCloudMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(mCloudFragmentShader->getName());
ModVertexAlpha(clouds_ent, 1);
// Sun
/// \todo calculate the sun position based on time of day
Vector3 sunPosition(0, 0, 1.f);
@ -107,18 +261,20 @@ namespace MWRender
atmosphere_ent->getSubEntity(0)->setMaterial(mAtmosphereMaterial);
// Default atmosphere color: light blue
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.235, 0.5, 0.73);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 1.0);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(0.235, 0.5, 0.73);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 0.0);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
// Set up an UV scroll animation to move the clouds
mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setScrollAnimation(0.01f, 0.01f);
mCloudMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
// Disable depth writing so that the sky does not cover any objects
mCloudMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
// Alpha-blend the clouds with the atmosphere
//mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCamera = pCamera;
mCamera->setFarClipDistance(50000.f);
mCamera->setFarClipDistance(500000.f);
}
MWSkyManager::~MWSkyManager()
{
@ -129,6 +285,9 @@ namespace MWRender
// Sync the position of the skydomes with the camera
/// \todo for some reason this is 1 frame delayed, which causes the skydome move funnily when the camera moves
mRootNode->_setDerivedPosition(mCamera->getParentSceneNode()->_getDerivedPosition());
// UV Scroll the clouds
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", 1);
}
void MWSkyManager::enable()
@ -237,12 +396,12 @@ namespace MWRender
{
SkyManager* pSkyManager = NULL;
try
{
//try
//{
//pSkyManager = new CaelumManager(pRenderWindow, pCamera, resDir);
pSkyManager = new MWSkyManager(pMwRoot, pCamera);
}
catch (Ogre::Exception& e)
//}
/*catch (Ogre::Exception& e)
{
std::cout << "\nOGRE Exception when attempting to add sky: "
<< e.getFullDescription().c_str() << std::endl;
@ -251,7 +410,7 @@ namespace MWRender
{
std::cout << "\nException when attempting to add sky: "
<< e.what() << std::endl;
}
}*/
return pSkyManager;
}

@ -63,9 +63,10 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getExterior (int x, int y)
result = mExteriors.insert (std::make_pair (
std::make_pair (x, y), Ptr::CellStore (cell))).first;
}
if (result->second.mState!=Ptr::CellStore::State_Loaded)
result->second.load (mStore, mReader);
}
return &result->second;
}
@ -79,9 +80,10 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getInterior (const std::string& name)
const ESM::Cell *cell = mStore.cells.findInt (name);
result = mInteriors.insert (std::make_pair (name, Ptr::CellStore (cell))).first;
}
if (result->second.mState!=Ptr::CellStore::State_Loaded)
result->second.load (mStore, mReader);
}
return &result->second;
}

@ -60,12 +60,12 @@ namespace MWWorld
std::cout << "Unloading cell\n";
ListHandles functor;
MWWorld::Ptr::CellStore* active = *iter;
active->forEach<ListHandles>(functor);
(*iter)->forEach<ListHandles>(functor);
{
@ -77,12 +77,14 @@ namespace MWWorld
mPhysics->removeObject (node->getName());
}
}
mRendering.removeCell(active);
mRendering.removeCell(*iter);
//mPhysics->removeObject("Unnamed_43");
mWorld->getLocalScripts().clearCell (active);
mEnvironment.mMechanicsManager->dropActors (active);
mEnvironment.mSoundManager->stopSound (active);
mActiveCells.erase(active);
mWorld->getLocalScripts().clearCell (*iter);
mEnvironment.mMechanicsManager->dropActors (*iter);
mEnvironment.mSoundManager->stopSound (*iter);
mActiveCells.erase(*iter);
}

@ -181,6 +181,7 @@ namespace MWWorld
}
World::~World()
{
delete mWorldScene;
@ -610,7 +611,7 @@ namespace MWWorld
bool World::toggleCollisionMode()
{
return mPhysics->toggleCollisionMode();
return mPhysics->toggleCollisionMode();;
}
bool World::toggleRenderMode (RenderMode mode)

@ -228,6 +228,7 @@ namespace MWWorld
/// references that are currently not in the rendered scene should be ignored.
void update (float duration);
};
}

@ -473,7 +473,7 @@ void read(NIFFile *nif)
int vertCount = nif->getInt();
nif->getByte();
int magic = nif->getInt();
int type = nif->getInt();
/*int type =*/ nif->getInt();
for(int i = 0; i < vertCount; i++){
float x = nif->getFloat();
@ -485,7 +485,7 @@ void read(NIFFile *nif)
for(int i=1; i<morphCount; i++)
{
magic = nif->getInt();
type = nif->getInt();
/*type =*/ nif->getInt();
std::vector<Ogre::Vector3> current;
std::vector<float> currentTime;
for(int i = 0; i < magic; i++){

@ -220,14 +220,15 @@ void NIFLoader::createMaterial(const String &name,
//Hardware Skinning code, textures may be the wrong color if enabled
/*if(!mSkel.isNull()){
/* if(!mSkel.isNull()){
material->removeAllTechniques();
Ogre::Technique* tech = material->createTechnique();
//tech->setSchemeName("blahblah");
Pass* pass = tech->createPass();
pass->setVertexProgram("Ogre/HardwareSkinningFourWeights");
}*/
pass->setVertexProgram("Ogre/BasicVertexPrograms/AmbientOneTexture");*/
// This assigns the texture to this material. If the texture name is
// a file name, and this file exists (in a resource directory), it
@ -358,7 +359,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
HardwareVertexBufferSharedPtr vbuf =
HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT3),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
numVerts, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false);
if(flip)
{
@ -424,6 +425,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
bind->setBinding(nextBuf++, vbuf);
}
// Vertex colors
if (data->colors.length)
{
@ -530,6 +532,8 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
{
sub->addBoneAssignment(*it);
}
if(mSkel.isNull())
needBoneAssignments.push_back(sub);
}
// Helper math functions. Reinventing linear algebra for the win!
@ -580,6 +584,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
{
assert(shape != NULL);
bool saveTheShape = inTheSkeletonTree;
// Interpret flags
bool hidden = (flags & 0x01) != 0; // Not displayed
bool collide = (flags & 0x02) != 0; // Use mesh for collision
@ -738,6 +743,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
std::list<VertexBoneAssignment> vertexBoneAssignments;
Nif::NiTriShapeCopy copy = shape->clone();
if(!shape->controller.empty())
{
Nif::Controller* cont = shape->controller.getPtr();
@ -747,6 +753,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
copy.morph = morph->data.get();
copy.morph.setStartTime(morph->timeStart);
copy.morph.setStopTime(morph->timeStop);
saveTheShape = true;
}
}
@ -888,6 +895,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
boneIndex++;
}
}
else
{
@ -924,10 +932,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
}
if(!mSkel.isNull() ){
int boneIndex;
Ogre::Bone *parentBone = mSkel->getBone(boneSequence[boneSequence.size() - 1]);
if(parentBone)
boneIndex = parentBone->getHandle();
else
boneIndex = mSkel->getNumBones() - 1;
for(int i = 0; i < numVerts; i++){
VertexBoneAssignment vba;
@ -943,6 +948,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
{
// Add this vertex set to the bounding box
bounds.add(optr, numVerts);
if(saveTheShape)
shapes.push_back(copy);
// Create the submesh
@ -1063,19 +1069,22 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
//FIXME: "Bip01" isn't every time the root bone
if (node->name == "Bip01" || node->name == "Root Bone") //root node, create a skeleton
{
inTheSkeletonTree = true;
mSkel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true);
}
else if (!mSkel.isNull() && !parentBone)
inTheSkeletonTree = false;
if (!mSkel.isNull()) //if there is a skeleton
{
std::string name = node->name.toString();
boneSequence.push_back(name);
// Quick-n-dirty workaround for the fact that several
// bones may have the same name.
if(!mSkel->hasBone(name))
{
boneSequence.push_back(name);
bone = mSkel->createBone(name);
if (parentBone)
@ -1140,8 +1149,11 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
void NIFLoader::loadResource(Resource *resource)
{
inTheSkeletonTree = false;
allanim.clear();
shapes.clear();
needBoneAssignments.clear();
// needBoneAssignments.clear();
mBoundingBox.setNull();
mesh = 0;
mSkel.setNull();
@ -1150,8 +1162,12 @@ void NIFLoader::loadResource(Resource *resource)
char suffix = name.at(name.length() - 2);
bool addAnim = true;
bool hasAnim = false;
bool baddin = false;
//bool baddin = false;
bNiTri = true;
if(name == "meshes\\base_anim.nif" || name == "meshes\\base_animkna.nif")
{
bNiTri = false;
}
if(suffix == '*')
{
@ -1168,7 +1184,7 @@ void NIFLoader::loadResource(Resource *resource)
}
else if(suffix == '>')
{
baddin = true;
//baddin = true;
bNiTri = true;
std::string sub = name.substr(name.length() - 6, 4);
@ -1268,7 +1284,7 @@ void NIFLoader::loadResource(Resource *resource)
Nif::Node *o = dynamic_cast<Nif::Node*>(f->target.getPtr());
Nif::NiKeyframeDataPtr data = f->data;
if (f->timeStart == 10000000000000000)
if (f->timeStart >= 10000000000000000.0f)
continue;
data->setBonename(o->name.toString());
data->setStartTime(f->timeStart);
@ -1299,15 +1315,24 @@ void NIFLoader::loadResource(Resource *resource)
mesh->_setBounds(mBoundingBox, false);
}
if (!mSkel.isNull())
if (!mSkel.isNull() )
{
for(std::vector<Ogre::SubMesh*>::iterator iter = needBoneAssignments.begin(); iter != needBoneAssignments.end(); iter++)
{
int boneIndex = mSkel->getNumBones() - 1;
VertexBoneAssignment vba;
vba.boneIndex = boneIndex;
vba.vertexIndex = 0;
vba.weight = 1;
(*iter)->addBoneAssignment(vba);
}
mesh->_notifySkeleton(mSkel);
}
}
void NIFLoader::addInMesh(Ogre::Mesh* input){
addin.push_back(input);
}

@ -111,7 +111,6 @@ class NIFLoader : Ogre::ManualResourceLoader
std::vector<Nif::NiKeyframeData>* getAnim(std::string name);
std::vector<Nif::NiTriShapeCopy>* getShapes(std::string name);
std::map<std::string, float>* getTextIndices(std::string name);
void addInMesh(Ogre::Mesh* input);
Ogre::Vector3 convertVector3(const Nif::Vector& vec);
@ -121,8 +120,9 @@ class NIFLoader : Ogre::ManualResourceLoader
void setVerbosePath(std::string path);
private:
NIFLoader() : resourceName(""), resourceGroup("General"), flip(false), mNormaliseNormals(false),
mFlipVertexWinding(false), mOutputAnimFiles(false) {}
mFlipVertexWinding(false), mOutputAnimFiles(false), inTheSkeletonTree(false) {}
NIFLoader(NIFLoader& n) {}
void calculateTransform();
@ -184,13 +184,16 @@ class NIFLoader : Ogre::ManualResourceLoader
std::string name;
std::string triname;
std::vector<Nif::NiKeyframeData> allanim;
std::map<std::string,float> textmappings;
std::map<std::string,std::map<std::string,float>,ciLessBoost> alltextmappings;
std::map<std::string,std::vector<Nif::NiKeyframeData>,ciLessBoost> allanimmap;
std::map<std::string,std::vector<Nif::NiTriShapeCopy>,ciLessBoost> allshapesmap;
std::vector<Ogre::Mesh*> addin;
std::vector<Nif::NiKeyframeData> mAnim;
std::vector<Nif::NiTriShapeCopy> mS;
std::vector<Ogre::SubMesh*> needBoneAssignments;
bool inTheSkeletonTree;
};

@ -19,7 +19,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.10</string>
<string>${OPENMW_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>

@ -7,6 +7,6 @@ PluginFolder=${OGRE_PLUGIN_DIR_REL}
Plugin=RenderSystem_GL
Plugin=Plugin_ParticleFX
Plugin=Plugin_OctreeSceneManager
# Plugin=Plugin_CgProgramManager
Plugin=Plugin_CgProgramManager

@ -7,6 +7,6 @@ PluginFolder=
Plugin=RenderSystem_GL.dylib
Plugin=Plugin_ParticleFX.dylib
Plugin=Plugin_OctreeSceneManager.dylib
# Plugin=Plugin_CgProgramManager
Plugin=Plugin_CgProgramManager

Loading…
Cancel
Save