diff --git a/CMakeLists.txt b/CMakeLists.txt index aa6979028..57f950612 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/apps/esmtool/esmtool_cmd.c b/apps/esmtool/esmtool_cmd.c index d6556d9e7..3fce77de2 100644 --- a/apps/esmtool/esmtool_cmd.c +++ b/apps/esmtool/esmtool_cmd.c @@ -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) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 2fc3189fc..e46a06205 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -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") diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 359a7b4e7..8caf6ad60 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -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) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index c8dca2d3a..7d65b95c5 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -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; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index b224df7d1..00d709be4 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -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); diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 2c50472ac..928fcc61c 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -26,18 +26,18 @@ namespace MWClass assert (ref->base != NULL); const std::string &model = ref->base->model; + MWRender::Objects& objects = renderingInterface.getObjects(); + objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); + if (!model.empty()) - { - MWRender::Objects& objects = renderingInterface.getObjects(); - objects.insertBegin(ptr, ptr.getRefData().isEnabled(), false); 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; - const float b = ((color >> 16) & 0xFF) / 255.0f; - const float radius = float (ref->base->data.radius); - objects.insertLight (ptr, r, g, b, radius); - } + + const int color = ref->base->data.color; + const float r = ((color >> 0) & 0xFF) / 255.0f; + const float g = ((color >> 8) & 0xFF) / 255.0f; + const float b = ((color >> 16) & 0xFF) / 255.0f; + 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 @@ -45,13 +45,12 @@ namespace MWClass ESMS::LiveCellRef *ref = ptr.get(); - - 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 diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index fbd96182f..48750dd01 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -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 *ref = ptr.get(); - - 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 diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 457a07582..3f3c89f39 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -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; diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index e0c819a71..88534ddda 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -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; diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 5a9731d2d..63855f3b8 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -101,7 +101,6 @@ namespace MWRender{ } void Animation::handleShapes(std::vector* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){ - bool useHandles = skel == creaturemodel->getSkeleton(); shapeNumber = 0; std::vector::iterator allshapesiter; @@ -112,6 +111,9 @@ namespace MWRender{ Nif::NiTriShapeCopy& copy = *allshapesiter; std::vector* allvertices = ©.vertices; + std::vector* allnormals = ©.normals; + + //std::set vertices; //std::set 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(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL)); - //Ogre::HardwareVertexBufferSharedPtr vbufNormal = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(1); - // Ogre::Real* pRealNormal = static_cast(vbufNormal->lock(Ogre::HardwareBuffer::HBL_NORMAL)); + std::vector initialVertices = copy.morph.getInitialVertices(); //Each shape has multiple indices @@ -181,146 +182,76 @@ namespace MWRender{ std::vector 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::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; - } - 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,11 +260,13 @@ namespace MWRender{ Ogre::Vector3 shapetrans = copy.trafo.trans; float shapescale = copy.trafo.scale; std::vector boneSequence = copy.boneSequence; - std::vector::iterator boneSequenceIter = boneSequence.begin(); + Ogre::Vector3 transmult; Ogre::Quaternion rotmult; float scale; - if(skel->hasBone(*boneSequenceIter)){ + if(boneSequence.size() > 0){ + std::vector::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(); + for(unsigned int i = 0; i < entityparts.size(); i++){ + //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::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++; } } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 15c25707c..bad7eca15 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -26,6 +26,7 @@ class Animation{ Ogre::SceneNode* insert; OEngine::Render::OgreRenderer &mRend; MWWorld::Environment& mEnvironment; + std::map vecRotPos; static std::map mUniqueIDs; diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index 3cb40f2f1..4de6453aa 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -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 diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 863f7577b..4c9c0e466 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -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*>::iterator shapepartsiter = shapeparts.begin(); std::vector::iterator entitypartsiter = entityparts.begin(); while(shapepartsiter != shapeparts.end()) { + vecRotPos.clear(); std::vector* 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++; } diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 1e3b4dda0..4e2a3caab 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -1,11 +1,11 @@ #include "objects.hpp" + #include + #include -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,90 +63,91 @@ 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 + // 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) - radius *= lightLinearRadiusMult; - if(lightQuadratic) - radius *= lightQuadraticRadiusMult; - - if(lightLinear) - lval = lightLinearValue / pow(radius, lightLinearMethod); - if(lightQuadratic) - qval = lightQuadraticValue / pow(radius, lightQuadraticMethod); - } - else - { - // FIXME: - // Do quadratic or linear, depending if we're in an exterior or interior - // cell, respectively. Ignore lightLinear and lightQuadratic. - } - - light->setAttenuation(10*radius, cval, lval, qval); - - insert->attachObject(light); + + if(!lightOutQuadInLin) + { + if(lightLinear) + radius *= lightLinearRadiusMult; + if(lightQuadratic) + radius *= lightQuadraticRadiusMult; + + if(lightLinear) + lval = lightLinearValue / pow(radius, lightLinearMethod); + if(lightQuadratic) + qval = lightQuadraticValue / pow(radius, lightQuadraticMethod); + } + else + { + // FIXME: + // Do quadratic or linear, depending if we're in an exterior or interior + // cell, respectively. Ignore lightLinear and lightQuadratic. + } + + light->setAttenuation(10*radius, cval, lval, qval); + + insert->attachObject(light); } bool Objects::deleteObject (const MWWorld::Ptr& ptr) @@ -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; inumChildren(); ++i) + clearSceneNode (static_cast (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& cell){ - if(mSG.find(&cell) != mSG.end()) + +void Objects::buildStaticGeometry(ESMS::CellStore& cell) +{ + if(mStaticGeometry.find(&cell) != mStaticGeometry.end()) { - Ogre::StaticGeometry* sg = mSG[&cell]; + Ogre::StaticGeometry* sg = mStaticGeometry[&cell]; sg->build(); } } diff --git a/apps/openmw/mwrender/objects.hpp b/apps/openmw/mwrender/objects.hpp index 6cd465fdd..d58455b9f 100644 --- a/apps/openmw/mwrender/objects.hpp +++ b/apps/openmw/mwrender/objects.hpp @@ -1,20 +1,21 @@ #ifndef _GAME_RENDER_OBJECTS_H #define _GAME_RENDER_OBJECTS_H -#include "components/esm_store/cell_store.hpp" +#include + +#include #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" -#include namespace MWRender{ class Objects{ - OEngine::Render::OgreRenderer &mRend; + OEngine::Render::OgreRenderer &mRenderer; std::map mCellSceneNodes; - std::map mSG; + std::map 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); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index b54cd3e43..84e40f47a 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -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 () { - mSkyManager->disable(); + if(mSkyManager) + mSkyManager->disable(); } void RenderingManager::skySetHour (double hour) { - mSkyManager->setHour(hour); + if(mSkyManager) + mSkyManager->setHour(hour); } void RenderingManager::skySetDate (int day, int month) { - mSkyManager->setDate(day, month); + if(mSkyManager) + mSkyManager->setDate(day, month); } int RenderingManager::skyGetMasserPhase() const { + return mSkyManager->getMasserPhase(); } @@ -163,9 +171,9 @@ int RenderingManager::skyGetSecundaPhase() const return mSkyManager->getSecundaPhase(); } -void RenderingManager::skySetMoonColour (bool red) -{ - mSkyManager->setMoonColour(red); +void RenderingManager::skySetMoonColour (bool red){ + if(mSkyManager) + mSkyManager->setMoonColour(red); } bool RenderingManager::toggleRenderMode(int mode) @@ -228,12 +236,15 @@ void RenderingManager::configureAmbient(ESMS::CellStore &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. diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 3ba60486b..0a84aea66 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -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 diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 07ef6e538..1a8d6a9cc 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include @@ -42,25 +44,123 @@ 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; igetNumVertices(); ++i) + { + // Get a pointer to the vertex colour + ves_diffuse->baseVertexPointerToElement( pData, ¤tVertex ); + + 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(255); + uint8 tmpG = static_cast(255); + uint8 tmpB = static_cast(255); + uint8 tmpA = static_cast(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"); @@ -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; } diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 143ce557b..079c888aa 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -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; } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 2f0d33c97..c332ebbc5 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -60,12 +60,12 @@ namespace MWWorld std::cout << "Unloading cell\n"; ListHandles functor; - MWWorld::Ptr::CellStore* active = *iter; - active->forEach(functor); + + (*iter)->forEach(functor); { @@ -77,13 +77,15 @@ 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); + + } void Scene::loadCell (Ptr::CellStore *cell) diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index a79f8ac22..f9e108f4c 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -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) diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 31e016308..a6e917961 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -228,6 +228,7 @@ namespace MWWorld /// references that are currently not in the rendered scene should be ignored. void update (float duration); + }; } diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 9e28e1534..df9079758 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -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; igetInt(); - type = nif->getInt(); + /*type =*/ nif->getInt(); std::vector current; std::vector currentTime; for(int i = 0; i < magic; i++){ diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index c62f59ea3..8b5540019 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -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 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,7 +948,8 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou { // Add this vertex set to the bounding box bounds.add(optr, numVerts); - shapes.push_back(copy); + if(saveTheShape) + shapes.push_back(copy); // Create the submesh createOgreSubMesh(shape, material, vertexBoneAssignments); @@ -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(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::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); -} + diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index 62239bb4c..794459e46 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -111,7 +111,6 @@ class NIFLoader : Ogre::ManualResourceLoader std::vector* getAnim(std::string name); std::vector* getShapes(std::string name); std::map* 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 allanim; - std::map textmappings; - std::map,ciLessBoost> alltextmappings; - std::map,ciLessBoost> allanimmap; - std::map,ciLessBoost> allshapesmap; - std::vector addin; + + std::map textmappings; + std::map,ciLessBoost> alltextmappings; + std::map,ciLessBoost> allanimmap; + std::map,ciLessBoost> allshapesmap; std::vector mAnim; - std::vector mS; + std::vector mS; + std::vector needBoneAssignments; + bool inTheSkeletonTree; + }; diff --git a/files/mac/Info.plist b/files/mac/Info.plist index 1872425e7..bc7efd075 100644 --- a/files/mac/Info.plist +++ b/files/mac/Info.plist @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 0.10 + ${OPENMW_VERSION} CSResourcesFileMapped LSRequiresCarbon diff --git a/files/plugins.cfg.linux b/files/plugins.cfg.linux index 3781f48e0..f34621a0f 100644 --- a/files/plugins.cfg.linux +++ b/files/plugins.cfg.linux @@ -7,6 +7,6 @@ PluginFolder=${OGRE_PLUGIN_DIR_REL} Plugin=RenderSystem_GL Plugin=Plugin_ParticleFX Plugin=Plugin_OctreeSceneManager -# Plugin=Plugin_CgProgramManager +Plugin=Plugin_CgProgramManager diff --git a/files/plugins.cfg.mac b/files/plugins.cfg.mac index baaca4479..0c16bddaf 100644 --- a/files/plugins.cfg.mac +++ b/files/plugins.cfg.mac @@ -7,6 +7,6 @@ PluginFolder= Plugin=RenderSystem_GL.dylib Plugin=Plugin_ParticleFX.dylib Plugin=Plugin_OctreeSceneManager.dylib -# Plugin=Plugin_CgProgramManager +Plugin=Plugin_CgProgramManager