Asynchronous streaming and memory management improvements in progress.
Note: This branch is unstable --HG-- branch : async_streaming
This commit is contained in:
@@ -109,6 +109,10 @@
|
||||
E461A176152E5C5600F2044A /* KRPointLight.h in Headers */ = {isa = PBXBuildFile; fileRef = E461A157152E555400F2044A /* KRPointLight.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
E461A177152E5C6600F2044A /* KRMat4.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017613C99BDC0098455B /* KRMat4.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
E461A17A152E5C9100F2044A /* KRMat4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E491017713C99BDC0098455B /* KRMat4.cpp */; };
|
||||
E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; };
|
||||
E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E468447D17FFDF51001F1FA1 /* KRLocator.cpp */; };
|
||||
E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; };
|
||||
E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E468447E17FFDF51001F1FA1 /* KRLocator.h */; };
|
||||
E46A6B6D1559E97D000DBD37 /* KRResource+blend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */; };
|
||||
E46A6B701559EF0A000DBD37 /* KRResource+blend.h in Headers */ = {isa = PBXBuildFile; fileRef = E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
E46C214515364BC8009CABF3 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E46C214215364BC8009CABF3 /* tinyxml2.cpp */; };
|
||||
@@ -438,6 +442,8 @@
|
||||
E461A15E152E565700F2044A /* KRDirectionalLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = KRDirectionalLight.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
|
||||
E461A164152E56C000F2044A /* KRSpotLight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRSpotLight.cpp; sourceTree = "<group>"; };
|
||||
E461A167152E570500F2044A /* KRSpotLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KRSpotLight.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
E468447D17FFDF51001F1FA1 /* KRLocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLocator.cpp; sourceTree = "<group>"; };
|
||||
E468447E17FFDF51001F1FA1 /* KRLocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLocator.h; sourceTree = "<group>"; };
|
||||
E46A6B6C1559E97D000DBD37 /* KRResource+blend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "KRResource+blend.cpp"; sourceTree = "<group>"; };
|
||||
E46A6B6F1559EF0A000DBD37 /* KRResource+blend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KRResource+blend.h"; sourceTree = "<group>"; };
|
||||
E46C214115364BC8009CABF3 /* tinyxml2_readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tinyxml2_readme.txt; sourceTree = "<group>"; };
|
||||
@@ -971,6 +977,8 @@
|
||||
E480BE6B1671C653004EC8AD /* KRBone.cpp */,
|
||||
E4AE635B1704FB0A00B460CD /* KRLODGroup.cpp */,
|
||||
E4AE635C1704FB0A00B460CD /* KRLODGroup.h */,
|
||||
E468447D17FFDF51001F1FA1 /* KRLocator.cpp */,
|
||||
E468447E17FFDF51001F1FA1 /* KRLocator.h */,
|
||||
);
|
||||
name = "Scene Graph Nodes";
|
||||
sourceTree = "<group>";
|
||||
@@ -1198,6 +1206,7 @@
|
||||
E461A152152E54B500F2044A /* KRLight.h in Headers */,
|
||||
E461A15C152E563100F2044A /* KRDirectionalLight.h in Headers */,
|
||||
E461A168152E570700F2044A /* KRSpotLight.h in Headers */,
|
||||
E468448117FFDF51001F1FA1 /* KRLocator.h in Headers */,
|
||||
E4F975321536220900FD60B2 /* KRNode.h in Headers */,
|
||||
E46C214715364BC8009CABF3 /* tinyxml2.h in Headers */,
|
||||
E48C696F15374F5B00232E28 /* KRContext.h in Headers */,
|
||||
@@ -1257,6 +1266,7 @@
|
||||
E497B948151BB89D00D3DC67 /* KRVector2.h in Headers */,
|
||||
E4D0683F1512A790005FFBEB /* KRVector3.h in Headers */,
|
||||
E461A177152E5C6600F2044A /* KRMat4.h in Headers */,
|
||||
E468448217FFDF51001F1FA1 /* KRLocator.h in Headers */,
|
||||
E4F975461536327C00FD60B2 /* KRMeshManager.h in Headers */,
|
||||
E497B94B151BCEE900D3DC67 /* KRResource.h in Headers */,
|
||||
E43B0AD915DDCA0F00A5CB9F /* KRContextObject.h in Headers */,
|
||||
@@ -1544,6 +1554,7 @@
|
||||
E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */,
|
||||
E461A156152E54F800F2044A /* KRLight.cpp in Sources */,
|
||||
E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */,
|
||||
E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */,
|
||||
E461A15F152E565700F2044A /* KRDirectionalLight.cpp in Sources */,
|
||||
E461A165152E56C000F2044A /* KRSpotLight.cpp in Sources */,
|
||||
E4F975361536221C00FD60B2 /* KRNode.cpp in Sources */,
|
||||
@@ -1607,6 +1618,7 @@
|
||||
E4BBBBA71512A6DC00F43B5B /* KRVector3.cpp in Sources */,
|
||||
E4B2A43B1523B02E004CB0EC /* KRMaterial.cpp in Sources */,
|
||||
E4BBBB8E1512A40300F43B5B /* krengine_osx.mm in Sources */,
|
||||
E468448017FFDF51001F1FA1 /* KRLocator.cpp in Sources */,
|
||||
E497B947151BA99500D3DC67 /* KRVector2.cpp in Sources */,
|
||||
E497B94E151BCF2500D3DC67 /* KRResource.cpp in Sources */,
|
||||
E497B951151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */,
|
||||
|
||||
@@ -85,9 +85,10 @@ bool KRAnimation::save(KRDataBlock &data) {
|
||||
|
||||
KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, KRDataBlock *data)
|
||||
{
|
||||
data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely
|
||||
std::string xml_string = data->getString();
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.Parse((char *)data->getStart());
|
||||
doc.Parse(xml_string.c_str());
|
||||
KRAnimation *new_animation = new KRAnimation(context, name);
|
||||
|
||||
tinyxml2::XMLElement *animation_node = doc.RootElement();
|
||||
|
||||
@@ -37,11 +37,13 @@ KRAnimationCurve::KRAnimationCurve(KRContext &context, const std::string &name)
|
||||
{
|
||||
m_pData = new KRDataBlock();
|
||||
m_pData->expand(sizeof(animation_curve_header));
|
||||
m_pData->lock();
|
||||
animation_curve_header *header = (animation_curve_header *)m_pData->getStart();
|
||||
strcpy(header->szTag, "KRCURVE1.0 ");
|
||||
header->frame_rate = 30.0f;
|
||||
header->frame_start = 0;
|
||||
header->frame_count = 0;
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
KRAnimationCurve::~KRAnimationCurve()
|
||||
@@ -84,11 +86,16 @@ KRAnimationCurve *KRAnimationCurve::Load(KRContext &context, const std::string &
|
||||
|
||||
int KRAnimationCurve::getFrameCount()
|
||||
{
|
||||
return ((animation_curve_header *)m_pData->getStart())->frame_count;
|
||||
m_pData->lock();
|
||||
int frame_count = ((animation_curve_header *)m_pData->getStart())->frame_count;
|
||||
m_pData->unlock();
|
||||
|
||||
return frame_count;
|
||||
}
|
||||
|
||||
void KRAnimationCurve::setFrameCount(int frame_count)
|
||||
{
|
||||
m_pData->lock();
|
||||
int prev_frame_count = getFrameCount();
|
||||
if(frame_count != prev_frame_count) {
|
||||
float fill_value = 0.0f;
|
||||
@@ -102,30 +109,42 @@ void KRAnimationCurve::setFrameCount(int frame_count)
|
||||
}
|
||||
((animation_curve_header *)m_pData->getStart())->frame_count = frame_count;
|
||||
}
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
float KRAnimationCurve::getFrameRate()
|
||||
{
|
||||
return ((animation_curve_header *)m_pData->getStart())->frame_rate;
|
||||
m_pData->lock();
|
||||
float frame_rate =((animation_curve_header *)m_pData->getStart())->frame_rate;
|
||||
m_pData->unlock();
|
||||
return frame_rate;
|
||||
}
|
||||
|
||||
void KRAnimationCurve::setFrameRate(float frame_rate)
|
||||
{
|
||||
m_pData->lock();
|
||||
((animation_curve_header *)m_pData->getStart())->frame_rate = frame_rate;
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
int KRAnimationCurve::getFrameStart()
|
||||
{
|
||||
return ((animation_curve_header *)m_pData->getStart())->frame_start;
|
||||
m_pData->lock();
|
||||
int frame_start = ((animation_curve_header *)m_pData->getStart())->frame_start;
|
||||
m_pData->unlock();
|
||||
return frame_start;
|
||||
}
|
||||
|
||||
void KRAnimationCurve::setFrameStart(int frame_number)
|
||||
{
|
||||
m_pData->lock();
|
||||
((animation_curve_header *)m_pData->getStart())->frame_start = frame_number;
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
float KRAnimationCurve::getValue(int frame_number)
|
||||
{
|
||||
m_pData->lock();
|
||||
//printf("frame_number: %i\n", frame_number);
|
||||
int clamped_frame = frame_number - getFrameStart();
|
||||
if(clamped_frame < 0) {
|
||||
@@ -134,43 +153,56 @@ float KRAnimationCurve::getValue(int frame_number)
|
||||
clamped_frame = getFrameCount()-1;
|
||||
}
|
||||
float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header));
|
||||
return frame_data[clamped_frame];
|
||||
float v = frame_data[clamped_frame];
|
||||
m_pData->unlock();
|
||||
return v;
|
||||
}
|
||||
|
||||
void KRAnimationCurve::setValue(int frame_number, float value)
|
||||
{
|
||||
m_pData->lock();
|
||||
int clamped_frame = frame_number - getFrameStart();
|
||||
if(clamped_frame >= 0 && clamped_frame < getFrameCount()) {
|
||||
float *frame_data = (float *)((char *)m_pData->getStart() + sizeof(animation_curve_header));
|
||||
frame_data[clamped_frame] = value;
|
||||
}
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
float KRAnimationCurve::getValue(float local_time)
|
||||
{
|
||||
// TODO - Need to add interpolation for time values between frames.
|
||||
// Must consider looping animations when determining which two frames to interpolate between.
|
||||
return getValue((int)(local_time * getFrameRate()));
|
||||
m_pData->lock();
|
||||
float v = getValue((int)(local_time * getFrameRate()));
|
||||
m_pData->unlock();
|
||||
return v;
|
||||
}
|
||||
|
||||
bool KRAnimationCurve::valueChanges(float start_time, float duration)
|
||||
{
|
||||
return valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate()));
|
||||
m_pData->lock();
|
||||
bool c = valueChanges((int)(start_time * getFrameRate()), (int)(duration * getFrameRate()));
|
||||
m_pData->unlock();
|
||||
return c;
|
||||
}
|
||||
|
||||
bool KRAnimationCurve::valueChanges(int start_frame, int frame_count)
|
||||
{
|
||||
|
||||
m_pData->lock();
|
||||
float first_value = getValue(start_frame);
|
||||
|
||||
bool change_found = false;
|
||||
|
||||
// Range of frames is not inclusive of last frame
|
||||
for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count; frame_number++) {
|
||||
for(int frame_number = start_frame + 1; frame_number < start_frame + frame_count && !change_found; frame_number++) {
|
||||
if(getValue(frame_number) != first_value) {
|
||||
return true;
|
||||
change_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
m_pData->unlock();
|
||||
return change_found;
|
||||
}
|
||||
|
||||
KRAnimationCurve *KRAnimationCurve::split(const std::string &name, float start_time, float duration)
|
||||
@@ -185,11 +217,13 @@ KRAnimationCurve *KRAnimationCurve::split(const std::string &name, int start_fra
|
||||
new_curve->setFrameRate(getFrameRate());
|
||||
new_curve->setFrameStart(start_frame);
|
||||
new_curve->setFrameCount(frame_count);
|
||||
new_curve->m_pData->lock();
|
||||
|
||||
// Range of frames is not inclusive of last frame
|
||||
for(int frame_number = start_frame; frame_number < start_frame + frame_count; frame_number++) {
|
||||
new_curve->setValue(frame_number, getValue(frame_number)); // TODO - MEMCPY here?
|
||||
}
|
||||
new_curve->m_pData->unlock();
|
||||
|
||||
getContext().getAnimationCurveManager()->addAnimationCurve(new_curve);
|
||||
return new_curve;
|
||||
|
||||
@@ -214,8 +214,8 @@ void KRAudioManager::renderAudio(UInt32 inNumberFrames, AudioBufferList *ioData)
|
||||
|
||||
|
||||
uint64_t end_time = mach_absolute_time();
|
||||
uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds
|
||||
uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100;
|
||||
// uint64_t duration = (end_time - start_time) * m_timebase_info.numer / m_timebase_info.denom; // Nanoseconds
|
||||
// uint64_t max_duration = (uint64_t)inNumberFrames * 1000000000 / 44100;
|
||||
// fprintf(stderr, "audio load: %5.1f%% hrtf channels: %li\n", (float)(duration * 1000 / max_duration) / 10.0f, m_mapped_sources.size());
|
||||
}
|
||||
|
||||
@@ -1364,14 +1364,14 @@ KRDataBlock *KRAudioManager::getBufferData(int size)
|
||||
data = new KRDataBlock();
|
||||
data->expand(size);
|
||||
}
|
||||
|
||||
data->lock();
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
void KRAudioManager::recycleBufferData(KRDataBlock *data)
|
||||
{
|
||||
if(data != NULL) {
|
||||
data->unlock();
|
||||
if(data->getSize() == KRENGINE_AUDIO_MAX_BUFFER_SIZE && m_bufferPoolIdle.size() < KRENGINE_AUDIO_MAX_POOL_SIZE) {
|
||||
m_bufferPoolIdle.push_back(data);
|
||||
} else {
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension) : KRResource(context, name)
|
||||
{
|
||||
m_pData = new KRDataBlock();
|
||||
m_pData->lock();
|
||||
m_extension = extension;
|
||||
|
||||
m_audio_file_id = 0;
|
||||
@@ -55,6 +56,7 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e
|
||||
KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name)
|
||||
{
|
||||
m_pData = data;
|
||||
m_pData->lock();
|
||||
m_extension = extension;
|
||||
|
||||
m_audio_file_id = 0;
|
||||
@@ -71,6 +73,7 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e
|
||||
KRAudioSample::~KRAudioSample()
|
||||
{
|
||||
closeFile();
|
||||
m_pData->unlock();
|
||||
delete m_pData;
|
||||
}
|
||||
|
||||
@@ -198,7 +201,8 @@ OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc
|
||||
KRAudioSample *sound = (KRAudioSample *)inClientData;
|
||||
UInt32 max_count = sound->m_pData->getSize() - inPosition;
|
||||
*actualCount = requestCount < max_count ? requestCount : max_count;
|
||||
memcpy(buffer, (unsigned char *)sound->m_pData->getStart() + inPosition, *actualCount);
|
||||
sound->m_pData->copy(buffer, inPosition, *actualCount);
|
||||
//memcpy(buffer, (unsigned char *)sound->m_pData->getStart() + inPosition, *actualCount);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
@@ -231,6 +235,7 @@ void KRAudioSample::openFile()
|
||||
{
|
||||
// AudioFileInitializeWithCallbacks
|
||||
if(m_fileRef == NULL) {
|
||||
|
||||
// Temp variables
|
||||
UInt32 propertySize;
|
||||
|
||||
|
||||
@@ -53,35 +53,18 @@ KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : K
|
||||
{
|
||||
m_pData = pData;
|
||||
|
||||
unsigned char *pFile = (unsigned char *)m_pData->getStart();
|
||||
while(pFile < m_pData->getEnd() ) {
|
||||
tar_header_type *file_header = (tar_header_type *)pFile;
|
||||
size_t file_size = strtol(file_header->file_size, NULL, 8);
|
||||
pFile += 512; // Skip past the header to the file contents
|
||||
|
||||
if(file_header->file_name[0] != '\0' && file_header->file_name[0] != '.') {
|
||||
__int64_t file_pos = 0;
|
||||
while(file_pos < m_pData->getSize()) {
|
||||
tar_header_type file_header;
|
||||
m_pData->copy(&file_header, file_pos, sizeof(file_header));
|
||||
size_t file_size = strtol(file_header.file_size, NULL, 8);
|
||||
file_pos += 512; // Skip past the header to the file contents
|
||||
if(file_header.file_name[0] != '\0' && file_header.file_name[0] != '.') {
|
||||
// We ignore the last two records in the tar file, which are zero'ed out tar_header structures
|
||||
KRDataBlock *pFileData = new KRDataBlock();
|
||||
if(pFileData->load(pFile, file_size)) {
|
||||
context.loadResource(file_header->file_name, pFileData);
|
||||
} else {
|
||||
delete pFileData;
|
||||
assert(false);
|
||||
KRDataBlock *pFileData = pData->getSubBlock(file_pos, file_size);
|
||||
context.loadResource(file_header.file_name, pFileData);
|
||||
}
|
||||
}
|
||||
|
||||
// Advance past the end of the file
|
||||
/*
|
||||
if((file_size & 0x01ff) == 0) {
|
||||
// file size is a multiple of 512 bytes, we can just add it
|
||||
pFile += file_size;
|
||||
} else {
|
||||
// We would not be on a 512 byte boundary, round up to the next one
|
||||
pFile += (file_size + 0x0200) - (file_size & 0x1ff);
|
||||
}
|
||||
*/
|
||||
pFile += RoundUpSize(file_size);
|
||||
|
||||
file_pos += RoundUpSize(file_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +73,9 @@ KRBundle::KRBundle(KRContext &context, std::string name) : KRResource(context, n
|
||||
// Create an empty krbundle (tar) file, initialized with two zero-ed out file headers, which terminate it.
|
||||
m_pData = new KRDataBlock();
|
||||
m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE * 2);
|
||||
m_pData->lock();
|
||||
memset(m_pData->getStart(), 0, m_pData->getSize());
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
size_t KRBundle::RoundUpSize(size_t s)
|
||||
@@ -142,6 +127,8 @@ void KRBundle::append(KRResource &resource)
|
||||
|
||||
m_pData->expand(KRENGINE_KRBUNDLE_HEADER_SIZE + resource_data.getSize() + padding_size - KRENGINE_KRBUNDLE_HEADER_SIZE * 2); // We will overwrite the existing zero-ed out file headers that marked the end of the archive, so we don't have to include their size here
|
||||
|
||||
m_pData->lock();
|
||||
|
||||
// Get location of file header
|
||||
tar_header_type *file_header = (tar_header_type *)((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize() - KRENGINE_KRBUNDLE_HEADER_SIZE);
|
||||
|
||||
@@ -149,7 +136,9 @@ void KRBundle::append(KRResource &resource)
|
||||
memset(file_header, 0, KRENGINE_KRBUNDLE_HEADER_SIZE);
|
||||
|
||||
// Copy resource data
|
||||
resource_data.lock();
|
||||
memcpy((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize(), resource_data.getStart(), resource_data.getSize());
|
||||
resource_data.unlock();
|
||||
|
||||
// Zero out alignment padding and terminating set of file header blocks
|
||||
memset((unsigned char *)m_pData->getEnd() - padding_size, 0, padding_size);
|
||||
@@ -172,4 +161,6 @@ void KRBundle::append(KRResource &resource)
|
||||
check_sum += byte_ptr[i];
|
||||
}
|
||||
sprintf(file_header->checksum, "%07o", check_sum);
|
||||
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
@@ -30,12 +30,18 @@
|
||||
//
|
||||
|
||||
#include "KRDataBlock.h"
|
||||
#include "KREngine-common.h"
|
||||
|
||||
KRDataBlock::KRDataBlock() {
|
||||
m_data = NULL;
|
||||
m_data_size = 0;
|
||||
m_data_offset = 0;
|
||||
m_fdPackFile = 0;
|
||||
m_mmapData = NULL;
|
||||
m_fileOwnerDataBlock = NULL;
|
||||
m_bMalloced = false;
|
||||
m_lockCount = 0;
|
||||
m_bReadOnly = false;
|
||||
}
|
||||
|
||||
KRDataBlock::~KRDataBlock() {
|
||||
@@ -45,10 +51,13 @@ KRDataBlock::~KRDataBlock() {
|
||||
// Unload a file, releasing any mmap'ed file handles or malloc'ed ram that was in use
|
||||
void KRDataBlock::unload()
|
||||
{
|
||||
assert(m_lockCount == 0);
|
||||
|
||||
if(m_fdPackFile) {
|
||||
// Memory mapped file
|
||||
munmap(m_data, m_data_size);
|
||||
if(m_fileOwnerDataBlock == this) {
|
||||
close(m_fdPackFile);
|
||||
}
|
||||
} else if(m_data != NULL && m_bMalloced) {
|
||||
// Malloc'ed data
|
||||
free(m_data);
|
||||
@@ -57,7 +66,11 @@ void KRDataBlock::unload()
|
||||
m_bMalloced = false;
|
||||
m_data = NULL;
|
||||
m_data_size = 0;
|
||||
m_data_offset = 0;
|
||||
m_fdPackFile = 0;
|
||||
m_mmapData = NULL;
|
||||
m_fileOwnerDataBlock = NULL;
|
||||
m_bReadOnly = false;
|
||||
}
|
||||
|
||||
// Encapsulate a pointer. Note - The pointer will not be free'ed
|
||||
@@ -66,6 +79,8 @@ bool KRDataBlock::load(void *data, size_t size)
|
||||
unload();
|
||||
m_data = data;
|
||||
m_data_size = size;
|
||||
m_data_offset = 0;
|
||||
m_bReadOnly = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -76,16 +91,16 @@ bool KRDataBlock::load(const std::string &path)
|
||||
unload();
|
||||
|
||||
struct stat statbuf;
|
||||
m_bReadOnly = true;
|
||||
m_fdPackFile = open(path.c_str(), O_RDONLY);
|
||||
if(m_fdPackFile >= 0) {
|
||||
m_fileOwnerDataBlock = this;
|
||||
if(fstat(m_fdPackFile, &statbuf) >= 0) {
|
||||
if ((m_data = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, m_fdPackFile, 0)) == (caddr_t) -1) {
|
||||
} else {
|
||||
m_data_size = statbuf.st_size;
|
||||
m_data_offset = 0;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!success) {
|
||||
// If anything failed, don't leave the object in an invalid state
|
||||
unload();
|
||||
@@ -93,13 +108,32 @@ bool KRDataBlock::load(const std::string &path)
|
||||
return success;
|
||||
}
|
||||
|
||||
// Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object.
|
||||
KRDataBlock *KRDataBlock::getSubBlock(int start, int length)
|
||||
{
|
||||
KRDataBlock *new_block = new KRDataBlock();
|
||||
|
||||
new_block->m_data_size = length;
|
||||
if(m_fdPackFile) {
|
||||
new_block->m_fdPackFile = m_fdPackFile;
|
||||
new_block->m_fileOwnerDataBlock = m_fileOwnerDataBlock;
|
||||
new_block->m_data_offset = start;
|
||||
} else if(m_bMalloced) {
|
||||
new_block->m_data = (unsigned char *)m_data + start;
|
||||
}
|
||||
new_block->m_bReadOnly = true;
|
||||
return new_block;
|
||||
}
|
||||
|
||||
// Return a pointer to the start of the data block
|
||||
void *KRDataBlock::getStart() {
|
||||
assertLocked();
|
||||
return m_data;
|
||||
}
|
||||
|
||||
// Return a pointer to the byte after the end of the data block
|
||||
void *KRDataBlock::getEnd() {
|
||||
assertLocked();
|
||||
return (unsigned char *)m_data + m_data_size;
|
||||
}
|
||||
|
||||
@@ -111,28 +145,33 @@ size_t KRDataBlock::getSize() const {
|
||||
// Expand the data block, and switch it to read-write mode. Note - this may result in a mmap'ed file being copied to malloc'ed ram and then closed
|
||||
void KRDataBlock::expand(size_t size)
|
||||
{
|
||||
if(m_data == NULL) {
|
||||
if(m_data == NULL && m_fdPackFile == 0) {
|
||||
// Starting with an empty data block; allocate memory on the heap
|
||||
m_data = malloc(size);
|
||||
assert(m_data != NULL);
|
||||
m_data_size = size;
|
||||
m_data_offset = 0;
|
||||
m_bMalloced = true;
|
||||
} else if(m_bMalloced) {
|
||||
// Starting with a malloc'ed data block; realloc it expand
|
||||
m_data = realloc(m_data, m_data_size + size);
|
||||
m_data_size += size;
|
||||
} else {
|
||||
// Starting with a mmap'ed data block; copy it to ram before expanding to avoid updating the original file until save() is called
|
||||
// Starting with a mmap'ed data block, an encapsulated pointer, or a sub-block; copy it to ram before expanding to avoid updating the original file until save() is called
|
||||
// ... Or starting with a pointer reference, we must make our own copy and must not free the pointer
|
||||
void *pNewData = malloc(m_data_size + size);
|
||||
assert(pNewData != NULL);
|
||||
memcpy((unsigned char *)pNewData, m_data, m_data_size); // Copy exising data
|
||||
|
||||
// Copy exising data
|
||||
copy(pNewData);
|
||||
|
||||
// Unload existing data allocation, which is now redundant
|
||||
size_t new_size = m_data_size + size; // We need to store this before unload() as unload() will reset it
|
||||
unload();
|
||||
m_bMalloced = true;
|
||||
m_data = pNewData;
|
||||
m_data_size = new_size;
|
||||
m_data_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,12 +181,31 @@ void KRDataBlock::append(void *data, size_t size) {
|
||||
expand(size);
|
||||
|
||||
// Fill the new space with the data to append
|
||||
lock();
|
||||
memcpy((unsigned char *)m_data + m_data_size - size, data, size);
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
// Copy the entire data block to the destination pointer
|
||||
void KRDataBlock::copy(void *dest) {
|
||||
lock();
|
||||
memcpy((unsigned char *)dest, m_data, m_data_size);
|
||||
unlock();
|
||||
}
|
||||
|
||||
// Copy a range of data to the destination pointer
|
||||
void KRDataBlock::copy(void *dest, int start, int count) {
|
||||
lock();
|
||||
memcpy((unsigned char *)dest, (unsigned char *)m_data + start, count);
|
||||
unlock();
|
||||
}
|
||||
|
||||
// Append data to the end of the block, increasing the size of the block and making it read-write.
|
||||
void KRDataBlock::append(KRDataBlock &data) {
|
||||
data.lock();
|
||||
append(data.getStart(), data.getSize());
|
||||
data.unlock();
|
||||
}
|
||||
|
||||
// Append string to the end of the block, increasing the size of the block and making it read-write. The null terminating character is included
|
||||
@@ -157,7 +215,7 @@ void KRDataBlock::append(const std::string &s)
|
||||
append((void *)szText, strlen(szText)+1);
|
||||
}
|
||||
|
||||
// Save the data to a file, and switch to read-only mode. The data pointer will be replaced with a mmap'ed address of the file; the malloc'ed data will be freed
|
||||
// Save the data to a file.
|
||||
bool KRDataBlock::save(const std::string& path) {
|
||||
int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
|
||||
if(fdNewFile == -1) {
|
||||
@@ -173,20 +231,16 @@ bool KRDataBlock::save(const std::string& path) {
|
||||
close(fdNewFile);
|
||||
return false;
|
||||
} else if(m_data != NULL) {
|
||||
|
||||
|
||||
// Copy data to new file
|
||||
memcpy(pNewData, m_data, m_data_size);
|
||||
copy(pNewData);
|
||||
|
||||
// Unload existing data allocation, which is now redundant
|
||||
size_t new_size = m_data_size; // We need to store this, as unload() will reset it
|
||||
unload();
|
||||
// Unmap the new file
|
||||
munmap(pNewData, m_data_size);
|
||||
|
||||
// Protect new mmap'ed memory
|
||||
mprotect(pNewData, m_data_size, PROT_READ);
|
||||
|
||||
// Switch pointer to use new mmap'ed memory
|
||||
m_data_size = new_size;
|
||||
m_fdPackFile = fdNewFile;
|
||||
m_data = pNewData;
|
||||
// Close the new file
|
||||
close(fdNewFile);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -195,8 +249,57 @@ bool KRDataBlock::save(const std::string& path) {
|
||||
// Get contents as a string
|
||||
std::string KRDataBlock::getString()
|
||||
{
|
||||
lock();
|
||||
KRDataBlock b;
|
||||
b.append(*this);
|
||||
b.append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely
|
||||
return std::string((char *)b.getStart());
|
||||
b.lock();
|
||||
std::string ret = std::string((char *)b.getStart());
|
||||
b.unlock();
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Lock the memory, forcing it to be loaded into a contiguous block of address space
|
||||
void KRDataBlock::lock()
|
||||
{
|
||||
m_lockCount++;
|
||||
if(m_lockCount == 1) {
|
||||
|
||||
// Memory mapped file; ensure data is mapped to ram
|
||||
if(m_fdPackFile) {
|
||||
// Round m_data_offset down to the next memory page, as required by mmap
|
||||
size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1);
|
||||
if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) {
|
||||
assert(false); // mmap() failed.
|
||||
}
|
||||
m_data = (unsigned char *)m_mmapData + alignment_offset;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock the memory, releasing the address space for use by other allocations
|
||||
void KRDataBlock::unlock()
|
||||
{
|
||||
// We expect that the data block was previously locked
|
||||
assertLocked();
|
||||
|
||||
m_lockCount--;
|
||||
if(m_lockCount == 0) {
|
||||
|
||||
// Memory mapped file; ensure data is unmapped from ram
|
||||
if(m_fdPackFile) {
|
||||
munmap(m_mmapData, m_data_size);
|
||||
m_data = NULL;
|
||||
m_mmapData = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Assert if not locked
|
||||
void KRDataBlock::assertLocked()
|
||||
{
|
||||
assert(m_lockCount > 0);
|
||||
}
|
||||
|
||||
@@ -45,9 +45,12 @@ public:
|
||||
// Load a file into memory using mmap. The data pointer will be protected as read-only until append() or expand() is called
|
||||
bool load(const std::string &path);
|
||||
|
||||
// Save the data to a file, and switch to read-only mode. The data pointer will be replaced with a mmap'ed address of the file; the malloc'ed data will be freed
|
||||
// Save the data to a file.
|
||||
bool save(const std::string& path);
|
||||
|
||||
// Create a KRDataBlock encapsulating a sub-region of this block. The caller is responsible to free the object.
|
||||
KRDataBlock *getSubBlock(int start, int length);
|
||||
|
||||
// Append data to the end of the block, increasing the size of the block and making it read-write.
|
||||
void append(void *data, size_t size);
|
||||
|
||||
@@ -74,15 +77,40 @@ public:
|
||||
|
||||
// Get the contents as a string
|
||||
std::string getString();
|
||||
|
||||
// Copy the entire data block to the destination pointer
|
||||
void copy(void *dest);
|
||||
|
||||
// Copy a range of data to the destination pointer
|
||||
void copy(void *dest, int start, int count);
|
||||
|
||||
// Lock the memory, forcing it to be loaded into a contiguous block of address space
|
||||
void lock();
|
||||
|
||||
// Unlock the memory, releasing the address space for use by other allocations
|
||||
void unlock();
|
||||
|
||||
private:
|
||||
void *m_data;
|
||||
size_t m_data_size;
|
||||
size_t m_data_offset;
|
||||
|
||||
// For memory mapped objects:
|
||||
int m_fdPackFile;
|
||||
KRDataBlock *m_fileOwnerDataBlock;
|
||||
void *m_mmapData;
|
||||
|
||||
// For malloc'ed objects:
|
||||
bool m_bMalloced;
|
||||
|
||||
// Lock refcount
|
||||
int m_lockCount;
|
||||
|
||||
// Read-only allocation
|
||||
bool m_bReadOnly;
|
||||
|
||||
// Assert if not locked
|
||||
void assertLocked();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#ifndef KRENGINE_COMMON_H
|
||||
#define KRENGINE_COMMON_H
|
||||
|
||||
#define KRAKEN_MEM_PAGE_SIZE 4096
|
||||
#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) (x & ~(KRAKEN_MEM_PAGE_SIZE - 1))
|
||||
#define KRENGINE_MAX_TEXTURE_UNITS 8
|
||||
|
||||
float const PI = 3.141592653589793f;
|
||||
|
||||
35
KREngine/kraken/KRLocator.cpp
Normal file
35
KREngine/kraken/KRLocator.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// KRLocator.cpp
|
||||
// KREngine
|
||||
//
|
||||
// Created by Kearwood Gilbert on 2012-12-06.
|
||||
// Copyright (c) 2012 Kearwood Software. All rights reserved.
|
||||
//
|
||||
|
||||
#include "KRLocator.h"
|
||||
#include "KRContext.h"
|
||||
|
||||
KRLocator::KRLocator(KRScene &scene, std::string name) : KRNode(scene, name)
|
||||
{
|
||||
setScaleCompensation(true);
|
||||
}
|
||||
|
||||
KRLocator::~KRLocator()
|
||||
{
|
||||
}
|
||||
|
||||
std::string KRLocator::getElementName() {
|
||||
return "locator";
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement *KRLocator::saveXML( tinyxml2::XMLNode *parent)
|
||||
{
|
||||
tinyxml2::XMLElement *e = KRNode::saveXML(parent);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void KRLocator::loadXML(tinyxml2::XMLElement *e)
|
||||
{
|
||||
KRNode::loadXML(e);
|
||||
}
|
||||
27
KREngine/kraken/KRLocator.h
Normal file
27
KREngine/kraken/KRLocator.h
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// KRLocator
|
||||
// KREngine
|
||||
//
|
||||
// Created by Kearwood Gilbert on 2012-12-06.
|
||||
// Copyright (c) 2012 Kearwood Software. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef KRLOCATOR_H
|
||||
#define KRLOCATOR_H
|
||||
|
||||
#include "KRResource.h"
|
||||
#include "KRNode.h"
|
||||
#include "KRTexture.h"
|
||||
|
||||
class KRLocator : public KRNode {
|
||||
public:
|
||||
KRLocator(KRScene &scene, std::string name);
|
||||
virtual ~KRLocator();
|
||||
virtual std::string getElementName();
|
||||
virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent);
|
||||
virtual void loadXML(tinyxml2::XMLElement *e);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -100,7 +100,7 @@ void KRMaterialManager::add(KRMaterial *new_material) {
|
||||
bool KRMaterialManager::load(const char *szName, KRDataBlock *data) {
|
||||
KRMaterial *pMaterial = NULL;
|
||||
char szSymbol[16][256];
|
||||
|
||||
data->lock();
|
||||
|
||||
char *pScan = (char *)data->getStart();
|
||||
char *pEnd = (char *)data->getEnd();
|
||||
@@ -282,7 +282,7 @@ bool KRMaterialManager::load(const char *szName, KRDataBlock *data) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data->unlock();
|
||||
delete data;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ KRMesh::KRMesh(KRContext &context, std::string name) : KRResource(context, name)
|
||||
m_materials.clear();
|
||||
m_uniqueMaterials.clear();
|
||||
m_pData = new KRDataBlock();
|
||||
m_pData->lock();
|
||||
setName(name);
|
||||
}
|
||||
|
||||
@@ -54,6 +55,7 @@ KRMesh::KRMesh(KRContext &context, std::string name, KRDataBlock *data) : KRReso
|
||||
m_materials.clear();
|
||||
m_uniqueMaterials.clear();
|
||||
m_pData = new KRDataBlock();
|
||||
m_pData->lock();
|
||||
setName(name);
|
||||
|
||||
loadPack(data);
|
||||
@@ -104,6 +106,7 @@ int KRMesh::GetLODCoverage(const std::string &name)
|
||||
|
||||
KRMesh::~KRMesh() {
|
||||
clearData();
|
||||
m_pData->unlock();
|
||||
if(m_pData) delete m_pData;
|
||||
}
|
||||
|
||||
@@ -124,8 +127,10 @@ bool KRMesh::save(KRDataBlock &data) {
|
||||
|
||||
void KRMesh::loadPack(KRDataBlock *data) {
|
||||
clearData();
|
||||
m_pData->unlock();
|
||||
delete m_pData;
|
||||
m_pData = data;
|
||||
m_pData->lock();
|
||||
updateAttributeOffsets();
|
||||
pack_header *pHeader = getHeader();
|
||||
m_minPoint = KRVector3(pHeader->minx, pHeader->miny, pHeader->minz);
|
||||
@@ -134,6 +139,8 @@ void KRMesh::loadPack(KRDataBlock *data) {
|
||||
|
||||
void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector<KRBone *> &bones) {
|
||||
|
||||
m_pData->lock();
|
||||
|
||||
//fprintf(stderr, "Rendering model: %s\n", m_name.c_str());
|
||||
if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {
|
||||
getSubmeshes();
|
||||
@@ -214,6 +221,8 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
GLfloat KRMesh::getMaxDimension() {
|
||||
@@ -429,8 +438,9 @@ void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector<std:
|
||||
size_t vertex_count = mi.vertices.size();
|
||||
size_t bone_count = mi.bone_names.size();
|
||||
size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + sizeof(pack_bone) * bone_count + KRALIGN(2 * index_count) + KRALIGN(8 * index_base_count) + vertex_size * vertex_count;
|
||||
|
||||
m_pData->unlock();
|
||||
m_pData->expand(new_file_size);
|
||||
m_pData->lock();
|
||||
|
||||
pack_header *pHeader = getHeader();
|
||||
memset(pHeader, 0, sizeof(pack_header));
|
||||
@@ -586,7 +596,9 @@ KRVector3 KRMesh::getMaxPoint() const {
|
||||
}
|
||||
|
||||
void KRMesh::clearData() {
|
||||
m_pData->unlock();
|
||||
m_pData->unload();
|
||||
m_pData->lock();
|
||||
}
|
||||
|
||||
void KRMesh::clearBuffers() {
|
||||
@@ -892,8 +904,11 @@ size_t KRMesh::AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_
|
||||
|
||||
int KRMesh::getBoneCount()
|
||||
{
|
||||
m_pData->lock();
|
||||
pack_header *header = getHeader();
|
||||
return header->bone_count;
|
||||
int bone_count = header->bone_count;
|
||||
m_pData->unlock();
|
||||
return bone_count;
|
||||
}
|
||||
|
||||
char *KRMesh::getBoneName(int bone_index)
|
||||
@@ -908,7 +923,10 @@ KRMat4 KRMesh::getBoneBindPose(int bone_index)
|
||||
|
||||
KRMesh::model_format_t KRMesh::getModelFormat() const
|
||||
{
|
||||
return (model_format_t)getHeader()->model_format;
|
||||
m_pData->lock();
|
||||
model_format_t f = (model_format_t)getHeader()->model_format;
|
||||
m_pData->unlock();
|
||||
return f;
|
||||
}
|
||||
|
||||
bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, const KRVector3 &tri_v0, const KRVector3 &tri_v1, const KRVector3 &tri_v2, const KRVector3 &tri_n0, const KRVector3 &tri_n1, const KRVector3 &tri_n2, KRHitInfo &hitinfo)
|
||||
@@ -1055,7 +1073,7 @@ bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitin
|
||||
|
||||
void KRMesh::convertToIndexed()
|
||||
{
|
||||
|
||||
m_pData->lock();
|
||||
char *szKey = new char[m_vertex_size * 2 + 1];
|
||||
|
||||
// Convert model to indexed vertices, identying vertexes with identical attributes and optimizing order of trianges for best usage post-vertex-transform cache on GPU
|
||||
@@ -1230,6 +1248,8 @@ void KRMesh::convertToIndexed()
|
||||
|
||||
|
||||
mi.format = KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES;
|
||||
|
||||
m_pData->unlock();
|
||||
LoadData(mi, false, false);
|
||||
}
|
||||
|
||||
@@ -1284,7 +1304,8 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const
|
||||
|
||||
void KRMesh::optimizeIndexes()
|
||||
{
|
||||
if(getModelFormat() != KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) return;
|
||||
m_pData->lock();
|
||||
if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) {
|
||||
|
||||
__uint16_t *new_indices = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t));
|
||||
__uint16_t *vertex_mapping = (__uint16_t *)malloc(0x10000 * sizeof(__uint16_t));
|
||||
@@ -1365,4 +1386,7 @@ void KRMesh::optimizeIndexes()
|
||||
free(new_indices);
|
||||
free(vertex_mapping);
|
||||
free(new_vertex_data);
|
||||
} // if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES)
|
||||
|
||||
m_pData->unlock();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "KRAABB.h"
|
||||
#include "KRQuaternion.h"
|
||||
#include "KRBone.h"
|
||||
#include "KRLocator.h"
|
||||
#include "KRAudioSource.h"
|
||||
#include "KRAmbientZone.h"
|
||||
#include "KRReverbZone.h"
|
||||
@@ -421,6 +422,8 @@ KRNode *KRNode::LoadXML(KRScene &scene, tinyxml2::XMLElement *e) {
|
||||
new_node = new KRCollider(scene, szName, e->Attribute("mesh"), 65535, 1.0f);
|
||||
} else if(strcmp(szElementName, "bone") == 0) {
|
||||
new_node = new KRBone(scene, szName);
|
||||
} else if(strcmp(szElementName, "locator") == 0) {
|
||||
new_node = new KRLocator(scene, szName);
|
||||
} else if(strcmp(szElementName, "audio_source") == 0) {
|
||||
new_node = new KRAudioSource(scene, szName);
|
||||
} else if(strcmp(szElementName, "ambient_zone") == 0) {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "KRScene.h"
|
||||
#include "KRQuaternion.h"
|
||||
#include "KRBone.h"
|
||||
#include "KRLocator.h"
|
||||
#include "KRBundle.h"
|
||||
#include "KRModel.h"
|
||||
#include "KRLODGroup.h"
|
||||
@@ -46,6 +47,7 @@ void LoadMesh(KRContext &context, KFbxScene* pFbxScene, FbxGeometryConverter *pG
|
||||
KRNode *LoadMesh(KRNode *parent_node, KFbxScene* pFbxScene, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
|
||||
KRNode *LoadLight(KRNode *parent_node, KFbxNode* pNode);
|
||||
KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode);
|
||||
KRNode *LoadLocator(KRNode *parent_node, FbxScene* pScene, KFbxNode* pNode);
|
||||
KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode);
|
||||
std::string GetFbxObjectName(FbxObject *obj);
|
||||
|
||||
@@ -54,9 +56,25 @@ const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f; // FINDME - This should be c
|
||||
|
||||
std::string GetFbxObjectName(FbxObject *obj)
|
||||
{
|
||||
bool is_locator = false;
|
||||
KFbxNode *node = FbxCast<KFbxNode>(obj);
|
||||
if(node) {
|
||||
KFbxNodeAttribute::EType attribute_type = (node->GetNodeAttribute()->GetAttributeType());
|
||||
if(attribute_type == KFbxNodeAttribute::eNull) {
|
||||
KFbxNull* pSourceNull = (KFbxNull*) node->GetNodeAttribute();
|
||||
if(pSourceNull->Look.Get() == KFbxNull::eCross ) {
|
||||
is_locator = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Object names from FBX files are now concatenated with the FBX numerical ID to ensure that they are unique
|
||||
// TODO - This should be updated to only add a prefix or suffix if needed to make the name unique
|
||||
if(strcmp(obj->GetName(), "default_camera") == 0) {
|
||||
if(is_locator) {
|
||||
// We do not rename locators
|
||||
return std::string(obj->GetName());
|
||||
} else if(strcmp(obj->GetName(), "default_camera") == 0) {
|
||||
// There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera
|
||||
return "default_camera";
|
||||
} else {
|
||||
@@ -955,37 +973,27 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
|
||||
case KFbxNodeAttribute::eSkeleton:
|
||||
new_node = LoadSkeleton(parent_node, pFbxScene, pNode);
|
||||
break;
|
||||
|
||||
case KFbxNodeAttribute::eCamera:
|
||||
new_node = LoadCamera(parent_node, pNode);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
bool is_locator = false;
|
||||
if(attribute_type == KFbxNodeAttribute::eNull) {
|
||||
KFbxNull* pSourceNull = (KFbxNull*) pNode->GetNodeAttribute();
|
||||
if(pSourceNull->Look.Get() == KFbxNull::eCross ) {
|
||||
is_locator = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_locator) {
|
||||
new_node = LoadLocator(parent_node, pFbxScene, pNode);
|
||||
} else {
|
||||
if(pNode->GetChildCount() > 0) {
|
||||
// Create an empty node, for inheritence of transforms
|
||||
std::string name = GetFbxObjectName(pNode);
|
||||
|
||||
float min_distance = 0.0f;
|
||||
float max_distance = 0.0f;
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > char_tokenizer;
|
||||
|
||||
int step = 0;
|
||||
|
||||
char_tokenizer name_components(name, boost::char_separator<char>("_"));
|
||||
for(char_tokenizer::iterator itr=name_components.begin(); itr != name_components.end(); itr++) {
|
||||
std::string component = *itr;
|
||||
std::transform(component.begin(), component.end(),
|
||||
component.begin(), ::tolower);
|
||||
if(component.compare("lod") == 0) {
|
||||
step = 1;
|
||||
} else if(step == 1) {
|
||||
min_distance = boost::lexical_cast<float>(component);
|
||||
step++;
|
||||
} else if(step == 2) {
|
||||
max_distance = boost::lexical_cast<float>(component);
|
||||
step++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if(min_distance == 0.0f && max_distance == 0.0f) {
|
||||
@@ -995,14 +1003,10 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, FbxGeometryConverter *p
|
||||
*/
|
||||
// LOD Enabled group node
|
||||
KRLODGroup *lod_group = new KRLODGroup(parent_node->getScene(), name);
|
||||
lod_group->setMinDistance(min_distance);
|
||||
lod_group->setMaxDistance(max_distance);
|
||||
lod_group->setMinDistance(0.0f);
|
||||
lod_group->setMaxDistance(0.0f);
|
||||
new_node = lod_group;
|
||||
/*
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1526,6 +1530,21 @@ KRNode *LoadSkeleton(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode)
|
||||
return new_bone;
|
||||
}
|
||||
|
||||
KRNode *LoadLocator(KRNode *parent_node, FbxScene* pFbxScene, KFbxNode* pNode) {
|
||||
std::string name = GetFbxObjectName(pNode);
|
||||
|
||||
KRLocator *new_locator = new KRLocator(parent_node->getScene(), name.c_str());
|
||||
|
||||
//static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray<int>& pIndex);
|
||||
// PoseList pose_list;
|
||||
// FbxArray<int> pose_indices;
|
||||
// if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) {
|
||||
// fprintf(stderr, "Found bind pose(s)!\n");
|
||||
// }
|
||||
|
||||
return new_locator;
|
||||
}
|
||||
|
||||
KRNode *LoadCamera(KRNode *parent_node, KFbxNode* pNode) {
|
||||
FbxCamera *camera = (FbxCamera *)pNode->GetNodeAttribute();
|
||||
const char *szName = pNode->GetName();
|
||||
|
||||
@@ -406,7 +406,9 @@ KRScene *KRScene::Load(KRContext &context, const std::string &name, KRDataBlock
|
||||
{
|
||||
data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely
|
||||
tinyxml2::XMLDocument doc;
|
||||
data->lock();
|
||||
doc.Parse((char *)data->getStart());
|
||||
data->unlock();
|
||||
KRScene *new_scene = new KRScene(context, name);
|
||||
|
||||
tinyxml2::XMLElement *scene_element = doc.RootElement();
|
||||
|
||||
@@ -254,12 +254,12 @@ bool KRShaderManager::selectShader(KRCamera &camera, KRShader *pShader, const KR
|
||||
}
|
||||
|
||||
void KRShaderManager::loadFragmentShader(const std::string &name, KRDataBlock *data) {
|
||||
m_fragShaderSource[name] = string((char *)data->getStart(), data->getSize());
|
||||
m_fragShaderSource[name] = data->getString();
|
||||
delete data;
|
||||
}
|
||||
|
||||
void KRShaderManager::loadVertexShader(const std::string &name, KRDataBlock *data) {
|
||||
m_vertShaderSource[name] = string((char *)data->getStart(), data->getSize());
|
||||
m_vertShaderSource[name] = data->getString();
|
||||
delete data;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,9 +36,11 @@
|
||||
KRTexture2D::KRTexture2D(KRContext &context, KRDataBlock *data, std::string name) : KRTexture(context, name) {
|
||||
m_current_lod_max_dim = 0;
|
||||
m_pData = data;
|
||||
m_pData->lock();
|
||||
}
|
||||
|
||||
KRTexture2D::~KRTexture2D() {
|
||||
m_pData->unlock();
|
||||
delete m_pData;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ typedef struct _PVRTexHeader
|
||||
|
||||
KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) {
|
||||
#if TARGET_OS_IPHONE
|
||||
m_pData->lock();
|
||||
PVRTexHeader *header = (PVRTexHeader *)m_pData->getStart();
|
||||
uint32_t formatFlags = header->flags & PVR_TEXTURE_FLAG_TYPE_MASK;
|
||||
if (formatFlags == kPVRTextureFlagTypePVRTC_4) {
|
||||
@@ -134,7 +135,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na
|
||||
|
||||
m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight;
|
||||
m_min_lod_max_dim = width > height ? width : height;
|
||||
|
||||
m_pData->unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -176,8 +177,6 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
int target_dim = lod_max_dim;
|
||||
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
|
||||
|
||||
GLenum err;
|
||||
|
||||
if(m_blocks.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,10 +28,12 @@ typedef struct {
|
||||
|
||||
KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name)
|
||||
{
|
||||
data->lock();
|
||||
TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart();
|
||||
|
||||
m_max_lod_max_dim = pHeader->width > pHeader->height ? pHeader->width : pHeader->height;
|
||||
m_min_lod_max_dim = m_max_lod_max_dim; // Mipmaps not yet supported for TGA images
|
||||
data->unlock();
|
||||
}
|
||||
|
||||
KRTextureTGA::~KRTextureTGA()
|
||||
@@ -73,7 +75,7 @@ bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
}
|
||||
//#endif
|
||||
glTexImage2D(target, 0, GL_RGBA, pHeader->width, pHeader->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)converted_image);
|
||||
delete converted_image;
|
||||
free(converted_image);
|
||||
err = glGetError();
|
||||
if (err != GL_NO_ERROR) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user