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:
@@ -230,3 +230,41 @@ float KRAABB::longest_radius() const
|
||||
float radius2 = (max - center()).magnitude();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ public:
|
||||
bool contains(const KRAABB &b) const;
|
||||
bool contains(const KRVector3 &v) 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);
|
||||
bool operator ==(const KRAABB& b) const;
|
||||
|
||||
@@ -61,7 +61,7 @@ void KRAnimation::addLayer(KRAnimationLayer *layer)
|
||||
m_layers[layer->getName()] = layer;
|
||||
}
|
||||
|
||||
bool KRAnimation::save(const std::string& path) {
|
||||
bool KRAnimation::save(KRDataBlock &data) {
|
||||
tinyxml2::XMLDocument doc;
|
||||
tinyxml2::XMLElement *animation_node = doc.NewElement( "animation" );
|
||||
doc.InsertEndChild(animation_node);
|
||||
@@ -73,11 +73,13 @@ bool KRAnimation::save(const std::string& path) {
|
||||
(*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;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
virtual ~KRAnimation();
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -51,10 +51,10 @@ tinyxml2::XMLElement *KRAnimationAttribute::saveXML( tinyxml2::XMLNode *parent)
|
||||
{
|
||||
tinyxml2::XMLDocument *doc = parent->GetDocument();
|
||||
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("target", m_target_name.c_str());
|
||||
char *szAttribute = "none";
|
||||
const char *szAttribute = "none";
|
||||
switch(m_node_attribute) {
|
||||
case KRNode::KRENGINE_NODE_ATTRIBUTE_NONE:
|
||||
szAttribute = "none";
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
//
|
||||
|
||||
#include "KRAnimationCurve.h"
|
||||
#include "KRDataBlock.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
bool KRAnimationCurve::save(KRDataBlock &data) {
|
||||
data.append(*m_pData);
|
||||
return true;
|
||||
}
|
||||
|
||||
KRAnimationCurve *KRAnimationCurve::Load(KRContext &context, const std::string &name, KRDataBlock *data)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
|
||||
virtual std::string getExtension();
|
||||
virtual bool save(const std::string& path);
|
||||
virtual bool save(KRDataBlock &data);
|
||||
virtual bool load(KRDataBlock *data);
|
||||
|
||||
float getFrameRate();
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
#include "KRBundle.h"
|
||||
#include "KRContext.h"
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
const int KRENGINE_KRBUNDLE_HEADER_SIZE = 512;
|
||||
|
||||
typedef struct _tar_header
|
||||
{
|
||||
@@ -47,7 +50,7 @@ typedef struct _tar_header
|
||||
|
||||
} 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;
|
||||
|
||||
@@ -69,6 +72,7 @@ KRBundle::KRBundle(KRContext &context, std::string name, KRDataBlock *pData) : K
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -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
|
||||
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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -35,13 +35,20 @@
|
||||
#import "KRResource.h"
|
||||
#import "KRDataBlock.h"
|
||||
|
||||
class KRBundle : public KRContextObject {
|
||||
class KRBundle : public KRResource {
|
||||
public:
|
||||
KRBundle(KRContext &context, std::string name, KRDataBlock *pData);
|
||||
KRBundle(KRContext &context, std::string name);
|
||||
virtual ~KRBundle();
|
||||
virtual std::string getExtension();
|
||||
virtual bool save(const std::string& path);
|
||||
virtual bool save(KRDataBlock &data);
|
||||
|
||||
void append(KRResource &resource);
|
||||
|
||||
private:
|
||||
KRDataBlock *m_pData;
|
||||
static size_t RoundUpSize(size_t s);
|
||||
};
|
||||
|
||||
#endif /* defined(KRBUNDLE_H) */
|
||||
|
||||
@@ -76,12 +76,14 @@ KRAABB KRCollider::getBounds() {
|
||||
bool KRCollider::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo)
|
||||
{
|
||||
if(m_models.size()) {
|
||||
KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode());
|
||||
KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0);
|
||||
KRVector3 v1_model_space = KRMat4::Dot(getModelMatrix(), v1);
|
||||
if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) {
|
||||
hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), hitinfo_model_space.getNode());
|
||||
return true;
|
||||
if(getBounds().intersectsLine(v0, v1)) {
|
||||
KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode());
|
||||
KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0);
|
||||
KRVector3 v1_model_space = KRMat4::Dot(getModelMatrix(), v1);
|
||||
if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) {
|
||||
hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
if(m_models.size()) {
|
||||
KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode());
|
||||
KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0);
|
||||
KRVector3 v1_model_space = v0_model_space + KRMat4::DotNoTranslate(getModelMatrix(), KRVector3::Normalize(v1 - v0));
|
||||
if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) {
|
||||
hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), hitinfo_model_space.getNode());
|
||||
return true;
|
||||
if(getBounds().intersectsRay(v0, v1)) {
|
||||
KRHitInfo hitinfo_model_space = KRHitInfo(KRMat4::Dot(getInverseModelMatrix(), hitinfo.getPosition()), KRMat4::DotNoTranslate(getInverseModelMatrix(), hitinfo.getNormal()), hitinfo.getNode());
|
||||
KRVector3 v0_model_space = KRMat4::Dot(getModelMatrix(), v0);
|
||||
KRVector3 v1_model_space = v0_model_space + KRMat4::DotNoTranslate(getModelMatrix(), KRVector3::Normalize(v1 - v0));
|
||||
if(m_models[0]->lineCast(v0_model_space, v1_model_space, hitinfo_model_space)) {
|
||||
hitinfo = KRHitInfo(KRMat4::Dot(getModelMatrix(), hitinfo_model_space.getPosition()), KRMat4::DotNoTranslate(getModelMatrix(), hitinfo_model_space.getNormal()), this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -65,7 +65,6 @@ public:
|
||||
|
||||
long getCurrentFrame() const;
|
||||
float getAbsoluteTime() const;
|
||||
|
||||
private:
|
||||
KRBundleManager *m_pBundleManager;
|
||||
KRSceneManager *m_pSceneManager;
|
||||
|
||||
@@ -153,6 +153,18 @@ void KRDataBlock::append(void *data, size_t 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
|
||||
bool KRDataBlock::save(const std::string& path) {
|
||||
int fdNewFile = open(path.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
|
||||
|
||||
@@ -49,6 +49,12 @@ public:
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
void expand(size_t size);
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ KRVector3 KRMat4::Dot(const KRMat4 &m, const KRVector3 &v) {
|
||||
}
|
||||
|
||||
// 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(
|
||||
v.x * (float)m[0*4 + 0] + v.y * (float)m[1*4 + 0] + v.z * (float)m[2*4 + 0],
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -77,67 +79,69 @@ KRMaterial::~KRMaterial() {
|
||||
std::string KRMaterial::getExtension() {
|
||||
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);
|
||||
fprintf(f, "ka %f %f %f\n", m_ambientColor.x, m_ambientColor.y, m_ambientColor.z);
|
||||
fprintf(f, "kd %f %f %f\n", m_diffuseColor.x, m_diffuseColor.y, m_diffuseColor.z);
|
||||
fprintf(f, "ks %f %f %f\n", m_specularColor.x, m_specularColor.y, m_specularColor.z);
|
||||
fprintf(f, "kr %f %f %f\n", m_reflectionColor.x, m_reflectionColor.y, m_reflectionColor.z);
|
||||
fprintf(f, "Tr %f\n", m_tr);
|
||||
fprintf(f, "Ns %f\n", m_ns);
|
||||
if(m_ambientMap.size()) {
|
||||
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);
|
||||
} else {
|
||||
fprintf(f, "# map_Ka filename.pvr -s 1.0 1.0 -o 0.0 0.0\n");
|
||||
}
|
||||
if(m_diffuseMap.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);
|
||||
} else {
|
||||
fprintf(f, "# map_Kd filename.pvr -s 1.0 1.0 -o 0.0 0.0\n");
|
||||
}
|
||||
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;
|
||||
bool KRMaterial::save(KRDataBlock &data) {
|
||||
std::stringstream stream;
|
||||
stream.precision(std::numeric_limits<long double>::digits10);
|
||||
stream.setf(ios::fixed,ios::floatfield);
|
||||
|
||||
stream << "newmtl " << m_szName;
|
||||
stream << "\nka " << m_ambientColor.x << " " << m_ambientColor.y << " " << m_ambientColor.z;
|
||||
stream << "\nkd " << m_diffuseColor.x << " " << m_diffuseColor.y << " " << m_diffuseColor.z;
|
||||
stream << "\nks " << m_specularColor.x << " " << m_specularColor.y << " " << m_specularColor.z;
|
||||
stream << "\nkr " << m_reflectionColor.x << " " << m_reflectionColor.y << " " << m_reflectionColor.z;
|
||||
stream << "\nTr " << m_tr;
|
||||
stream << "\nNs " << m_ns;
|
||||
if(m_ambientMap.size()) {
|
||||
stream << "\nmap_Ka " << m_ambientMap << ".pvr -s " << m_ambientMapScale.x << " " << m_ambientMapScale.y << " -o " << m_ambientMapOffset.x << " " << m_ambientMapOffset.y;
|
||||
} else {
|
||||
stream << "\n# map_Ka filename.pvr -s 1.0 1.0 -o 0.0 0.0";
|
||||
}
|
||||
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) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
virtual ~KRMaterial();
|
||||
|
||||
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);
|
||||
|
||||
@@ -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() {
|
||||
clearData();
|
||||
if(m_pData) delete m_pData;
|
||||
@@ -100,6 +122,12 @@ bool KRModel::save(const std::string& path) {
|
||||
return m_pData->save(path);
|
||||
}
|
||||
|
||||
bool KRModel::save(KRDataBlock &data) {
|
||||
clearBuffers();
|
||||
data.append(*m_pData);
|
||||
return true;
|
||||
}
|
||||
|
||||
void KRModel::loadPack(KRDataBlock *data) {
|
||||
clearData();
|
||||
delete m_pData;
|
||||
@@ -802,12 +830,12 @@ bool KRModel::rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitin
|
||||
switch(getModelFormat()) {
|
||||
case KRENGINE_MODEL_FORMAT_TRIANGLES:
|
||||
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;
|
||||
case KRENGINE_MODEL_FORMAT_STRIP:
|
||||
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;
|
||||
default:
|
||||
|
||||
@@ -99,6 +99,7 @@ public:
|
||||
|
||||
virtual std::string getExtension();
|
||||
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 loadPack(KRDataBlock *data);
|
||||
@@ -186,6 +187,8 @@ public:
|
||||
|
||||
bool lineCast(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:
|
||||
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);
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include "KROctree.h"
|
||||
#include "KRNode.h"
|
||||
#include "KRHitInfo.h"
|
||||
#include "KRCollider.h"
|
||||
|
||||
KROctree::KROctree()
|
||||
{
|
||||
@@ -91,3 +93,34 @@ std::set<KRNode *> &KROctree::getOuterSceneNodes()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#import "KREngine-common.h"
|
||||
#include "KROctreeNode.h"
|
||||
#include "KRMat4.h"
|
||||
#include "KRHitInfo.h"
|
||||
|
||||
class KRNode;
|
||||
|
||||
@@ -26,10 +27,13 @@ public:
|
||||
|
||||
KROctreeNode *getRootNode();
|
||||
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:
|
||||
KROctreeNode *m_pRootNode;
|
||||
std::set<KRNode *>m_outerSceneNodes;
|
||||
std::set<KRNode *> m_outerSceneNodes;
|
||||
//std::set<KRMat4> visibleMVPs;
|
||||
|
||||
void shrink();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "KROctreeNode.h"
|
||||
#include "KRNode.h"
|
||||
#include "KRCollider.h"
|
||||
|
||||
KROctreeNode::KROctreeNode(const KRAABB &bounds) : m_bounds(bounds)
|
||||
{
|
||||
@@ -173,3 +174,61 @@ std::set<KRNode *> &KROctreeNode::getSceneNodes()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#import "KREngine-common.h"
|
||||
#include "KRVector3.h"
|
||||
#include "KRAABB.h"
|
||||
#include "KRHitInfo.h"
|
||||
|
||||
class KRNode;
|
||||
|
||||
@@ -45,6 +46,9 @@ public:
|
||||
GLuint m_occlusionQuery;
|
||||
bool m_occlusionTested;
|
||||
bool m_activeQuery;
|
||||
|
||||
bool lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
|
||||
bool rayCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo);
|
||||
private:
|
||||
|
||||
KRAABB m_bounds;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "KRScene.h"
|
||||
#include "KRQuaternion.h"
|
||||
#include "KRBone.h"
|
||||
#include "KRBundle.h"
|
||||
|
||||
#ifdef IOS_REF
|
||||
#undef IOS_REF
|
||||
@@ -47,6 +48,8 @@ KRAnimationCurve *LoadAnimationCurve(KRContext &context, FbxAnimCurve* pAnimCurv
|
||||
KRAnimationLayer *LoadAnimationLayer(KRContext &context, FbxAnimLayer *pAnimLayer);
|
||||
void LoadNode(KFbxScene* pFbxScene, KRNode *parent_node, std::vector<KRResource *> &resources, FbxGeometryConverter *pGeometryConverter, 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 *LoadLight(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();
|
||||
}
|
||||
|
||||
// ----====---- 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 ----====----
|
||||
printf("\nLoading scene graph...\n");
|
||||
if(pNode)
|
||||
{
|
||||
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);
|
||||
|
||||
// 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++) {
|
||||
KRAnimation *animation = dynamic_cast<KRAnimation *>(*resource_itr);
|
||||
KRAnimationCurve *animation_curve = dynamic_cast<KRAnimationCurve *>(*resource_itr);
|
||||
if(animation) {
|
||||
context.getAnimationManager()->getAnimations().erase(animation->getName());
|
||||
}
|
||||
if(animation_curve) {
|
||||
context.getAnimationCurveManager()->getAnimationCurves().erase(animation_curve->getName());
|
||||
KRResource *resource = *resource_itr;
|
||||
if(dynamic_cast<KRTexture *>(resource) != NULL) {
|
||||
texture_bundle.append(*resource);
|
||||
} else if(dynamic_cast<KRAnimation *>(resource) != NULL) {
|
||||
animation_bundle.append(*resource);
|
||||
// } else if(dynamic_cast<KRMaterial *>(resource) != NULL) {
|
||||
// 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) {
|
||||
std::string name = GetFbxObjectName(pNode);
|
||||
printf("Mesh: %s\n", name.c_str());
|
||||
KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute();
|
||||
void LoadMaterial(KRContext &context, std::vector<KRResource *> &resources, FbxSurfaceMaterial *pMaterial) {
|
||||
//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(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);
|
||||
|
||||
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].bone_indexes[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
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 tangent_count = pMesh->GetElementTangentCount();
|
||||
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<int> > bone_indexes;
|
||||
|
||||
@@ -803,9 +1007,9 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
|
||||
std::vector<std::string> material_names;
|
||||
|
||||
int dest_vertex_id = 0;
|
||||
|
||||
|
||||
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 mat_vertex_count = 0;
|
||||
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]);
|
||||
}
|
||||
uvb.push_back(new_uvb);
|
||||
}
|
||||
}
|
||||
|
||||
// ----====---- Read Normals ----====----
|
||||
|
||||
@@ -910,9 +1114,9 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
source_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_lengths.push_back(mat_vertex_count);
|
||||
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;
|
||||
|
||||
|
||||
// ----====---- Generate Output Mesh Object ----====----
|
||||
|
||||
KRModel *new_mesh = new KRModel(parent_node->getContext(), pNode->GetName());
|
||||
KRModel *new_mesh = new KRModel(context, pSourceMesh->GetNode()->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);
|
||||
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
|
||||
std::string light_map = pNode->GetName();
|
||||
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;
|
||||
} else {
|
||||
return NULL;
|
||||
|
||||
@@ -72,3 +72,13 @@ std::vector<KRResource *> KRResource::Load(KRContext &context, const std::string
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
bool KRResource::save(const std::string& path)
|
||||
{
|
||||
KRDataBlock data;
|
||||
if(save(data)) {
|
||||
return data.save(path);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
#import <string>
|
||||
#import "KREngine-common.h"
|
||||
#import "KRContextObject.h"
|
||||
#import "KRDataBlock.h"
|
||||
|
||||
#ifndef KREngine_KRResource_h
|
||||
#define KREngine_KRResource_h
|
||||
@@ -22,7 +23,8 @@ class KRResource : public KRContextObject
|
||||
public:
|
||||
std::string getName();
|
||||
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 GetFileBase(const std::string& name);
|
||||
|
||||
@@ -320,13 +320,17 @@ KRNode *KRScene::getRootNode() {
|
||||
return m_pRootNode;
|
||||
}
|
||||
|
||||
bool KRScene::save(const std::string& path) {
|
||||
bool KRScene::save(KRDataBlock &data) {
|
||||
tinyxml2::XMLDocument doc;
|
||||
tinyxml2::XMLElement *scene_node = doc.NewElement( "scene" );
|
||||
doc.InsertEndChild(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
|
||||
doc.SaveFile(path.c_str());
|
||||
|
||||
tinyxml2::XMLPrinter p;
|
||||
doc.Print(&p);
|
||||
data.append((void *)p.CStr(), strlen(p.CStr())+1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -435,4 +439,15 @@ KRAABB KRScene::getRootOctreeBounds()
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -53,13 +53,16 @@ public:
|
||||
virtual ~KRScene();
|
||||
|
||||
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);
|
||||
|
||||
KRNode *getRootNode();
|
||||
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
|
||||
|
||||
void render(KRCamera *pCamera, std::map<KRAABB, int> &visibleBounds, const KRViewport &viewport, KRNode::RenderPass renderPass, bool new_frame);
|
||||
|
||||
@@ -12,9 +12,8 @@
|
||||
#include "KRContext.h"
|
||||
#include "KRTextureManager.h"
|
||||
|
||||
KRTexture::KRTexture(KRContext &context) : KRContextObject(context)
|
||||
KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name)
|
||||
{
|
||||
|
||||
m_iHandle = 0;
|
||||
m_textureMemUsed = 0;
|
||||
m_last_frame_used = 0;
|
||||
@@ -131,4 +130,8 @@ bool KRTexture::isAnimated()
|
||||
return false;
|
||||
}
|
||||
|
||||
KRTexture *KRTexture::compress()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,13 +36,14 @@
|
||||
|
||||
#import "KREngine-common.h"
|
||||
#import "KRContextObject.h"
|
||||
#import "KRResource.h"
|
||||
|
||||
|
||||
class KRDataBlock;
|
||||
|
||||
class KRTexture : public KRContextObject{
|
||||
class KRTexture : public KRResource {
|
||||
public:
|
||||
KRTexture(KRContext &context);
|
||||
KRTexture(KRContext &context, std::string name);
|
||||
virtual ~KRTexture();
|
||||
|
||||
virtual void bind() = 0;
|
||||
@@ -59,6 +60,8 @@ public:
|
||||
virtual void resetPoolExpiry();
|
||||
virtual bool isAnimated();
|
||||
|
||||
KRTexture *compress();
|
||||
|
||||
protected:
|
||||
virtual bool createGLTexture(int lod_max_dim) = 0;
|
||||
GLuint getHandle();
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#import <stdint.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_pData = data;
|
||||
}
|
||||
@@ -97,4 +97,22 @@ int KRTexture2D::getMinMipMap() {
|
||||
|
||||
bool KRTexture2D::hasMipmaps() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -45,8 +45,10 @@ using std::list;
|
||||
|
||||
class KRTexture2D : public KRTexture {
|
||||
public:
|
||||
KRTexture2D(KRContext &context, KRDataBlock *data);
|
||||
KRTexture2D(KRContext &context, KRDataBlock *data, std::string name);
|
||||
virtual ~KRTexture2D();
|
||||
virtual bool save(const std::string& path);
|
||||
virtual bool save(KRDataBlock &data);
|
||||
|
||||
bool hasMipmaps();
|
||||
int getMaxMipMap();
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "KRTexture2D.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:
|
||||
// animate:texturebasename,xx,yy
|
||||
@@ -138,3 +138,18 @@ bool KRTextureAnimated::isAnimated()
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,9 @@ class KRTextureAnimated : public KRTexture {
|
||||
public:
|
||||
KRTextureAnimated(KRContext &context, std::string name);
|
||||
virtual ~KRTextureAnimated();
|
||||
virtual std::string getExtension();
|
||||
virtual bool save(const std::string& path);
|
||||
virtual bool save(KRDataBlock &data);
|
||||
|
||||
virtual void bind();
|
||||
virtual long getMemRequiredForSize(int max_dim);
|
||||
|
||||
@@ -34,15 +34,14 @@
|
||||
#include "KRTexture2D.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_min_lod_max_dim = 64;
|
||||
|
||||
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());
|
||||
if(faceTexture) {
|
||||
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;
|
||||
|
||||
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());
|
||||
if(faceTexture) {
|
||||
if(faceTexture->hasMipmaps()) bMipMaps = true;
|
||||
@@ -93,7 +92,7 @@ long KRTextureCube::getMemRequiredForSize(int max_dim)
|
||||
|
||||
long memoryRequired = 0;
|
||||
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());
|
||||
if(faceTexture) {
|
||||
memoryRequired += faceTexture->getMemRequiredForSize(target_dim);
|
||||
@@ -107,7 +106,7 @@ void KRTextureCube::resetPoolExpiry()
|
||||
{
|
||||
KRTexture::resetPoolExpiry();
|
||||
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());
|
||||
if(faceTexture) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ class KRTextureCube : public KRTexture {
|
||||
public:
|
||||
KRTextureCube(KRContext &context, std::string name);
|
||||
virtual ~KRTextureCube();
|
||||
virtual std::string getExtension();
|
||||
virtual bool save(const std::string& path);
|
||||
virtual bool save(KRDataBlock &data);
|
||||
|
||||
virtual void bind();
|
||||
virtual long getMemRequiredForSize(int max_dim);
|
||||
@@ -45,8 +48,6 @@ public:
|
||||
|
||||
private:
|
||||
virtual bool createGLTexture(int lod_max_dim);
|
||||
|
||||
std::string m_name;
|
||||
|
||||
const GLenum TARGETS[6] = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
|
||||
@@ -66,9 +66,9 @@ KRTexture *KRTextureManager::loadTexture(const char *szName, const char *szExten
|
||||
|
||||
|
||||
if(strcmp(szExtension, "pvr") == 0) {
|
||||
pTexture = new KRTexturePVR(getContext(), data);
|
||||
pTexture = new KRTexturePVR(getContext(), data, szName);
|
||||
} else if(strcmp(szExtension, "tga") == 0) {
|
||||
pTexture = new KRTextureTGA(getContext(), data);
|
||||
pTexture = new KRTextureTGA(getContext(), data, szName);
|
||||
}
|
||||
|
||||
if(pTexture) {
|
||||
@@ -264,3 +264,40 @@ void KRTextureManager::memoryChanged(long 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;
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,10 @@ public:
|
||||
void startFrame(float deltaTime);
|
||||
void endFrame(float deltaTime);
|
||||
|
||||
std::map<std::string, KRTexture *> &getTextures();
|
||||
|
||||
void compress();
|
||||
|
||||
private:
|
||||
long m_memoryTransferredThisFrame;
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ typedef struct _PVRTexHeader
|
||||
uint32_t numSurfs;
|
||||
} 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
|
||||
PVRTexHeader *header = (PVRTexHeader *)m_pData->getStart();
|
||||
uint32_t formatFlags = header->flags & PVR_TEXTURE_FLAG_TYPE_MASK;
|
||||
@@ -236,3 +236,9 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lo
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
std::string KRTexturePVR::getExtension()
|
||||
{
|
||||
return "pvr";
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
class KRTexturePVR : public KRTexture2D
|
||||
{
|
||||
public:
|
||||
KRTexturePVR(KRContext &context, KRDataBlock *data);
|
||||
KRTexturePVR(KRContext &context, KRDataBlock *data, std::string name);
|
||||
virtual ~KRTexturePVR();
|
||||
virtual std::string getExtension();
|
||||
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ typedef struct {
|
||||
} __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();
|
||||
|
||||
@@ -132,3 +132,8 @@ long KRTextureTGA::getMemRequiredForSize(int max_dim)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string KRTextureTGA::getExtension()
|
||||
{
|
||||
return "tga";
|
||||
}
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
class KRTextureTGA : public KRTexture2D
|
||||
{
|
||||
public:
|
||||
KRTextureTGA(KRContext &context, KRDataBlock *data);
|
||||
KRTextureTGA(KRContext &context, KRDataBlock *data, std::string name);
|
||||
virtual ~KRTextureTGA();
|
||||
virtual std::string getExtension();
|
||||
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user