Added demo project to research root motion
This commit is contained in:
@@ -78,6 +78,7 @@ add_subdirectory(assets/blender/buildings/parts)
|
||||
add_subdirectory(assets/blender/characters)
|
||||
add_subdirectory(resources)
|
||||
add_subdirectory(src/text_editor)
|
||||
add_subdirectory(src/features)
|
||||
|
||||
add_executable(Game Game.cpp ${WATER_SRC})
|
||||
target_include_directories(Game PRIVATE src/gamedata)
|
||||
|
||||
@@ -13,6 +13,17 @@ foreach(DIR_NAME ${DIRECTORY_LIST})
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${DIR_NAME})
|
||||
list(APPEND TARGET_PATHS ${CMAKE_CURRENT_BINARY_DIR}/${DIR_NAME})
|
||||
endforeach()
|
||||
set(COPY_FILES main/flare.png)
|
||||
set(TARGET_FILES)
|
||||
foreach(PFILE ${COPY_FILES})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PFILE}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${PFILE}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PFILE}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PFILE}
|
||||
)
|
||||
list(APPEND TARGET_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PFILE})
|
||||
endforeach()
|
||||
|
||||
#add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/terrain/world_map.png
|
||||
# COMMAND unzip -o ${CMAKE_CURRENT_SOURCE_DIR}/world_map.kra mergedimage.png -d ${CMAKE_CURRENT_BINARY_DIR}/world_map
|
||||
@@ -31,4 +42,4 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/terrain/brushes.png
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/brushes.kra)
|
||||
list(APPEND TARGET_PATHS ${CMAKE_CURRENT_BINARY_DIR}/terrain/brushes.png)
|
||||
|
||||
add_custom_target(stage_resources ALL DEPENDS ${TARGET_PATHS})
|
||||
add_custom_target(stage_resources ALL DEPENDS ${TARGET_PATHS} ${TARGET_FILES})
|
||||
|
||||
BIN
resources/main/flare.png
Normal file
BIN
resources/main/flare.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
19
resources/main/particles.material
Normal file
19
resources/main/particles.material
Normal file
@@ -0,0 +1,19 @@
|
||||
material Examples/Flare
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
lighting off
|
||||
scene_blend add
|
||||
depth_write off
|
||||
diffuse vertexcolour
|
||||
|
||||
texture_unit
|
||||
{
|
||||
texture flare.png
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3
src/features/CMakeLists.txt
Normal file
3
src/features/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
project(features)
|
||||
# ...
|
||||
add_subdirectory(characters)
|
||||
33
src/features/characters/CMakeLists.txt
Normal file
33
src/features/characters/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
project(characters)
|
||||
find_package(OGRE REQUIRED COMPONENTS Bites Paging Terrain CONFIG)
|
||||
find_package(ZLIB)
|
||||
find_package(SDL2)
|
||||
find_package(assimp REQUIRED CONFIG)
|
||||
find_package(OgreProcedural REQUIRED CONFIG)
|
||||
find_package(pugixml REQUIRED CONFIG)
|
||||
find_package(flecs REQUIRED CONFIG)
|
||||
find_package(Tracy REQUIRED CONFIG)
|
||||
add_executable(demo main.cpp TimeEvents.cpp)
|
||||
target_link_libraries(demo OgreMain OgreBites)
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/resources.cfg"
|
||||
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
add_custom_command(TARGET demo POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${CMAKE_BINARY_DIR}/resources"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/resources"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/resources/main/jaiqua.mesh"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/resources/main/jaiqua.mesh"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/resources/main/jaiqua.skeleton"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/resources/main/jaiqua.skeleton"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/resources/main/jaiqua.material"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/resources/main/jaiqua.material"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/resources/main/blue_jaiqua.jpg"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/resources/main/blue_jaiqua.jpg"
|
||||
DEPENDS "${CMAKE_BINARY_DIR}/resources"
|
||||
COMMENT "Copying generated resources from root build dir to local build dir"
|
||||
)
|
||||
|
||||
207
src/features/characters/TimeEvents.cpp
Normal file
207
src/features/characters/TimeEvents.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
//
|
||||
// TimeEvents.cpp
|
||||
// OGRE
|
||||
//
|
||||
// Created by Chilly Willy on 11/29/25.
|
||||
//
|
||||
|
||||
#include "TimeEvents.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
void TimeEventDispatcher::addEventList(const TimeEventList * list)
|
||||
{
|
||||
if (std::find(mEventLists.begin(), mEventLists.end(), list) == mEventLists.end())
|
||||
{
|
||||
mEventLists.push_back(list);
|
||||
}
|
||||
}
|
||||
|
||||
void TimeEventDispatcher::removeEventList(const TimeEventList * list)
|
||||
{
|
||||
auto i = std::find(mEventLists.begin(), mEventLists.end(), list);
|
||||
if (i != mEventLists.end())
|
||||
{
|
||||
mEventLists.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void TimeEventDispatcher::addListener(TimeEventListener * listener)
|
||||
{
|
||||
if (std::find(mListeners.begin(), mListeners.end(), listener) == mListeners.end())
|
||||
{
|
||||
mListeners.push_back(listener);
|
||||
}
|
||||
}
|
||||
|
||||
void TimeEventDispatcher::removeListener(TimeEventListener * listener)
|
||||
{
|
||||
auto i = std::find(mListeners.begin(), mListeners.end(), listener);
|
||||
if (i != mListeners.end())
|
||||
{
|
||||
mListeners.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
lastTime, thisTime, n=loops
|
||||
|
||||
lastTime is the thisTime from the last frame and thisTime will be the lastTime in the next frame.
|
||||
Events at those times should only be dispatched once so we should include one and exclude the other.
|
||||
|
||||
If we include thisTime and exclude lastTime, then we need to dispatch events before we start playing,
|
||||
eg when we call setTimePosition(), and we would need to somehow know whether it should be dispatched
|
||||
as Forward or Backward.
|
||||
|
||||
If we include lastTime and exclude thisTime, then we don't need to do anything before playing but
|
||||
we need to include the length/0 when we loop or finish, which requires special handling anyway.
|
||||
|
||||
Looping Forward:
|
||||
next lastTime
|
||||
thisTime < length thisTime lastTime <= t < thisTime
|
||||
thisTime = length 0 lastTime <= t <= length
|
||||
thisTime > length thisTime - n * length lastTime <= t <= length ... 0 <= t < thisTime
|
||||
|
||||
... 0 <= t <= length
|
||||
|
||||
Looping Backward:
|
||||
next lastTime
|
||||
thisTime > 0 thisTime lastTime >= t > thisTime
|
||||
thisTime = 0 0 !!! lastTime >= t >= 0
|
||||
thisTime < 0 thisTime + n * length lastTime >= t >= 0 ... length >= t > thisTime
|
||||
|
||||
... length >= t >= 0
|
||||
|
||||
Not-Looping Forward:
|
||||
next lastTime
|
||||
thisTime < length thisTime lastTime <= t < thisTime
|
||||
thisTime = length length lastTime <= t <= length
|
||||
thisTime > length length lastTime <= t <= length
|
||||
|
||||
|
||||
Not-Looping Backward:
|
||||
next lastTime
|
||||
thisTime > 0 thisTime lastTime >= t > thisTime
|
||||
thisTime = 0 0 lastTime >= t >= 0
|
||||
thisTime < 0 0 lastTime >= t >= 0
|
||||
|
||||
*/
|
||||
|
||||
void TimeEventDispatcher::dispatch(float lastTime, float thisTime, int loops, float length)
|
||||
{
|
||||
if ((loops > 0) || (thisTime > lastTime))
|
||||
{
|
||||
while (loops--)
|
||||
{
|
||||
dispatchForwardInclusive(lastTime, length);
|
||||
lastTime = 0.0f;
|
||||
}
|
||||
if (thisTime >= length)
|
||||
{
|
||||
dispatchForwardInclusive(lastTime, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatchForwardExclusive(lastTime, thisTime);
|
||||
}
|
||||
}
|
||||
else if ((loops < 0) || (thisTime < lastTime))
|
||||
{
|
||||
if (lastTime == 0.0f)
|
||||
{
|
||||
/* length mod length = 0 mod length
|
||||
|
||||
Either we've already been looping backward and the last frame just happened
|
||||
to stop on 0, in which case we already triggered its events, or we are just
|
||||
starting to to loop backward, in which case we should not trigger events at
|
||||
0 until we do a full backward run through the animation. If we haven't been
|
||||
looping then we would not get in here because thisTime == lastTime == 0.0f.
|
||||
For the same reason we also know loops < 0.
|
||||
*/
|
||||
lastTime = length;
|
||||
++loops;
|
||||
}
|
||||
while (loops++)
|
||||
{
|
||||
dispatchBackwardInclusive(lastTime, 0.0f);
|
||||
lastTime = length;
|
||||
}
|
||||
if (thisTime <= 0.0f)
|
||||
{
|
||||
dispatchBackwardInclusive(lastTime, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatchBackwardExclusive(lastTime, thisTime);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing doing
|
||||
}
|
||||
}
|
||||
|
||||
void TimeEventDispatcher::dispatchForwardInclusive(float lastTime, float thisTime)
|
||||
{
|
||||
for (const TimeEventList * events : mEventLists)
|
||||
{
|
||||
for (auto ie = events->begin(); ie != events->end(); ++ie)
|
||||
{
|
||||
if (ie->first >= lastTime && ie->first <= thisTime)
|
||||
{
|
||||
dispatchEvent(ie->second, TED_FORWARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimeEventDispatcher::dispatchForwardExclusive(float lastTime, float thisTime)
|
||||
{
|
||||
for (const TimeEventList * events : mEventLists)
|
||||
{
|
||||
for (auto ie = events->begin(); ie != events->end(); ++ie)
|
||||
{
|
||||
if (ie->first >= lastTime && ie->first < thisTime)
|
||||
{
|
||||
dispatchEvent(ie->second, TED_FORWARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimeEventDispatcher::dispatchBackwardInclusive(float lastTime, float thisTime)
|
||||
{
|
||||
for (const TimeEventList * events : mEventLists)
|
||||
{
|
||||
for (auto ie = events->rbegin(); ie != events->rend(); ++ie)
|
||||
{
|
||||
if (ie->first <= lastTime && ie->first >= thisTime)
|
||||
{
|
||||
dispatchEvent(ie->second, TED_BACKWARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimeEventDispatcher::dispatchBackwardExclusive(float lastTime, float thisTime)
|
||||
{
|
||||
for (const TimeEventList * events : mEventLists)
|
||||
{
|
||||
for (auto ie = events->rbegin(); ie != events->rend(); ++ie)
|
||||
{
|
||||
if (ie->first <= lastTime && ie->first > thisTime)
|
||||
{
|
||||
dispatchEvent(ie->second, TED_BACKWARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimeEventDispatcher::dispatchEvent(const std::string & name, TimeEventDirection direction)
|
||||
{
|
||||
for (TimeEventListener * listener : mListeners)
|
||||
{
|
||||
listener->eventOccurred(name, direction);
|
||||
}
|
||||
}
|
||||
58
src/features/characters/TimeEvents.h
Normal file
58
src/features/characters/TimeEvents.h
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// TimeEvents.h
|
||||
// OGRE
|
||||
//
|
||||
// Created by Chilly Willy on 11/29/25.
|
||||
//
|
||||
|
||||
#ifndef INCLUDE_OGRE_TIME_EVENTS_H
|
||||
#define INCLUDE_OGRE_TIME_EVENTS_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
typedef std::multimap<float, std::string> TimeEventList;
|
||||
|
||||
|
||||
enum TimeEventDirection
|
||||
{
|
||||
TED_FORWARD,
|
||||
TED_BACKWARD,
|
||||
};
|
||||
|
||||
|
||||
class TimeEventListener
|
||||
{
|
||||
public:
|
||||
virtual void eventOccurred(const std::string & name, TimeEventDirection direction) {}
|
||||
};
|
||||
|
||||
|
||||
class TimeEventDispatcher
|
||||
{
|
||||
public:
|
||||
void addEventList(const TimeEventList * list);
|
||||
void removeEventList(const TimeEventList * list);
|
||||
|
||||
void addListener(TimeEventListener * listener);
|
||||
void removeListener(TimeEventListener * listener);
|
||||
|
||||
void dispatch(float lastTime, float thisTime, int loops, float length);
|
||||
|
||||
private:
|
||||
void dispatchForwardInclusive(float lastTime, float thisTime);
|
||||
void dispatchForwardExclusive(float lastTime, float thisTime);
|
||||
void dispatchBackwardInclusive(float lastTime, float thisTime);
|
||||
void dispatchBackwardExclusive(float lastTime, float thisTime);
|
||||
|
||||
void dispatchEvent(const std::string & name, TimeEventDirection direction);
|
||||
|
||||
std::vector<const TimeEventList *> mEventLists;
|
||||
std::vector<TimeEventListener *> mListeners;
|
||||
};
|
||||
|
||||
|
||||
#endif /* INCLUDE_OGRE_TIME_EVENTS_H */
|
||||
1043
src/features/characters/main.cpp
Normal file
1043
src/features/characters/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
82
src/features/characters/resources.cfg
Normal file
82
src/features/characters/resources.cfg
Normal file
@@ -0,0 +1,82 @@
|
||||
# Ogre Core Resources
|
||||
[OgreInternal]
|
||||
#FileSystem=./Media/Main
|
||||
FileSystem=resources/main
|
||||
FileSystem=resources/shaderlib
|
||||
#FileSystem=./Media/RTShaderLib
|
||||
FileSystem=resources/terrain
|
||||
|
||||
# Resources required by OgreBites::Trays
|
||||
[Essential]
|
||||
#Zip=./Media/packs/SdkTrays.zip
|
||||
#Zip=./Media/packs/profiler.zip
|
||||
|
||||
## this line will end up in the [Essential] group
|
||||
#FileSystem=./Media/thumbnails
|
||||
|
||||
# Common sample resources needed by many of the samples.
|
||||
# Rarely used resources should be separately loaded by the
|
||||
# samples which require them.
|
||||
[General]
|
||||
FileSystem=skybox
|
||||
FileSystem=resources/buildings
|
||||
FileSystem=resources/buildings/parts/pier
|
||||
FileSystem=resources/buildings/parts/furniture
|
||||
FileSystem=resources/vehicles
|
||||
FileSystem=resources/debug
|
||||
FileSystem=resources/fonts
|
||||
# PBR media must come before the scripts that reference it
|
||||
#FileSystem=./Media/PBR
|
||||
#FileSystem=./Media/PBR/filament
|
||||
|
||||
#FileSystem=./Media/materials/programs/GLSL
|
||||
#FileSystem=./Media/materials/programs/GLSL120
|
||||
#FileSystem=./Media/materials/programs/GLSL150
|
||||
#FileSystem=./Media/materials/programs/GLSL400
|
||||
#FileSystem=./Media/materials/programs/GLSLES
|
||||
#FileSystem=./Media/materials/programs/SPIRV
|
||||
#FileSystem=./Media/materials/programs/Cg
|
||||
#FileSystem=./Media/materials/programs/HLSL
|
||||
#FileSystem=./Media/materials/programs/HLSL_Cg
|
||||
#FileSystem=./Media/materials/scripts
|
||||
#FileSystem=./Media/materials/textures
|
||||
#FileSystem=./Media/materials/textures/terrain
|
||||
#FileSystem=./Media/models
|
||||
#FileSystem=./Media/particle
|
||||
#FileSystem=./Media/DeferredShadingMedia
|
||||
#FileSystem=./Media/DeferredShadingMedia/DeferredShading/post
|
||||
#FileSystem=./Media/PCZAppMedia
|
||||
#FileSystem=./Media/materials/scripts/SSAO
|
||||
#FileSystem=./Media/materials/textures/SSAO
|
||||
#FileSystem=./Media/volumeTerrain
|
||||
#FileSystem=./Media/CSMShadows
|
||||
|
||||
#Zip=./Media/packs/cubemap.zip
|
||||
#Zip=./Media/packs/cubemapsJS.zip
|
||||
#Zip=./Media/packs/dragon.zip
|
||||
#Zip=./Media/packs/fresneldemo.zip
|
||||
#Zip=./Media/packs/ogredance.zip
|
||||
#Zip=./Media/packs/Sinbad.zip
|
||||
#Zip=./Media/packs/skybox.zip
|
||||
#Zip=./Media/volumeTerrain/volumeTerrainBig.zip
|
||||
|
||||
#Zip=./Media/packs/DamagedHelmet.zip
|
||||
#Zip=./Media/packs/filament_shaders.zip
|
||||
|
||||
#[BSPWorld]
|
||||
#Zip=./Media/packs/oa_rpg3dm2.pk3
|
||||
#Zip=./Media/packs/ogretestmap.zip
|
||||
|
||||
# Materials for visual tests
|
||||
#[Tests]
|
||||
#FileSystem=/media/slapin/library/ogre/ogre-sdk/Tests/Media
|
||||
[LuaScripts]
|
||||
FileSystem=lua-scripts
|
||||
|
||||
#[Characters]
|
||||
#FileSystem=./characters
|
||||
[Audio]
|
||||
FileSystem=./audio/gui
|
||||
|
||||
[Water]
|
||||
FileSystem=water
|
||||
BIN
src/features/characters/resources/main/blue_jaiqua.jpg
Normal file
BIN
src/features/characters/resources/main/blue_jaiqua.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
24
src/features/characters/resources/main/jaiqua.material
Normal file
24
src/features/characters/resources/main/jaiqua.material
Normal file
@@ -0,0 +1,24 @@
|
||||
material jaiqua
|
||||
{
|
||||
technique
|
||||
{
|
||||
pass
|
||||
{
|
||||
texture_unit
|
||||
{
|
||||
texture blue_jaiqua.jpg
|
||||
tex_address_mode clamp
|
||||
}
|
||||
|
||||
rtshader_system
|
||||
{
|
||||
// In case the system uses the RTSS, the following line will ensure
|
||||
// that hardware animation is used.
|
||||
// Alternatively, you can derive this information programatically via
|
||||
// HardwareSkinningFactory::prepareEntityForSkinning
|
||||
hardware_skinning 38 2 dual_quaternion true false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
BIN
src/features/characters/resources/main/jaiqua.mesh
Normal file
BIN
src/features/characters/resources/main/jaiqua.mesh
Normal file
Binary file not shown.
BIN
src/features/characters/resources/main/jaiqua.skeleton
Normal file
BIN
src/features/characters/resources/main/jaiqua.skeleton
Normal file
Binary file not shown.
Reference in New Issue
Block a user