Initial import of KREngine
--HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%404
This commit is contained in:
215
objpack/objpack.xcodeproj/project.pbxproj
Normal file
215
objpack/objpack.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,215 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E404C89D136B8E2F00B6C99B /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E404C89C136B8E2F00B6C99B /* main.cpp */; };
|
||||
E404C8A6136B901400B6C99B /* KROBJPacker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E404C8A4136B901400B6C99B /* KROBJPacker.cpp */; };
|
||||
E404C8A9136B919F00B6C99B /* KRVector3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E404C8A7136B919F00B6C99B /* KRVector3.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
E404C896136B8E2F00B6C99B /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
E404C898136B8E2F00B6C99B /* objpack */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = objpack; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E404C89C136B8E2F00B6C99B /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
E404C89E136B8E2F00B6C99B /* objpack.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = objpack.1; sourceTree = "<group>"; };
|
||||
E404C8A4136B901400B6C99B /* KROBJPacker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KROBJPacker.cpp; sourceTree = "<group>"; };
|
||||
E404C8A5136B901400B6C99B /* KROBJPacker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KROBJPacker.h; sourceTree = "<group>"; };
|
||||
E404C8A7136B919F00B6C99B /* KRVector3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRVector3.cpp; sourceTree = "<group>"; };
|
||||
E404C8A8136B919F00B6C99B /* KRVector3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRVector3.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
E404C895136B8E2F00B6C99B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
E404C88D136B8E2F00B6C99B = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E404C89B136B8E2F00B6C99B /* objpack */,
|
||||
E404C899136B8E2F00B6C99B /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E404C899136B8E2F00B6C99B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E404C898136B8E2F00B6C99B /* objpack */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E404C89B136B8E2F00B6C99B /* objpack */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E404C89C136B8E2F00B6C99B /* main.cpp */,
|
||||
E404C89E136B8E2F00B6C99B /* objpack.1 */,
|
||||
E404C8A4136B901400B6C99B /* KROBJPacker.cpp */,
|
||||
E404C8A5136B901400B6C99B /* KROBJPacker.h */,
|
||||
E404C8A7136B919F00B6C99B /* KRVector3.cpp */,
|
||||
E404C8A8136B919F00B6C99B /* KRVector3.h */,
|
||||
);
|
||||
path = objpack;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
E404C897136B8E2F00B6C99B /* objpack */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E404C8A1136B8E3000B6C99B /* Build configuration list for PBXNativeTarget "objpack" */;
|
||||
buildPhases = (
|
||||
E404C894136B8E2F00B6C99B /* Sources */,
|
||||
E404C895136B8E2F00B6C99B /* Frameworks */,
|
||||
E404C896136B8E2F00B6C99B /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = objpack;
|
||||
productName = objpack;
|
||||
productReference = E404C898136B8E2F00B6C99B /* objpack */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
E404C88F136B8E2F00B6C99B /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0420;
|
||||
ORGANIZATIONNAME = "Kearwood Software";
|
||||
};
|
||||
buildConfigurationList = E404C892136B8E2F00B6C99B /* Build configuration list for PBXProject "objpack" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = E404C88D136B8E2F00B6C99B;
|
||||
productRefGroup = E404C899136B8E2F00B6C99B /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
E404C897136B8E2F00B6C99B /* objpack */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
E404C894136B8E2F00B6C99B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E404C89D136B8E2F00B6C99B /* main.cpp in Sources */,
|
||||
E404C8A6136B901400B6C99B /* KROBJPacker.cpp in Sources */,
|
||||
E404C8A9136B919F00B6C99B /* KRVector3.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
E404C89F136B8E3000B6C99B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E404C8A0136B8E3000B6C99B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E404C8A2136B8E3000B6C99B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E404C8A3136B8E3000B6C99B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
E404C892136B8E2F00B6C99B /* Build configuration list for PBXProject "objpack" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E404C89F136B8E3000B6C99B /* Debug */,
|
||||
E404C8A0136B8E3000B6C99B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E404C8A1136B8E3000B6C99B /* Build configuration list for PBXNativeTarget "objpack" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E404C8A2136B8E3000B6C99B /* Debug */,
|
||||
E404C8A3136B8E3000B6C99B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = E404C88F136B8E2F00B6C99B /* Project object */;
|
||||
}
|
||||
7
objpack/objpack.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
objpack/objpack.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:objpack.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
491
objpack/objpack/KROBJPacker.cpp
Normal file
491
objpack/objpack/KROBJPacker.cpp
Normal file
@@ -0,0 +1,491 @@
|
||||
//
|
||||
// objpacker.cpp
|
||||
// objpack
|
||||
//
|
||||
// Created by Kearwood Gilbert on 11-04-29.
|
||||
// Copyright 2011 Kearwood Software. All rights reserved.
|
||||
//
|
||||
|
||||
#import <stdint.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <vector.h>
|
||||
|
||||
#include "KROBJPacker.h"
|
||||
|
||||
#include "KRVector3.h"
|
||||
|
||||
KROBJPacker::KROBJPacker() {
|
||||
|
||||
}
|
||||
|
||||
KROBJPacker::~KROBJPacker() {
|
||||
|
||||
}
|
||||
|
||||
void KROBJPacker::pack(const char *szPath) {
|
||||
int fdFile = 0;
|
||||
int fileSize = 0;
|
||||
void *pFile = NULL;
|
||||
char szSymbol[16][64];
|
||||
|
||||
std::vector<std::string> materials;
|
||||
|
||||
Vertex3D *pVertices = NULL;
|
||||
Vector3D *pNormals = NULL;
|
||||
TexCoord *pTexCoords = NULL;
|
||||
int *pFaces = NULL;
|
||||
|
||||
vector<pack_material *> m_materials;
|
||||
VertexData *m_pVertexData = NULL;
|
||||
|
||||
pack_header header;
|
||||
strcpy(header.szTag, "KROBJPACK1.0 ");
|
||||
|
||||
struct stat statbuf;
|
||||
fdFile = open(szPath, O_RDONLY);
|
||||
if(fdFile >= 0) {
|
||||
if(fstat(fdFile, &statbuf) >= 0) {
|
||||
if ((pFile = mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdFile, 0)) == (caddr_t) -1) {
|
||||
} else {
|
||||
fileSize = statbuf.st_size;
|
||||
|
||||
// Pass 1 - Get counts
|
||||
cout << " Pass 1 - Getting Counts\n";
|
||||
|
||||
int cVertices = 0;
|
||||
int cNormals = 0;
|
||||
int cTexCoords = 0;
|
||||
int cVertexData = 0;
|
||||
|
||||
|
||||
cVertices = 0;
|
||||
int cFaces = 1;
|
||||
int cMaterialFaceStart = 1;
|
||||
|
||||
char *pScan = (char *)pFile;
|
||||
char *pEnd = (char *)pFile + fileSize;
|
||||
while(pScan < pEnd) {
|
||||
|
||||
// Scan through whitespace
|
||||
while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) {
|
||||
pScan++;
|
||||
}
|
||||
|
||||
if(*pScan == '#') {
|
||||
// Line is a comment line
|
||||
|
||||
// Scan to the end of the line
|
||||
while(pScan < pEnd && *pScan != '\r' && *pScan != '\n') {
|
||||
pScan++;
|
||||
}
|
||||
} else {
|
||||
int cSymbols = 0;
|
||||
while(pScan < pEnd && *pScan != '\n' && *pScan != '\r') {
|
||||
|
||||
char *pDest = szSymbol[cSymbols++];
|
||||
while(pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') {
|
||||
*pDest++ = *pScan++;
|
||||
}
|
||||
*pDest = '\0';
|
||||
|
||||
// Scan through whitespace, but don't advance to next line
|
||||
while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) {
|
||||
pScan++;
|
||||
}
|
||||
}
|
||||
|
||||
if(strcmp(szSymbol[0], "v") == 0) {
|
||||
// Vertex (v)
|
||||
cVertices++;
|
||||
} else if(strcmp(szSymbol[0], "vt") == 0) {
|
||||
// Vertex Texture UV Coordinate (vt)
|
||||
cTexCoords++;
|
||||
} else if(strcmp(szSymbol[0], "vn") == 0) {
|
||||
// Vertex Normal (vn)
|
||||
cNormals++;
|
||||
} else if(strcmp(szSymbol[0], "f") == 0) {
|
||||
// Face (f)
|
||||
int cFaceVertexes = (cSymbols - 3) * 3; // 3 vertexes per triangle. Triangles have 4 symbols. Quads have 5 symbols and generate two triangles.
|
||||
cVertexData += cFaceVertexes;
|
||||
cFaces += cFaceVertexes * 3 + 1; // Allocate space for count of vertices, Vertex Index, Texture Coordinate Index, and Normal Index
|
||||
|
||||
} else if(strcmp(szSymbol[0], "usemtl") == 0) {
|
||||
// Use Material (usemtl)
|
||||
if(cMaterialFaceStart - cFaces > 0) {
|
||||
cFaces++;
|
||||
|
||||
}
|
||||
materials.push_back(std::string(szSymbol[1]));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Pass 2 - Populate vertexes and faces
|
||||
cout << " Pass 2 - Populate vertexes and faces\n";
|
||||
|
||||
Vertex3D *pVertices = (Vertex3D *)malloc(sizeof(Vertex3D) * cVertices);
|
||||
Vector3D *pNormals = (Vector3D *)malloc(sizeof(Vector3D) *cNormals);
|
||||
TexCoord *pTexCoords = (TexCoord *)malloc(sizeof(TexCoord) * cTexCoords);
|
||||
int *pFaces = (int *)malloc(sizeof(int *) * (cFaces + 1));
|
||||
|
||||
|
||||
Vertex3D *pVertice = pVertices;
|
||||
Vector3D *pNormal = pNormals;
|
||||
TexCoord *pTexCoord = pTexCoords;
|
||||
int *pFace = pFaces;
|
||||
int *pMaterialFaces = pFace++;
|
||||
*pMaterialFaces = 0;
|
||||
|
||||
|
||||
std::vector<std::string>::iterator material_itr = materials.begin();
|
||||
|
||||
// --------
|
||||
|
||||
pScan = (char *)pFile;
|
||||
while(pScan < pEnd) {
|
||||
|
||||
// Scan through whitespace
|
||||
while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) {
|
||||
pScan++;
|
||||
}
|
||||
|
||||
if(*pScan == '#') {
|
||||
// Line is a comment line
|
||||
|
||||
// Scan to the end of the line
|
||||
while(pScan < pEnd && *pScan != '\r' && *pScan != '\n') {
|
||||
pScan++;
|
||||
}
|
||||
} else {
|
||||
int cSymbols = 0;
|
||||
while(pScan < pEnd && *pScan != '\n' && *pScan != '\r') {
|
||||
|
||||
char *pDest = szSymbol[cSymbols++];
|
||||
while(pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') {
|
||||
*pDest++ = *pScan++;
|
||||
}
|
||||
*pDest = '\0';
|
||||
|
||||
// Scan through whitespace, but don't advance to next line
|
||||
while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) {
|
||||
pScan++;
|
||||
}
|
||||
}
|
||||
|
||||
if(strcmp(szSymbol[0], "v") == 0) {
|
||||
// Vertex (v)
|
||||
char *pChar = szSymbol[1];
|
||||
pVertice -> x = strtof(pChar, &pChar);
|
||||
pChar = szSymbol[2];
|
||||
pVertice -> y = strtof(pChar, &pChar);
|
||||
pChar = szSymbol[3];
|
||||
pVertice -> z = strtof(pChar, &pChar);
|
||||
pVertice++;
|
||||
} else if(strcmp(szSymbol[0], "vt") == 0) {
|
||||
// Vertex Texture UV Coordinate (vt)
|
||||
char *pChar = szSymbol[1];
|
||||
pTexCoord -> u = strtof(pChar, &pChar);
|
||||
pChar = szSymbol[2];
|
||||
pTexCoord -> v = strtof(pChar, &pChar);
|
||||
pTexCoord++;
|
||||
} else if(strcmp(szSymbol[0], "vn") == 0) {
|
||||
// Vertex Normal (vn)
|
||||
char *pChar = szSymbol[1];
|
||||
pNormal -> x = strtof(pChar, &pChar);
|
||||
pChar = szSymbol[2];
|
||||
pNormal -> y = strtof(pChar, &pChar);
|
||||
pChar = szSymbol[3];
|
||||
pNormal -> z = strtof(pChar, &pChar);
|
||||
pNormal++;
|
||||
} else if(strcmp(szSymbol[0], "f") == 0) {
|
||||
// Face (f)
|
||||
int cFaceVertices = cSymbols - 1;
|
||||
|
||||
*pFace++ = cFaceVertices;
|
||||
for(int iSymbol=1; iSymbol < cSymbols; iSymbol++) {
|
||||
char *pChar = szSymbol[iSymbol];
|
||||
if(*pChar == '.' || (*pChar >= '0' && *pChar <= '9')) {
|
||||
*pFace++ = strtol(pChar, &pChar, 10) - 1; // Vertex Index
|
||||
|
||||
if(*pChar == '/') {
|
||||
pChar++;
|
||||
if(*pChar == '/') {
|
||||
*pFace++ = -1;
|
||||
} else {
|
||||
*pFace++ = strtol(pChar, &pChar, 10) - 1; // Texture Coordinate Index
|
||||
}
|
||||
} else {
|
||||
*pFace++ = -1;
|
||||
}
|
||||
|
||||
if(*pChar == '/') {
|
||||
pChar++;
|
||||
if(*pChar == '/') {
|
||||
*pFace++ = -1;
|
||||
} else {
|
||||
*pFace++ = strtol(pChar, &pChar, 10) - 1; // Normal Index
|
||||
}
|
||||
} else {
|
||||
*pFace++ = -1;
|
||||
}
|
||||
while(*pChar == '/') {
|
||||
pChar++;
|
||||
strtol(pChar, &pChar, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else if(strcmp(szSymbol[0], "usemtl") == 0) {
|
||||
// Use Material (usemtl)
|
||||
if(pFace - pMaterialFaces > 1) {
|
||||
*pMaterialFaces = pFace - pMaterialFaces - 1;
|
||||
pMaterialFaces = pFace++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*pMaterialFaces = pFace - pMaterialFaces - 1;
|
||||
*pFace++ = 0;
|
||||
|
||||
|
||||
m_pVertexData = (VertexData *)malloc(sizeof(VertexData) * cVertexData);
|
||||
|
||||
VertexData *pData = m_pVertexData;
|
||||
|
||||
int iVertex = 0;
|
||||
pack_material *pMaterial = new pack_material();
|
||||
pMaterial->start_vertex = iVertex;
|
||||
pMaterial->vertex_count = 0;
|
||||
memset(pMaterial->szName, 64, 0);
|
||||
if(material_itr < materials.end()) {
|
||||
strncpy(pMaterial->szName, (*material_itr++).c_str(), 64);
|
||||
}
|
||||
m_materials.push_back(pMaterial);
|
||||
|
||||
|
||||
pFace = pFaces;
|
||||
while(*pFace != 0 && iVertex < cVertexData) {
|
||||
pMaterial->start_vertex = iVertex;
|
||||
|
||||
int *pMaterialEndFace = pFace + *pFace++;
|
||||
while(pFace < pMaterialEndFace && iVertex < cVertexData) {
|
||||
int cFaceVertexes = *pFace;
|
||||
VertexData *pFirstFaceVertex = NULL;
|
||||
VertexData *pPrevFaceVertex = NULL;
|
||||
for(int iFaceVertex=0; iFaceVertex < cFaceVertexes; iFaceVertex++) {
|
||||
if(iFaceVertex > 2) {
|
||||
// There have already been 3 vertices. Now we need to split the quad into a second triangle composed of the 1st, 3rd, and 4th vertices
|
||||
memcpy(pData++, pFirstFaceVertex, sizeof(VertexData));
|
||||
memcpy(pData++, pPrevFaceVertex, sizeof(VertexData));
|
||||
iVertex+=2;
|
||||
}
|
||||
Vertex3D *pVertex = pVertices + pFace[iFaceVertex*3+1];
|
||||
if(iFaceVertex==0) {
|
||||
pFirstFaceVertex = pData;
|
||||
}
|
||||
pPrevFaceVertex = pData;
|
||||
pData->vertex.x = pVertex -> x;
|
||||
pData->vertex.y = pVertex -> y;
|
||||
pData->vertex.z = pVertex -> z;
|
||||
|
||||
if(pFace[iFaceVertex*3+2] >= 0) {
|
||||
TexCoord *pTexCoord = pTexCoords + pFace[iFaceVertex*3+2];
|
||||
pData->texcoord.u = pTexCoord -> u;
|
||||
pData->texcoord.v = pTexCoord -> v;
|
||||
} else {
|
||||
pData->texcoord.u = 0;
|
||||
pData->texcoord.v = 0;
|
||||
}
|
||||
|
||||
if(pFace[iFaceVertex*3+3] >= 0){
|
||||
Vector3D *pNormal = pNormals + pFace[iFaceVertex*3+3];
|
||||
pData->normal.x = pNormal -> x;
|
||||
pData->normal.y = pNormal -> y;
|
||||
pData->normal.z = pNormal -> z;
|
||||
} else {
|
||||
pData->normal.x = 0;
|
||||
pData->normal.y = 0;
|
||||
pData->normal.z = 0;
|
||||
}
|
||||
|
||||
pData++;
|
||||
iVertex++;
|
||||
}
|
||||
pFace += cFaceVertexes * 3 + 1;
|
||||
}
|
||||
pMaterial->vertex_count = iVertex - pMaterial->start_vertex;
|
||||
if(*pFace != 0) {
|
||||
pMaterial = new pack_material();
|
||||
pMaterial->start_vertex = iVertex;
|
||||
pMaterial->vertex_count = 0;
|
||||
memset(pMaterial->szName, 64, 0);
|
||||
|
||||
if(material_itr < materials.end()) {
|
||||
strncpy(pMaterial->szName, (*material_itr++).c_str(), 64);
|
||||
}
|
||||
m_materials.push_back(pMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
header.minx = 0.0;
|
||||
header.miny = 0.0;
|
||||
header.minz = 0.0;
|
||||
header.maxx = 0.0;
|
||||
header.maxy = 0.0;
|
||||
header.maxz = 0.0;
|
||||
|
||||
// Calculate surface normals and tangents
|
||||
cout << " Pass 3 - Calculate surface normals and tangents\n";
|
||||
// http://www.terathon.com/code/tangent.html
|
||||
// http://www.fabiensanglard.net/bumpMapping/index.php
|
||||
|
||||
for(std::vector<pack_material *>::iterator itr = m_materials.begin(); itr != m_materials.end(); itr++) {
|
||||
VertexData *pStart = m_pVertexData + (*itr)->start_vertex;
|
||||
VertexData *pEnd = pStart + (*itr)->vertex_count;
|
||||
for(VertexData *pVertex = pStart; pVertex < pEnd; pVertex+=3) {
|
||||
if(pVertex->vertex.x < header.minx) header.minx = pVertex->vertex.x;
|
||||
if(pVertex->vertex.x > header.maxx) header.maxx = pVertex->vertex.x;
|
||||
if(pVertex->vertex.y < header.miny) header.miny = pVertex->vertex.y;
|
||||
if(pVertex->vertex.y > header.maxy) header.maxy = pVertex->vertex.y;
|
||||
if(pVertex->vertex.z < header.minz) header.minz = pVertex->vertex.z;
|
||||
if(pVertex->vertex.z > header.maxz) header.maxz = pVertex->vertex.z;
|
||||
}
|
||||
|
||||
|
||||
for(VertexData *pVertex = pStart; pVertex < pEnd; pVertex+=3) {
|
||||
Vector3 p1(pVertex[0].vertex.x, pVertex[0].vertex.y, pVertex[0].vertex.z);
|
||||
Vector3 p2(pVertex[1].vertex.x, pVertex[1].vertex.y, pVertex[1].vertex.z);
|
||||
Vector3 p3(pVertex[2].vertex.x, pVertex[2].vertex.y, pVertex[2].vertex.z);
|
||||
Vector3 v1 = p2 - p1;
|
||||
Vector3 v2 = p3 - p1;
|
||||
|
||||
// -- Calculate normal --
|
||||
if(pVertex->normal.x == 0 && pVertex->normal.y == 0 && pVertex->normal.z == 0) {
|
||||
|
||||
|
||||
Vector3 normal = v1.cross( v2 );
|
||||
|
||||
normal.normalize();
|
||||
|
||||
pVertex[0].normal.x = normal.x;
|
||||
pVertex[0].normal.y = normal.y;
|
||||
pVertex[0].normal.z = normal.z;
|
||||
|
||||
pVertex[1].normal.x = normal.x;
|
||||
pVertex[1].normal.y = normal.y;
|
||||
pVertex[1].normal.z = normal.z;
|
||||
|
||||
pVertex[2].normal.x = normal.x;
|
||||
pVertex[2].normal.y = normal.y;
|
||||
pVertex[2].normal.z = normal.z;
|
||||
}
|
||||
|
||||
// -- Calculate tangent --
|
||||
TexCoord st1; // = pVertex[2].texcoord;
|
||||
TexCoord st2; // = pVertex[1].texcoord;
|
||||
st1.u = pVertex[1].texcoord.u - pVertex[0].texcoord.u;
|
||||
st1.v = pVertex[1].texcoord.v - pVertex[0].texcoord.v;
|
||||
st2.u = pVertex[2].texcoord.u - pVertex[0].texcoord.u;
|
||||
st2.v = pVertex[2].texcoord.v - pVertex[0].texcoord.v;
|
||||
double coef = 1/ (st1.u * st2.v - st2.u * st1.v);
|
||||
|
||||
pVertex[0].tangent.x = coef * ((v1.x * st2.v) + (v2.x * -st1.v));
|
||||
pVertex[0].tangent.y = coef * ((v1.y * st2.v) + (v2.y * -st1.v));
|
||||
pVertex[0].tangent.z = coef * ((v1.z * st2.v) + (v2.z * -st1.v));
|
||||
|
||||
Vector3 tangent(
|
||||
coef * ((v1.x * st2.v) + (v2.x * -st1.v)),
|
||||
coef * ((v1.y * st2.v) + (v2.y * -st1.v)),
|
||||
coef * ((v1.z * st2.v) + (v2.z * -st1.v))
|
||||
);
|
||||
|
||||
tangent.normalize();
|
||||
|
||||
pVertex[0].tangent.x = tangent.x;
|
||||
pVertex[0].tangent.y = tangent.y;
|
||||
pVertex[0].tangent.z = tangent.z;
|
||||
pVertex[1].tangent.x = tangent.x;
|
||||
pVertex[1].tangent.y = tangent.y;
|
||||
pVertex[1].tangent.z = tangent.z;
|
||||
pVertex[2].tangent.x = tangent.x;
|
||||
pVertex[2].tangent.y = tangent.y;
|
||||
pVertex[2].tangent.z = tangent.z;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Write output file
|
||||
std::string out_file_name = szPath;
|
||||
out_file_name.append(".pack");
|
||||
cout << " Writing obj.pack file:" << out_file_name << " ... \n";
|
||||
FILE *out_file = fopen(out_file_name.c_str(), "w");
|
||||
|
||||
header.material_count = 0;
|
||||
for(std::vector<pack_material *>::iterator itr = m_materials.begin(); itr != m_materials.end(); itr++) {
|
||||
pack_material *pMaterial = (*itr);
|
||||
if(pMaterial->vertex_count) { // Skip materials with no vertices
|
||||
header.material_count++;
|
||||
}
|
||||
}
|
||||
|
||||
header.vertex_count = cVertexData;
|
||||
|
||||
fwrite(&header, sizeof(header), 1, out_file);
|
||||
|
||||
for(std::vector<pack_material *>::iterator itr = m_materials.begin(); itr != m_materials.end(); itr++) {
|
||||
pack_material *pMaterial = (*itr);
|
||||
if(pMaterial->vertex_count) { // Skip materials with no vertices
|
||||
fwrite(pMaterial, sizeof(pack_material), 1, out_file);
|
||||
cout << " " << pMaterial->szName << ": " << pMaterial->vertex_count << " vertices\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fwrite(m_pVertexData, sizeof(VertexData), cVertexData, out_file);
|
||||
|
||||
fclose(out_file);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pFile != NULL) {
|
||||
munmap(pFile, fileSize);
|
||||
}
|
||||
|
||||
if(fdFile != 0) {
|
||||
close(fdFile);
|
||||
}
|
||||
|
||||
if(m_pVertexData) {
|
||||
free(m_pVertexData);
|
||||
}
|
||||
|
||||
if(pVertices) {
|
||||
free(pVertices);
|
||||
}
|
||||
if(pNormals) {
|
||||
free(pNormals);
|
||||
}
|
||||
if(pTexCoords) {
|
||||
free(pTexCoords);
|
||||
}
|
||||
if(pFaces) {
|
||||
free(pFaces);
|
||||
}
|
||||
}
|
||||
55
objpack/objpack/KROBJPacker.h
Normal file
55
objpack/objpack/KROBJPacker.h
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// objpacker.h
|
||||
// objpack
|
||||
//
|
||||
// Created by Kearwood Gilbert on 11-04-29.
|
||||
// Copyright 2011 Kearwood Software. All rights reserved.
|
||||
//
|
||||
|
||||
#import <vector.h>
|
||||
#import <stdint.h>
|
||||
|
||||
#ifndef OBJPACKER_H
|
||||
#define OBJPACKER_H
|
||||
|
||||
|
||||
class KROBJPacker {
|
||||
public:
|
||||
KROBJPacker();
|
||||
~KROBJPacker();
|
||||
void pack(const char *szPath);
|
||||
|
||||
private:
|
||||
typedef struct {
|
||||
char szTag[16];
|
||||
float minx, miny, minz, maxx, maxy, maxz;
|
||||
int32_t vertex_count;
|
||||
int32_t material_count;
|
||||
} pack_header;
|
||||
|
||||
typedef struct {
|
||||
int32_t start_vertex;
|
||||
int32_t vertex_count;
|
||||
char szName[64];
|
||||
} pack_material;
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} Vertex3D, Vector3D;
|
||||
|
||||
typedef struct {
|
||||
float u;
|
||||
float v;
|
||||
} TexCoord;
|
||||
|
||||
typedef struct {
|
||||
Vertex3D vertex;
|
||||
Vector3D normal;
|
||||
Vector3D tangent;
|
||||
TexCoord texcoord;
|
||||
} VertexData;
|
||||
};
|
||||
|
||||
#endif // OBJPACKER_H
|
||||
76
objpack/objpack/KRVector3.cpp
Normal file
76
objpack/objpack/KRVector3.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// KRVector3.cpp
|
||||
// gldemo
|
||||
//
|
||||
// Created by Kearwood Gilbert on 10-12-31.
|
||||
// Copyright 2010 Kearwood Software. All rights reserved.
|
||||
//
|
||||
|
||||
#include "KRVector3.h"
|
||||
|
||||
//default constructor
|
||||
Vector3::Vector3(float X = 0, float Y = 0, float Z = 0)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
z = Z;
|
||||
}
|
||||
|
||||
Vector3::~Vector3()
|
||||
{
|
||||
}
|
||||
|
||||
//calculate and return the magnitude of this vector
|
||||
float Vector3::GetMagnitude()
|
||||
{
|
||||
return sqrtf(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
//multiply this vector by a scalar
|
||||
Vector3 Vector3::operator*(float num) const
|
||||
{
|
||||
return Vector3(x * num, y * num, z * num);
|
||||
}
|
||||
|
||||
//pass in a vector, pass in a scalar, return the product
|
||||
/*
|
||||
Vector3 Vector3::operator*(float num, Vector3 const &vec)
|
||||
{
|
||||
return Vector3(vec.x * num, vec.y * num, vec.z * num);
|
||||
}
|
||||
*/
|
||||
|
||||
//add two vectors
|
||||
Vector3 Vector3::operator+(const Vector3 &vec) const
|
||||
{
|
||||
return Vector3(x + vec.x, y + vec.y, z + vec.z);
|
||||
}
|
||||
|
||||
//subtract two vectors
|
||||
Vector3 Vector3::operator-(const Vector3 &vec) const
|
||||
{
|
||||
return Vector3(x - vec.x, y - vec.y, z - vec.z);
|
||||
}
|
||||
|
||||
//normalize this vector
|
||||
void Vector3::normalize()
|
||||
{
|
||||
float magnitude = sqrtf(x * x + y * y + z * z);
|
||||
x /= magnitude;
|
||||
y /= magnitude;
|
||||
z /= magnitude;
|
||||
}
|
||||
|
||||
//calculate and return dot product
|
||||
float Vector3::dot(const Vector3 &vec) const
|
||||
{
|
||||
return x * vec.x + y * vec.y + z * vec.z;
|
||||
}
|
||||
|
||||
//calculate and return cross product
|
||||
Vector3 Vector3::cross(const Vector3 &vec) const
|
||||
{
|
||||
return Vector3(y * vec.z - z * vec.y,
|
||||
z * vec.x - x * vec.z,
|
||||
x * vec.y - y * vec.x);
|
||||
}
|
||||
49
objpack/objpack/KRVector3.h
Normal file
49
objpack/objpack/KRVector3.h
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// KRVector3.h
|
||||
// gldemo
|
||||
//
|
||||
// Created by Kearwood Gilbert on 10-12-31.
|
||||
// Copyright 2010 Kearwood Software. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef KRVECTOR3
|
||||
#define KRVECTOR3
|
||||
#include <math.h>
|
||||
|
||||
class Vector3
|
||||
{
|
||||
|
||||
public:
|
||||
float x, y, z;
|
||||
|
||||
//default constructor
|
||||
|
||||
Vector3(float X, float Y, float Z);
|
||||
~Vector3();
|
||||
|
||||
//calculate and return the magnitude of this vector
|
||||
float GetMagnitude();
|
||||
|
||||
//multiply this vector by a scalar
|
||||
Vector3 operator*(float num) const;
|
||||
|
||||
//pass in a vector, pass in a scalar, return the product
|
||||
//friend Vector3 operator*(float num, Vector3 const &vec);
|
||||
|
||||
//add two vectors
|
||||
Vector3 operator+(const Vector3 &vec) const;
|
||||
|
||||
//subtract two vectors
|
||||
Vector3 operator-(const Vector3 &vec) const;
|
||||
|
||||
//normalize this vector
|
||||
void normalize();
|
||||
|
||||
//calculate and return dot product
|
||||
float dot(const Vector3 &vec) const;
|
||||
|
||||
//calculate and return cross product
|
||||
Vector3 cross(const Vector3 &vec) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
29
objpack/objpack/main.cpp
Normal file
29
objpack/objpack/main.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// main.cpp
|
||||
// objpack
|
||||
//
|
||||
// Created by Kearwood Gilbert on 11-04-29.
|
||||
// Copyright 2011 Kearwood Software. All rights reserved.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#import "KROBJPacker.h"
|
||||
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
|
||||
if(argc < 2) {
|
||||
std::cout << "You must pass an .obj file as a parameter. An .obj.pack file will be written for each .obj file.\n";
|
||||
} else {
|
||||
KROBJPacker p;
|
||||
for(int i=1; i < argc; i++) {
|
||||
std::cout << "Packing " << argv[i] << " ...\n";
|
||||
p.pack(argv[i]);
|
||||
}
|
||||
std::cout << "Done.\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
79
objpack/objpack/objpack.1
Normal file
79
objpack/objpack/objpack.1
Normal file
@@ -0,0 +1,79 @@
|
||||
.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
|
||||
.\"See Also:
|
||||
.\"man mdoc.samples for a complete listing of options
|
||||
.\"man mdoc for the short list of editing options
|
||||
.\"/usr/share/misc/mdoc.template
|
||||
.Dd 11-04-29 \" DATE
|
||||
.Dt objpack 1 \" Program name and manual section number
|
||||
.Os Darwin
|
||||
.Sh NAME \" Section Header - required - don't modify
|
||||
.Nm objpack,
|
||||
.\" The following lines are read in generating the apropos(man -k) database. Use only key
|
||||
.\" words here as the database is built based on the words here and in the .ND line.
|
||||
.Nm Other_name_for_same_program(),
|
||||
.Nm Yet another name for the same program.
|
||||
.\" Use .Nm macro to designate other names for the documented program.
|
||||
.Nd This line parsed for whatis database.
|
||||
.Sh SYNOPSIS \" Section Header - required - don't modify
|
||||
.Nm
|
||||
.Op Fl abcd \" [-abcd]
|
||||
.Op Fl a Ar path \" [-a path]
|
||||
.Op Ar file \" [file]
|
||||
.Op Ar \" [file ...]
|
||||
.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
|
||||
arg2 ... \" Arguments
|
||||
.Sh DESCRIPTION \" Section Header - required - don't modify
|
||||
Use the .Nm macro to refer to your program throughout the man page like such:
|
||||
.Nm
|
||||
Underlining is accomplished with the .Ar macro like this:
|
||||
.Ar underlined text .
|
||||
.Pp \" Inserts a space
|
||||
A list of items with descriptions:
|
||||
.Bl -tag -width -indent \" Begins a tagged list
|
||||
.It item a \" Each item preceded by .It macro
|
||||
Description of item a
|
||||
.It item b
|
||||
Description of item b
|
||||
.El \" Ends the list
|
||||
.Pp
|
||||
A list of flags and their descriptions:
|
||||
.Bl -tag -width -indent \" Differs from above in tag removed
|
||||
.It Fl a \"-a flag as a list item
|
||||
Description of -a flag
|
||||
.It Fl b
|
||||
Description of -b flag
|
||||
.El \" Ends the list
|
||||
.Pp
|
||||
.\" .Sh ENVIRONMENT \" May not be needed
|
||||
.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
|
||||
.\" .It Ev ENV_VAR_1
|
||||
.\" Description of ENV_VAR_1
|
||||
.\" .It Ev ENV_VAR_2
|
||||
.\" Description of ENV_VAR_2
|
||||
.\" .El
|
||||
.Sh FILES \" File used or created by the topic of the man page
|
||||
.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
|
||||
.It Pa /usr/share/file_name
|
||||
FILE_1 description
|
||||
.It Pa /Users/joeuser/Library/really_long_file_name
|
||||
FILE_2 description
|
||||
.El \" Ends the list
|
||||
.\" .Sh DIAGNOSTICS \" May not be needed
|
||||
.\" .Bl -diag
|
||||
.\" .It Diagnostic Tag
|
||||
.\" Diagnostic informtion here.
|
||||
.\" .It Diagnostic Tag
|
||||
.\" Diagnostic informtion here.
|
||||
.\" .El
|
||||
.Sh SEE ALSO
|
||||
.\" List links in ascending order by section, alphabetically within a section.
|
||||
.\" Please do not reference files that do not exist without filing a bug report
|
||||
.Xr a 1 ,
|
||||
.Xr b 1 ,
|
||||
.Xr c 1 ,
|
||||
.Xr a 2 ,
|
||||
.Xr b 2 ,
|
||||
.Xr a 3 ,
|
||||
.Xr b 3
|
||||
.\" .Sh BUGS \" Document known, unremedied bugs
|
||||
.\" .Sh HISTORY \" Document history if command behaves in a unique manner
|
||||
Reference in New Issue
Block a user