Physics system in progress

Now export writes krbundles directly

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40194
This commit is contained in:
kearwood
2012-12-20 01:23:57 +00:00
parent eb7f07d654
commit 23004557fd
43 changed files with 810 additions and 360 deletions

View File

@@ -230,3 +230,41 @@ float KRAABB::longest_radius() const
float radius2 = (max - center()).magnitude(); float radius2 = (max - center()).magnitude();
return radius1 > radius2 ? radius1 : radius2; return radius1 > radius2 ? radius1 : radius2;
} }
bool KRAABB::intersectsLine(const KRVector3 &v1, const KRVector3 &v2) const
{
// http://www.3dkingdoms.com/weekly/bbox.h
/*
// Put line in box space
KRMat4 MInv = m_M.InvertSimple();
KRVector3 LB1 = MInv * L1;
KRVector3 LB2 = MInv * L2;
// Get line midpoint and extent
KRVector3 LMid = (LB1 + LB2) * 0.5f;
KRVector3 L = (LB1 - LMid);
KRVector3 LExt = KRVector3( fabs(L.x), fabs(L.y), fabs(L.z) );
// Use Separating Axis Test
// Separation vector from box center to line center is LMid, since the line is in box space
if ( fabs( LMid.x ) > m_Extent.x + LExt.x ) return false;
if ( fabs( LMid.y ) > m_Extent.y + LExt.y ) return false;
if ( fabs( LMid.z ) > m_Extent.z + LExt.z ) return false;
// Crossproducts of line and each axis
if ( fabs( LMid.y * L.z - LMid.z * L.y) > (m_Extent.y * LExt.z + m_Extent.z * LExt.y) ) return false;
if ( fabs( LMid.x * L.z - LMid.z * L.x) > (m_Extent.x * LExt.z + m_Extent.z * LExt.x) ) return false;
if ( fabs( LMid.x * L.y - LMid.y * L.x) > (m_Extent.x * LExt.y + m_Extent.y * LExt.x) ) return false;
// No separating axis, the line intersects
return true;
*/
return false;
}
bool KRAABB::intersectsRay(const KRVector3 &v1, const KRVector3 &v2) const
{
// TODO - Implementation needed
return true;
}

View File

@@ -32,6 +32,8 @@ public:
bool contains(const KRAABB &b) const; bool contains(const KRAABB &b) const;
bool contains(const KRVector3 &v) const; bool contains(const KRVector3 &v) const;
bool visible(const KRMat4 &matViewProjection) const; bool visible(const KRMat4 &matViewProjection) const;
bool intersectsLine(const KRVector3 &v1, const KRVector3 &v2) const;
bool intersectsRay(const KRVector3 &v1, const KRVector3 &v2) const;
KRAABB& operator =(const KRAABB& b); KRAABB& operator =(const KRAABB& b);
bool operator ==(const KRAABB& b) const; bool operator ==(const KRAABB& b) const;

View File

@@ -61,7 +61,7 @@ void KRAnimation::addLayer(KRAnimationLayer *layer)
m_layers[layer->getName()] = layer; m_layers[layer->getName()] = layer;
} }
bool KRAnimation::save(const std::string& path) { bool KRAnimation::save(KRDataBlock &data) {
tinyxml2::XMLDocument doc; tinyxml2::XMLDocument doc;
tinyxml2::XMLElement *animation_node = doc.NewElement( "animation" ); tinyxml2::XMLElement *animation_node = doc.NewElement( "animation" );
doc.InsertEndChild(animation_node); doc.InsertEndChild(animation_node);
@@ -73,11 +73,13 @@ bool KRAnimation::save(const std::string& path) {
(*itr).second->saveXML(animation_node); (*itr).second->saveXML(animation_node);
} }
doc.SaveFile(path.c_str()); tinyxml2::XMLPrinter p;
doc.Print(&p);
data.append((void *)p.CStr(), strlen(p.CStr())+1);
return true; return true;
} }
KRAnimation *KRAnimation::Load(KRContext &context, const std::string &name, 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 data->append((void *)"\0", 1); // Ensure data is null terminated, to read as a string safely

View File

@@ -46,7 +46,7 @@ public:
virtual ~KRAnimation(); virtual ~KRAnimation();
virtual std::string getExtension(); virtual std::string getExtension();
virtual bool save(const std::string& path); virtual bool save(KRDataBlock &data);
static KRAnimation *Load(KRContext &context, const std::string &name, KRDataBlock *data); static KRAnimation *Load(KRContext &context, const std::string &name, KRDataBlock *data);

View File

@@ -51,10 +51,10 @@ tinyxml2::XMLElement *KRAnimationAttribute::saveXML( tinyxml2::XMLNode *parent)
{ {
tinyxml2::XMLDocument *doc = parent->GetDocument(); tinyxml2::XMLDocument *doc = parent->GetDocument();
tinyxml2::XMLElement *e = doc->NewElement("attribute"); tinyxml2::XMLElement *e = doc->NewElement("attribute");
tinyxml2::XMLNode *n = parent->InsertEndChild(e); parent->InsertEndChild(e);
e->SetAttribute("curve", m_curve_name.c_str()); e->SetAttribute("curve", m_curve_name.c_str());
e->SetAttribute("target", m_target_name.c_str()); e->SetAttribute("target", m_target_name.c_str());
char *szAttribute = "none"; const char *szAttribute = "none";
switch(m_node_attribute) { switch(m_node_attribute) {
case KRNode::KRENGINE_NODE_ATTRIBUTE_NONE: case KRNode::KRENGINE_NODE_ATTRIBUTE_NONE:
szAttribute = "none"; szAttribute = "none";

View File

@@ -30,6 +30,7 @@
// //
#include "KRAnimationCurve.h" #include "KRAnimationCurve.h"
#include "KRDataBlock.h"
KRAnimationCurve::KRAnimationCurve(KRContext &context, std::string name) : KRResource(context, name) KRAnimationCurve::KRAnimationCurve(KRContext &context, std::string name) : KRResource(context, name)
{ {
@@ -64,6 +65,10 @@ bool KRAnimationCurve::save(const std::string& path) {
return m_pData->save(path); return m_pData->save(path);
} }
bool KRAnimationCurve::save(KRDataBlock &data) {
data.append(*m_pData);
return true;
}
KRAnimationCurve *KRAnimationCurve::Load(KRContext &context, const std::string &name, KRDataBlock *data) KRAnimationCurve *KRAnimationCurve::Load(KRContext &context, const std::string &name, KRDataBlock *data)
{ {

View File

@@ -46,6 +46,7 @@ public:
virtual std::string getExtension(); virtual std::string getExtension();
virtual bool save(const std::string& path); virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
virtual bool load(KRDataBlock *data); virtual bool load(KRDataBlock *data);
float getFrameRate(); float getFrameRate();

View File

@@ -32,6 +32,9 @@
#include "KRBundle.h" #include "KRBundle.h"
#include "KRContext.h" #include "KRContext.h"
#include <assert.h> #include <assert.h>
#include <time.h>
const int KRENGINE_KRBUNDLE_HEADER_SIZE = 512;
typedef struct _tar_header typedef struct _tar_header
{ {
@@ -47,7 +50,7 @@ typedef struct _tar_header
} tar_header_type; } tar_header_type;
KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : KRContextObject(context) KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : KRResource(context, name)
{ {
m_pData = pData; m_pData = pData;
@@ -69,6 +72,7 @@ KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : K
} }
// Advance past the end of the file // Advance past the end of the file
/*
if((file_size & 0x01ff) == 0) { if((file_size & 0x01ff) == 0) {
// file size is a multiple of 512 bytes, we can just add it // file size is a multiple of 512 bytes, we can just add it
pFile += file_size; pFile += file_size;
@@ -76,11 +80,97 @@ KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : K
// We would not be on a 512 byte boundary, round up to the next one // We would not be on a 512 byte boundary, round up to the next one
pFile += (file_size + 0x0200) - (file_size & 0x1ff); pFile += (file_size + 0x0200) - (file_size & 0x1ff);
} }
*/
pFile += RoundUpSize(file_size);
} }
} }
KRBundle::KRBundle(KRContext &context, std::string name) : KRResource(context, name)
{
// 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);
memset(m_pData->getStart(), 0, m_pData->getSize());
}
size_t KRBundle::RoundUpSize(size_t s)
{
// Get amount of padding needed to increase s to a 512 byte alignment
if((s & 0x01ff) == 0) {
// file size is a multiple of 512 bytes, we can just add it
return s;
} else {
// We would not be on a 512 byte boundary, round up to the next one
return (s + 0x0200) - (s & 0x1ff);
}
}
KRBundle::~KRBundle() KRBundle::~KRBundle()
{ {
delete m_pData; delete m_pData;
} }
std::string KRBundle::getExtension()
{
return "krbundle";
}
bool KRBundle::save(const std::string& path)
{
return m_pData->save(path);
}
bool KRBundle::save(KRDataBlock &data) {
if(m_pData->getSize() > KRENGINE_KRBUNDLE_HEADER_SIZE * 2) {
// Only output krbundles that contain files
data.append(*m_pData);
}
return true;
}
void KRBundle::append(KRResource &resource)
{
// Serialize resource to binary representation
KRDataBlock resource_data;
resource.save(resource_data);
std::string file_name = resource.getName() + "." + resource.getExtension();
// Padding is added at the end of file to align next header to a 512 byte boundary. Padding at the end of the archive includes an additional 1024 bytes -- two zero-ed out file headers that mark the end of the archive
size_t padding_size = RoundUpSize(resource_data.getSize()) - resource_data.getSize() + KRENGINE_KRBUNDLE_HEADER_SIZE * 2;
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
// 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);
// Zero out new file header
memset(file_header, 0, KRENGINE_KRBUNDLE_HEADER_SIZE);
// Copy resource data
memcpy((unsigned char *)m_pData->getEnd() - padding_size - resource_data.getSize(), resource_data.getStart(), resource_data.getSize());
// Zero out alignment padding and terminating set of file header blocks
memset((unsigned char *)m_pData->getEnd() - padding_size, 0, padding_size);
// Populate new file header fields
strncpy(file_header->file_name, file_name.c_str(), 100);
strcpy(file_header->file_mode, "000644 ");
strcpy(file_header->owner_id, "000000 ");
strcpy(file_header->group_id, "000000 ");
sprintf(file_header->file_size, "%011o", (int)resource_data.getSize());
file_header->file_size[11] = ' '; // Terminate with space rather than '\0'
sprintf(file_header->mod_time, "%011o", (int)time(NULL));
file_header->mod_time[11] = ' '; // Terminate with space rather than '\0'
// Calculate and write checksum for header
memset(file_header->checksum, ' ', 8); // Must be filled with spaces and no null terminator during checksum calculation
int check_sum = 0;
for(int i=0; i < KRENGINE_KRBUNDLE_HEADER_SIZE; i++) {
unsigned char *byte_ptr = (unsigned char *)file_header;
check_sum += byte_ptr[i];
}
sprintf(file_header->checksum, "%07o", check_sum);
}

View File

@@ -35,13 +35,20 @@
#import "KRResource.h" #import "KRResource.h"
#import "KRDataBlock.h" #import "KRDataBlock.h"
class KRBundle : public KRContextObject { class KRBundle : public KRResource {
public: public:
KRBundle(KRContext &context, std::string name, KRDataBlock *pData); KRBundle(KRContext &context, std::string name, KRDataBlock *pData);
KRBundle(KRContext &context, std::string name);
virtual ~KRBundle(); virtual ~KRBundle();
virtual std::string getExtension();
virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
void append(KRResource &resource);
private: private:
KRDataBlock *m_pData; KRDataBlock *m_pData;
static size_t RoundUpSize(size_t s);
}; };
#endif /* defined(KRBUNDLE_H) */ #endif /* defined(KRBUNDLE_H) */

View File

@@ -76,12 +76,14 @@ KRAABB KRCollider::getBounds() {
bool KRCollider::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) bool KRCollider::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{ {
if(m_models.size()) { if(m_models.size()) {
KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode()); if(getBounds().intersectsLine(v0, v1)) {
KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0); KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode());
KRVector3 v1_model_space = KRMat4::Dot(getModelMatrix(), v1); KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0);
if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) { KRVector3 v1_model_space = KRMat4::Dot(getModelMatrix(), v1);
hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), hitinfo_model_space.getNode()); if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) {
return true; hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), this);
return true;
}
} }
} }
return false; return false;
@@ -90,12 +92,14 @@ bool KRCollider::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &h
bool KRCollider::rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) bool KRCollider::rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{ {
if(m_models.size()) { if(m_models.size()) {
KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode()); if(getBounds().intersectsRay(v0, v1)) {
KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0); KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode());
KRVector3 v1_model_space = v0_model_space + KRMat4::DotNoTranslate(getModelMatrix(), KRVector3::Normalize(v1 - v0)); KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0);
if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) { KRVector3 v1_model_space = v0_model_space + KRMat4::DotNoTranslate(getModelMatrix(), KRVector3::Normalize(v1 - v0));
hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), hitinfo_model_space.getNode()); if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) {
return true; hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), this);
return true;
}
} }
} }
return false; return false;

View File

@@ -65,7 +65,6 @@ public:
long getCurrentFrame() const; long getCurrentFrame() const;
float getAbsoluteTime() const; float getAbsoluteTime() const;
private: private:
KRBundleManager *m_pBundleManager; KRBundleManager *m_pBundleManager;
KRSceneManager *m_pSceneManager; KRSceneManager *m_pSceneManager;

View File

@@ -153,6 +153,18 @@ void KRDataBlock::append(void *data, size_t size) {
memcpy((unsigned char *)m_data + m_data_size - size, data, size); memcpy((unsigned char *)m_data + m_data_size - size, data, size);
} }
// Append data to the end of the block, increasing the size of the block and making it read-write.
void KRDataBlock::append(KRDataBlock &data) {
append(data.getStart(), data.getSize());
}
// 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
void KRDataBlock::append(const std::string &s)
{
const char *szText = s.c_str();
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, 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
bool KRDataBlock::save(const std::string& path) { bool KRDataBlock::save(const std::string& path) {
int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);

View File

@@ -49,6 +49,12 @@ public:
// Append data to the end of the block, increasing the size of the block and making it read-write. // 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); void append(void *data, size_t size);
// Append data to the end of the block, increasing the size of the block and making it read-write.
void append(KRDataBlock &data);
// 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
void append(const std::string &s);
// Expand or shrink 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 // Expand or shrink 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 expand(size_t size); void expand(size_t size);

View File

@@ -294,7 +294,7 @@ KRVector3 KRMat4::Dot(const KRMat4 &m, const KRVector3 &v) {
} }
// Dot product without including translation; useful for transforming normals and tangents // Dot product without including translation; useful for transforming normals and tangents
KRVector3 DotNoTranslate(const KRMat4 &m, const KRVector3 &v) KRVector3 KRMat4::DotNoTranslate(const KRMat4 &m, const KRVector3 &v)
{ {
return KRVector3( return KRVector3(
v.x * (float)m[0*4 + 0] + v.y * (float)m[1*4 + 0] + v.z * (float)m[2*4 + 0], v.x * (float)m[0*4 + 0] + v.y * (float)m[1*4 + 0] + v.z * (float)m[2*4 + 0],

View File

@@ -34,6 +34,8 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <iostream>
#include <sstream>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
@@ -77,67 +79,69 @@ KRMaterial::~KRMaterial() {
std::string KRMaterial::getExtension() { std::string KRMaterial::getExtension() {
return "mtl"; return "mtl";
} }
bool KRMaterial::save(const std::string& path) {
FILE *f = fopen(path.c_str(), "w+");
if(f == NULL) {
return false;
} else {
fprintf(f, "newmtl %s\n", m_szName); bool KRMaterial::save(KRDataBlock &data) {
fprintf(f, "ka %f %f %f\n", m_ambientColor.x, m_ambientColor.y, m_ambientColor.z); std::stringstream stream;
fprintf(f, "kd %f %f %f\n", m_diffuseColor.x, m_diffuseColor.y, m_diffuseColor.z); stream.precision(std::numeric_limits<long double>::digits10);
fprintf(f, "ks %f %f %f\n", m_specularColor.x, m_specularColor.y, m_specularColor.z); stream.setf(ios::fixed,ios::floatfield);
fprintf(f, "kr %f %f %f\n", m_reflectionColor.x, m_reflectionColor.y, m_reflectionColor.z);
fprintf(f, "Tr %f\n", m_tr); stream << "newmtl " << m_szName;
fprintf(f, "Ns %f\n", m_ns); stream << "\nka " << m_ambientColor.x << " " << m_ambientColor.y << " " << m_ambientColor.z;
if(m_ambientMap.size()) { stream << "\nkd " << m_diffuseColor.x << " " << m_diffuseColor.y << " " << m_diffuseColor.z;
fprintf(f, "map_Ka %s.pvr -s %f %f -o %f %f\n", m_ambientMap.c_str(), m_ambientMapScale.x, m_ambientMapScale.y, m_ambientMapOffset.x, m_ambientMapOffset.y); stream << "\nks " << m_specularColor.x << " " << m_specularColor.y << " " << m_specularColor.z;
} else { stream << "\nkr " << m_reflectionColor.x << " " << m_reflectionColor.y << " " << m_reflectionColor.z;
fprintf(f, "# map_Ka filename.pvr -s 1.0 1.0 -o 0.0 0.0\n"); stream << "\nTr " << m_tr;
} stream << "\nNs " << m_ns;
if(m_diffuseMap.size()) { if(m_ambientMap.size()) {
fprintf(f, "map_Kd %s.pvr -s %f %f -o %f %f\n", m_diffuseMap.c_str(), m_diffuseMapScale.x, m_diffuseMapScale.y, m_diffuseMapOffset.x, m_diffuseMapOffset.y); stream << "\nmap_Ka " << m_ambientMap << ".pvr -s " << m_ambientMapScale.x << " " << m_ambientMapScale.y << " -o " << m_ambientMapOffset.x << " " << m_ambientMapOffset.y;
} else { } else {
fprintf(f, "# map_Kd filename.pvr -s 1.0 1.0 -o 0.0 0.0\n"); stream << "\n# map_Ka filename.pvr -s 1.0 1.0 -o 0.0 0.0";
}
if(m_specularMap.size()) {
fprintf(f, "map_Ks %s.pvr -s %f %f -o %f %f\n", m_specularMap.c_str(), m_specularMapScale.x, m_specularMapScale.y, m_specularMapOffset.x, m_specularMapOffset.y);
} else {
fprintf(f, "# map_Ks filename.pvr -s 1.0 1.0 -o 0.0 0.0\n");
}
if(m_normalMap.size()) {
fprintf(f, "map_Normal %s.pvr -s %f %f -o %f %f\n", m_normalMap.c_str(), m_normalMapScale.x, m_normalMapScale.y, m_normalMapOffset.x, m_normalMapOffset.y);
} else {
fprintf(f, "# map_Normal filename.pvr -s 1.0 1.0 -o 0.0 0.0\n");
}
if(m_reflectionMap.size()) {
fprintf(f, "map_Reflection %s.pvr -s %f %f -o %f %f\n", m_reflectionMap.c_str(), m_reflectionMapScale.x, m_reflectionMapScale.y, m_reflectionMapOffset.x, m_reflectionMapOffset.y);
} else {
fprintf(f, "# map_Reflection filename.pvr -s 1.0 1.0 -o 0.0 0.0\n");
}
if(m_reflectionCube.size()) {
fprintf(f, "map_ReflectionCube %s.pvr\n", m_reflectionCube.c_str());
} else {
fprintf(f, "# map_ReflectionCube cubemapname\n");
}
switch(m_alpha_mode) {
case KRMATERIAL_ALPHA_MODE_OPAQUE:
fprintf(f, "alpha_mode opaque\n");
break;
case KRMATERIAL_ALPHA_MODE_TEST:
fprintf(f, "alpha_mode test\n");
break;
case KRMATERIAL_ALPHA_MODE_BLENDONESIDE:
fprintf(f, "alpha_mode blendoneside\n");
break;
case KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE:
fprintf(f, "alpha_mode blendtwoside\n");
break;
}
fprintf(f, "# alpha_mode opaque, test, blendoneside, or blendtwoside\n");
fclose(f);
return true;
} }
if(m_diffuseMap.size()) {
stream << "\nmap_Kd " << m_diffuseMap << ".pvr -s " << m_diffuseMapScale.x << " " << m_diffuseMapScale.y << " -o " << m_diffuseMapOffset.x << " " << m_diffuseMapOffset.y;
} else {
stream << "\n# map_Kd filename.pvr -s 1.0 1.0 -o 0.0 0.0";
}
if(m_specularMap.size()) {
stream << "\nmap_Ks " << m_specularMap << ".pvr -s " << m_specularMapScale.x << " " << m_specularMapScale.y << " -o " << m_specularMapOffset.x << " " << m_specularMapOffset.y << "\n";
} else {
stream << "\n# map_Ks filename.pvr -s 1.0 1.0 -o 0.0 0.0";
}
if(m_normalMap.size()) {
stream << "\nmap_Normal " << m_normalMap << ".pvr -s " << m_normalMapScale.x << " " << m_normalMapScale.y << " -o " << m_normalMapOffset.x << " " << m_normalMapOffset.y;
} else {
stream << "\n# map_Normal filename.pvr -s 1.0 1.0 -o 0.0 0.0";
}
if(m_reflectionMap.size()) {
stream << "\nmap_Reflection " << m_reflectionMap << ".pvr -s " << m_reflectionMapScale.x << " " << m_reflectionMapScale.y << " -o " << m_reflectionMapOffset.x << " " << m_reflectionMapOffset.y;
} else {
stream << "\n# map_Reflection filename.pvr -s 1.0 1.0 -o 0.0 0.0";
}
if(m_reflectionCube.size()) {
stream << "map_ReflectionCube " << m_reflectionCube << ".pvr";
} else {
stream << "\n# map_ReflectionCube cubemapname";
}
switch(m_alpha_mode) {
case KRMATERIAL_ALPHA_MODE_OPAQUE:
stream << "\nalpha_mode opaque";
break;
case KRMATERIAL_ALPHA_MODE_TEST:
stream << "\nalpha_mode test";
break;
case KRMATERIAL_ALPHA_MODE_BLENDONESIDE:
stream << "\nalpha_mode blendoneside";
break;
case KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE:
stream << "\nalpha_mode blendtwoside";
break;
}
stream << "\n# alpha_mode opaque, test, blendoneside, or blendtwoside";
stream << "\n";
data.append(stream.str());
return true;
} }
void KRMaterial::setAmbientMap(std::string texture_name, KRVector2 texture_scale, KRVector2 texture_offset) { void KRMaterial::setAmbientMap(std::string texture_name, KRVector2 texture_scale, KRVector2 texture_offset) {

View File

@@ -67,7 +67,7 @@ public:
virtual ~KRMaterial(); virtual ~KRMaterial();
virtual std::string getExtension(); virtual std::string getExtension();
virtual bool save(const std::string& path); virtual bool save(KRDataBlock &data);
void setAmbientMap(std::string texture_name, KRVector2 texture_scale, KRVector2 texture_offset); void setAmbientMap(std::string texture_name, KRVector2 texture_scale, KRVector2 texture_offset);

View File

@@ -86,6 +86,28 @@ void KRModel::setName(const std::string name) {
} }
int KRModel::GetLODCoverage(const std::string &name)
{
int lod_coverage = 100;
size_t last_underscore_pos = name.find_last_of('_');
if(last_underscore_pos != std::string::npos) {
// Found an underscore
std::string suffix = name.substr(last_underscore_pos + 1);
if(suffix.find_first_of("lod") == 0) {
std::string lod_level_string = suffix.substr(3);
char *end = NULL;
int c = (int)strtol(lod_level_string.c_str(), &end, 10);
if(c >= 0 && c <= 100 && *end == '\0') {
lod_coverage = c;
//m_lodBaseName = name.substr(0, last_underscore_pos);
}
}
}
return lod_coverage;
}
KRModel::~KRModel() { KRModel::~KRModel() {
clearData(); clearData();
if(m_pData) delete m_pData; if(m_pData) delete m_pData;
@@ -100,6 +122,12 @@ bool KRModel::save(const std::string& path) {
return m_pData->save(path); return m_pData->save(path);
} }
bool KRModel::save(KRDataBlock &data) {
clearBuffers();
data.append(*m_pData);
return true;
}
void KRModel::loadPack(KRDataBlock *data) { void KRModel::loadPack(KRDataBlock *data) {
clearData(); clearData();
delete m_pData; delete m_pData;
@@ -802,12 +830,12 @@ bool KRModel::rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitin
switch(getModelFormat()) { switch(getModelFormat()) {
case KRENGINE_MODEL_FORMAT_TRIANGLES: case KRENGINE_MODEL_FORMAT_TRIANGLES:
for(int triangle_index=0; triangle_index < vertex_count / 3; triangle_index++) { for(int triangle_index=0; triangle_index < vertex_count / 3; triangle_index++) {
hit_found |= rayCast(v0, v1, getVertexPosition(triangle_index*3), getVertexPosition(triangle_index*3+1), getVertexPosition(triangle_index*3+2), getVertexNormal(triangle_index*3), getVertexNormal(triangle_index*3+1), getVertexNormal(triangle_index*3+2), hitinfo); if(rayCast(v0, v1, getVertexPosition(triangle_index*3), getVertexPosition(triangle_index*3+1), getVertexPosition(triangle_index*3+2), getVertexNormal(triangle_index*3), getVertexNormal(triangle_index*3+1), getVertexNormal(triangle_index*3+2), hitinfo)) hit_found = true;
} }
break; break;
case KRENGINE_MODEL_FORMAT_STRIP: case KRENGINE_MODEL_FORMAT_STRIP:
for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) { for(int triangle_index=0; triangle_index < vertex_count - 2; triangle_index++) {
hit_found |= rayCast(v0, v1, getVertexPosition(triangle_index), getVertexPosition(triangle_index+1), getVertexPosition(triangle_index+2), getVertexNormal(triangle_index), getVertexNormal(triangle_index+1), getVertexNormal(triangle_index+2), hitinfo); if(rayCast(v0, v1, getVertexPosition(triangle_index), getVertexPosition(triangle_index+1), getVertexPosition(triangle_index+2), getVertexNormal(triangle_index), getVertexNormal(triangle_index+1), getVertexNormal(triangle_index+2), hitinfo)) hit_found = true;
} }
break; break;
default: default:

View File

@@ -99,6 +99,7 @@ public:
virtual std::string getExtension(); virtual std::string getExtension();
virtual bool save(const std::string& path); virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
void LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights, model_format_t model_format); void LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names, std::vector<std::string> bone_names, std::vector<std::vector<int> > bone_indexes, std::vector<std::vector<float> > bone_weights, model_format_t model_format);
void loadPack(KRDataBlock *data); void loadPack(KRDataBlock *data);
@@ -186,6 +187,8 @@ public:
bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const; bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const;
bool rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const; bool rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const;
static int GetLODCoverage(const std::string &name);
private: private:
bool rayCast(const KRVector3 &line_v0, const KRVector3 &line_v1, int tri_index0, int tri_index1, int tri_index2, KRHitInfo &hitinfo) const; bool rayCast(const KRVector3 &line_v0, const KRVector3 &line_v1, int tri_index0, int tri_index1, int tri_index2, KRHitInfo &hitinfo) const;
static bool rayCast(const KRVector3 &line_v0, const KRVector3 &line_v1, 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); static bool rayCast(const KRVector3 &line_v0, const KRVector3 &line_v1, 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);

View File

@@ -8,6 +8,8 @@
#include "KROctree.h" #include "KROctree.h"
#include "KRNode.h" #include "KRNode.h"
#include "KRHitInfo.h"
#include "KRCollider.h"
KROctree::KROctree() KROctree::KROctree()
{ {
@@ -91,3 +93,34 @@ std::set<KRNode *> &KROctree::getOuterSceneNodes()
{ {
return m_outerSceneNodes; return m_outerSceneNodes;
} }
bool KROctree::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{
bool hit_found = false;
for(std::set<KRNode *>::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*outer_nodes_itr);
if(collider) {
if(collider->lineCast(v0, v1, hitinfo)) hit_found = true;
}
}
if(m_pRootNode) {
if(m_pRootNode->lineCast(v0, v1, hitinfo)) hit_found = true;
}
return hit_found;
}
bool KROctree::rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{
bool hit_found = false;
for(std::set<KRNode *>::iterator outer_nodes_itr=m_outerSceneNodes.begin(); outer_nodes_itr != m_outerSceneNodes.end(); outer_nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*outer_nodes_itr);
if(collider) {
if(collider->rayCast(v0, v1, hitinfo)) hit_found = true;
}
}
if(m_pRootNode) {
if(m_pRootNode->lineCast(v0, v1, hitinfo)) hit_found = true;
}
return hit_found;
}

View File

@@ -12,6 +12,7 @@
#import "KREngine-common.h" #import "KREngine-common.h"
#include "KROctreeNode.h" #include "KROctreeNode.h"
#include "KRMat4.h" #include "KRMat4.h"
#include "KRHitInfo.h"
class KRNode; class KRNode;
@@ -26,10 +27,13 @@ public:
KROctreeNode *getRootNode(); KROctreeNode *getRootNode();
std::set<KRNode *> &getOuterSceneNodes(); std::set<KRNode *> &getOuterSceneNodes();
bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
bool rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
private: private:
KROctreeNode *m_pRootNode; KROctreeNode *m_pRootNode;
std::set<KRNode *>m_outerSceneNodes; std::set<KRNode *> m_outerSceneNodes;
//std::set<KRMat4> visibleMVPs; //std::set<KRMat4> visibleMVPs;
void shrink(); void shrink();

View File

@@ -8,6 +8,7 @@
#include "KROctreeNode.h" #include "KROctreeNode.h"
#include "KRNode.h" #include "KRNode.h"
#include "KRCollider.h"
KROctreeNode::KROctreeNode(const KRAABB &bounds) : m_bounds(bounds) KROctreeNode::KROctreeNode(const KRAABB &bounds) : m_bounds(bounds)
{ {
@@ -173,3 +174,61 @@ std::set<KRNode *> &KROctreeNode::getSceneNodes()
{ {
return m_sceneNodes; return m_sceneNodes;
} }
bool KROctreeNode::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{
bool hit_found = false;
if(hitinfo.didHit() && v1 != hitinfo.getPosition()) {
// Optimization: If we already have a hit, only search for hits that are closer
hit_found = lineCast(v0, hitinfo.getPosition(), hitinfo);
} else {
bool hit_found = false;
if(getBounds().intersectsLine(v0, v1)) {
for(std::set<KRNode *>::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*nodes_itr);
if(collider) {
if(collider->lineCast(v0, v1, hitinfo)) hit_found = true;
}
}
for(int i=0; i<8; i++) {
if(m_children[i]) {
if(m_children[i]->lineCast(v0, v1, hitinfo)) {
hit_found = true;
}
}
}
}
}
return hit_found;
}
bool KROctreeNode::rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{
bool hit_found = false;
if(hitinfo.didHit()) {
// Optimization: If we already have a hit, only search for hits that are closer
hit_found = lineCast(v0, hitinfo.getPosition(), hitinfo); // Note: This is purposefully lineCast as opposed to RayCast
} else {
if(getBounds().intersectsRay(v0, v1)) {
for(std::set<KRNode *>::iterator nodes_itr=m_sceneNodes.begin(); nodes_itr != m_sceneNodes.end(); nodes_itr++) {
KRCollider *collider = dynamic_cast<KRCollider *>(*nodes_itr);
if(collider) {
if(collider->rayCast(v0, v1, hitinfo)) hit_found = true;
}
}
for(int i=0; i<8; i++) {
if(m_children[i]) {
if(m_children[i]->rayCast(v0, v1, hitinfo)) {
hit_found = true;
}
}
}
}
}
return hit_found;
}

View File

@@ -12,6 +12,7 @@
#import "KREngine-common.h" #import "KREngine-common.h"
#include "KRVector3.h" #include "KRVector3.h"
#include "KRAABB.h" #include "KRAABB.h"
#include "KRHitInfo.h"
class KRNode; class KRNode;
@@ -45,6 +46,9 @@ public:
GLuint m_occlusionQuery; GLuint m_occlusionQuery;
bool m_occlusionTested; bool m_occlusionTested;
bool m_activeQuery; bool m_activeQuery;
bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
bool rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
private: private:
KRAABB m_bounds; KRAABB m_bounds;

View File

@@ -33,6 +33,7 @@
#include "KRScene.h" #include "KRScene.h"
#include "KRQuaternion.h" #include "KRQuaternion.h"
#include "KRBone.h" #include "KRBone.h"
#include "KRBundle.h"
#ifdef IOS_REF #ifdef IOS_REF
#undef IOS_REF #undef IOS_REF
@@ -47,6 +48,8 @@ KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurv
KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer); KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer);
void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
//void BakeNode(KFbxNode* pNode); //void BakeNode(KFbxNode* pNode);
void LoadMaterial(KRContext &context, std::vector<KRResource *> &resources, FbxSurfaceMaterial *pMaterial);
void LoadMesh(KRContext &context, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh);
KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode); KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode);
KRNode *LoadLight(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode); KRNode *LoadLight(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode);
KRNode *LoadSkeleton(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode); KRNode *LoadSkeleton(KRNode *parent_node, std::vector<KRResource *> &resources, KFbxNode* pNode);
@@ -98,25 +101,8 @@ std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::str
pNode->ResetPivotSetAndConvertAnimation(); pNode->ResetPivotSetAndConvertAnimation();
} }
// ----====---- Import Animation Layers ----====----
int animation_count = pFbxScene->GetSrcObjectCount<FbxAnimStack>();
for(int i = 0; i < animation_count; i++) {
// FbxAnimStack* pAnimStack = FbxCast<FbxAnimStack>(pFbxScene->GetSrcObject(FBX_TYPE(FbxAnimStack), i));
KRAnimation *new_animation = LoadAnimation(context, pFbxScene->GetSrcObject<FbxAnimStack>(i));
context.getAnimationManager()->addAnimation(new_animation);
resources.push_back(new_animation);
}
// ----====---- Import Animation Curves ----====----
int curve_count = pFbxScene->GetSrcObjectCount<FbxAnimCurve>();
for(int i=0; i < curve_count; i++) {
KRAnimationCurve *new_curve = LoadAnimationCurve(context, pFbxScene->GetSrcObject<FbxAnimCurve>(i));
context.getAnimationCurveManager()->addAnimationCurve(new_curve);
resources.push_back(new_curve);
}
// ----====---- Import Scene Graph Nodes ----====---- // ----====---- Import Scene Graph Nodes ----====----
printf("\nLoading scene graph...\n");
if(pNode) if(pNode)
{ {
for(int i = 0; i < pNode->GetChildCount(); i++) for(int i = 0; i < pNode->GetChildCount(); i++)
@@ -125,24 +111,97 @@ std::vector<KRResource *> KRResource::LoadFbx(KRContext &context, const std::str
} }
} }
// ----====---- Import Animation Layers ----====----
printf("\nLoading animations...\n");
int animation_count = pFbxScene->GetSrcObjectCount<FbxAnimStack>();
for(int i = 0; i < animation_count; i++) {
FbxAnimStack *animation = pFbxScene->GetSrcObject<FbxAnimStack>(i);
printf(" Animation %i of %i: %s\n", i+1, animation_count, animation->GetName());
KRAnimation *new_animation = LoadAnimation(context, animation);
context.getAnimationManager()->addAnimation(new_animation);
resources.push_back(new_animation);
}
// ----====---- Import Animation Curves ----====----
printf("\nLoading animation curves...\n");
int curve_count = pFbxScene->GetSrcObjectCount<FbxAnimCurve>();
for(int i=0; i < curve_count; i++) {
FbxAnimCurve *curve = pFbxScene->GetSrcObject<FbxAnimCurve>(i);
printf(" Animation Curve %i of %i: %s\n", i+1, curve_count, curve->GetName());
KRAnimationCurve *new_curve = LoadAnimationCurve(context, curve);
context.getAnimationCurveManager()->addAnimationCurve(new_curve);
resources.push_back(new_curve);
}
// ----====---- Import Meshes ----====----
int mesh_count = pFbxScene->GetSrcObjectCount<FbxMesh>();
printf("\nLoading meshes...\n");
for(int i=0; i < mesh_count; i++) {
FbxMesh *mesh = pFbxScene->GetSrcObject<FbxMesh>(i);
printf(" Mesh %i of %i: %s\n", i+1, mesh_count, mesh->GetNode()->GetName());
LoadMesh(context, resources, pGeometryConverter, mesh);
}
// ----====---- Import Materials ----====----
int material_count = pFbxScene->GetSrcObjectCount<FbxSurfaceMaterial>();
printf("\nLoading materials...\n");
for(int i=0; i < material_count; i++) {
FbxSurfaceMaterial *material = pFbxScene->GetSrcObject<FbxSurfaceMaterial>(i);
printf(" Material %i of %i: %s\n", i+1, material_count, material->GetName());
LoadMaterial(context, resources, material);
}
// ----====---- Import Textures ----====----
int texture_count = pFbxScene->GetSrcObjectCount<FbxFileTexture>();
printf("\nLoading textures...\n");
for(int i=0; i < texture_count; i++) {
FbxFileTexture *texture = pFbxScene->GetSrcObject<FbxFileTexture>(i);
const char *file_name = texture->GetFileName();
printf(" Texture %i of %i: %s\n", i+1, texture_count, (KRResource::GetFileBase(file_name) + "." + KRResource::GetFileExtension(file_name)).c_str());
context.loadResource(file_name);
}
for(std::map<std::string, KRTexture *>::iterator texture_itr = context.getTextureManager()->getTextures().begin(); texture_itr != context.getTextureManager()->getTextures().end(); texture_itr++) {
resources.push_back((*texture_itr).second);
}
DestroySdkObjects(lSdkManager); DestroySdkObjects(lSdkManager);
// Compress textures to PVR format
context.getTextureManager()->compress(); // TODO, HACK, FINDME - This should be configurable and exposed through the World Builder GUI
std::string base_name = KRResource::GetFileBase(path);
KRBundle *main_bundle = new KRBundle(context, base_name);
KRBundle texture_bundle(context, base_name + "_textures");
KRBundle animation_bundle(context, base_name + "_animations");
// KRBundle material_bundle(context, base_name + "_materials");
KRBundle meshes_bundle(context, base_name + "_meshes");
// FINDME - HACK - This logic removes the animations and animation curves from their manager objects so they don't get dealloced twice. In the future, we should keep all objects in their manager objects while importing and just return a KRContext containing all the managers.
for(std::vector<KRResource *>::iterator resource_itr=resources.begin(); resource_itr != resources.end(); resource_itr++) { for(std::vector<KRResource *>::iterator resource_itr=resources.begin(); resource_itr != resources.end(); resource_itr++) {
KRAnimation *animation = dynamic_cast<KRAnimation *>(*resource_itr); KRResource *resource = *resource_itr;
KRAnimationCurve *animation_curve = dynamic_cast<KRAnimationCurve *>(*resource_itr); if(dynamic_cast<KRTexture *>(resource) != NULL) {
if(animation) { texture_bundle.append(*resource);
context.getAnimationManager()->getAnimations().erase(animation->getName()); } else if(dynamic_cast<KRAnimation *>(resource) != NULL) {
} animation_bundle.append(*resource);
if(animation_curve) { // } else if(dynamic_cast<KRMaterial *>(resource) != NULL) {
context.getAnimationCurveManager()->getAnimationCurves().erase(animation_curve->getName()); // material_bundle.append(*resource);
} else if(dynamic_cast<KRModel *>(resource) != NULL) {
meshes_bundle.append(*resource);
} else {
main_bundle->append(*resource);
} }
} }
return resources; main_bundle->append(texture_bundle);
main_bundle->append(animation_bundle);
// main_bundle->append(material_bundle);
main_bundle->append(meshes_bundle);
std::vector<KRResource *> output_resources;
output_resources.push_back(main_bundle);
return output_resources;
} }
@@ -695,10 +754,158 @@ void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vector<KRResource
} }
} }
KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) { void LoadMaterial(KRContext &context, std::vector<KRResource *> &resources, FbxSurfaceMaterial *pMaterial) {
std::string name = GetFbxObjectName(pNode); //printf(" %s: %i - %i\n", pMaterial->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1);
printf("Mesh: %s\n", name.c_str());
KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute(); // ----====---- Output Material File ----====----
KRMaterial *new_material = new KRMaterial(context, pMaterial->GetName());
FbxPropertyT<FbxDouble3> lKFbxDouble3;
FbxPropertyT<FbxDouble> lKFbxDouble1;
if (pMaterial->GetClassId().Is(KFbxSurfacePhong::ClassId)) {
// We found a Phong material.
// Ambient Color
lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Ambient;
new_material->setAmbient(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Diffuse Color
lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Diffuse;
new_material->setDiffuse(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Specular Color (unique to Phong materials)
lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Specular;
new_material->setSpecular(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Emissive Color
//lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Emissive;
// Transparency
lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->TransparencyFactor;
new_material->setTransparency(lKFbxDouble1.Get());
// Shininess
lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->Shininess;
new_material->setShininess(lKFbxDouble1.Get());
// Specular Factor
lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->SpecularFactor;
double specular_factor = lKFbxDouble1.Get();
// Reflection factor
lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->ReflectionFactor;
// Reflection color
lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Reflection;
// We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken
new_material->setReflection(KRVector3(lKFbxDouble3.Get()[0] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[1] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[2] * lKFbxDouble1.Get()));
} else if(pMaterial->GetClassId().Is(KFbxSurfaceLambert::ClassId) ) {
// We found a Lambert material.
// Ambient Color
lKFbxDouble3=((KFbxSurfaceLambert *)pMaterial)->Ambient;
new_material->setAmbient(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Diffuse Color
lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Diffuse;
new_material->setDiffuse(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Emissive
//lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Emissive;
// Opacity
lKFbxDouble1 =((KFbxSurfaceLambert *)pMaterial)->TransparencyFactor;
new_material->setTransparency(lKFbxDouble1.Get());
} else {
printf("Error! Unable to convert material: %s", pMaterial->GetName());
}
KFbxProperty pProperty;
// Diffuse Map Texture
pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sDiffuse);
if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) {
printf("Warning! Layered textures not supported.\n");
}
int texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId);
if(texture_count > 1) {
printf("Error! Multiple diffuse textures not supported.\n");
} else if(texture_count == 1) {
KFbxTexture* pTexture = FbxCast <KFbxTexture> (pProperty.GetSrcObject(KFbxTexture::ClassId,0));
assert(!pTexture->GetSwapUV());
assert(pTexture->GetCroppingTop() == 0);
assert(pTexture->GetCroppingLeft() == 0);
assert(pTexture->GetCroppingRight() == 0);
assert(pTexture->GetCroppingBottom() == 0);
assert(pTexture->GetWrapModeU() == KFbxTexture::eRepeat);
assert(pTexture->GetWrapModeV() == KFbxTexture::eRepeat);
assert(pTexture->GetRotationU() == 0.0f);
assert(pTexture->GetRotationV() == 0.0f);
assert(pTexture->GetRotationW() == 0.0f);
KFbxFileTexture *pFileTexture = FbxCast<KFbxFileTexture>(pTexture);
if(pFileTexture) {
new_material->setDiffuseMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV()));
}
}
// Specular Map Texture
pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sSpecular);
if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) {
printf("Warning! Layered textures not supported.\n");
}
texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId);
if(texture_count > 1) {
printf("Error! Multiple specular textures not supported.\n");
} else if(texture_count == 1) {
KFbxTexture* pTexture = FbxCast <KFbxTexture> (pProperty.GetSrcObject(KFbxTexture::ClassId,0));
KFbxFileTexture *pFileTexture = FbxCast<KFbxFileTexture>(pTexture);
if(pFileTexture) {
new_material->setSpecularMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV()));
}
}
// Normal Map Texture
pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sNormalMap);
if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) {
printf("Warning! Layered textures not supported.\n");
}
texture_count = pProperty.GetSrcObjectCount<FbxTexture>();
if(texture_count > 1) {
printf("Error! Multiple normal map textures not supported.\n");
} else if(texture_count == 1) {
KFbxTexture* pTexture = pProperty.GetSrcObject<KFbxTexture>(0);
KFbxFileTexture *pFileTexture = FbxCast<KFbxFileTexture>(pTexture);
if(pFileTexture) {
new_material->setNormalMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV()));
}
}
bool bFound = false;
for(vector<KRResource *>::iterator resource_itr = resources.begin(); resource_itr != resources.end(); resource_itr++) {
KRResource *pResource = (*resource_itr);
if(pResource->getName() == new_material->getName() && pResource->getExtension() == new_material->getExtension()) {
bFound = true;
}
}
if(bFound) {
delete new_material;
} else {
resources.push_back(new_material);
}
}
void LoadMesh(KRContext &context, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxMesh* pSourceMesh) {
KFbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh); KFbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh);
int control_point_count = pMesh->GetControlPointsCount(); int control_point_count = pMesh->GetControlPointsCount();
@@ -715,7 +922,7 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
control_point_weights[control_point].weights[i] = 0.0f; control_point_weights[control_point].weights[i] = 0.0f;
control_point_weights[control_point].bone_indexes[i] = 0; control_point_weights[control_point].bone_indexes[i] = 0;
} }
} }
std::vector<std::string> bone_names; std::vector<std::string> bone_names;
@@ -785,11 +992,8 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
int normal_count = pMesh->GetElementNormalCount(); int normal_count = pMesh->GetElementNormalCount();
int tangent_count = pMesh->GetElementTangentCount(); int tangent_count = pMesh->GetElementTangentCount();
int elementmaterial_count = pMesh->GetElementMaterialCount(); int elementmaterial_count = pMesh->GetElementMaterialCount();
int material_count = pNode->GetMaterialCount(); int material_count = pSourceMesh->GetNode()->GetMaterialCount(); // FINDME, TODO - To support instancing, material names should be stored in the instance rather than the mesh
printf(" Polygon Count: %i (before triangulation: %i)\n", polygon_count, pSourceMesh->GetPolygonCount());
std::vector<std::vector<float> > bone_weights; std::vector<std::vector<float> > bone_weights;
std::vector<std::vector<int> > bone_indexes; std::vector<std::vector<int> > bone_indexes;
@@ -803,9 +1007,9 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
std::vector<std::string> material_names; std::vector<std::string> material_names;
int dest_vertex_id = 0; int dest_vertex_id = 0;
for(int iMaterial=0; iMaterial < material_count; iMaterial++) { for(int iMaterial=0; iMaterial < material_count; iMaterial++) {
KFbxSurfaceMaterial *pMaterial = pNode->GetMaterial(iMaterial); KFbxSurfaceMaterial *pMaterial = pSourceMesh->GetNode()->GetMaterial(iMaterial);
int source_vertex_id = 0; int source_vertex_id = 0;
int mat_vertex_count = 0; int mat_vertex_count = 0;
int mat_vertex_start = dest_vertex_id; int mat_vertex_start = dest_vertex_id;
@@ -874,7 +1078,7 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
new_uvb = KRVector2(uv[0], uv[1]); new_uvb = KRVector2(uv[0], uv[1]);
} }
uvb.push_back(new_uvb); uvb.push_back(new_uvb);
} }
// ----====---- Read Normals ----====---- // ----====---- Read Normals ----====----
@@ -910,9 +1114,9 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
} }
} }
source_vertex_id++; source_vertex_id++;
dest_vertex_id++; dest_vertex_id++;
@@ -928,171 +1132,27 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
submesh_starts.push_back(mat_vertex_start); submesh_starts.push_back(mat_vertex_start);
submesh_lengths.push_back(mat_vertex_count); submesh_lengths.push_back(mat_vertex_count);
material_names.push_back(pMaterial->GetName()); material_names.push_back(pMaterial->GetName());
printf(" %s: %i - %i\n", pMaterial->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1);
// ----====---- Output Material File ----====----
KRMaterial *new_material = new KRMaterial(parent_node->getContext(), pMaterial->GetName());
FbxPropertyT<FbxDouble3> lKFbxDouble3;
FbxPropertyT<FbxDouble> lKFbxDouble1;
if (pMaterial->GetClassId().Is(KFbxSurfacePhong::ClassId)) {
// We found a Phong material.
// Ambient Color
lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Ambient;
new_material->setAmbient(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Diffuse Color
lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Diffuse;
new_material->setDiffuse(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Specular Color (unique to Phong materials)
lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Specular;
new_material->setSpecular(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Emissive Color
//lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Emissive;
// Transparency
lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->TransparencyFactor;
new_material->setTransparency(lKFbxDouble1.Get());
// Shininess
lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->Shininess;
new_material->setShininess(lKFbxDouble1.Get());
// Specular Factor
lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->SpecularFactor;
double specular_factor = lKFbxDouble1.Get();
// Reflection factor
lKFbxDouble1 =((KFbxSurfacePhong *) pMaterial)->ReflectionFactor;
// Reflection color
lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Reflection;
// We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken
new_material->setReflection(KRVector3(lKFbxDouble3.Get()[0] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[1] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[2] * lKFbxDouble1.Get()));
} else if(pMaterial->GetClassId().Is(KFbxSurfaceLambert::ClassId) ) {
// We found a Lambert material.
// Ambient Color
lKFbxDouble3=((KFbxSurfaceLambert *)pMaterial)->Ambient;
new_material->setAmbient(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Diffuse Color
lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Diffuse;
new_material->setDiffuse(KRVector3(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]));
// Emissive
//lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Emissive;
// Opacity
lKFbxDouble1 =((KFbxSurfaceLambert *)pMaterial)->TransparencyFactor;
new_material->setTransparency(lKFbxDouble1.Get());
} else {
printf("Error! Unable to convert material: %s", pMaterial->GetName());
}
KFbxProperty pProperty;
// Diffuse Map Texture
pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sDiffuse);
if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) {
printf("Warning! Layered textures not supported.\n");
}
int texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId);
if(texture_count > 1) {
printf("Error! Multiple diffuse textures not supported.\n");
} else if(texture_count == 1) {
KFbxTexture* pTexture = FbxCast <KFbxTexture> (pProperty.GetSrcObject(KFbxTexture::ClassId,0));
assert(!pTexture->GetSwapUV());
assert(pTexture->GetCroppingTop() == 0);
assert(pTexture->GetCroppingLeft() == 0);
assert(pTexture->GetCroppingRight() == 0);
assert(pTexture->GetCroppingBottom() == 0);
assert(pTexture->GetWrapModeU() == KFbxTexture::eRepeat);
assert(pTexture->GetWrapModeV() == KFbxTexture::eRepeat);
assert(pTexture->GetRotationU() == 0.0f);
assert(pTexture->GetRotationV() == 0.0f);
assert(pTexture->GetRotationW() == 0.0f);
KFbxFileTexture *pFileTexture = FbxCast<KFbxFileTexture>(pTexture);
if(pFileTexture) {
new_material->setDiffuseMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV()));
}
}
// Specular Map Texture
pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sSpecular);
if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) {
printf("Warning! Layered textures not supported.\n");
}
texture_count = pProperty.GetSrcObjectCount(KFbxTexture::ClassId);
if(texture_count > 1) {
printf("Error! Multiple specular textures not supported.\n");
} else if(texture_count == 1) {
KFbxTexture* pTexture = FbxCast <KFbxTexture> (pProperty.GetSrcObject(KFbxTexture::ClassId,0));
KFbxFileTexture *pFileTexture = FbxCast<KFbxFileTexture>(pTexture);
if(pFileTexture) {
new_material->setSpecularMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV()));
}
}
// Normal Map Texture
pProperty = pMaterial->FindProperty(KFbxSurfaceMaterial::sNormalMap);
if(pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId) > 0) {
printf("Warning! Layered textures not supported.\n");
}
texture_count = pProperty.GetSrcObjectCount<FbxTexture>();
if(texture_count > 1) {
printf("Error! Multiple normal map textures not supported.\n");
} else if(texture_count == 1) {
KFbxTexture* pTexture = pProperty.GetSrcObject<KFbxTexture>(0);
KFbxFileTexture *pFileTexture = FbxCast<KFbxFileTexture>(pTexture);
if(pFileTexture) {
new_material->setNormalMap(KRResource::GetFileBase(pFileTexture->GetFileName()), KRVector2(pTexture->GetScaleU(), pTexture->GetScaleV()), KRVector2(pTexture->GetTranslationU(), pTexture->GetTranslationV()));
}
}
bool bFound = false;
for(vector<KRResource *>::iterator resource_itr = resources.begin(); resource_itr != resources.end(); resource_itr++) {
KRResource *pResource = (*resource_itr);
if(pResource->getName() == new_material->getName() && pResource->getExtension() == new_material->getExtension()) {
bFound = true;
}
}
if(bFound) {
delete new_material;
} else {
resources.push_back(new_material);
}
} }
} }
delete control_point_weights; delete control_point_weights;
KRModel *new_mesh = new KRModel(context, pSourceMesh->GetNode()->GetName());
// ----====---- Generate Output Mesh Object ----====----
KRModel *new_mesh = new KRModel(parent_node->getContext(), pNode->GetName());
new_mesh->LoadData(vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights,KRModel::KRENGINE_MODEL_FORMAT_TRIANGLES); new_mesh->LoadData(vertices, uva, uvb, normals, tangents, submesh_starts, submesh_lengths, material_names, bone_names, bone_indexes, bone_weights,KRModel::KRENGINE_MODEL_FORMAT_TRIANGLES);
resources.push_back(new_mesh); resources.push_back(new_mesh);
}
KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, KFbxNode* pNode) {
std::string name = GetFbxObjectName(pNode);
if(new_mesh->getLODCoverage() == 100) { KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute();
if(KRModel::GetLODCoverage(pNode->GetName()) == 100) {
// If this is the full detail model, add an instance of it to the scene file // If this is the full detail model, add an instance of it to the scene file
std::string light_map = pNode->GetName(); std::string light_map = pNode->GetName();
light_map.append("_lightmap"); light_map.append("_lightmap");
KRInstance *new_instance = new KRInstance(parent_node->getScene(), name, pNode->GetName(), light_map, 0.0f, true, false); KRInstance *new_instance = new KRInstance(parent_node->getScene(), GetFbxObjectName(pNode), pSourceMesh->GetNode()->GetName(), light_map, 0.0f, true, false);
return new_instance; return new_instance;
} else { } else {
return NULL; return NULL;

View File

@@ -72,3 +72,13 @@ std::vector<KRResource *> KRResource::Load(KRContext &context, const std::string
return resources; return resources;
} }
bool KRResource::save(const std::string& path)
{
KRDataBlock data;
if(save(data)) {
return data.save(path);
} else {
return false;
}
}

View File

@@ -13,6 +13,7 @@
#import <string> #import <string>
#import "KREngine-common.h" #import "KREngine-common.h"
#import "KRContextObject.h" #import "KRContextObject.h"
#import "KRDataBlock.h"
#ifndef KREngine_KRResource_h #ifndef KREngine_KRResource_h
#define KREngine_KRResource_h #define KREngine_KRResource_h
@@ -22,7 +23,8 @@ class KRResource : public KRContextObject
public: public:
std::string getName(); std::string getName();
virtual std::string getExtension() = 0; virtual std::string getExtension() = 0;
virtual bool save(const std::string& path) = 0; virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data) = 0;
static std::string GetFileExtension(const std::string& name); static std::string GetFileExtension(const std::string& name);
static std::string GetFileBase(const std::string& name); static std::string GetFileBase(const std::string& name);

View File

@@ -320,13 +320,17 @@ KRNode *KRScene::getRootNode() {
return m_pRootNode; return m_pRootNode;
} }
bool KRScene::save(const std::string& path) { bool KRScene::save(KRDataBlock &data) {
tinyxml2::XMLDocument doc; tinyxml2::XMLDocument doc;
tinyxml2::XMLElement *scene_node = doc.NewElement( "scene" ); tinyxml2::XMLElement *scene_node = doc.NewElement( "scene" );
doc.InsertEndChild(scene_node); doc.InsertEndChild(scene_node);
m_pRootNode->saveXML(scene_node); m_pRootNode->saveXML(scene_node);
scene_node->SetAttribute("skybox", m_skyBoxName.c_str()); // This is temporary until the camera is moved into the scene graph scene_node->SetAttribute("skybox", m_skyBoxName.c_str()); // This is temporary until the camera is moved into the scene graph
doc.SaveFile(path.c_str());
tinyxml2::XMLPrinter p;
doc.Print(&p);
data.append((void *)p.CStr(), strlen(p.CStr())+1);
return true; return true;
} }
@@ -435,4 +439,15 @@ KRAABB KRScene::getRootOctreeBounds()
} else { } else {
return KRAABB(-KRVector3::One(), KRVector3::One()); return KRAABB(-KRVector3::One(), KRVector3::One());
} }
} }
bool KRScene::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{
return m_nodeTree.lineCast(v0, v1, hitinfo);
}
bool KRScene::rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
{
return m_nodeTree.rayCast(v0, v1, hitinfo);
}

View File

@@ -53,13 +53,16 @@ public:
virtual ~KRScene(); virtual ~KRScene();
virtual std::string getExtension(); virtual std::string getExtension();
virtual bool save(const std::string& path); virtual bool save(KRDataBlock &data);
static KRScene *Load(KRContext &context, const std::string &name, KRDataBlock *data); static KRScene *Load(KRContext &context, const std::string &name, KRDataBlock *data);
KRNode *getRootNode(); KRNode *getRootNode();
KRLight *getFirstLight(); KRLight *getFirstLight();
bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
bool rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame); void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame);

View File

@@ -12,9 +12,8 @@
#include "KRContext.h" #include "KRContext.h"
#include "KRTextureManager.h" #include "KRTextureManager.h"
KRTexture::KRTexture(KRContext &context) : KRContextObject(context) KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name)
{ {
m_iHandle = 0; m_iHandle = 0;
m_textureMemUsed = 0; m_textureMemUsed = 0;
m_last_frame_used = 0; m_last_frame_used = 0;
@@ -131,4 +130,8 @@ bool KRTexture::isAnimated()
return false; return false;
} }
KRTexture *KRTexture::compress()
{
return NULL;
}

View File

@@ -36,13 +36,14 @@
#import "KREngine-common.h" #import "KREngine-common.h"
#import "KRContextObject.h" #import "KRContextObject.h"
#import "KRResource.h"
class KRDataBlock; class KRDataBlock;
class KRTexture : public KRContextObject{ class KRTexture : public KRResource {
public: public:
KRTexture(KRContext &context); KRTexture(KRContext &context, std::string name);
virtual ~KRTexture(); virtual ~KRTexture();
virtual void bind() = 0; virtual void bind() = 0;
@@ -59,6 +60,8 @@ public:
virtual void resetPoolExpiry(); virtual void resetPoolExpiry();
virtual bool isAnimated(); virtual bool isAnimated();
KRTexture *compress();
protected: protected:
virtual bool createGLTexture(int lod_max_dim) = 0; virtual bool createGLTexture(int lod_max_dim) = 0;
GLuint getHandle(); GLuint getHandle();

View File

@@ -41,7 +41,7 @@
#import <stdint.h> #import <stdint.h>
#import <assert.h> #import <assert.h>
KRTexture2D::KRTexture2D(KRContext &context, KRDataBlock *data) : KRTexture(context) { KRTexture2D::KRTexture2D(KRContext &context, KRDataBlock *data, std::string name) : KRTexture(context, name) {
m_current_lod_max_dim = 0; m_current_lod_max_dim = 0;
m_pData = data; m_pData = data;
} }
@@ -97,4 +97,22 @@ int KRTexture2D::getMinMipMap() {
bool KRTexture2D::hasMipmaps() { bool KRTexture2D::hasMipmaps() {
return m_max_lod_max_dim != m_min_lod_max_dim; return m_max_lod_max_dim != m_min_lod_max_dim;
}
bool KRTexture2D::save(const std::string& path)
{
if(m_pData) {
return m_pData->save(path);
} else {
return false;
}
}
bool KRTexture2D::save(KRDataBlock &data) {
if(m_pData) {
data.append(*m_pData);
return true;
} else {
return false;
}
} }

View File

@@ -45,8 +45,10 @@ using std::list;
class KRTexture2D : public KRTexture { class KRTexture2D : public KRTexture {
public: public:
KRTexture2D(KRContext &context, KRDataBlock *data); KRTexture2D(KRContext &context, KRDataBlock *data, std::string name);
virtual ~KRTexture2D(); virtual ~KRTexture2D();
virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
bool hasMipmaps(); bool hasMipmaps();
int getMaxMipMap(); int getMaxMipMap();

View File

@@ -34,7 +34,7 @@
#include "KRTexture2D.h" #include "KRTexture2D.h"
#include "KRContext.h" #include "KRContext.h"
KRTextureAnimated::KRTextureAnimated(KRContext &context, std::string name) : KRTexture(context) KRTextureAnimated::KRTextureAnimated(KRContext &context, std::string name) : KRTexture(context, name)
{ {
// Format of name: // Format of name:
// animate:texturebasename,xx,yy // animate:texturebasename,xx,yy
@@ -138,3 +138,18 @@ bool KRTextureAnimated::isAnimated()
return true; return true;
} }
std::string KRTextureAnimated::getExtension()
{
return ""; // Animated textures are just references; there are no files to output
}
bool KRTextureAnimated::save(const std::string &path)
{
return true; // Animated textures are just references; there are no files to output
}
bool KRTextureAnimated::save(KRDataBlock &data)
{
return true; // Animated textures are just references; there are no files to output
}

View File

@@ -39,6 +39,9 @@ class KRTextureAnimated : public KRTexture {
public: public:
KRTextureAnimated(KRContext &context, std::string name); KRTextureAnimated(KRContext &context, std::string name);
virtual ~KRTextureAnimated(); virtual ~KRTextureAnimated();
virtual std::string getExtension();
virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
virtual void bind(); virtual void bind();
virtual long getMemRequiredForSize(int max_dim); virtual long getMemRequiredForSize(int max_dim);

View File

@@ -34,15 +34,14 @@
#include "KRTexture2D.h" #include "KRTexture2D.h"
#include "KRContext.h" #include "KRContext.h"
KRTextureCube::KRTextureCube(KRContext &context, std::string name) : KRTexture(context) KRTextureCube::KRTextureCube(KRContext &context, std::string name) : KRTexture(context, name)
{ {
m_name = name;
m_max_lod_max_dim = 2048; m_max_lod_max_dim = 2048;
m_min_lod_max_dim = 64; m_min_lod_max_dim = 64;
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
std::string faceName = m_name + SUFFIXES[i]; std::string faceName = getName() + SUFFIXES[i];
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str()); KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str());
if(faceTexture) { if(faceTexture) {
if(faceTexture->getMaxMipMap() < m_max_lod_max_dim) m_max_lod_max_dim = faceTexture->getMaxMipMap(); if(faceTexture->getMaxMipMap() < m_max_lod_max_dim) m_max_lod_max_dim = faceTexture->getMaxMipMap();
@@ -68,7 +67,7 @@ bool KRTextureCube::createGLTexture(int lod_max_dim)
bool bMipMaps = false; bool bMipMaps = false;
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
std::string faceName = m_name + SUFFIXES[i]; std::string faceName = getName() + SUFFIXES[i];
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str()); KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str());
if(faceTexture) { if(faceTexture) {
if(faceTexture->hasMipmaps()) bMipMaps = true; if(faceTexture->hasMipmaps()) bMipMaps = true;
@@ -93,7 +92,7 @@ long KRTextureCube::getMemRequiredForSize(int max_dim)
long memoryRequired = 0; long memoryRequired = 0;
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
std::string faceName = m_name + SUFFIXES[i]; std::string faceName = getName() + SUFFIXES[i];
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str()); KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str());
if(faceTexture) { if(faceTexture) {
memoryRequired += faceTexture->getMemRequiredForSize(target_dim); memoryRequired += faceTexture->getMemRequiredForSize(target_dim);
@@ -107,7 +106,7 @@ void KRTextureCube::resetPoolExpiry()
{ {
KRTexture::resetPoolExpiry(); KRTexture::resetPoolExpiry();
for(int i=0; i<6; i++) { for(int i=0; i<6; i++) {
std::string faceName = m_name + SUFFIXES[i]; std::string faceName = getName() + SUFFIXES[i];
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str()); KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName.c_str());
if(faceTexture) { if(faceTexture) {
faceTexture->resetPoolExpiry(); // Ensure that side of cube maps do not expire from the texture pool prematurely, as they are referenced indirectly faceTexture->resetPoolExpiry(); // Ensure that side of cube maps do not expire from the texture pool prematurely, as they are referenced indirectly
@@ -125,3 +124,17 @@ void KRTextureCube::bind()
} }
} }
std::string KRTextureCube::getExtension()
{
return ""; // Cube maps are just references; there are no files to output
}
bool KRTextureCube::save(const std::string &path)
{
return true; // Cube maps are just references; there are no files to output
}
bool KRTextureCube::save(KRDataBlock &data)
{
return true; // Cube maps are just references; there are no files to output
}

View File

@@ -38,6 +38,9 @@ class KRTextureCube : public KRTexture {
public: public:
KRTextureCube(KRContext &context, std::string name); KRTextureCube(KRContext &context, std::string name);
virtual ~KRTextureCube(); virtual ~KRTextureCube();
virtual std::string getExtension();
virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
virtual void bind(); virtual void bind();
virtual long getMemRequiredForSize(int max_dim); virtual long getMemRequiredForSize(int max_dim);
@@ -45,8 +48,6 @@ public:
private: private:
virtual bool createGLTexture(int lod_max_dim); virtual bool createGLTexture(int lod_max_dim);
std::string m_name;
const GLenum TARGETS[6] = { const GLenum TARGETS[6] = {
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X,

View File

@@ -66,9 +66,9 @@ KRTexture *KRTextureManager::loadTexture(const char *szName, const char *szExten
if(strcmp(szExtension, "pvr") == 0) { if(strcmp(szExtension, "pvr") == 0) {
pTexture = new KRTexturePVR(getContext(), data); pTexture = new KRTexturePVR(getContext(), data, szName);
} else if(strcmp(szExtension, "tga") == 0) { } else if(strcmp(szExtension, "tga") == 0) {
pTexture = new KRTextureTGA(getContext(), data); pTexture = new KRTextureTGA(getContext(), data, szName);
} }
if(pTexture) { if(pTexture) {
@@ -264,3 +264,40 @@ void KRTextureManager::memoryChanged(long memoryDelta)
{ {
m_textureMemUsed += memoryDelta; m_textureMemUsed += memoryDelta;
} }
std::map<std::string, KRTexture *> &KRTextureManager::getTextures()
{
return m_textures;
}
void KRTextureManager::compress()
{
std::vector<KRTexture *> textures_to_remove;
std::vector<KRTexture *> textures_to_add;
for(std::map<std::string, KRTexture *>::iterator itr=m_textures.begin(); itr != m_textures.end(); itr++) {
KRTexture *texture = (*itr).second;
KRTexture *compressed_texture = texture->compress();
if(compressed_texture) {
textures_to_remove.push_back(texture);
textures_to_add.push_back(compressed_texture);
}
}
for(std::vector<KRTexture *>::iterator itr = textures_to_remove.begin(); itr != textures_to_remove.end(); itr++) {
KRTexture *texture = *itr;
std::string lowerName = texture->getName();
std::transform(lowerName.begin(), lowerName.end(),
lowerName.begin(), ::tolower);
m_textures.erase(lowerName);
delete texture;
}
for(std::vector<KRTexture *>::iterator itr = textures_to_add.begin(); itr != textures_to_add.end(); itr++) {
KRTexture *texture = *itr;
std::string lowerName = texture->getName();
std::transform(lowerName.begin(), lowerName.end(),
lowerName.begin(), ::tolower);
m_textures[lowerName] = texture;
}
}

View File

@@ -65,6 +65,10 @@ public:
void startFrame(float deltaTime); void startFrame(float deltaTime);
void endFrame(float deltaTime); void endFrame(float deltaTime);
std::map<std::string, KRTexture *> &getTextures();
void compress();
private: private:
long m_memoryTransferredThisFrame; long m_memoryTransferredThisFrame;

View File

@@ -70,7 +70,7 @@ typedef struct _PVRTexHeader
uint32_t numSurfs; uint32_t numSurfs;
} PVRTexHeader; } PVRTexHeader;
KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data) : KRTexture2D(context, data) { KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name) {
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
PVRTexHeader *header = (PVRTexHeader *)m_pData->getStart(); PVRTexHeader *header = (PVRTexHeader *)m_pData->getStart();
uint32_t formatFlags = header->flags & PVR_TEXTURE_FLAG_TYPE_MASK; uint32_t formatFlags = header->flags & PVR_TEXTURE_FLAG_TYPE_MASK;
@@ -236,3 +236,9 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
return true; return true;
} }
std::string KRTexturePVR::getExtension()
{
return "pvr";
}

View File

@@ -14,8 +14,9 @@
class KRTexturePVR : public KRTexture2D class KRTexturePVR : public KRTexture2D
{ {
public: public:
KRTexturePVR(KRContext &context, KRDataBlock *data); KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name);
virtual ~KRTexturePVR(); virtual ~KRTexturePVR();
virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed); bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed);

View File

@@ -26,7 +26,7 @@ typedef struct {
} __attribute__((packed)) TGA_HEADER; } __attribute__((packed)) TGA_HEADER;
KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data) : KRTexture2D(context, data) KRTextureTGA::KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name) : KRTexture2D(context, data, name)
{ {
TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart(); TGA_HEADER *pHeader = (TGA_HEADER *)data->getStart();
@@ -132,3 +132,8 @@ long KRTextureTGA::getMemRequiredForSize(int max_dim)
return 0; return 0;
} }
std::string KRTextureTGA::getExtension()
{
return "tga";
}

View File

@@ -14,8 +14,9 @@
class KRTextureTGA : public KRTexture2D class KRTextureTGA : public KRTexture2D
{ {
public: public:
KRTextureTGA(KRContext &context, KRDataBlock *data); KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name);
virtual ~KRTextureTGA(); virtual ~KRTextureTGA();
virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed); bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed);

View File

@@ -1,29 +0,0 @@
//
// KRWorld.cpp
// KREngine
//
// Created by Kearwood Gilbert on 12-05-11.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#include <iostream>
#include "KRWorld.h"
#include "KRDataBlock.h"
KRWorld::KRWorld() {
}
KRWorld::~KRWorld() {
}
void KRWorld::Load(void *data, int data_size) {
}
KRDataBlock *KRWorld::Save() {
KRDataBlock *block = new KRDataBlock();
return block;
}

View File

@@ -1,24 +0,0 @@
//
// KRWorld.h
// KREngine
//
// Created by Kearwood Gilbert on 12-05-11.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
#ifndef KREngine_KRWorld_h
#define KREngine_KRWorld_h
class KRDataBlock;
class KRWorld {
public:
KRWorld();
~KRWorld();
void Load(void *data, int data_size);
KRDataBlock *Save();
private:
};
#endif