Initial commit.
This commit is contained in:
commit
d3bb49b3f5
1073 changed files with 484757 additions and 0 deletions
17
Framework/external/embree/tutorials/common/scenegraph/CMakeLists.txt
vendored
Normal file
17
Framework/external/embree/tutorials/common/scenegraph/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
## Copyright 2009-2021 Intel Corporation
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ADD_LIBRARY(scenegraph STATIC
|
||||
xml_parser.cpp
|
||||
xml_loader.cpp
|
||||
xml_writer.cpp
|
||||
obj_loader.cpp
|
||||
ply_loader.cpp
|
||||
corona_loader.cpp
|
||||
texture.cpp
|
||||
scenegraph.cpp
|
||||
geometry_creation.cpp)
|
||||
|
||||
TARGET_LINK_LIBRARIES(scenegraph sys math lexers image embree)
|
||||
SET_PROPERTY(TARGET scenegraph PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET scenegraph APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
|
||||
299
Framework/external/embree/tutorials/common/scenegraph/corona_loader.cpp
vendored
Normal file
299
Framework/external/embree/tutorials/common/scenegraph/corona_loader.cpp
vendored
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "corona_loader.h"
|
||||
#include "xml_parser.h"
|
||||
#include "obj_loader.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
class CoronaLoader
|
||||
{
|
||||
public:
|
||||
|
||||
static Ref<SceneGraph::Node> load(const FileName& fileName, const AffineSpace3fa& space);
|
||||
CoronaLoader(const FileName& fileName, const AffineSpace3fa& space);
|
||||
|
||||
private:
|
||||
template<typename T> T load(const Ref<XML>& xml) { assert(false); return T(zero); }
|
||||
Ref<SceneGraph::MaterialNode> loadMaterial(const Ref<XML>& xml);
|
||||
void loadMaterialDefinition(const Ref<XML>& xml);
|
||||
std::shared_ptr<Texture> loadMap(const Ref<XML>& xml);
|
||||
void loadMapDefinition(const Ref<XML>& xml);
|
||||
Ref<SceneGraph::Node> loadMaterialLibrary(const FileName& fileName);
|
||||
Ref<SceneGraph::Node> loadObject(const Ref<XML>& xml);
|
||||
std::pair<Ref<SceneGraph::MaterialNode>, avector<AffineSpace3fa> > loadInstances(const Ref<XML>& xml);
|
||||
Ref<SceneGraph::Node> loadGroupNode(const Ref<XML>& xml);
|
||||
Ref<SceneGraph::Node> loadNode(const Ref<XML>& xml);
|
||||
|
||||
private:
|
||||
FileName path;
|
||||
std::map<std::string,Ref<SceneGraph::MaterialNode> > materialMap;
|
||||
std::map<std::string,std::shared_ptr<Texture>> textureMap;
|
||||
std::map<std::string,std::shared_ptr<Texture>> textureFileMap;
|
||||
public:
|
||||
Ref<SceneGraph::Node> root;
|
||||
};
|
||||
|
||||
template<> FileName CoronaLoader::load<FileName>(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->body.size() != 1) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong FileName body");
|
||||
return xml->body[0].Identifier();
|
||||
}
|
||||
|
||||
template<> std::string CoronaLoader::load<std::string>(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->body.size() != 1) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong string body");
|
||||
return xml->body[0].Identifier();
|
||||
}
|
||||
|
||||
template<> int CoronaLoader::load<int>(const Ref<XML>& xml) {
|
||||
if (xml->body.size() < 1) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong int body");
|
||||
return xml->body[0].Int();
|
||||
}
|
||||
|
||||
template<> float CoronaLoader::load<float>(const Ref<XML>& xml) {
|
||||
if (xml->body.size() < 1) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong float body");
|
||||
return xml->body[0].Float();
|
||||
}
|
||||
|
||||
template<> Vec3f CoronaLoader::load<Vec3f>(const Ref<XML>& xml) {
|
||||
if (xml->body.size() < 3) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong float3 body");
|
||||
return Vec3f(xml->body[0].Float(),xml->body[1].Float(),xml->body[2].Float());
|
||||
}
|
||||
|
||||
template<> Vec3fa CoronaLoader::load<Vec3fa>(const Ref<XML>& xml) {
|
||||
if (xml->body.size() < 3) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong float3 body");
|
||||
return Vec3fa(xml->body[0].Float(),xml->body[1].Float(),xml->body[2].Float());
|
||||
}
|
||||
|
||||
template<> AffineSpace3fa CoronaLoader::load<AffineSpace3fa>(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->body.size() != 12) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong AffineSpace body");
|
||||
return AffineSpace3fa(LinearSpace3fa(xml->body[0].Float(),xml->body[1].Float(),xml->body[ 2].Float(),
|
||||
xml->body[4].Float(),xml->body[5].Float(),xml->body[ 6].Float(),
|
||||
xml->body[8].Float(),xml->body[9].Float(),xml->body[10].Float()),
|
||||
Vec3fa(xml->body[3].Float(),xml->body[7].Float(),xml->body[11].Float()));
|
||||
}
|
||||
|
||||
Ref<SceneGraph::MaterialNode> CoronaLoader::loadMaterial(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "material")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid material: "+xml->name);
|
||||
|
||||
/* native material */
|
||||
if (xml->parm("class") == "Native")
|
||||
{
|
||||
/* we convert into an OBJ material */
|
||||
Ref<OBJMaterial> objmaterial = new OBJMaterial;
|
||||
for (auto& child : xml->children)
|
||||
{
|
||||
if (child->name == "diffuse") {
|
||||
objmaterial->Kd = load<Vec3fa>(child);
|
||||
if (child->children.size() && child->children[0]->name == "map")
|
||||
objmaterial->_map_Kd = loadMap(child->children[0]);
|
||||
}
|
||||
else if (child->name == "reflect") {
|
||||
objmaterial->Ks = load<Vec3fa>(child->child("color"));
|
||||
objmaterial->Ni = load<float >(child->child("ior"));
|
||||
objmaterial->Ns = load<float >(child->child("glossiness"));
|
||||
}
|
||||
else if (child->name == "translucency") {
|
||||
objmaterial->Kt = load<Vec3fa>(child->child("color"));
|
||||
}
|
||||
else if (child->name == "opacity") {
|
||||
objmaterial->d = load<Vec3fa>(child).x;
|
||||
if (child->children.size() && child->children[0]->name == "map")
|
||||
objmaterial->_map_d = loadMap(child->children[0]);
|
||||
}
|
||||
}
|
||||
return objmaterial.dynamicCast<SceneGraph::MaterialNode>();
|
||||
}
|
||||
|
||||
/* reference by name */
|
||||
else if (xml->parm("class") == "Reference")
|
||||
{
|
||||
const std::string name = load<std::string>(xml);
|
||||
return materialMap[name];
|
||||
}
|
||||
|
||||
/* else return default material */
|
||||
else
|
||||
return new OBJMaterial;
|
||||
}
|
||||
|
||||
void CoronaLoader::loadMaterialDefinition(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "materialDefinition")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid material definition: "+xml->name);
|
||||
if (xml->children.size() != 1)
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid material definition");
|
||||
|
||||
const std::string name = xml->parm("name");
|
||||
materialMap[name] = loadMaterial(xml->children[0]);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> CoronaLoader::loadMap(const Ref<XML>& xml)
|
||||
{
|
||||
/* process map node */
|
||||
if (xml->name == "map")
|
||||
{
|
||||
std::string mapClass = xml->parm("class");
|
||||
|
||||
/* load textures */
|
||||
if (mapClass == "Texture")
|
||||
{
|
||||
const FileName src = load<FileName>(xml->child("image"));
|
||||
|
||||
/* load images only once */
|
||||
if (textureFileMap.find(src) != textureFileMap.end())
|
||||
return textureFileMap[src];
|
||||
|
||||
try {
|
||||
return Texture::load(path+src);
|
||||
} catch (const std::runtime_error& e) {
|
||||
std::cerr << "failed to load " << path+src << ": " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
else if (mapClass == "Reference") {
|
||||
const std::string name = load<std::string>(xml);
|
||||
return textureMap[name];
|
||||
}
|
||||
}
|
||||
|
||||
/* recurse into every unknown node to find some texture */
|
||||
for (auto& child : xml->children) {
|
||||
std::shared_ptr<Texture> texture = loadMap(child);
|
||||
if (texture) return texture;
|
||||
}
|
||||
return std::shared_ptr<Texture>();
|
||||
}
|
||||
|
||||
void CoronaLoader::loadMapDefinition(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "mapDefinition")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid map definition: "+xml->name);
|
||||
if (xml->children.size() != 1)
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid map definition");
|
||||
|
||||
const std::string name = xml->parm("name");
|
||||
std::shared_ptr<Texture> texture = loadMap(xml->children[0]);
|
||||
if (texture) textureMap[name] = texture;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::loadMaterialLibrary(const FileName& fileName)
|
||||
{
|
||||
Ref<XML> xml = parseXML(path+fileName,"/.-",false);
|
||||
if (xml->name != "mtlLib")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid material library");
|
||||
|
||||
for (auto& child : xml->children)
|
||||
{
|
||||
if (child->name == "materialDefinition") {
|
||||
loadMaterialDefinition(child);
|
||||
}
|
||||
else if (child->name == "mapDefinition")
|
||||
loadMapDefinition(child);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::loadObject(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "object")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid object node");
|
||||
if (xml->parm("class") != "file")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid object class");
|
||||
const FileName fileName = load<FileName>(xml);
|
||||
return SceneGraph::load(path+fileName);
|
||||
}
|
||||
|
||||
std::pair<Ref<SceneGraph::MaterialNode>, avector<AffineSpace3fa> > CoronaLoader::loadInstances(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "instance")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid instance node");
|
||||
|
||||
/* create default material */
|
||||
Ref<SceneGraph::MaterialNode> material = new OBJMaterial;
|
||||
|
||||
avector<AffineSpace3fa> xfms;
|
||||
for (size_t i=0; i<xml->children.size(); i++)
|
||||
{
|
||||
Ref<XML> child = xml->children[i];
|
||||
if (child->name == "material" ) material = loadMaterial(child);
|
||||
else if (child->name == "transform") xfms.push_back(load<AffineSpace3fa>(child));
|
||||
else THROW_RUNTIME_ERROR(child->loc.str()+": unknown node: "+child->name);
|
||||
}
|
||||
|
||||
return std::make_pair(material,xfms);
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::loadGroupNode(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->children.size() < 1)
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid group node");
|
||||
|
||||
/* load instances */
|
||||
auto p = loadInstances(xml->children[0]);
|
||||
Ref<SceneGraph::MaterialNode> material = p.first;
|
||||
avector<AffineSpace3fa>& xfms = p.second;
|
||||
|
||||
/* load meshes */
|
||||
Ref<SceneGraph::GroupNode> objects = new SceneGraph::GroupNode;
|
||||
for (size_t i=1; i<xml->children.size(); i++)
|
||||
objects->add(loadObject(xml->children[i]));
|
||||
|
||||
/* force material */
|
||||
objects->setMaterial(material);
|
||||
|
||||
/* create instances */
|
||||
Ref<SceneGraph::GroupNode> instances = new SceneGraph::GroupNode;
|
||||
for (size_t i=0; i<xfms.size(); i++)
|
||||
instances->add(new SceneGraph::TransformNode(xfms[i],objects.cast<SceneGraph::Node>()));
|
||||
|
||||
return instances.cast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::loadNode(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name == "conffile" ) return nullptr;
|
||||
else if (xml->name == "mtllib" ) return loadMaterialLibrary(load<FileName>(xml));
|
||||
else if (xml->name == "camera" ) return nullptr;
|
||||
else if (xml->name == "environment" ) return nullptr;
|
||||
else if (xml->name == "geometryGroup") return loadGroupNode(xml);
|
||||
else if (xml->name == "renderElement") return nullptr;
|
||||
else THROW_RUNTIME_ERROR(xml->loc.str()+": unknown tag: "+xml->name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::load(const FileName& fileName, const AffineSpace3fa& space) {
|
||||
CoronaLoader loader(fileName,space); return loader.root;
|
||||
}
|
||||
|
||||
CoronaLoader::CoronaLoader(const FileName& fileName, const AffineSpace3fa& space)
|
||||
{
|
||||
path = fileName.path();
|
||||
Ref<XML> xml = parseXML(fileName,"/.-",false);
|
||||
if (xml->name == "scene")
|
||||
{
|
||||
Ref<SceneGraph::GroupNode> group = new SceneGraph::GroupNode;
|
||||
for (size_t i=0; i<xml->children.size(); i++) {
|
||||
group->add(loadNode(xml->children[i]));
|
||||
}
|
||||
root = group.cast<SceneGraph::Node>();
|
||||
}
|
||||
else
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid scene tag");
|
||||
|
||||
if (space == AffineSpace3fa(one))
|
||||
return;
|
||||
|
||||
root = new SceneGraph::TransformNode(space,root);
|
||||
}
|
||||
|
||||
/*! read from disk */
|
||||
Ref<SceneGraph::Node> SceneGraph::loadCorona(const FileName& fileName, const AffineSpace3fa& space) {
|
||||
return CoronaLoader::load(fileName,space);
|
||||
}
|
||||
}
|
||||
14
Framework/external/embree/tutorials/common/scenegraph/corona_loader.h
vendored
Normal file
14
Framework/external/embree/tutorials/common/scenegraph/corona_loader.h
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
Ref<SceneGraph::Node> loadCorona(const FileName& fileName, const AffineSpace3fa& space = one);
|
||||
}
|
||||
}
|
||||
693
Framework/external/embree/tutorials/common/scenegraph/geometry_creation.cpp
vendored
Normal file
693
Framework/external/embree/tutorials/common/scenegraph/geometry_creation.cpp
vendored
Normal file
|
|
@ -0,0 +1,693 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "geometry_creation.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
Ref<SceneGraph::Node> SceneGraph::createTrianglePlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize((width+1)*(height+1));
|
||||
mesh->triangles.resize(2*width*height);
|
||||
|
||||
for (size_t y=0; y<=height; y++) {
|
||||
for (size_t x=0; x<=width; x++) {
|
||||
Vec3fa p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy;
|
||||
size_t i = y*(width+1)+x;
|
||||
mesh->positions[0][i].x = p.x;
|
||||
mesh->positions[0][i].y = p.y;
|
||||
mesh->positions[0][i].z = p.z;
|
||||
}
|
||||
}
|
||||
for (size_t y=0; y<height; y++) {
|
||||
for (size_t x=0; x<width; x++) {
|
||||
size_t i = 2*y*width+2*x;
|
||||
size_t p00 = (y+0)*(width+1)+(x+0);
|
||||
size_t p01 = (y+0)*(width+1)+(x+1);
|
||||
size_t p10 = (y+1)*(width+1)+(x+0);
|
||||
size_t p11 = (y+1)*(width+1)+(x+1);
|
||||
mesh->triangles[i+0].v0 = unsigned(p00); mesh->triangles[i+0].v1 = unsigned(p01); mesh->triangles[i+0].v2 = unsigned(p10);
|
||||
mesh->triangles[i+1].v0 = unsigned(p11); mesh->triangles[i+1].v1 = unsigned(p10); mesh->triangles[i+1].v2 = unsigned(p01);
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createQuadPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize((width+1)*(height+1));
|
||||
mesh->quads.resize(width*height);
|
||||
|
||||
for (size_t y=0; y<=height; y++) {
|
||||
for (size_t x=0; x<=width; x++) {
|
||||
Vec3fa p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy;
|
||||
size_t i = y*(width+1)+x;
|
||||
mesh->positions[0][i].x = p.x;
|
||||
mesh->positions[0][i].y = p.y;
|
||||
mesh->positions[0][i].z = p.z;
|
||||
}
|
||||
}
|
||||
for (size_t y=0; y<height; y++) {
|
||||
for (size_t x=0; x<width; x++) {
|
||||
size_t i = y*width+x;
|
||||
size_t p00 = (y+0)*(width+1)+(x+0);
|
||||
size_t p01 = (y+0)*(width+1)+(x+1);
|
||||
size_t p10 = (y+1)*(width+1)+(x+0);
|
||||
size_t p11 = (y+1)*(width+1)+(x+1);
|
||||
mesh->quads[i].v0 = unsigned(p00);
|
||||
mesh->quads[i].v1 = unsigned(p01);
|
||||
mesh->quads[i].v2 = unsigned(p11);
|
||||
mesh->quads[i].v3 = unsigned(p10);
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGridPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize((width+1)*(height+1));
|
||||
mesh->grids.push_back(SceneGraph::GridMeshNode::Grid(0,(unsigned)width+1,(unsigned)width+1,(unsigned)height+1));
|
||||
|
||||
for (size_t y=0; y<=height; y++) {
|
||||
for (size_t x=0; x<=width; x++) {
|
||||
Vec3fa p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy;
|
||||
size_t i = y*(width+1)+x;
|
||||
mesh->positions[0][i].x = p.x;
|
||||
mesh->positions[0][i].y = p.y;
|
||||
mesh->positions[0][i].z = p.z;
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createSubdivPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, float tessellationRate, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->tessellationRate = tessellationRate;
|
||||
mesh->positions[0].resize((width+1)*(height+1));
|
||||
mesh->position_indices.resize(4*width*height);
|
||||
mesh->verticesPerFace.resize(width*height);
|
||||
|
||||
for (size_t y=0; y<=height; y++) {
|
||||
for (size_t x=0; x<=width; x++) {
|
||||
Vec3fa p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy;
|
||||
size_t i = y*(width+1)+x;
|
||||
mesh->positions[0][i].x = p.x;
|
||||
mesh->positions[0][i].y = p.y;
|
||||
mesh->positions[0][i].z = p.z;
|
||||
}
|
||||
}
|
||||
for (size_t y=0; y<height; y++) {
|
||||
for (size_t x=0; x<width; x++) {
|
||||
size_t i = y*width+x;
|
||||
size_t p00 = (y+0)*(width+1)+(x+0);
|
||||
size_t p01 = (y+0)*(width+1)+(x+1);
|
||||
size_t p10 = (y+1)*(width+1)+(x+0);
|
||||
size_t p11 = (y+1)*(width+1)+(x+1);
|
||||
mesh->position_indices[4*i+0] = unsigned(p00);
|
||||
mesh->position_indices[4*i+1] = unsigned(p01);
|
||||
mesh->position_indices[4*i+2] = unsigned(p11);
|
||||
mesh->position_indices[4*i+3] = unsigned(p10);
|
||||
mesh->verticesPerFace[i] = 4;
|
||||
}
|
||||
}
|
||||
mesh->position_subdiv_mode = RTC_SUBDIVISION_MODE_PIN_CORNERS;
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createTriangleSphere (const Vec3fa& center, const float radius, size_t N, Ref<MaterialNode> material)
|
||||
{
|
||||
unsigned numPhi = unsigned(N);
|
||||
unsigned numTheta = 2*numPhi;
|
||||
unsigned numVertices = numTheta*(numPhi+1);
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize(numVertices);
|
||||
|
||||
/* create sphere geometry */
|
||||
const float rcpNumTheta = rcp(float(numTheta));
|
||||
const float rcpNumPhi = rcp(float(numPhi));
|
||||
for (unsigned int phi=0; phi<=numPhi; phi++)
|
||||
{
|
||||
for (unsigned int theta=0; theta<numTheta; theta++)
|
||||
{
|
||||
const float phif = phi*float(pi)*rcpNumPhi;
|
||||
const float thetaf = theta*2.0f*float(pi)*rcpNumTheta;
|
||||
mesh->positions[0][phi*numTheta+theta].x = center.x + radius*sin(phif)*sin(thetaf);
|
||||
mesh->positions[0][phi*numTheta+theta].y = center.y + radius*cos(phif);
|
||||
mesh->positions[0][phi*numTheta+theta].z = center.z + radius*sin(phif)*cos(thetaf);
|
||||
}
|
||||
if (phi == 0) continue;
|
||||
|
||||
if (phi == 1)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = numTheta-1;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->triangles.push_back(TriangleMeshNode::Triangle(p10,p00,p11));
|
||||
}
|
||||
}
|
||||
else if (phi == numPhi)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = numPhi*numTheta;
|
||||
mesh->triangles.push_back(TriangleMeshNode::Triangle(p10,p00,p01));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->triangles.push_back(TriangleMeshNode::Triangle(p10,p00,p11));
|
||||
mesh->triangles.push_back(TriangleMeshNode::Triangle(p01,p11,p00));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createQuadSphere (const Vec3fa& center, const float radius, size_t N, Ref<MaterialNode> material)
|
||||
{
|
||||
unsigned numPhi = unsigned(N);
|
||||
unsigned numTheta = 2*numPhi;
|
||||
unsigned numVertices = numTheta*(numPhi+1);
|
||||
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize(numVertices);
|
||||
|
||||
/* create sphere geometry */
|
||||
const float rcpNumTheta = rcp(float(numTheta));
|
||||
const float rcpNumPhi = rcp(float(numPhi));
|
||||
for (unsigned int phi=0; phi<=numPhi; phi++)
|
||||
{
|
||||
for (unsigned int theta=0; theta<numTheta; theta++)
|
||||
{
|
||||
const float phif = phi*float(pi)*rcpNumPhi;
|
||||
const float thetaf = theta*2.0f*float(pi)*rcpNumTheta;
|
||||
mesh->positions[0][phi*numTheta+theta].x = center.x + radius*sin(phif)*sin(thetaf);
|
||||
mesh->positions[0][phi*numTheta+theta].y = center.y + radius*cos(phif);
|
||||
mesh->positions[0][phi*numTheta+theta].z = center.z + radius*sin(phif)*cos(thetaf);
|
||||
}
|
||||
if (phi == 0) continue;
|
||||
|
||||
if (phi == 1)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = numTheta-1;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->quads.push_back(QuadMeshNode::Quad(p10,p00,p11,p11));
|
||||
}
|
||||
}
|
||||
else if (phi == numPhi)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = numPhi*numTheta;
|
||||
mesh->quads.push_back(QuadMeshNode::Quad(p10,p00,p01,p01));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->quads.push_back(QuadMeshNode::Quad(p10,p00,p01,p11));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGridSphere (const Vec3fa& center, const float radius, size_t N, Ref<MaterialNode> material)
|
||||
{
|
||||
size_t grid_size = (N+1)*(N+1);
|
||||
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize(grid_size*6);
|
||||
|
||||
for (size_t i=0; i<6; i++)
|
||||
{
|
||||
mesh->grids.push_back(SceneGraph::GridMeshNode::Grid(unsigned(i*grid_size),unsigned(N+1),unsigned(N+1),unsigned(N+1)));
|
||||
Vec3fa p0, dx, dy;
|
||||
switch (i) {
|
||||
case 0: p0 = Vec3fa(-0.5f,-0.5f,-0.5f); dx = Vec3fa(+1,0, 0); dy = Vec3fa(0,1,0); break;
|
||||
case 1: p0 = Vec3fa(+0.5f,-0.5f,-0.5f); dx = Vec3fa( 0,0,+1); dy = Vec3fa(0,1,0); break;
|
||||
case 2: p0 = Vec3fa(+0.5f,-0.5f,+0.5f); dx = Vec3fa(-1,0, 0); dy = Vec3fa(0,1,0); break;
|
||||
case 3: p0 = Vec3fa(-0.5f,-0.5f,+0.5f); dx = Vec3fa( 0,0,-1); dy = Vec3fa(0,1,0); break;
|
||||
case 4: p0 = Vec3fa(-0.5f,-0.5f,-0.5f); dx = Vec3fa( 0,0,+1); dy = Vec3fa(1,0,0); break;
|
||||
case 5: p0 = Vec3fa(-0.5f,+0.5f,-0.5f); dx = Vec3fa( 1,0, 0); dy = Vec3fa(0,0,1); break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
for (size_t y=0; y<=N; y++) {
|
||||
for (size_t x=0; x<=N; x++) {
|
||||
size_t j = i*grid_size + y*(N+1) + x;
|
||||
Vec3fa p = p0+float(x)/float(N)*dx+float(y)/float(N)*dy;
|
||||
mesh->positions[0][j] = center + radius*normalize(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createSubdivSphere (const Vec3fa& center, const float radius, size_t N, float tessellationRate, Ref<MaterialNode> material)
|
||||
{
|
||||
unsigned numPhi = unsigned(N);
|
||||
unsigned numTheta = 2*numPhi;
|
||||
unsigned numVertices = numTheta*(numPhi+1);
|
||||
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->tessellationRate = tessellationRate;
|
||||
mesh->positions[0].resize(numVertices);
|
||||
|
||||
/* create sphere geometry */
|
||||
const float rcpNumTheta = rcp((float)numTheta);
|
||||
const float rcpNumPhi = rcp((float)numPhi);
|
||||
for (unsigned int phi=0; phi<=numPhi; phi++)
|
||||
{
|
||||
for (unsigned int theta=0; theta<numTheta; theta++)
|
||||
{
|
||||
const float phif = phi*float(pi)*rcpNumPhi;
|
||||
const float thetaf = theta*2.0f*float(pi)*rcpNumTheta;
|
||||
mesh->positions[0][phi*numTheta+theta].x = center.x + radius*sin(phif)*sin(thetaf);
|
||||
mesh->positions[0][phi*numTheta+theta].y = center.y + radius*cos(phif);
|
||||
mesh->positions[0][phi*numTheta+theta].z = center.z + radius*sin(phif)*cos(thetaf);
|
||||
}
|
||||
if (phi == 0) continue;
|
||||
|
||||
if (phi == 1)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = numTheta-1;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->verticesPerFace.push_back(3);
|
||||
mesh->position_indices.push_back(p10);
|
||||
mesh->position_indices.push_back(p00);
|
||||
mesh->position_indices.push_back(p11);
|
||||
}
|
||||
}
|
||||
else if (phi == numPhi)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = numPhi*numTheta;
|
||||
mesh->verticesPerFace.push_back(3);
|
||||
mesh->position_indices.push_back(p10);
|
||||
mesh->position_indices.push_back(p00);
|
||||
mesh->position_indices.push_back(p01);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->verticesPerFace.push_back(4);
|
||||
mesh->position_indices.push_back(p10);
|
||||
mesh->position_indices.push_back(p00);
|
||||
mesh->position_indices.push_back(p01);
|
||||
mesh->position_indices.push_back(p11);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createSphereShapedHair(const Vec3fa& center, const float radius, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,material,BBox1f(0,1),1);
|
||||
mesh->hairs.push_back(SceneGraph::HairSetNode::Hair(0,0));
|
||||
mesh->positions[0].push_back(Vec3ff(center+Vec3fa(-radius,0,0),radius));
|
||||
mesh->positions[0].push_back(Vec3ff(center+Vec3fa(0,0,0),radius));
|
||||
mesh->positions[0].push_back(Vec3ff(center+Vec3fa(0,0,0),radius));
|
||||
mesh->positions[0].push_back(Vec3ff(center+Vec3fa(+radius,0,0),radius));
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createSphere (const Vec3fa& center, const float radius, Ref<MaterialNode> material)
|
||||
{
|
||||
RTCGeometryType type = RTC_GEOMETRY_TYPE_SPHERE_POINT;
|
||||
Ref<SceneGraph::PointSetNode> mesh = new SceneGraph::PointSetNode(type, material, BBox1f(0,1), 1);
|
||||
mesh->positions[0].resize(1);
|
||||
mesh->positions[0][0].x = center.x;
|
||||
mesh->positions[0][0].y = center.y;
|
||||
mesh->positions[0][0].z = center.z;
|
||||
mesh->positions[0][0].w = radius;
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createPointSphere (const Vec3fa& center, const float radius, const float pointRadius,
|
||||
size_t N, PointSubtype subtype, Ref<MaterialNode> material)
|
||||
{
|
||||
unsigned numPhi = unsigned(N);
|
||||
unsigned numTheta = 2 * numPhi;
|
||||
unsigned numVertices = numTheta * (numPhi + 1);
|
||||
|
||||
RTCGeometryType type;
|
||||
switch (subtype) {
|
||||
case SPHERE:
|
||||
type = RTC_GEOMETRY_TYPE_SPHERE_POINT;
|
||||
break;
|
||||
case DISC:
|
||||
type = RTC_GEOMETRY_TYPE_DISC_POINT;
|
||||
break;
|
||||
case ORIENTED_DISC:
|
||||
type = RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT;
|
||||
break;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::PointSetNode> mesh = new SceneGraph::PointSetNode(type, material, BBox1f(0,1), 1);
|
||||
mesh->positions[0].resize(numVertices);
|
||||
if (subtype == ORIENTED_DISC) {
|
||||
mesh->normals.push_back(avector<Vec3fa>());
|
||||
mesh->normals[0].resize(numVertices);
|
||||
}
|
||||
|
||||
/* create sphere geometry */
|
||||
const float rcpNumTheta = rcp(float(numTheta));
|
||||
const float rcpNumPhi = rcp(float(numPhi));
|
||||
for (unsigned int phi = 0; phi <= numPhi; phi++)
|
||||
{
|
||||
for (unsigned int theta = 0; theta < numTheta; theta++)
|
||||
{
|
||||
const float phif = phi * float(pi) * rcpNumPhi;
|
||||
const float thetaf = theta * 2.0f * float(pi) * rcpNumTheta;
|
||||
mesh->positions[0][phi * numTheta + theta].x = center.x + radius * sin(phif) * sin(thetaf);
|
||||
mesh->positions[0][phi * numTheta + theta].y = center.y + radius * cos(phif);
|
||||
mesh->positions[0][phi * numTheta + theta].z = center.z + radius * sin(phif) * cos(thetaf);
|
||||
mesh->positions[0][phi * numTheta + theta].w = pointRadius;
|
||||
if (subtype == ORIENTED_DISC)
|
||||
mesh->normals[0][phi * numTheta + theta] =
|
||||
normalize(mesh->positions[0][phi * numTheta + theta] - center);
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createHairyPlane (int hash, const Vec3fa& pos, const Vec3fa& dx, const Vec3fa& dy, const float len, const float r, size_t numHairs, CurveSubtype subtype, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
|
||||
RTCGeometryType type = (subtype == ROUND_CURVE) ? RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE : RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE;
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(type,material,BBox1f(0,1),1);
|
||||
|
||||
if (numHairs == 1) {
|
||||
const Vec3fa p0 = pos;
|
||||
const Vec3fa p1 = p0 + len*Vec3fa(1,0,0);
|
||||
const Vec3fa p2 = p0 + len*Vec3fa(0,1,1);
|
||||
const Vec3fa p3 = p0 + len*Vec3fa(0,1,0);
|
||||
mesh->hairs.push_back(HairSetNode::Hair(0,0));
|
||||
mesh->positions[0].push_back(Vec3ff(p0,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p1,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p2,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p3,r));
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Vec3fa dz = cross(dx,dy);
|
||||
for (size_t i=0; i<numHairs; i++)
|
||||
{
|
||||
const Vec3fa p0 = pos + RandomSampler_getFloat(sampler)*dx + RandomSampler_getFloat(sampler)*dy;
|
||||
const Vec3fa p1 = p0 + len*normalize(dx);
|
||||
const Vec3fa p2 = p0 + len*(normalize(dz)+normalize(dy));
|
||||
const Vec3fa p3 = p0 + len*normalize(dz);
|
||||
mesh->hairs.push_back(HairSetNode::Hair(unsigned(4*i),unsigned(i)));
|
||||
mesh->positions[0].push_back(Vec3ff(p0,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p1,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p2,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p3,r));
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageTriangleMesh (int hash, size_t numTriangles, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->triangles.resize(numTriangles);
|
||||
for (size_t i=0; i<numTriangles; i++) {
|
||||
const unsigned v0 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(3*i+0);
|
||||
const unsigned v1 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(3*i+1);
|
||||
const unsigned v2 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(3*i+2);
|
||||
mesh->triangles[i] = TriangleMeshNode::Triangle(v0,v1,v2);
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(3*numTriangles);
|
||||
for (size_t i=0; i<3*numTriangles; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3ff(x,y,z,w);
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(3*numTriangles);
|
||||
for (size_t i=0; i<3*numTriangles; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3ff(x,y,z,w);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageQuadMesh (int hash, size_t numQuads, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->quads.resize(numQuads);
|
||||
for (size_t i=0; i<numQuads; i++) {
|
||||
const unsigned v0 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+0);
|
||||
const unsigned v1 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+1);
|
||||
const unsigned v2 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+2);
|
||||
const unsigned v3 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+3);
|
||||
mesh->quads[i] = QuadMeshNode::Quad(v0,v1,v2,v3);
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(4*numQuads);
|
||||
for (size_t i=0; i<4*numQuads; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3fa(Vec3ff(x,y,z,w));
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(4*numQuads);
|
||||
for (size_t i=0; i<4*numQuads; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3fa(Vec3ff(x,y,z,w));
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageGridMesh (int hash, size_t numGrids, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->grids.resize(numGrids);
|
||||
for (size_t i=0; i<numGrids; i++) {
|
||||
const unsigned v0 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+0);
|
||||
mesh->grids[i] = GridMeshNode::Grid(v0,2,2,2);
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(4*numGrids);
|
||||
for (size_t i=0; i<4*numGrids; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3fa(Vec3ff(x,y,z,w));
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(4*numGrids);
|
||||
for (size_t i=0; i<4*numGrids; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3fa(Vec3ff(x,y,z,w));
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageLineSegments (int hash, size_t numLineSegments, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE,material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->hairs.resize(numLineSegments);
|
||||
for (size_t i=0; i<numLineSegments; i++) {
|
||||
mesh->hairs[i].vertex = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(2*i);
|
||||
mesh->hairs[i].id = 0;
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(2*numLineSegments);
|
||||
for (size_t i=0; i<2*numLineSegments; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3ff(x,y,z,r);
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(2*numLineSegments);
|
||||
for (size_t i=0; i<2*numLineSegments; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3ff(x,y,z,r);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageHair (int hash, size_t numHairs, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->hairs.resize(numHairs);
|
||||
for (size_t i=0; i<numHairs; i++) {
|
||||
const unsigned v0 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i);
|
||||
mesh->hairs[i] = HairSetNode::Hair(v0,0);
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(4*numHairs);
|
||||
for (size_t i=0; i<4*numHairs; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3ff(x,y,z,r);
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(4*numHairs);
|
||||
for (size_t i=0; i<4*numHairs; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3ff(x,y,z,r);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageSubdivMesh (int hash, size_t numFaces, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
for (size_t i=0; i<numFaces; i++)
|
||||
{
|
||||
const unsigned f = RandomSampler_getInt(sampler) % 20;
|
||||
mesh->verticesPerFace.push_back(f);
|
||||
for (size_t j=0; j<f; j++)
|
||||
{
|
||||
mesh->position_indices.push_back((RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(mesh->numPositions()));
|
||||
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0].push_back(Vec3fa(Vec3ff(x,y,z,w)));
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1].push_back(Vec3fa(Vec3ff(x,y,z,w)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbagePointSet(int hash, size_t numPoints, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
|
||||
Ref<SceneGraph::PointSetNode> mesh = new SceneGraph::PointSetNode(RTC_GEOMETRY_TYPE_SPHERE_POINT, material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
for (size_t i = 0; i < numPoints; i++)
|
||||
{
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0].push_back(Vec3ff(x, y, z, r));
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1].push_back(Vec3ff(x, y, z, r));
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
}
|
||||
35
Framework/external/embree/tutorials/common/scenegraph/geometry_creation.h
vendored
Normal file
35
Framework/external/embree/tutorials/common/scenegraph/geometry_creation.h
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
Ref<Node> createTrianglePlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createQuadPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGridPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createSubdivPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, float tessellationRate, Ref<MaterialNode> material = nullptr);
|
||||
|
||||
Ref<Node> createSphere (const Vec3fa& center, const float radius, Ref<MaterialNode> materiall = nullptr);
|
||||
Ref<Node> createTriangleSphere(const Vec3fa& center, const float radius, size_t numPhi, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createQuadSphere (const Vec3fa& center, const float radius, size_t numPhi, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGridSphere (const Vec3fa& center, const float radius, size_t size, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createSubdivSphere (const Vec3fa& center, const float radius, size_t numPhi, float tessellationRate, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createSphereShapedHair(const Vec3fa& center, const float radius, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createPointSphere (const Vec3fa& center, const float radius, const float pointRadius, size_t numPhi, PointSubtype subtype, Ref<MaterialNode> materiall = nullptr);
|
||||
|
||||
Ref<Node> createHairyPlane (int hash, const Vec3fa& pos, const Vec3fa& dx, const Vec3fa& dy, const float len, const float r, size_t numHairs, CurveSubtype subtype, Ref<MaterialNode> material = nullptr);
|
||||
|
||||
Ref<Node> createGarbageTriangleMesh (int hash, size_t numTriangles, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageQuadMesh (int hash, size_t numQuads, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageGridMesh (int hash, size_t numGrids, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageHair (int hash, size_t numHairs, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageLineSegments (int hash, size_t numLineSegments, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageSubdivMesh (int hash, size_t numFaces, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbagePointSet(int hash, size_t numPoints, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
}
|
||||
}
|
||||
199
Framework/external/embree/tutorials/common/scenegraph/lights.h
vendored
Normal file
199
Framework/external/embree/tutorials/common/scenegraph/lights.h
vendored
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../default.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
enum LightType
|
||||
{
|
||||
LIGHT_AMBIENT,
|
||||
LIGHT_POINT,
|
||||
LIGHT_DIRECTIONAL,
|
||||
LIGHT_SPOT,
|
||||
LIGHT_DISTANT,
|
||||
LIGHT_TRIANGLE,
|
||||
LIGHT_QUAD,
|
||||
};
|
||||
|
||||
class Light
|
||||
{
|
||||
ALIGNED_CLASS_(16)
|
||||
|
||||
public:
|
||||
Light(LightType type) : type(type) {}
|
||||
|
||||
LightType getType() const { return type; }
|
||||
|
||||
private:
|
||||
LightType type;
|
||||
};
|
||||
|
||||
class AmbientLight : public Light
|
||||
{
|
||||
public:
|
||||
AmbientLight (const Vec3fa& L)
|
||||
: Light(LIGHT_AMBIENT), L(L) {}
|
||||
|
||||
AmbientLight transform(const AffineSpace3fa& space) const {
|
||||
return AmbientLight(L);
|
||||
}
|
||||
|
||||
static AmbientLight lerp(const AmbientLight& light0, const AmbientLight& light1, const float f) {
|
||||
return AmbientLight(embree::lerp(light0.L,light1.L,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa L; //!< radiance of ambient light
|
||||
};
|
||||
|
||||
class PointLight : public Light
|
||||
{
|
||||
public:
|
||||
PointLight (const Vec3fa& P, const Vec3fa& I)
|
||||
: Light(LIGHT_POINT), P(P), I(I) {}
|
||||
|
||||
PointLight transform(const AffineSpace3fa& space) const {
|
||||
return PointLight(xfmPoint(space,P),I);
|
||||
}
|
||||
|
||||
static PointLight lerp(const PointLight& light0, const PointLight& light1, const float f)
|
||||
{
|
||||
return PointLight(embree::lerp(light0.P,light1.P,f),
|
||||
embree::lerp(light0.I,light1.I,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa P; //!< position of point light
|
||||
Vec3fa I; //!< radiant intensity of point light
|
||||
};
|
||||
|
||||
class DirectionalLight : public Light
|
||||
{
|
||||
public:
|
||||
DirectionalLight (const Vec3fa& D, const Vec3fa& E)
|
||||
: Light(LIGHT_DIRECTIONAL), D(D), E(E) {}
|
||||
|
||||
DirectionalLight transform(const AffineSpace3fa& space) const {
|
||||
return DirectionalLight(xfmVector(space,D),E);
|
||||
}
|
||||
|
||||
static DirectionalLight lerp(const DirectionalLight& light0, const DirectionalLight& light1, const float f)
|
||||
{
|
||||
return DirectionalLight(embree::lerp(light0.D,light1.D,f),
|
||||
embree::lerp(light0.E,light1.E,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa D; //!< Light direction
|
||||
Vec3fa E; //!< Irradiance (W/m^2)
|
||||
};
|
||||
|
||||
class SpotLight : public Light
|
||||
{
|
||||
public:
|
||||
SpotLight (const Vec3fa& P, const Vec3fa& D, const Vec3fa& I, float angleMin, float angleMax)
|
||||
: Light(LIGHT_SPOT), P(P), D(D), I(I), angleMin(angleMin), angleMax(angleMax) {}
|
||||
|
||||
SpotLight transform(const AffineSpace3fa& space) const {
|
||||
return SpotLight(xfmPoint(space,P),xfmVector(space,D),I,angleMin,angleMax);
|
||||
}
|
||||
|
||||
static SpotLight lerp(const SpotLight& light0, const SpotLight& light1, const float f)
|
||||
{
|
||||
return SpotLight(embree::lerp(light0.P,light1.P,f),
|
||||
embree::lerp(light0.D,light1.D,f),
|
||||
embree::lerp(light0.I,light1.I,f),
|
||||
embree::lerp(light0.angleMin,light1.angleMin,f),
|
||||
embree::lerp(light0.angleMax,light1.angleMax,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa P; //!< Position of the spot light
|
||||
Vec3fa D; //!< Light direction of the spot light
|
||||
Vec3fa I; //!< Radiant intensity (W/sr)
|
||||
float angleMin, angleMax; //!< Linear falloff region
|
||||
};
|
||||
|
||||
class DistantLight : public Light
|
||||
{
|
||||
public:
|
||||
DistantLight (const Vec3fa& D, const Vec3fa& L, const float halfAngle)
|
||||
: Light(LIGHT_DISTANT), D(D), L(L), halfAngle(halfAngle), radHalfAngle(deg2rad(halfAngle)), cosHalfAngle(cos(deg2rad(halfAngle))) {}
|
||||
|
||||
DistantLight transform(const AffineSpace3fa& space) const {
|
||||
return DistantLight(xfmVector(space,D),L,halfAngle);
|
||||
}
|
||||
|
||||
static DistantLight lerp(const DistantLight& light0, const DistantLight& light1, const float f)
|
||||
{
|
||||
return DistantLight(embree::lerp(light0.D,light1.D,f),
|
||||
embree::lerp(light0.L,light1.L,f),
|
||||
embree::lerp(light0.halfAngle,light1.halfAngle,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa D; //!< Light direction
|
||||
Vec3fa L; //!< Radiance (W/(m^2*sr))
|
||||
float halfAngle; //!< Half illumination angle
|
||||
float radHalfAngle; //!< Half illumination angle in radians
|
||||
float cosHalfAngle; //!< Cosine of half illumination angle
|
||||
};
|
||||
|
||||
class TriangleLight : public Light
|
||||
{
|
||||
public:
|
||||
TriangleLight (const Vec3fa& v0, const Vec3fa& v1, const Vec3fa& v2, const Vec3fa& L)
|
||||
: Light(LIGHT_TRIANGLE), v0(v0), v1(v1), v2(v2), L(L) {}
|
||||
|
||||
TriangleLight transform(const AffineSpace3fa& space) const {
|
||||
return TriangleLight(xfmPoint(space,v0),xfmPoint(space,v1),xfmPoint(space,v2),L);
|
||||
}
|
||||
|
||||
static TriangleLight lerp(const TriangleLight& light0, const TriangleLight& light1, const float f)
|
||||
{
|
||||
return TriangleLight(embree::lerp(light0.v0,light1.v0,f),
|
||||
embree::lerp(light0.v1,light1.v1,f),
|
||||
embree::lerp(light0.v2,light1.v2,f),
|
||||
embree::lerp(light0.L,light1.L,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa v0;
|
||||
Vec3fa v1;
|
||||
Vec3fa v2;
|
||||
Vec3fa L;
|
||||
};
|
||||
|
||||
class QuadLight : public Light
|
||||
{
|
||||
public:
|
||||
QuadLight (const Vec3fa& v0, const Vec3fa& v1, const Vec3fa& v2, const Vec3fa& v3, const Vec3fa& L)
|
||||
: Light(LIGHT_QUAD), v0(v0), v1(v1), v2(v2), v3(v3), L(L) {}
|
||||
|
||||
QuadLight transform(const AffineSpace3fa& space) const {
|
||||
return QuadLight(xfmPoint(space,v0),xfmPoint(space,v1),xfmPoint(space,v2),xfmPoint(space,v3),L);
|
||||
}
|
||||
|
||||
static QuadLight lerp(const QuadLight& light0, const QuadLight& light1, const float f)
|
||||
{
|
||||
return QuadLight(embree::lerp(light0.v0,light1.v0,f),
|
||||
embree::lerp(light0.v1,light1.v1,f),
|
||||
embree::lerp(light0.v2,light1.v2,f),
|
||||
embree::lerp(light0.v3,light1.v3,f),
|
||||
embree::lerp(light0.L,light1.L,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa v0;
|
||||
Vec3fa v1;
|
||||
Vec3fa v2;
|
||||
Vec3fa v3;
|
||||
Vec3fa L;
|
||||
};
|
||||
}
|
||||
}
|
||||
260
Framework/external/embree/tutorials/common/scenegraph/materials.h
vendored
Normal file
260
Framework/external/embree/tutorials/common/scenegraph/materials.h
vendored
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#if defined (CPPTUTORIAL) && !defined(_MATERIALS_H_CPPTUTORIAL) || !defined(_MATERIALS_H_)
|
||||
|
||||
#if defined (CPPTUTORIAL)
|
||||
#define _MATERIALS_H_CPPTUTORIAL
|
||||
#else
|
||||
#define _MATERIALS_H_
|
||||
#endif
|
||||
|
||||
//#pragma once
|
||||
|
||||
#if !defined(ISPC)
|
||||
#include "texture.h"
|
||||
#include "scenegraph.h"
|
||||
#endif
|
||||
|
||||
#if !defined(ISPC)
|
||||
namespace embree
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined(ISPC) || defined(CPPTUTORIAL)
|
||||
#define MATERIAL_BASE_CLASS
|
||||
#define PREFIX(x) ISPC##x
|
||||
#else
|
||||
#define MATERIAL_BASE_CLASS : public SceneGraph::MaterialNode
|
||||
#define PREFIX(x) x
|
||||
#endif
|
||||
|
||||
#if !defined(CPPTUTORIAL)
|
||||
enum MaterialType
|
||||
{
|
||||
MATERIAL_OBJ,
|
||||
MATERIAL_THIN_DIELECTRIC,
|
||||
MATERIAL_METAL,
|
||||
MATERIAL_VELVET,
|
||||
MATERIAL_DIELECTRIC,
|
||||
MATERIAL_METALLIC_PAINT,
|
||||
MATERIAL_MATTE,
|
||||
MATERIAL_MIRROR,
|
||||
MATERIAL_REFLECTIVE_METAL,
|
||||
MATERIAL_HAIR
|
||||
};
|
||||
#endif
|
||||
|
||||
struct PREFIX(Material)
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
Material (MaterialType type)
|
||||
: type(type) {}
|
||||
#endif
|
||||
#if !defined(ISPC)
|
||||
__aligned(16)
|
||||
#endif
|
||||
int type;
|
||||
int align[3];
|
||||
};
|
||||
|
||||
struct PREFIX(MatteMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
MatteMaterial (const Vec3fa& reflectance)
|
||||
: base(MATERIAL_MATTE), reflectance(reflectance) {}
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa reflectance;
|
||||
};
|
||||
|
||||
struct PREFIX(MirrorMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
MirrorMaterial (const Vec3fa& reflectance)
|
||||
: base(MATERIAL_MIRROR), reflectance(reflectance) {}
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa reflectance;
|
||||
};
|
||||
|
||||
struct PREFIX(ThinDielectricMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
ThinDielectricMaterial (const Vec3fa& transmission, const float eta, const float thickness)
|
||||
: base(MATERIAL_THIN_DIELECTRIC), transmission(transmission), transmissionFactor(log(transmission)*thickness), eta(eta), thickness(thickness) {}
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa transmission;
|
||||
Vec3fa transmissionFactor;
|
||||
float eta;
|
||||
float thickness;
|
||||
};
|
||||
|
||||
struct PREFIX(OBJMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
OBJMaterial (const std::string name = "")
|
||||
: SceneGraph::MaterialNode(name), base(MATERIAL_OBJ), illum(0), d(1.f), Ns(1.f), Ni(1.f), Ka(0.f), Kd(1.f), Ks(0.f), Kt(1.0f),
|
||||
map_d(nullptr), map_Ka(nullptr), map_Kd(nullptr), map_Ks(nullptr), map_Kt(nullptr), map_Ns(nullptr), map_Displ(nullptr) {}
|
||||
|
||||
OBJMaterial (float d, const Vec3fa& Kd, const Vec3fa& Ks, const float Ns, const std::string name = "")
|
||||
: base(MATERIAL_OBJ), illum(0), d(d), Ns(Ns), Ni(1.f), Ka(0.f), Kd(Kd), Ks(Ks), Kt(1.0f),
|
||||
map_d(nullptr), map_Ka(nullptr), map_Kd(nullptr), map_Ks(nullptr), map_Kt(nullptr), map_Ns(nullptr), map_Displ(nullptr) {}
|
||||
|
||||
OBJMaterial (float d, const std::shared_ptr<Texture> map_d,
|
||||
const Vec3fa& Ka, const std::shared_ptr<Texture> map_Ka,
|
||||
const Vec3fa& Kd, const std::shared_ptr<Texture> map_Kd,
|
||||
const Vec3fa& Ks, const std::shared_ptr<Texture> map_Ks,
|
||||
const Vec3fa& Kt, const std::shared_ptr<Texture> map_Kt,
|
||||
const float Ns, const std::shared_ptr<Texture> map_Ns,
|
||||
const std::shared_ptr<Texture> map_Displ)
|
||||
: base(MATERIAL_OBJ), illum(0), d(d), Ns(Ns), Ni(1.f), Ka(Ka), Kd(Kd), Ks(Ks), Kt(Kt),
|
||||
map_d(nullptr), map_Ka(nullptr), map_Kd(nullptr), map_Ks(nullptr), map_Kt(nullptr), map_Ns(nullptr), map_Displ(nullptr),
|
||||
_map_d(map_d), _map_Ka(map_Ka), _map_Kd(map_Kd), _map_Ks(map_Ks), _map_Kt(map_Kt), _map_Ns(map_Ns), _map_Displ(map_Displ) {}
|
||||
|
||||
virtual Material* material()
|
||||
{
|
||||
map_d = _map_d.get();
|
||||
map_Ka = _map_Ka.get();
|
||||
map_Kd = _map_Kd.get();
|
||||
map_Ks = _map_Ks.get();
|
||||
map_Kt = _map_Kt.get();
|
||||
map_Ns = _map_Ns.get();
|
||||
map_Displ = _map_Displ.get();
|
||||
return &base;
|
||||
}
|
||||
|
||||
~OBJMaterial() { // FIXME: destructor never called
|
||||
}
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
int illum; /*< illumination model */
|
||||
float d; /*< dissolve factor, 1=opaque, 0=transparent */
|
||||
float Ns; /*< specular exponent */
|
||||
float Ni; /*< optical density for the surface (index of refraction) */
|
||||
|
||||
Vec3fa Ka; /*< ambient reflectivity */
|
||||
Vec3fa Kd; /*< diffuse reflectivity */
|
||||
Vec3fa Ks; /*< specular reflectivity */
|
||||
Vec3fa Kt; /*< transmission filter */
|
||||
|
||||
const Texture* map_d; /*< d texture */
|
||||
const Texture* map_Ka; /*< Ka texture */
|
||||
const Texture* map_Kd; /*< Kd texture */
|
||||
const Texture* map_Ks; /*< Ks texture */
|
||||
const Texture* map_Kt; /*< Kt texture */
|
||||
const Texture* map_Ns; /*< Ns texture */
|
||||
const Texture* map_Displ; /*< Displ texture */
|
||||
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
std::shared_ptr<Texture> _map_d; /*< d texture */
|
||||
std::shared_ptr<Texture> _map_Ka; /*< Ka texture */
|
||||
std::shared_ptr<Texture> _map_Kd; /*< Kd texture */
|
||||
std::shared_ptr<Texture> _map_Ks; /*< Ks texture */
|
||||
std::shared_ptr<Texture> _map_Kt; /*< Kt texture */
|
||||
std::shared_ptr<Texture> _map_Ns; /*< Ns texture */
|
||||
std::shared_ptr<Texture> _map_Displ; /*< Displ texture */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PREFIX(MetalMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
MetalMaterial (const Vec3fa& reflectance, const Vec3fa& eta, const Vec3fa& k)
|
||||
: base(MATERIAL_REFLECTIVE_METAL), reflectance(reflectance), eta(eta), k(k), roughness(0.0f) {}
|
||||
|
||||
MetalMaterial (const Vec3fa& reflectance, const Vec3fa& eta, const Vec3fa& k, const float roughness)
|
||||
: base(MATERIAL_METAL), reflectance(reflectance), eta(eta), k(k), roughness(roughness) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa reflectance;
|
||||
Vec3fa eta;
|
||||
Vec3fa k;
|
||||
float roughness;
|
||||
};
|
||||
|
||||
typedef PREFIX(MetalMaterial) PREFIX(ReflectiveMetalMaterial);
|
||||
|
||||
struct PREFIX(VelvetMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
VelvetMaterial (const Vec3fa& reflectance, const float backScattering, const Vec3fa& horizonScatteringColor, const float horizonScatteringFallOff)
|
||||
: base(MATERIAL_VELVET), reflectance(reflectance), horizonScatteringColor(horizonScatteringColor), backScattering(backScattering), horizonScatteringFallOff(horizonScatteringFallOff) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa reflectance;
|
||||
Vec3fa horizonScatteringColor;
|
||||
float backScattering;
|
||||
float horizonScatteringFallOff;
|
||||
};
|
||||
|
||||
struct PREFIX(DielectricMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
DielectricMaterial (const Vec3fa& transmissionOutside, const Vec3fa& transmissionInside, const float etaOutside, const float etaInside)
|
||||
: base(MATERIAL_DIELECTRIC), transmissionOutside(transmissionOutside), transmissionInside(transmissionInside), etaOutside(etaOutside), etaInside(etaInside) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa transmissionOutside;
|
||||
Vec3fa transmissionInside;
|
||||
float etaOutside;
|
||||
float etaInside;
|
||||
};
|
||||
|
||||
struct PREFIX(MetallicPaintMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
MetallicPaintMaterial (const Vec3fa& shadeColor, const Vec3fa& glitterColor, float glitterSpread, float eta)
|
||||
: base(MATERIAL_METALLIC_PAINT), shadeColor(shadeColor), glitterColor(glitterColor), glitterSpread(glitterSpread), eta(eta) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa shadeColor;
|
||||
Vec3fa glitterColor;
|
||||
float glitterSpread;
|
||||
float eta;
|
||||
};
|
||||
|
||||
struct PREFIX(HairMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
HairMaterial (const Vec3fa& Kr, const Vec3fa& Kt, float nx, float ny)
|
||||
: base(MATERIAL_HAIR), Kr(Kr), Kt(Kt), nx(nx), ny(ny) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa Kr;
|
||||
Vec3fa Kt;
|
||||
float nx;
|
||||
float ny;
|
||||
};
|
||||
|
||||
#undef MATERIAL_BASE_CLASS
|
||||
#undef PREFIX
|
||||
|
||||
#if !defined(ISPC)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
652
Framework/external/embree/tutorials/common/scenegraph/obj_loader.cpp
vendored
Normal file
652
Framework/external/embree/tutorials/common/scenegraph/obj_loader.cpp
vendored
Normal file
|
|
@ -0,0 +1,652 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "obj_loader.h"
|
||||
#include "texture.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
/*! Three-index vertex, indexing start at 0, -1 means invalid vertex. */
|
||||
struct Vertex {
|
||||
unsigned int v, vt, vn;
|
||||
Vertex() {};
|
||||
Vertex(unsigned int v) : v(v), vt(v), vn(v) {};
|
||||
Vertex(unsigned int v, unsigned int vt, unsigned int vn) : v(v), vt(vt), vn(vn) {};
|
||||
};
|
||||
|
||||
struct Crease {
|
||||
float w;
|
||||
unsigned int a, b;
|
||||
Crease() : w(0), a(-1), b(-1) {};
|
||||
Crease(float w, unsigned int a, unsigned int b) : w(w), a(a), b(b) {};
|
||||
};
|
||||
|
||||
static inline bool operator < ( const Vertex& a, const Vertex& b ) {
|
||||
if (a.v != b.v) return a.v < b.v;
|
||||
if (a.vn != b.vn) return a.vn < b.vn;
|
||||
if (a.vt != b.vt) return a.vt < b.vt;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Fill space at the end of the token with 0s. */
|
||||
static inline const char* trimEnd(const char* token)
|
||||
{
|
||||
if (*token == 0) return token;
|
||||
char* pe = (char*) token;
|
||||
while (*pe) pe++;
|
||||
pe--;
|
||||
while ((*pe == ' ' || *pe == '\t' || *pe == '\r') && pe >= token) *pe-- = 0;
|
||||
return token;
|
||||
}
|
||||
|
||||
/*! Determine if character is a separator. */
|
||||
static inline bool isSep(const char c) {
|
||||
return (c == ' ') || (c == '\t');
|
||||
}
|
||||
|
||||
/*! Parse separator. */
|
||||
static inline const char* parseSep(const char*& token) {
|
||||
size_t sep = strspn(token, " \t");
|
||||
if (!sep) THROW_RUNTIME_ERROR("separator expected");
|
||||
return token+=sep;
|
||||
}
|
||||
|
||||
/*! Parse optional separator. */
|
||||
static inline const char* parseSepOpt(const char*& token) {
|
||||
return token+=strspn(token, " \t");
|
||||
}
|
||||
|
||||
/*! Read float from a string. */
|
||||
static inline float getFloat(const char*& token) {
|
||||
token += strspn(token, " \t");
|
||||
float n = (float)atof(token);
|
||||
token += strcspn(token, " \t\r");
|
||||
return n;
|
||||
}
|
||||
|
||||
/*! Read int from a string. */
|
||||
static inline int getInt(const char*& token) {
|
||||
token += strspn(token, " \t");
|
||||
int n = atoi(token);
|
||||
token += strcspn(token, " \t\r");
|
||||
return n;
|
||||
}
|
||||
|
||||
/*! Read Vec2f from a string. */
|
||||
static inline Vec2f getVec2f(const char*& token) {
|
||||
float x = getFloat(token);
|
||||
float y = getFloat(token);
|
||||
return Vec2f(x,y);
|
||||
}
|
||||
|
||||
/*! Read Vec3f from a string. */
|
||||
static inline Vec3f getVec3f(const char*& token) {
|
||||
float x = getFloat(token);
|
||||
token += strspn(token, " \t");
|
||||
if (*token == 0) return Vec3f(x);
|
||||
float y = getFloat(token);
|
||||
float z = getFloat(token);
|
||||
return Vec3f(x,y,z);
|
||||
}
|
||||
|
||||
/*! Read Vec3fa from a string. */
|
||||
static inline Vec3fa getVec3fa(const char*& token) {
|
||||
float x = getFloat(token);
|
||||
token += strspn(token, " \t");
|
||||
if (*token == 0) return Vec3f(x);
|
||||
float y = getFloat(token);
|
||||
float z = getFloat(token);
|
||||
return Vec3fa(x,y,z);
|
||||
}
|
||||
|
||||
class OBJLoader
|
||||
{
|
||||
public:
|
||||
|
||||
/*! Constructor. */
|
||||
OBJLoader(const FileName& fileName, const bool subdivMode, const bool combineIntoSingleObject);
|
||||
|
||||
/*! output model */
|
||||
Ref<SceneGraph::GroupNode> group;
|
||||
|
||||
private:
|
||||
|
||||
/*! file to load */
|
||||
FileName path;
|
||||
|
||||
/*! load only quads and ignore triangles */
|
||||
bool subdivMode;
|
||||
|
||||
/*! Geometry buffer. */
|
||||
avector<Vec3fa> v;
|
||||
avector<Vec3fa> vn;
|
||||
std::vector<Vec2f> vt;
|
||||
std::vector<Crease> ec;
|
||||
|
||||
std::vector<std::vector<Vertex> > curGroup;
|
||||
std::vector<avector<Vec3ff> > curGroupHair;
|
||||
|
||||
/*! Material handling. */
|
||||
std::string curMaterialName;
|
||||
Ref<SceneGraph::MaterialNode> curMaterial;
|
||||
std::map<std::string, Ref<SceneGraph::MaterialNode> > material;
|
||||
std::map<std::string, std::shared_ptr<Texture>> textureMap;
|
||||
|
||||
private:
|
||||
void loadMTL(const FileName& fileName);
|
||||
unsigned int fix_v (int index);
|
||||
unsigned int fix_vt(int index);
|
||||
unsigned int fix_vn(int index);
|
||||
void flushFaceGroup();
|
||||
void flushTriGroup();
|
||||
void flushHairGroup();
|
||||
Vertex getUInt3(const char*& token);
|
||||
uint32_t getVertex(std::map<Vertex,uint32_t>& vertexMap, Ref<SceneGraph::TriangleMeshNode> mesh, const Vertex& i);
|
||||
std::shared_ptr<Texture> loadTexture(const FileName& fname);
|
||||
};
|
||||
|
||||
OBJLoader::OBJLoader(const FileName &fileName, const bool subdivMode, const bool combineIntoSingleObject)
|
||||
: group(new SceneGraph::GroupNode), path(fileName.path()), subdivMode(subdivMode)
|
||||
{
|
||||
/* open file */
|
||||
std::ifstream cin;
|
||||
cin.open(fileName.c_str());
|
||||
if (!cin.is_open()) {
|
||||
THROW_RUNTIME_ERROR("cannot open " + fileName.str());
|
||||
return;
|
||||
}
|
||||
|
||||
/* generate default material */
|
||||
Ref<SceneGraph::MaterialNode> defaultMaterial = new OBJMaterial("default");
|
||||
curMaterialName = "default";
|
||||
curMaterial = defaultMaterial;
|
||||
|
||||
while (cin.peek() != -1)
|
||||
{
|
||||
/* load next multiline */
|
||||
std::string line; std::getline(cin,line);
|
||||
while (!line.empty() && line[line.size()-1] == '\\') {
|
||||
line[line.size()-1] = ' ';
|
||||
std::string next_line; std::getline(cin,next_line);
|
||||
if (next_line.empty()) break;
|
||||
line += next_line;
|
||||
}
|
||||
const char* token = trimEnd(line.c_str() + strspn(line.c_str(), " \t"));
|
||||
if (token[0] == 0) continue;
|
||||
|
||||
/*! parse position */
|
||||
if (token[0] == 'v' && isSep(token[1])) {
|
||||
v.push_back(getVec3f(token += 2)); continue;
|
||||
}
|
||||
|
||||
/* parse normal */
|
||||
if (token[0] == 'v' && token[1] == 'n' && isSep(token[2])) {
|
||||
vn.push_back(getVec3f(token += 3));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* parse texcoord */
|
||||
if (token[0] == 'v' && token[1] == 't' && isSep(token[2])) { vt.push_back(getVec2f(token += 3)); continue; }
|
||||
|
||||
/*! parse face */
|
||||
if (token[0] == 'f' && isSep(token[1]))
|
||||
{
|
||||
parseSep(token += 1);
|
||||
|
||||
std::vector<Vertex> face;
|
||||
while (token[0]) {
|
||||
Vertex vtx = getUInt3(token);
|
||||
face.push_back(vtx);
|
||||
parseSepOpt(token);
|
||||
}
|
||||
curGroup.push_back(face);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*! parse corona hair */
|
||||
if (!strncmp(token,"hair",4) && isSep(token[4]))
|
||||
{
|
||||
parseSep(token += 4);
|
||||
bool plane = !strncmp(token,"plane",5) && isSep(token[5]);
|
||||
if (plane) {
|
||||
parseSep(token += 5);
|
||||
}
|
||||
else if (!strncmp(token,"cylinder",8) && isSep(token[8])) {
|
||||
parseSep(token += 8);
|
||||
}
|
||||
else continue;
|
||||
|
||||
unsigned int N = getInt(token);
|
||||
avector<Vec3ff> hair;
|
||||
for (unsigned int i=0; i<3*N+1; i++) {
|
||||
hair.push_back((Vec3ff)getVec3fa(token));
|
||||
}
|
||||
|
||||
for (unsigned int i=0; i<N+1; i++)
|
||||
{
|
||||
float r = getFloat(token);
|
||||
MAYBE_UNUSED float t = (float)getInt(token);
|
||||
if (i != 0) hair[3*i-1].w = r;
|
||||
hair[3*i+0].w = r;
|
||||
if (i != N) hair[3*i+1].w = r;
|
||||
}
|
||||
curGroupHair.push_back(hair);
|
||||
}
|
||||
|
||||
/*! parse edge crease */
|
||||
if (token[0] == 'e' && token[1] == 'c' && isSep(token[2]))
|
||||
{
|
||||
parseSep(token += 2);
|
||||
float w = getFloat(token);
|
||||
parseSepOpt(token);
|
||||
unsigned int a = fix_v(getInt(token));
|
||||
parseSepOpt(token);
|
||||
unsigned int b = fix_v(getInt(token));
|
||||
parseSepOpt(token);
|
||||
ec.push_back(Crease(w, a, b));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*! use material */
|
||||
if (!strncmp(token, "usemtl", 6) && isSep(token[6]))
|
||||
{
|
||||
if (!combineIntoSingleObject) flushFaceGroup();
|
||||
std::string name(parseSep(token += 6));
|
||||
if (material.find(name) == material.end()) {
|
||||
curMaterial = defaultMaterial;
|
||||
curMaterialName = "default";
|
||||
}
|
||||
else {
|
||||
curMaterial = material[name];
|
||||
curMaterialName = name;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* load material library */
|
||||
if (!strncmp(token, "mtllib", 6) && isSep(token[6])) {
|
||||
loadMTL(path + std::string(parseSep(token += 6)));
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignore unknown stuff
|
||||
}
|
||||
flushFaceGroup();
|
||||
|
||||
cin.close();
|
||||
}
|
||||
|
||||
struct ExtObjMaterial
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type { NONE, MATTE, GLASS, METAL, METALLIC_PAINT };
|
||||
|
||||
Ref<SceneGraph::MaterialNode> select() const
|
||||
{
|
||||
std::shared_ptr<Texture> nulltex;
|
||||
if (type == NONE) {
|
||||
return new OBJMaterial(d,map_d,Ka,map_Ka,Kd,map_Kd,Ks,map_Ks,Kt,map_Kt,Ns,map_Ns,map_Displ);
|
||||
} else if (type == MATTE) {
|
||||
if (coat_eta != 1.0f) return new MetallicPaintMaterial (Kd,zero,0.0f,eta.x);
|
||||
else return new OBJMaterial(1.0f,nulltex,zero,nulltex,Kd,map_Kd,Ks,nulltex,zero,nulltex,1.0f/(1E-6f+roughness),nulltex,nulltex);
|
||||
} else if (type == GLASS) {
|
||||
return new ThinDielectricMaterial(Vec3fa(1.0f),eta.x,0.1f);
|
||||
} else if (type == METAL) {
|
||||
if (roughness == 0.0f) {
|
||||
if (eta == Vec3fa(1.0f) && k == Vec3fa(0.0f)) return new MirrorMaterial(Kd);
|
||||
else return new MetalMaterial(Kd,eta,k);
|
||||
}
|
||||
else return new MetalMaterial(Kd,eta,k,roughness);
|
||||
} else if (type == METALLIC_PAINT) {
|
||||
return new MetallicPaintMaterial (Kd,Ks,0.0f,coat_eta);
|
||||
}
|
||||
return new MatteMaterial(Vec3fa(0.5f));
|
||||
}
|
||||
|
||||
public:
|
||||
Type type = NONE;
|
||||
|
||||
int illum = 0; /*< illumination model */
|
||||
float d = 1.0f; /*< dissolve factor, 1=opaque, 0=transparent */
|
||||
float Ns = 1.0f; /*< specular exponent */
|
||||
float Ni = 1.0f; /*< optical density for the surface (index of refraction) */
|
||||
|
||||
Vec3fa Ka = zero; /*< ambient reflectivity */
|
||||
Vec3fa Kd = one; /*< diffuse reflectivity */
|
||||
Vec3fa Ks = zero; /*< specular reflectivity */
|
||||
Vec3fa Kt = zero; /*< transmission filter */
|
||||
|
||||
std::shared_ptr<Texture> map_d; /*< d texture */
|
||||
std::shared_ptr<Texture> map_Ka; /*< Ka texture */
|
||||
std::shared_ptr<Texture> map_Kd; /*< Kd texture */
|
||||
std::shared_ptr<Texture> map_Ks; /*< Ks texture */
|
||||
std::shared_ptr<Texture> map_Kt; /*< Kt texture */
|
||||
std::shared_ptr<Texture> map_Ns; /*< Ns texture */
|
||||
std::shared_ptr<Texture> map_Displ; /*< Displ texture */
|
||||
|
||||
float roughness = zero;
|
||||
std::shared_ptr<Texture> roughnessMap;
|
||||
float coat_eta = one;
|
||||
float coat_roughness = zero;
|
||||
std::shared_ptr<Texture> coat_roughnessMap;
|
||||
float bump = zero;
|
||||
Vec3f eta = Vec3f(1.4f);
|
||||
Vec3f k = Vec3f(3.0f);
|
||||
};
|
||||
|
||||
std::shared_ptr<Texture> OBJLoader::loadTexture(const FileName& fname)
|
||||
{
|
||||
if (textureMap.find(fname.str()) != textureMap.end())
|
||||
return textureMap[fname.str()];
|
||||
|
||||
return std::shared_ptr<Texture>(Texture::load(path+fname));
|
||||
}
|
||||
|
||||
/* load material file */
|
||||
void OBJLoader::loadMTL(const FileName &fileName)
|
||||
{
|
||||
std::ifstream cin;
|
||||
cin.open(fileName.c_str());
|
||||
if (!cin.is_open()) {
|
||||
std::cerr << "cannot open " << fileName.str() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
ExtObjMaterial cur;
|
||||
|
||||
while (cin.peek() != -1)
|
||||
{
|
||||
/* load next multiline */
|
||||
std::string line; std::getline(cin,line);
|
||||
while (!line.empty() && line[line.size()-1] == '\\') {
|
||||
line[line.size()-1] = ' ';
|
||||
std::string next_line; std::getline(cin,next_line);
|
||||
if (next_line.empty()) break;
|
||||
line += next_line;
|
||||
}
|
||||
const char* token = trimEnd(line.c_str() + strspn(line.c_str(), " \t"));
|
||||
|
||||
if (token[0] == 0 ) continue; // ignore empty lines
|
||||
if (token[0] == '#') continue; // ignore comments
|
||||
|
||||
if (!strncmp(token, "newmtl", 6))
|
||||
{
|
||||
if (name != "") {
|
||||
material[name] = cur.select();
|
||||
material[name]->name = name;
|
||||
}
|
||||
|
||||
parseSep(token+=6);
|
||||
name = token;
|
||||
cur = ExtObjMaterial();
|
||||
continue;
|
||||
}
|
||||
if (name == "") THROW_RUNTIME_ERROR("invalid material file: newmtl expected first");
|
||||
|
||||
try
|
||||
{
|
||||
if (!strncmp(token, "illum", 5)) { parseSep(token += 5); continue; }
|
||||
|
||||
if (!strncmp(token, "d", 1)) { parseSep(token += 1); cur.d = getFloat(token); continue; }
|
||||
if (!strncmp(token, "Ns", 2)) { parseSep(token += 2); cur.Ns = getFloat(token); continue; }
|
||||
if (!strncmp(token, "Ni", 2)) { parseSep(token += 2); cur.Ni = getFloat(token); continue; }
|
||||
|
||||
if (!strncmp(token, "map_d", 5) || !strncmp(token, "d_map", 5)) {
|
||||
parseSep(token += 5);
|
||||
cur.map_d = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Ka", 6) || !strncmp(token, "Ka_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Ka = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Kd", 6) || !strncmp(token, "Kd_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Kd = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Ks", 6) || !strncmp(token, "Ks_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Ks = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Kt", 6) || !strncmp(token, "Kt_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Kt = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Tf", 6) || !strncmp(token, "Tf_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Kt = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Ns", 6) || !strncmp(token, "Ns_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Ns = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Displ", 9) || !strncmp(token, "Displ_map", 9)) {
|
||||
parseSep(token += 9);
|
||||
cur.map_Displ = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strncmp(token, "Ka", 2)) { parseSep(token += 2); cur.Ka = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "Kd", 2)) { parseSep(token += 2); cur.Kd = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "Ks", 2)) { parseSep(token += 2); cur.Ks = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "Kt", 2)) { parseSep(token += 2); cur.Kt = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "Tf", 2)) { parseSep(token += 2); cur.Kt = getVec3f(token); continue; }
|
||||
|
||||
/* extended OBJ */
|
||||
if (!strncmp(token, "type", 4)) {
|
||||
parseSep(token += 4); std::string type = token;
|
||||
if (type == "matte") cur.type = ExtObjMaterial::MATTE;
|
||||
else if (type == "glass") cur.type = ExtObjMaterial::GLASS;
|
||||
else if (type == "metal") cur.type = ExtObjMaterial::METAL;
|
||||
else if (type == "metallicPaint") cur.type = ExtObjMaterial::METALLIC_PAINT;
|
||||
else if (type == "principled") cur.type = ExtObjMaterial::NONE;
|
||||
else if (type == "luminous") cur.type = ExtObjMaterial::NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* OSPRay principled material extensions */
|
||||
if (!strncmp(token, "baseColor", 9)) { parseSep(token += 9); cur.Kd = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "ior", 3)) { parseSep(token += 3); cur.Ni = getFloat(token); continue; }
|
||||
if (!strncmp(token, "map_baseColor", 13)) { parseSep(token += 13); cur.map_Kd = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "map_specular", 12)) { parseSep(token += 12); cur.map_Ks = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "map_normal.scale", 16)) { parseSep(token += 16); continue; }
|
||||
if (!strncmp(token, "map_normal", 10)) { parseSep(token += 10); cur.map_Displ = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "transmissionColor",17)) { parseSep(token += 17); cur.Kt = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "transmission", 12)) { parseSep(token += 12); cur.Kt = Vec3f(getFloat(token)); continue; }
|
||||
|
||||
if (!strncmp(token, "roughnessMap", 12)) { parseSep(token += 12); cur.roughnessMap = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "roughness", 9)) { parseSep(token += 9); cur.roughness = getFloat(token); cur.Ns = 1.0f/(cur.roughness+1E-6f); continue; }
|
||||
if (!strncmp(token, "colorMap", 8)) { parseSep(token += 8); cur.map_Kd = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "color", 5)) { parseSep(token += 5); cur.Kd = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "coat.color", 10)) { parseSep(token += 10); cur.Kd = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "coat.eta", 8)) { parseSep(token += 8); cur.coat_eta = getFloat(token); continue; }
|
||||
if (!strncmp(token, "coat.roughnessMap",17)) { parseSep(token += 17); cur.coat_roughnessMap = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "coat.roughness", 14)) { parseSep(token += 14); cur.coat_roughness = getFloat(token); continue; }
|
||||
if (!strncmp(token, "bumpMap", 7)) { parseSep(token += 7); cur.map_Displ = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "bump", 4)) { parseSep(token += 4); cur.bump = getFloat(token); continue; }
|
||||
if (!strncmp(token, "eta", 3)) { parseSep(token += 3); cur.eta = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "k", 1)) { parseSep(token += 1); cur.k = getVec3f(token); continue; }
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (name != "") {
|
||||
material[name] = cur.select();
|
||||
material[name]->name = name;
|
||||
}
|
||||
|
||||
cin.close();
|
||||
}
|
||||
|
||||
/*! handles relative indices and starts indexing from 0 */
|
||||
unsigned int OBJLoader::fix_v (int index) { return (index > 0 ? index - 1 : (index == 0 ? 0 : (int) v .size() + index)); }
|
||||
unsigned int OBJLoader::fix_vt(int index) { return (index > 0 ? index - 1 : (index == 0 ? 0 : (int) vt.size() + index)); }
|
||||
unsigned int OBJLoader::fix_vn(int index) { return (index > 0 ? index - 1 : (index == 0 ? 0 : (int) vn.size() + index)); }
|
||||
|
||||
/*! Parse differently formatted triplets like: n0, n0/n1/n2, n0//n2, n0/n1. */
|
||||
/*! All indices are converted to C-style (from 0). Missing entries are assigned -1. */
|
||||
Vertex OBJLoader::getUInt3(const char*& token)
|
||||
{
|
||||
Vertex v(-1);
|
||||
v.v = fix_v(atoi(token));
|
||||
token += strcspn(token, "/ \t\r");
|
||||
if (token[0] != '/') return(v);
|
||||
token++;
|
||||
|
||||
// it is i//n
|
||||
if (token[0] == '/') {
|
||||
token++;
|
||||
v.vn = fix_vn(atoi(token));
|
||||
token += strcspn(token, " \t\r");
|
||||
return(v);
|
||||
}
|
||||
|
||||
// it is i/t/n or i/t
|
||||
v.vt = fix_vt(atoi(token));
|
||||
token += strcspn(token, "/ \t\r");
|
||||
if (token[0] != '/') return(v);
|
||||
token++;
|
||||
|
||||
// it is i/t/n
|
||||
v.vn = fix_vn(atoi(token));
|
||||
token += strcspn(token, " \t\r");
|
||||
return(v);
|
||||
}
|
||||
|
||||
uint32_t OBJLoader::getVertex(std::map<Vertex,uint32_t>& vertexMap, Ref<SceneGraph::TriangleMeshNode> mesh, const Vertex& i)
|
||||
{
|
||||
const std::map<Vertex, uint32_t>::iterator& entry = vertexMap.find(i);
|
||||
if (entry != vertexMap.end()) return(entry->second);
|
||||
|
||||
if (i.v >= v.size()) std::cout << "WARNING: corrupted OBJ file" << std::endl;
|
||||
else mesh->positions[0].push_back(v[i.v]);
|
||||
|
||||
if (i.vn != -1) {
|
||||
while (mesh->normals[0].size() < mesh->positions[0].size()) mesh->normals[0].push_back(zero); // some vertices might not had a normal
|
||||
|
||||
if (i.vn >= vn.size()) std::cout << "WARNING: corrupted OBJ file" << std::endl;
|
||||
else mesh->normals[0][mesh->positions[0].size()-1] = vn[i.vn];
|
||||
}
|
||||
if (i.vt != -1) {
|
||||
while (mesh->texcoords.size() < mesh->positions[0].size()) mesh->texcoords.push_back(zero); // some vertices might not had a texture coordinate
|
||||
|
||||
if (i.vt >= vt.size()) std::cout << "WARNING: corrupted OBJ file" << std::endl;
|
||||
else mesh->texcoords[mesh->positions[0].size()-1] = vt[i.vt];
|
||||
}
|
||||
return (vertexMap[i] = (unsigned int)(mesh->positions[0].size()) - 1);
|
||||
}
|
||||
|
||||
void OBJLoader::flushFaceGroup()
|
||||
{
|
||||
flushTriGroup();
|
||||
flushHairGroup();
|
||||
}
|
||||
|
||||
/*! end current facegroup and append to mesh */
|
||||
void OBJLoader::flushTriGroup()
|
||||
{
|
||||
if (curGroup.empty()) return;
|
||||
|
||||
if (subdivMode)
|
||||
{
|
||||
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(curMaterial,BBox1f(0,1),1);
|
||||
mesh->normals.resize(1);
|
||||
group->add(mesh.cast<SceneGraph::Node>());
|
||||
|
||||
for (size_t i=0; i<v.size(); i++) mesh->positions[0].push_back(v[i]);
|
||||
for (size_t i=0; i<vn.size(); i++) mesh->normals[0].push_back(vn[i]);
|
||||
for (size_t i=0; i<vt.size(); i++) mesh->texcoords.push_back(vt[i]);
|
||||
|
||||
for (size_t i=0; i<ec.size(); ++i) {
|
||||
assert(((size_t)ec[i].a < v.size()) && ((size_t)ec[i].b < v.size()));
|
||||
mesh->edge_creases.push_back(Vec2i(ec[i].a, ec[i].b));
|
||||
mesh->edge_crease_weights.push_back(ec[i].w);
|
||||
}
|
||||
|
||||
for (size_t j=0; j<curGroup.size(); j++)
|
||||
{
|
||||
const std::vector<Vertex>& face = curGroup[j];
|
||||
mesh->verticesPerFace.push_back(int(face.size()));
|
||||
for (size_t i=0; i<face.size(); i++)
|
||||
mesh->position_indices.push_back(face[i].v);
|
||||
}
|
||||
if (mesh->normals[0].size() == 0)
|
||||
mesh->normals.clear();
|
||||
mesh->verify();
|
||||
}
|
||||
else
|
||||
{
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(curMaterial,BBox1f(0,1),1);
|
||||
mesh->normals.resize(1);
|
||||
group->add(mesh.cast<SceneGraph::Node>());
|
||||
// merge three indices into one
|
||||
std::map<Vertex, uint32_t> vertexMap;
|
||||
for (size_t j=0; j<curGroup.size(); j++)
|
||||
{
|
||||
/* iterate over all faces */
|
||||
const std::vector<Vertex>& face = curGroup[j];
|
||||
|
||||
/* triangulate the face with a triangle fan */
|
||||
Vertex i0 = face[0], i1 = Vertex(-1), i2 = face[1];
|
||||
for (size_t k=2; k < face.size(); k++)
|
||||
{
|
||||
i1 = i2; i2 = face[k];
|
||||
uint32_t v0,v1,v2;
|
||||
v0 = getVertex(vertexMap, mesh, i0);
|
||||
v1 = getVertex(vertexMap, mesh, i1);
|
||||
v2 = getVertex(vertexMap, mesh, i2);
|
||||
assert(v0 < mesh->numVertices());
|
||||
assert(v1 < mesh->numVertices());
|
||||
assert(v2 < mesh->numVertices());
|
||||
mesh->triangles.push_back(SceneGraph::TriangleMeshNode::Triangle(v0,v1,v2));
|
||||
}
|
||||
}
|
||||
/* there may be vertices without normals or texture coordinates, thus we have to make these arrays the same size here */
|
||||
if (mesh->normals[0].size()) while (mesh->normals[0].size() < mesh->numVertices()) mesh->normals[0].push_back(zero);
|
||||
if (mesh->texcoords.size()) while (mesh->texcoords.size() < mesh->numVertices()) mesh->texcoords.push_back(zero);
|
||||
|
||||
if (mesh->normals[0].size() == 0)
|
||||
mesh->normals.clear();
|
||||
mesh->verify();
|
||||
}
|
||||
|
||||
curGroup.clear();
|
||||
ec.clear();
|
||||
}
|
||||
|
||||
void OBJLoader::flushHairGroup()
|
||||
{
|
||||
if (curGroupHair.empty()) return;
|
||||
|
||||
avector<Vec3ff> vertices;
|
||||
std::vector<SceneGraph::HairSetNode::Hair> curves;
|
||||
|
||||
for (size_t i=0; i<curGroupHair.size(); i++) {
|
||||
for (size_t j=0; j<curGroupHair[i].size(); j++) {
|
||||
if (j%3 == 0) curves.push_back(SceneGraph::HairSetNode::Hair((unsigned int)vertices.size(),(unsigned int)i));
|
||||
vertices.push_back(curGroupHair[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(vertices,curves,curMaterial,RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE);
|
||||
group->add(mesh.cast<SceneGraph::Node>());
|
||||
mesh->verify();
|
||||
curGroupHair.clear();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> loadOBJ(const FileName& fileName, const bool subdivMode, const bool combineIntoSingleObject) {
|
||||
OBJLoader loader(fileName,subdivMode,combineIntoSingleObject);
|
||||
return loader.group.cast<SceneGraph::Node>();
|
||||
}
|
||||
}
|
||||
|
||||
13
Framework/external/embree/tutorials/common/scenegraph/obj_loader.h
vendored
Normal file
13
Framework/external/embree/tutorials/common/scenegraph/obj_loader.h
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
Ref<SceneGraph::Node> loadOBJ(const FileName& fileName,
|
||||
const bool subdivMode = false,
|
||||
const bool combineIntoSingleObject = false);
|
||||
}
|
||||
332
Framework/external/embree/tutorials/common/scenegraph/ply_loader.cpp
vendored
Normal file
332
Framework/external/embree/tutorials/common/scenegraph/ply_loader.cpp
vendored
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "ply_loader.h"
|
||||
#include <list>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
/*! PLY type */
|
||||
struct Type {
|
||||
enum Tag { PTY_CHAR, PTY_UCHAR, PTY_SHORT, PTY_USHORT, PTY_INT, PTY_UINT, PTY_FLOAT, PTY_DOUBLE, PTY_LIST, PTY_NONE } ty, index, data;
|
||||
Type() : ty(PTY_NONE), index(PTY_NONE), data(PTY_NONE) {}
|
||||
Type(Tag ty) : ty(ty), index(PTY_NONE), data(PTY_NONE) {}
|
||||
Type(Tag ty, Tag index, Tag data) : ty(ty), index(index), data(data) {}
|
||||
};
|
||||
|
||||
/*! an element stored in the PLY file, such as vertex, face, etc. */
|
||||
struct Element {
|
||||
std::string name;
|
||||
size_t size; /// number of data items of the element
|
||||
std::vector<std::string> properties; /// list of all properties of the element (e.g. x, y, z) (not strictly necessary)
|
||||
std::map<std::string,Type> type; /// mapping of property name to type
|
||||
std::map<std::string,std::vector<float> > data; /// data array properties (all represented as floats)
|
||||
std::map<std::string,std::vector<std::vector<size_t> > > list; /// list properties (integer lists supported only)
|
||||
};
|
||||
|
||||
/*! mesh structure that reflects the PLY file format */
|
||||
struct Mesh {
|
||||
std::vector<std::string> order; /// order of all elements in file (not strictly necessary)
|
||||
std::map<std::string,Element> elements; /// all elements of the file, e.g. vertex, face, ...
|
||||
};
|
||||
|
||||
/* returns the size of a type in bytes */
|
||||
size_t sizeOfType(Type::Tag ty)
|
||||
{
|
||||
switch (ty) {
|
||||
case Type::PTY_CHAR : return 1;
|
||||
case Type::PTY_UCHAR : return 1;
|
||||
case Type::PTY_SHORT : return 2;
|
||||
case Type::PTY_USHORT : return 2;
|
||||
case Type::PTY_INT : return 4;
|
||||
case Type::PTY_UINT : return 4;
|
||||
case Type::PTY_FLOAT : return 4;
|
||||
case Type::PTY_DOUBLE : return 8;
|
||||
default : throw std::runtime_error("invalid type");
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the type of a string */
|
||||
Type::Tag typeTagOfString(const std::string& ty) {
|
||||
if (ty == "char") return Type::PTY_CHAR;
|
||||
if (ty == "int8") return Type::PTY_CHAR;
|
||||
if (ty == "uchar") return Type::PTY_UCHAR;
|
||||
if (ty == "uint8") return Type::PTY_UCHAR;
|
||||
if (ty == "short") return Type::PTY_SHORT;
|
||||
if (ty == "int16") return Type::PTY_SHORT;
|
||||
if (ty == "ushort") return Type::PTY_USHORT;
|
||||
if (ty == "uint16") return Type::PTY_USHORT;
|
||||
if (ty == "int") return Type::PTY_INT;
|
||||
if (ty == "int32") return Type::PTY_INT;
|
||||
if (ty == "uint") return Type::PTY_UINT;
|
||||
if (ty == "uint32") return Type::PTY_UINT;
|
||||
if (ty == "float") return Type::PTY_FLOAT;
|
||||
if (ty == "float32") return Type::PTY_FLOAT;
|
||||
if (ty == "double") return Type::PTY_DOUBLE;
|
||||
throw std::runtime_error("invalid type " + ty);
|
||||
return Type::PTY_NONE;
|
||||
}
|
||||
|
||||
/* compute the type of a string */
|
||||
std::string stringOfTypeTag(Type::Tag ty) {
|
||||
if (ty == Type::PTY_CHAR) return "char";
|
||||
if (ty == Type::PTY_UCHAR) return "uchar";
|
||||
if (ty == Type::PTY_SHORT) return "short";
|
||||
if (ty == Type::PTY_USHORT) return "ushort";
|
||||
if (ty == Type::PTY_INT) return "int";
|
||||
if (ty == Type::PTY_UINT) return "uint";
|
||||
if (ty == Type::PTY_FLOAT) return "float";
|
||||
if (ty == Type::PTY_DOUBLE) return "double";
|
||||
if (ty == Type::PTY_LIST) return "list";
|
||||
throw std::runtime_error("invalid type");
|
||||
return "";
|
||||
}
|
||||
|
||||
/* compute the type of a string */
|
||||
std::string stringOfType(Type ty) {
|
||||
if (ty.ty == Type::PTY_LIST) return "list " + stringOfTypeTag(ty.index) + " " + stringOfTypeTag(ty.data);
|
||||
else return stringOfTypeTag(ty.ty);
|
||||
}
|
||||
|
||||
/* PLY parser class */
|
||||
struct PlyParser
|
||||
{
|
||||
std::fstream fs;
|
||||
Mesh mesh;
|
||||
Ref<SceneGraph::Node> scene;
|
||||
|
||||
/* storage format of data in file */
|
||||
enum Format { ASCII, BINARY_BIG_ENDIAN, BINARY_LITTLE_ENDIAN } format;
|
||||
|
||||
/* constructor parses the input stream */
|
||||
PlyParser(const FileName& fileName) : format(ASCII)
|
||||
{
|
||||
/* open file */
|
||||
fs.open (fileName.c_str(), std::fstream::in | std::fstream::binary);
|
||||
if (!fs.is_open()) throw std::runtime_error("cannot open file : " + fileName.str());
|
||||
|
||||
/* check for file signature */
|
||||
std::string signature; getline(fs,signature);
|
||||
if (signature != "ply") throw std::runtime_error("invalid PLY file signature: " + signature);
|
||||
|
||||
/* read header */
|
||||
std::list<std::string> header;
|
||||
while (true) {
|
||||
std::string line; getline(fs,line);
|
||||
if (line == "end_header") break;
|
||||
if (line.find_first_of('#') == 0) continue;
|
||||
if (line == "") continue;
|
||||
header.push_back(line);
|
||||
}
|
||||
|
||||
/* parse header */
|
||||
parseHeader(header);
|
||||
|
||||
/* now parse all elements */
|
||||
for (std::vector<std::string>::iterator i = mesh.order.begin(); i!=mesh.order.end(); i++)
|
||||
parseElementData(mesh.elements[*i]);
|
||||
|
||||
/* create triangle mesh */
|
||||
scene = import();
|
||||
}
|
||||
|
||||
/* parse the PLY header */
|
||||
void parseHeader(std::list<std::string>& header)
|
||||
{
|
||||
while (!header.empty())
|
||||
{
|
||||
std::stringstream line(header.front());
|
||||
header.pop_front();
|
||||
|
||||
std::string tag; line >> tag;
|
||||
|
||||
/* ignore comments */
|
||||
if (tag == "comment") {
|
||||
}
|
||||
|
||||
/* parse format */
|
||||
else if (tag == "format")
|
||||
{
|
||||
std::string fmt; line >> fmt;
|
||||
if (fmt == "ascii") format = ASCII;
|
||||
else if (fmt == "binary_big_endian") format = BINARY_BIG_ENDIAN;
|
||||
else if (fmt == "binary_little_endian") format = BINARY_LITTLE_ENDIAN;
|
||||
else throw std::runtime_error("invalid PLY file format: " + fmt);
|
||||
std::string version; line >> version;
|
||||
if (version != "1.0") throw std::runtime_error("invalid PLY file version: " + version);
|
||||
}
|
||||
|
||||
/* parse end of header tag */
|
||||
else if (tag == "end_header")
|
||||
break;
|
||||
|
||||
/* parse elements */
|
||||
else if (tag == "element") parseElementDescr(line,header);
|
||||
|
||||
/* report unknown tags */
|
||||
else throw std::runtime_error("unknown tag in PLY file: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
/* parses a PLY element description */
|
||||
void parseElementDescr(std::stringstream& cin, std::list<std::string>& header)
|
||||
{
|
||||
Element elt;
|
||||
std::string name; cin >> name;
|
||||
size_t num; cin >> num;
|
||||
mesh.order.push_back(name);
|
||||
elt.name = name;
|
||||
elt.size = num;
|
||||
|
||||
/* parse all properties */
|
||||
while (!header.empty())
|
||||
{
|
||||
std::stringstream line(header.front());
|
||||
std::string tag; line >> tag;
|
||||
if (tag != "property") break;
|
||||
header.pop_front();
|
||||
|
||||
Type ty = parseType(line);
|
||||
std::string name; line >> name;
|
||||
elt.type[name] = ty;
|
||||
elt.properties.push_back(name);
|
||||
}
|
||||
|
||||
mesh.elements[name] = elt;
|
||||
}
|
||||
|
||||
/* parses a PLY type */
|
||||
Type parseType(std::stringstream& cin)
|
||||
{
|
||||
std::string ty; cin >> ty;
|
||||
if (ty == "list") {
|
||||
std::string ty0; cin >> ty0;
|
||||
std::string ty1; cin >> ty1;
|
||||
return Type(Type::PTY_LIST,typeTagOfString(ty0),typeTagOfString(ty1));
|
||||
} else return Type(typeTagOfString(ty));
|
||||
}
|
||||
|
||||
/* parses data of a PLY element */
|
||||
void parseElementData(Element& elt)
|
||||
{
|
||||
/* allocate data for all properties */
|
||||
for (std::vector<std::string>::iterator i=elt.properties.begin(); i!=elt.properties.end(); i++) {
|
||||
if (elt.type[*i].ty == Type::PTY_LIST) elt.list[*i] = std::vector<std::vector<size_t> >();
|
||||
else elt.data[*i] = std::vector<float>();
|
||||
}
|
||||
|
||||
/* parse all elements */
|
||||
for (size_t e=0; e<elt.size; e++)
|
||||
{
|
||||
/* load all properties of the element */
|
||||
for (std::vector<std::string>::iterator i=elt.properties.begin(); i!=elt.properties.end(); i++) {
|
||||
Type ty = elt.type[*i];
|
||||
if (ty.ty == Type::PTY_LIST) loadPropertyList(elt.list[*i],ty.index,ty.data);
|
||||
else loadPropertyData(elt.data[*i],ty.ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* load bytes from file and take care of little and big endian encoding */
|
||||
void readBytes(void* dst, int num) {
|
||||
if (format == BINARY_LITTLE_ENDIAN) fs.read((char*)dst,num);
|
||||
else if (format == BINARY_BIG_ENDIAN) for (int i=0; i<num; i++) fs.read((char*)dst+num-i-1,1);
|
||||
else throw std::runtime_error("internal error on PLY loader");
|
||||
}
|
||||
|
||||
int read_ascii_int () { int i; fs >> i; return i; }
|
||||
float read_ascii_float() { float f; fs >> f; return f; }
|
||||
signed char read_char () { if (format == ASCII) return read_ascii_int(); signed char r = 0; readBytes(&r,1); return r; }
|
||||
unsigned char read_uchar () { if (format == ASCII) return read_ascii_int(); unsigned char r = 0; readBytes(&r,1); return r; }
|
||||
signed short read_short () { if (format == ASCII) return read_ascii_int(); signed short r = 0; readBytes(&r,2); return r; }
|
||||
unsigned short read_ushort() { if (format == ASCII) return read_ascii_int(); unsigned short r = 0; readBytes(&r,2); return r; }
|
||||
signed int read_int () { if (format == ASCII) return read_ascii_int(); signed int r = 0; readBytes(&r,4); return r; }
|
||||
unsigned int read_uint () { if (format == ASCII) return read_ascii_int(); unsigned int r = 0; readBytes(&r,4); return r; }
|
||||
float read_float () { if (format == ASCII) return read_ascii_float(); float r = 0; readBytes(&r,4); return r; }
|
||||
double read_double() { if (format == ASCII) return read_ascii_float(); double r = 0; readBytes(&r,8); return r; }
|
||||
|
||||
/* load an integer type */
|
||||
size_t loadInteger(Type::Tag ty)
|
||||
{
|
||||
switch (ty) {
|
||||
case Type::PTY_CHAR : return read_char(); break;
|
||||
case Type::PTY_UCHAR : return read_uchar(); break;
|
||||
case Type::PTY_SHORT : return read_short(); break;
|
||||
case Type::PTY_USHORT : return read_ushort(); break;
|
||||
case Type::PTY_INT : return read_int(); break;
|
||||
case Type::PTY_UINT : return read_uint(); break;
|
||||
default : throw std::runtime_error("invalid type"); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* load a list */
|
||||
void loadPropertyList(std::vector<std::vector<size_t> >& vec,Type::Tag index_ty,Type::Tag data_ty)
|
||||
{
|
||||
std::vector<size_t> lst;
|
||||
size_t num = loadInteger(index_ty);
|
||||
for (size_t i=0; i<num; i++) lst.push_back(loadInteger(data_ty));
|
||||
vec.push_back(lst);
|
||||
}
|
||||
|
||||
/* load a data element */
|
||||
void loadPropertyData(std::vector<float>& vec, Type::Tag ty)
|
||||
{
|
||||
switch (ty) {
|
||||
case Type::PTY_CHAR : vec.push_back(float(read_char())); break;
|
||||
case Type::PTY_UCHAR : vec.push_back(float(read_uchar())); break;
|
||||
case Type::PTY_SHORT : vec.push_back(float(read_short())); break;
|
||||
case Type::PTY_USHORT : vec.push_back(float(read_ushort())); break;
|
||||
case Type::PTY_INT : vec.push_back(float(read_int())); break;
|
||||
case Type::PTY_UINT : vec.push_back(float(read_uint())); break;
|
||||
case Type::PTY_FLOAT : vec.push_back(float(read_float())); break;
|
||||
case Type::PTY_DOUBLE : vec.push_back(float(read_double())); break;
|
||||
default : throw std::runtime_error("invalid type");
|
||||
}
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> import()
|
||||
{
|
||||
Ref<SceneGraph::MaterialNode> material = new OBJMaterial;
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh_o = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
|
||||
|
||||
/* convert all vertices */
|
||||
const Element& vertices = mesh.elements.at("vertex");
|
||||
const std::vector<float>& posx = vertices.data.at("x");
|
||||
const std::vector<float>& posy = vertices.data.at("y");
|
||||
const std::vector<float>& posz = vertices.data.at("z");
|
||||
|
||||
mesh_o->positions[0].resize(vertices.size);
|
||||
for (size_t i=0; i<vertices.size; i++) {
|
||||
mesh_o->positions[0][i].x = posx[i];
|
||||
mesh_o->positions[0][i].y = posy[i];
|
||||
mesh_o->positions[0][i].z = posz[i];
|
||||
}
|
||||
|
||||
/* convert all faces */
|
||||
const Element& faces = mesh.elements.at("face");
|
||||
const std::vector<std::vector<size_t> >& polygons = faces.list.at("vertex_indices");
|
||||
|
||||
for (size_t j=0; j<polygons.size(); j++)
|
||||
{
|
||||
const std::vector<size_t>& face = polygons[j];
|
||||
if (face.size() < 3) continue;
|
||||
|
||||
/* triangulate the face with a triangle fan */
|
||||
size_t i0 = face[0], i1 = 0, i2 = face[1];
|
||||
for (size_t k=2; k<face.size(); k++) {
|
||||
i1 = i2; i2 = face[k];
|
||||
mesh_o->triangles.push_back(SceneGraph::TriangleMeshNode::Triangle((unsigned int)i0, (unsigned int)i1, (unsigned int)i2));
|
||||
}
|
||||
}
|
||||
return mesh_o.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
};
|
||||
|
||||
Ref<Node> loadPLY(const FileName& fileName) {
|
||||
return PlyParser(fileName).scene;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
Framework/external/embree/tutorials/common/scenegraph/ply_loader.h
vendored
Normal file
14
Framework/external/embree/tutorials/common/scenegraph/ply_loader.h
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
Ref<Node> loadPLY(const FileName& fileName);
|
||||
}
|
||||
}
|
||||
2129
Framework/external/embree/tutorials/common/scenegraph/scenegraph.cpp
vendored
Normal file
2129
Framework/external/embree/tutorials/common/scenegraph/scenegraph.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
1660
Framework/external/embree/tutorials/common/scenegraph/scenegraph.h
vendored
Normal file
1660
Framework/external/embree/tutorials/common/scenegraph/scenegraph.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
91
Framework/external/embree/tutorials/common/scenegraph/texture.cpp
vendored
Normal file
91
Framework/external/embree/tutorials/common/scenegraph/texture.cpp
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
bool isPowerOf2 (unsigned int x)
|
||||
{
|
||||
while (((x % 2) == 0) && x > 1)
|
||||
x /= 2;
|
||||
return (x == 1);
|
||||
}
|
||||
|
||||
static std::map<std::string,std::shared_ptr<Texture>> texture_cache;
|
||||
|
||||
void Texture::clearTextureCache() {
|
||||
texture_cache.clear();
|
||||
}
|
||||
|
||||
Texture::Texture ()
|
||||
: width(-1), height(-1), format(INVALID), bytesPerTexel(0), width_mask(0), height_mask(0), data(nullptr) {}
|
||||
|
||||
Texture::Texture(Ref<Image> img, const std::string fileName)
|
||||
: width(unsigned(img->width)), height(unsigned(img->height)), format(RGBA8), bytesPerTexel(4), width_mask(0), height_mask(0), data(nullptr), fileName(fileName)
|
||||
{
|
||||
width_mask = isPowerOf2(width) ? width-1 : 0;
|
||||
height_mask = isPowerOf2(height) ? height-1 : 0;
|
||||
|
||||
data = alignedUSMMalloc(4*width*height,16);
|
||||
img->convertToRGBA8((unsigned char*)data);
|
||||
}
|
||||
|
||||
Texture::Texture (unsigned width, unsigned height, const Format format, const char* in)
|
||||
: width(width), height(height), format(format), bytesPerTexel(getFormatBytesPerTexel(format)), width_mask(0), height_mask(0), data(nullptr)
|
||||
{
|
||||
width_mask = isPowerOf2(width) ? width-1 : 0;
|
||||
height_mask = isPowerOf2(height) ? height-1 : 0;
|
||||
|
||||
data = alignedUSMMalloc(bytesPerTexel*width*height,16);
|
||||
if (in) {
|
||||
for (size_t i=0; i<bytesPerTexel*width*height; i++)
|
||||
((char*)data)[i] = in[i];
|
||||
}
|
||||
else {
|
||||
memset(data,0 ,bytesPerTexel*width*height);
|
||||
}
|
||||
}
|
||||
|
||||
Texture::~Texture () {
|
||||
alignedUSMFree(data);
|
||||
}
|
||||
|
||||
const char* Texture::format_to_string(const Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case RGBA8 : return "RGBA8";
|
||||
case RGB8 : return "RGB8";
|
||||
case FLOAT32: return "FLOAT32";
|
||||
default : THROW_RUNTIME_ERROR("invalid texture format");
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Format Texture::string_to_format(const std::string& str)
|
||||
{
|
||||
if (str == "RGBA8") return RGBA8;
|
||||
else if (str == "RGB8") return RGB8;
|
||||
else if (str == "FLOAT32") return FLOAT32;
|
||||
else THROW_RUNTIME_ERROR("invalid texture format string");
|
||||
}
|
||||
|
||||
unsigned Texture::getFormatBytesPerTexel(const Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case RGBA8 : return 4;
|
||||
case RGB8 : return 3;
|
||||
case FLOAT32: return 4;
|
||||
default : THROW_RUNTIME_ERROR("invalid texture format");
|
||||
}
|
||||
}
|
||||
|
||||
/*! read png texture from disk */
|
||||
std::shared_ptr<Texture> Texture::load(const FileName& fileName)
|
||||
{
|
||||
if (texture_cache.find(fileName.str()) != texture_cache.end())
|
||||
return texture_cache[fileName.str()];
|
||||
|
||||
std::shared_ptr<Texture> tex(new Texture(loadImage(fileName),fileName));
|
||||
return texture_cache[fileName.str()] = tex;
|
||||
}
|
||||
}
|
||||
71
Framework/external/embree/tutorials/common/scenegraph/texture.h
vendored
Normal file
71
Framework/external/embree/tutorials/common/scenegraph/texture.h
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(ISPC)
|
||||
|
||||
enum TEXTURE_FORMAT {
|
||||
Texture_RGBA8 = 1,
|
||||
Texture_RGB8 = 2,
|
||||
Texture_FLOAT32 = 3,
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
int width;
|
||||
int height;
|
||||
int format;
|
||||
int bytesPerTexel;
|
||||
int width_mask;
|
||||
int height_mask;
|
||||
void* data;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include "../default.h"
|
||||
#include "../image/image.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
struct Texture // FIXME: should be derived from SceneGraph::Node
|
||||
{
|
||||
ALIGNED_STRUCT_USM_(16);
|
||||
|
||||
enum Format {
|
||||
INVALID = 0,
|
||||
RGBA8 = 1,
|
||||
RGB8 = 2,
|
||||
FLOAT32 = 3,
|
||||
};
|
||||
|
||||
public:
|
||||
Texture ();
|
||||
Texture (Ref<Image> image, const std::string fileName);
|
||||
Texture (unsigned width, unsigned height, const Format format, const char* in = nullptr);
|
||||
~Texture ();
|
||||
|
||||
private:
|
||||
Texture (const Texture& other) DELETED; // do not implement
|
||||
Texture& operator= (const Texture& other) DELETED; // do not implement
|
||||
|
||||
public:
|
||||
static const char* format_to_string(const Format format);
|
||||
static Format string_to_format(const std::string& str);
|
||||
static unsigned getFormatBytesPerTexel(const Format format);
|
||||
|
||||
static std::shared_ptr<Texture> load(const FileName& fileName);
|
||||
static void clearTextureCache();
|
||||
|
||||
public:
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
Format format;
|
||||
unsigned bytesPerTexel;
|
||||
unsigned width_mask;
|
||||
unsigned height_mask;
|
||||
void* data;
|
||||
std::string fileName;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
2019
Framework/external/embree/tutorials/common/scenegraph/xml_loader.cpp
vendored
Normal file
2019
Framework/external/embree/tutorials/common/scenegraph/xml_loader.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
15
Framework/external/embree/tutorials/common/scenegraph/xml_loader.h
vendored
Normal file
15
Framework/external/embree/tutorials/common/scenegraph/xml_loader.h
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
Ref<Node> loadXML(const FileName& fileName, const AffineSpace3fa& space = one);
|
||||
}
|
||||
}
|
||||
|
||||
196
Framework/external/embree/tutorials/common/scenegraph/xml_parser.cpp
vendored
Normal file
196
Framework/external/embree/tutorials/common/scenegraph/xml_parser.cpp
vendored
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "xml_parser.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// XML Input
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*! parse a list of XML comments */
|
||||
void parseComments(Ref<Stream<Token> >& cin)
|
||||
{
|
||||
while (cin->peek() == Token::Sym("<!--")) {
|
||||
cin->drop();
|
||||
while (cin->peek() != Token::Sym("-->")) {
|
||||
if (cin->peek() == Token::Eof())
|
||||
THROW_RUNTIME_ERROR(cin->get().Location().str()+": --> expected");
|
||||
cin->drop();
|
||||
}
|
||||
cin->drop();
|
||||
}
|
||||
}
|
||||
|
||||
/*! parse XML parameter */
|
||||
void parseParm(Ref<Stream<Token> >& cin, std::map<std::string,std::string>& parms)
|
||||
{
|
||||
std::string name = cin->get().Identifier();
|
||||
if (cin->get() != Token::Sym("=")) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": symbol \"=\" expected");
|
||||
parms[name] = cin->get().String();
|
||||
}
|
||||
|
||||
/*! parse XML header */
|
||||
Ref<XML> parseHeader(Ref<Stream<Token> >& cin)
|
||||
{
|
||||
Ref<XML> xml = new XML;
|
||||
if (cin->get() != Token::Sym("<?")) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": wrong XML header");
|
||||
xml->name = cin->get().Identifier();
|
||||
parseComments(cin);
|
||||
while (cin->peek() != Token::Sym("?>")) {
|
||||
parseParm(cin,xml->parms);
|
||||
parseComments(cin);
|
||||
}
|
||||
cin->drop();
|
||||
return xml;
|
||||
}
|
||||
|
||||
/*! parse XML tag */
|
||||
Ref<XML> parseXML(Ref<Stream<Token> >& cin, size_t depth)
|
||||
{
|
||||
if (depth > 1024)
|
||||
THROW_RUNTIME_ERROR(cin->peek().Location().str()+": maximal nesting depth reached");
|
||||
|
||||
Ref<XML> xml = new XML;
|
||||
xml->loc = cin->peek().Location();
|
||||
|
||||
/* parse tag opening */
|
||||
if (cin->get() != Token::Sym("<")) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": tag expected");
|
||||
|
||||
xml->name = cin->get().Identifier();
|
||||
parseComments(cin);
|
||||
while (cin->peek() != Token::Sym("/>") && cin->peek() != Token::Sym(">")) {
|
||||
parseParm(cin,xml->parms);
|
||||
parseComments(cin);
|
||||
}
|
||||
if (cin->peek() == Token::Sym("/>")) {
|
||||
cin->drop();
|
||||
return xml;
|
||||
}
|
||||
cin->drop();
|
||||
|
||||
/* parse body token list */
|
||||
parseComments(cin);
|
||||
while (cin->peek() != Token::Sym("<") && cin->peek() != Token::Sym("</")) {
|
||||
xml->body.push_back(cin->get());
|
||||
parseComments(cin);
|
||||
}
|
||||
|
||||
/* the body also contains children */
|
||||
if (cin->peek() == Token::Sym("<")) {
|
||||
while (cin->peek() != Token::Sym("</")) {
|
||||
xml->children.push_back(parseXML(cin,depth+1));
|
||||
parseComments(cin);
|
||||
}
|
||||
}
|
||||
|
||||
/* parse tag closing */
|
||||
if (cin->get() != Token::Sym("</") ) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": symbol \"</\" expected");
|
||||
if (cin->get() != Token::Id(xml->name)) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": closing "+xml->name+" expected");
|
||||
if (cin->get() != Token::Sym(">") ) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": symbol \">\" expected");
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/* load XML from token stream */
|
||||
Ref<XML> parseXML(Ref<Stream<int> > chars, std::string id, bool hasHeader = true, bool hasTail = false)
|
||||
{
|
||||
/* create lexer for XML file */
|
||||
std::vector<std::string> symbols;
|
||||
symbols.push_back("<!--");
|
||||
symbols.push_back("-->");
|
||||
symbols.push_back("<?");
|
||||
symbols.push_back("?>");
|
||||
symbols.push_back("</");
|
||||
symbols.push_back("/>");
|
||||
symbols.push_back("<");
|
||||
symbols.push_back(">");
|
||||
symbols.push_back("=");
|
||||
Ref<Stream<Token> > cin = new TokenStream(chars,TokenStream::alpha + TokenStream::ALPHA + "_" + id, TokenStream::separators, symbols);
|
||||
|
||||
if (hasHeader) parseHeader(cin);
|
||||
parseComments(cin);
|
||||
Ref<XML> xml = parseXML(cin,0);
|
||||
parseComments(cin);
|
||||
|
||||
if (!hasTail)
|
||||
if (cin->peek() != Token::Eof()) THROW_RUNTIME_ERROR(cin->peek().Location().str()+": end of file expected");
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/*! load XML file from stream */
|
||||
std::istream& operator>>(std::istream& cin, Ref<XML>& xml) {
|
||||
xml = parseXML(new StdStream(cin),"",false,true);
|
||||
return cin;
|
||||
}
|
||||
|
||||
/*! load XML file from disk */
|
||||
Ref<XML> parseXML(const FileName& fileName, std::string id, bool hasHeader) {
|
||||
return parseXML(new FileStream(fileName),id,hasHeader,false);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// XML Output
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/* indent to some hierarchy level using spaces */
|
||||
void indent(std::ostream& cout, size_t depth) {
|
||||
for (size_t i=0; i<2*depth; i++) cout << " ";
|
||||
}
|
||||
|
||||
/* store XML to a stream */
|
||||
std::ostream& emitXML(std::ostream& cout, const Ref<XML>& xml, size_t depth = 0)
|
||||
{
|
||||
/* print header */
|
||||
if (depth == 0) cout << "<?xml version=\"1.0\"?>" << std::endl << std::endl;
|
||||
|
||||
/* print tag opening */
|
||||
indent(cout,depth); cout << "<" << xml->name;
|
||||
for (std::map<std::string,std::string>::const_iterator i=xml->parms.begin(); i!=xml->parms.end(); i++)
|
||||
cout << " " << i->first << "=" << "\"" << i->second << "\"";
|
||||
if (xml->children.size() == 0 && xml->body.size() == 0) {
|
||||
cout << "/>" << std::endl;
|
||||
return cout;
|
||||
}
|
||||
cout << ">";
|
||||
|
||||
bool compact = xml->body.size() < 16 && xml->children.size() == 0;
|
||||
if (!compact) cout << std::endl;
|
||||
|
||||
/* print token list */
|
||||
if (xml->body.size()) {
|
||||
if (!compact) indent(cout,depth+1);
|
||||
for (size_t i=0; i<xml->body.size(); i++)
|
||||
cout << xml->body[i] << (i!=xml->body.size()-1?" ":"");
|
||||
if (!compact) cout << std::endl;
|
||||
}
|
||||
|
||||
/* print children */
|
||||
for (size_t i=0; i<xml->children.size(); i++)
|
||||
emitXML(cout,xml->children[i],depth+1);
|
||||
|
||||
/* print tag closing */
|
||||
if (!compact) indent(cout,depth);
|
||||
return cout << "</" << xml->name << ">" << std::endl;
|
||||
}
|
||||
|
||||
/* store XML to stream */
|
||||
std::ostream& operator<<(std::ostream& cout, const Ref<XML>& xml) {
|
||||
return emitXML(cout,xml);
|
||||
}
|
||||
|
||||
/*! store XML to disk */
|
||||
void emitXML(const FileName& fileName, const Ref<XML>& xml)
|
||||
{
|
||||
std::ofstream cout(fileName.c_str());
|
||||
if (!cout.is_open()) THROW_RUNTIME_ERROR("cannot open file " + fileName.str() + " for writing");
|
||||
emitXML(cout,xml);
|
||||
cout.close();
|
||||
}
|
||||
}
|
||||
127
Framework/external/embree/tutorials/common/scenegraph/xml_parser.h
vendored
Normal file
127
Framework/external/embree/tutorials/common/scenegraph/xml_parser.h
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../default.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
/* an XML node */
|
||||
class XML : public RefCount
|
||||
{
|
||||
public:
|
||||
XML (const std::string& name = "") : name(name) {}
|
||||
|
||||
/*! returns number of children of XML node */
|
||||
size_t size() const { return children.size(); }
|
||||
|
||||
/*! checks if child with specified node tag exists */
|
||||
bool hasChild(const std::string& childID) const
|
||||
{
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
if (children[i]->name == childID) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! returns a parameter of the XML node */
|
||||
std::string parm(const std::string& parmID) const {
|
||||
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
|
||||
if (i == parms.end()) return ""; else return i->second;
|
||||
}
|
||||
|
||||
Vec2f parm_Vec2f(const std::string& parmID) const {
|
||||
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
|
||||
if (i == parms.end()) THROW_RUNTIME_ERROR (loc.str()+": XML node has no parameter \"" + parmID + "\"");
|
||||
return string_to_Vec2f(i->second);
|
||||
}
|
||||
|
||||
Vec3fa parm_Vec3fa(const std::string& parmID) const {
|
||||
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
|
||||
if (i == parms.end()) THROW_RUNTIME_ERROR (loc.str()+": XML node has no parameter \"" + parmID + "\"");
|
||||
return Vec3fa(string_to_Vec3f(i->second));
|
||||
}
|
||||
|
||||
float parm_float(const std::string& parmID) const {
|
||||
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
|
||||
if (i == parms.end()) THROW_RUNTIME_ERROR (loc.str()+": XML node has no parameter \"" + parmID + "\"");
|
||||
return std::stof(i->second);
|
||||
}
|
||||
|
||||
/*! returns the nth child */
|
||||
const Ref<XML> child(const size_t id) const
|
||||
{
|
||||
if (id >= children.size())
|
||||
THROW_RUNTIME_ERROR (loc.str()+": XML node has no child \"" + toString(id) + "\"");
|
||||
return children[id];
|
||||
}
|
||||
|
||||
/*! returns child by node tag */
|
||||
const Ref<XML> child(const std::string& childID) const
|
||||
{
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
if (children[i]->name == childID) return children[i];
|
||||
THROW_RUNTIME_ERROR (loc.str()+": XML node has no child \"" + childID + "\"");
|
||||
}
|
||||
|
||||
/*! returns child by node tag without failing */
|
||||
const Ref<XML> childOpt(const std::string& childID) const
|
||||
{
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
if (children[i]->name == childID) return children[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
/*! adds a new parameter to the node */
|
||||
Ref<XML> add(const std::string& name, const std::string& val) {
|
||||
parms[name] = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*! adds a new child */
|
||||
Ref<XML> add(const Ref<XML>& xml) {
|
||||
children.push_back(xml);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*! adds new data tokens to the body of the node */
|
||||
Ref<XML> add(const Token& tok) {
|
||||
body.push_back(tok);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*! compares two XML nodes */
|
||||
friend bool operator ==( const Ref<XML>& a, const Ref<XML>& b ) {
|
||||
return a->name == b->name && a->parms == b->parms && a->children == b->children && a->body == b->body;
|
||||
}
|
||||
|
||||
/*! orders two XML nodes */
|
||||
friend bool operator <( const Ref<XML>& a, const Ref<XML>& b ) {
|
||||
if (a->name != b->name ) return a->name < b->name;
|
||||
if (a->parms != b->parms ) return a->parms < b->parms;
|
||||
if (a->children != b->children) return a->children < b->children;
|
||||
if (a->body != b->body ) return a->body < b->body;
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
ParseLocation loc;
|
||||
std::string name;
|
||||
std::map<std::string,std::string> parms;
|
||||
std::vector<Ref<XML> > children;
|
||||
std::vector<Token> body;
|
||||
};
|
||||
|
||||
/*! load XML file from stream */
|
||||
std::istream& operator>>(std::istream& cin, Ref<XML>& xml);
|
||||
|
||||
/*! load XML file from disk */
|
||||
Ref<XML> parseXML(const FileName& fileName, std::string id = "", bool hasHeader = true);
|
||||
|
||||
/* store XML to stream */
|
||||
std::ostream& operator<<(std::ostream& cout, const Ref<XML>& xml);
|
||||
|
||||
/*! store XML to disk */
|
||||
void emitXML(const FileName& fileName, const Ref<XML>& xml);
|
||||
}
|
||||
|
||||
798
Framework/external/embree/tutorials/common/scenegraph/xml_writer.cpp
vendored
Normal file
798
Framework/external/embree/tutorials/common/scenegraph/xml_writer.cpp
vendored
Normal file
|
|
@ -0,0 +1,798 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "xml_writer.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
class XMLWriter
|
||||
{
|
||||
public:
|
||||
|
||||
XMLWriter(Ref<SceneGraph::Node> root, const FileName& fileName, bool embedTextures, bool referenceMaterials, bool binaryFormat);
|
||||
|
||||
public:
|
||||
void tab();
|
||||
void open(std::string str);
|
||||
void open(std::string str, size_t id);
|
||||
void open(std::string str, size_t id, std::string name);
|
||||
void close(std::string str);
|
||||
|
||||
void store(const char* name, const char* str);
|
||||
void store(const char* name, const float& v);
|
||||
void store(const char* name, const Vec3fa& v);
|
||||
|
||||
void store_array_elt(const int& v);
|
||||
void store_array_elt(const Vec2f& v);
|
||||
void store_array_elt(const Vec3f& v);
|
||||
void store_array_elt(const Vec3fa& v);
|
||||
void store_array_elt(const Vec3ff& v);
|
||||
void store_array_elt(const SceneGraph::TriangleMeshNode::Triangle& v);
|
||||
void store_array_elt(const SceneGraph::QuadMeshNode::Quad& v);
|
||||
|
||||
template<typename T> void store_array_text (const char* name, const std::vector<T>& vec);
|
||||
template<typename T> void store_array_binary(const char* name, const std::vector<T>& vec);
|
||||
template<typename T> void store (const char* name, const std::vector<T>& vec);
|
||||
|
||||
void store_array_text (const char* name, const avector<Vec3fa>& vec);
|
||||
void store_array_binary(const char* name, const avector<Vec3fa>& vec);
|
||||
void store (const char* name, const avector<Vec3fa>& vec);
|
||||
|
||||
void store_array_text (const char* name, const avector<Vec3ff>& vec);
|
||||
void store_array_binary(const char* name, const avector<Vec3ff>& vec);
|
||||
void store (const char* name, const avector<Vec3ff>& vec);
|
||||
|
||||
void store_parm(const char* name, const float& v);
|
||||
void store_parm(const char* name, const Vec3fa& v);
|
||||
void store_parm(const char* name, const std::shared_ptr<Texture> tex);
|
||||
void store(const char* name, const AffineSpace3fa& space);
|
||||
|
||||
void store(const SceneGraph::PointLight& light, ssize_t id);
|
||||
void store(const SceneGraph::SpotLight& light, ssize_t id);
|
||||
void store(const SceneGraph::DirectionalLight& light, ssize_t id);
|
||||
void store(const SceneGraph::DistantLight& light, ssize_t id);
|
||||
void store(const SceneGraph::AmbientLight& light, ssize_t id);
|
||||
void store(const SceneGraph::TriangleLight& light, ssize_t id);
|
||||
void store(const SceneGraph::QuadLight& light, ssize_t id);
|
||||
void store(Ref<SceneGraph::LightNode> light, ssize_t id);
|
||||
void store(Ref<SceneGraph::AnimatedLightNode> light, ssize_t id);
|
||||
|
||||
void store(Ref<MatteMaterial> material, ssize_t id);
|
||||
void store(Ref<MirrorMaterial> material, ssize_t id);
|
||||
void store(Ref<ThinDielectricMaterial> material, ssize_t id);
|
||||
void store(Ref<OBJMaterial> material, ssize_t id);
|
||||
void store(Ref<MetalMaterial> material, ssize_t id);
|
||||
void store(Ref<VelvetMaterial> material, ssize_t id);
|
||||
void store(Ref<DielectricMaterial> material, ssize_t id);
|
||||
void store(Ref<MetallicPaintMaterial> material, ssize_t id);
|
||||
void store(Ref<HairMaterial> material, ssize_t id);
|
||||
void store(Ref<SceneGraph::MaterialNode> material);
|
||||
|
||||
void store(Ref<SceneGraph::TriangleMeshNode> mesh, ssize_t id);
|
||||
void store(Ref<SceneGraph::QuadMeshNode> mesh, ssize_t id);
|
||||
void store(Ref<SceneGraph::SubdivMeshNode> mesh, ssize_t id);
|
||||
void store(Ref<SceneGraph::HairSetNode> hair, ssize_t id);
|
||||
|
||||
void store(Ref<SceneGraph::PerspectiveCameraNode> camera, ssize_t id);
|
||||
void store(Ref<SceneGraph::AnimatedPerspectiveCameraNode> camera, ssize_t id);
|
||||
void store(Ref<SceneGraph::TransformNode> node, ssize_t id);
|
||||
void store(std::vector<Ref<SceneGraph::TransformNode>> nodes);
|
||||
void store(Ref<SceneGraph::GroupNode> group, ssize_t id);
|
||||
void store(Ref<SceneGraph::Node> node);
|
||||
|
||||
private:
|
||||
std::fstream xml; //!< .xml file for writing XML data
|
||||
std::fstream bin; //!< .bin file for writing binary data
|
||||
|
||||
private:
|
||||
size_t ident;
|
||||
size_t currentNodeID;
|
||||
std::map<Ref<SceneGraph::Node>, size_t> nodeMap;
|
||||
std::map<std::shared_ptr<Texture>, size_t> textureMap; // FIXME: use Ref<Texture>
|
||||
bool embedTextures;
|
||||
bool referenceMaterials;
|
||||
bool binaryFormat;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Storing of objects to XML file
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void XMLWriter::tab()
|
||||
{
|
||||
for (size_t i=0; i<ident; i++)
|
||||
xml << " ";
|
||||
}
|
||||
|
||||
void XMLWriter::open(std::string str)
|
||||
{
|
||||
tab(); xml << "<" << str << ">" << std::endl;
|
||||
ident+=2;
|
||||
}
|
||||
|
||||
void XMLWriter::open(std::string str, size_t id)
|
||||
{
|
||||
tab(); xml << "<" << str << " id=\"" << id << "\">" << std::endl;
|
||||
ident+=2;
|
||||
}
|
||||
|
||||
void XMLWriter::open(std::string str, size_t id, std::string name)
|
||||
{
|
||||
tab(); xml << "<" << str << " id=\"" << id << "\" name=\"" << name << "\">" << std::endl;
|
||||
ident+=2;
|
||||
}
|
||||
|
||||
void XMLWriter::close(std::string str)
|
||||
{
|
||||
assert(ident>=2);
|
||||
ident-=2;
|
||||
tab(); xml << "</" << str << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const char* str) {
|
||||
tab(); xml << "<" << name << ">\"" << str << "\"</" << name << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const float& v) {
|
||||
tab(); xml << "<" << name << ">" << v << "</" << name << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const Vec3fa& v) {
|
||||
tab(); xml << "<" << name << ">" << v.x << " " << v.y << " " << v.z << "</" << name << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const int& v) {
|
||||
xml << v << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const Vec2f& v) {
|
||||
xml << v.x << " " << v.y << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const Vec3f& v) {
|
||||
xml << v.x << " " << v.y << " " << v.z << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const Vec3fa& v) {
|
||||
xml << v.x << " " << v.y << " " << v.z << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const Vec3ff& v) {
|
||||
xml << v.x << " " << v.y << " " << v.z << " " << v.w << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const SceneGraph::TriangleMeshNode::Triangle& v) {
|
||||
xml << v.v0 << " " << v.v1 << " " << v.v2 << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const SceneGraph::QuadMeshNode::Quad& v) {
|
||||
xml << v.v0 << " " << v.v1 << " " << v.v2 << " " << v.v3 << std::endl;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void XMLWriter::store_array_text(const char* name, const std::vector<T>& vec)
|
||||
{
|
||||
open(name);
|
||||
for (size_t i=0; i<vec.size(); i++) {
|
||||
tab(); store_array_elt(vec[i]);
|
||||
}
|
||||
close(name);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void XMLWriter::store_array_binary(const char* name, const std::vector<T>& vec)
|
||||
{
|
||||
std::streampos offset = bin.tellg();
|
||||
tab(); xml << "<" << name << " ofs=\"" << offset << "\" size=\"" << vec.size() << "\"/>" << std::endl;
|
||||
if (vec.size()) bin.write((char*)vec.data(),vec.size()*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void XMLWriter::store(const char* name, const std::vector<T>& vec)
|
||||
{
|
||||
if (binaryFormat) store_array_binary(name,vec);
|
||||
else store_array_text (name,vec);
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_text(const char* name, const avector<Vec3fa>& vec)
|
||||
{
|
||||
open(name);
|
||||
for (size_t i=0; i<vec.size(); i++) {
|
||||
tab(); store_array_elt(vec[i]);
|
||||
}
|
||||
close(name);
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_binary(const char* name, const avector<Vec3fa>& vec)
|
||||
{
|
||||
std::streampos offset = bin.tellg();
|
||||
tab(); xml << "<" << name << " ofs=\"" << offset << "\" size=\"" << vec.size() << "\"/>" << std::endl;
|
||||
for (size_t i=0; i<vec.size(); i++) bin.write((char*)&vec[i],sizeof(Vec3f));
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const avector<Vec3fa>& vec)
|
||||
{
|
||||
if (binaryFormat) store_array_binary(name,vec);
|
||||
else store_array_text (name,vec);
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_text(const char* name, const avector<Vec3ff>& vec)
|
||||
{
|
||||
open(name);
|
||||
for (size_t i=0; i<vec.size(); i++) {
|
||||
tab(); store_array_elt(vec[i]);
|
||||
}
|
||||
close(name);
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_binary(const char* name, const avector<Vec3ff>& vec)
|
||||
{
|
||||
std::streampos offset = bin.tellg();
|
||||
tab(); xml << "<" << name << " ofs=\"" << offset << "\" size=\"" << vec.size() << "\"/>" << std::endl;
|
||||
for (size_t i=0; i<vec.size(); i++) bin.write((char*)&vec[i],sizeof(Vec3ff));
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const avector<Vec3ff>& vec)
|
||||
{
|
||||
if (binaryFormat) store_array_binary(name,vec);
|
||||
else store_array_text (name,vec);
|
||||
}
|
||||
|
||||
void XMLWriter::store_parm(const char* name, const float& v) {
|
||||
tab(); xml << "<float name=\"" << name << "\">" << v << "</float>" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_parm(const char* name, const Vec3fa& v) {
|
||||
tab(); xml << "<float3 name=\"" << name << "\">" << v.x << " " << v.y << " " << v.z << "</float3>" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_parm(const char* name, const std::shared_ptr<Texture> tex)
|
||||
{
|
||||
if (tex == nullptr) return;
|
||||
|
||||
if (textureMap.find(tex) != textureMap.end()) {
|
||||
tab(); xml << "<texture3d name=\"" << name << "\" id=\"" << textureMap[tex] << "\"/>" << std::endl;
|
||||
} else if (embedTextures) {
|
||||
std::streampos offset = bin.tellg();
|
||||
bin.write((char*)tex->data,tex->width*tex->height*tex->bytesPerTexel);
|
||||
const size_t id = textureMap[tex] = currentNodeID++;
|
||||
tab(); xml << "<texture3d name=\"" << name << "\" id=\"" << id << "\" ofs=\"" << offset
|
||||
<< "\" width=\"" << tex->width << "\" height=\"" << tex->height
|
||||
<< "\" format=\"" << Texture::format_to_string(tex->format) << "\"/>" << std::endl;
|
||||
}
|
||||
else {
|
||||
const size_t id = textureMap[tex] = currentNodeID++;
|
||||
tab(); xml << "<texture3d name=\"" << name << "\" id=\"" << id << "\" src=\"" << tex->fileName << "\"/>" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const AffineSpace3fa& space)
|
||||
{
|
||||
tab(); xml << "<" << name << ">" << std::endl;
|
||||
tab(); xml << " " << space.l.vx.x << " " << space.l.vy.x << " " << space.l.vz.x << " " << space.p.x << std::endl;
|
||||
tab(); xml << " " << space.l.vx.y << " " << space.l.vy.y << " " << space.l.vz.y << " " << space.p.y << std::endl;
|
||||
tab(); xml << " " << space.l.vx.z << " " << space.l.vy.z << " " << space.l.vz.z << " " << space.p.z << std::endl;
|
||||
tab(); xml << "</" << name << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::PointLight& light, ssize_t id)
|
||||
{
|
||||
open("PointLight",id);
|
||||
store("AffineSpace",AffineSpace3fa::translate(light.P));
|
||||
store("I",light.I);
|
||||
close("PointLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::SpotLight& light, ssize_t id)
|
||||
{
|
||||
open("SpotLight",id);
|
||||
store("AffineSpace",AffineSpace3fa(frame(light.D),light.P));
|
||||
store("I",light.I);
|
||||
store("angleMin",light.angleMin);
|
||||
store("angleMax",light.angleMax);
|
||||
close("SpotLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::DirectionalLight& light, ssize_t id)
|
||||
{
|
||||
open("DirectionalLight",id);
|
||||
store("AffineSpace",frame(light.D));
|
||||
store("E",light.E);
|
||||
close("DirectionalLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::DistantLight& light, ssize_t id)
|
||||
{
|
||||
open("DistantLight",id);
|
||||
store("AffineSpace",frame(light.D));
|
||||
store("L",light.L);
|
||||
store("halfAngle",light.halfAngle);
|
||||
close("DistantLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::AmbientLight& light, ssize_t id)
|
||||
{
|
||||
open("AmbientLight");
|
||||
store("L",light.L);
|
||||
close("AmbientLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::TriangleLight& light, ssize_t id)
|
||||
{
|
||||
open("TriangleLight",id);
|
||||
const Vec3fa dx = light.v0-light.v2;
|
||||
const Vec3fa dy = light.v1-light.v2;
|
||||
const Vec3fa dz = cross(dx,dy);
|
||||
const Vec3fa p = light.v2;
|
||||
store("AffineSpace",AffineSpace3fa(dx,dy,dz,p));
|
||||
store("L",light.L);
|
||||
close("TriangleLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::QuadLight& light, ssize_t id)
|
||||
{
|
||||
open("QuadLight",id);
|
||||
const Vec3fa dx = light.v3-light.v0;
|
||||
const Vec3fa dy = light.v1-light.v0;
|
||||
const Vec3fa dz = cross(dx,dy);
|
||||
const Vec3fa p = light.v2;
|
||||
store("AffineSpace",AffineSpace3fa(dx,dy,dz,p));
|
||||
store("L",light.L);
|
||||
close("QuadLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::LightNode> node, ssize_t id)
|
||||
{
|
||||
if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::AmbientLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::PointLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::DirectionalLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::SpotLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::DistantLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::TriangleLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::QuadLight>>())
|
||||
store(light->light,id);
|
||||
else
|
||||
throw std::runtime_error("unsupported light");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::AnimatedLightNode> node, ssize_t id)
|
||||
{
|
||||
open(std::string("AnimatedLight ")+
|
||||
"time_range=\""+std::to_string(node->time_range.lower)+" "+std::to_string(node->time_range.upper)+"\"");
|
||||
|
||||
for (size_t i=0; i<node->lights.size(); i++)
|
||||
store(node->lights[i].dynamicCast<SceneGraph::Node>());
|
||||
|
||||
close("AnimatedLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<MatteMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Matte");
|
||||
open("parameters");
|
||||
store_parm("reflectance",material->reflectance);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<MirrorMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Mirror");
|
||||
open("parameters");
|
||||
store_parm("reflectance",material->reflectance);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<ThinDielectricMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","ThinDielectric");
|
||||
open("parameters");
|
||||
store_parm("transmission",material->transmission);
|
||||
store_parm("eta",material->eta);
|
||||
store_parm("thickness",material->thickness);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<OBJMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","OBJ");
|
||||
open("parameters");
|
||||
store_parm("d",material->d);
|
||||
store_parm("Ka",material->Ka);
|
||||
store_parm("Kd",material->Kd);
|
||||
store_parm("Ks",material->Ks);
|
||||
store_parm("Kt",material->Kt);
|
||||
store_parm("Ns",material->Ns);
|
||||
store_parm("Ni",material->Ni);
|
||||
store_parm("map_d",material->_map_d);
|
||||
store_parm("map_Kd",material->_map_Kd);
|
||||
store_parm("map_Ks",material->_map_Ks);
|
||||
store_parm("map_Ns",material->_map_Ns);
|
||||
store_parm("map_Displ",material->_map_Displ);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<MetalMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Metal");
|
||||
open("parameters");
|
||||
store_parm("reflectance",material->reflectance);
|
||||
store_parm("eta",material->eta);
|
||||
store_parm("k",material->k);
|
||||
store_parm("roughness",material->roughness);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<VelvetMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Velvet");
|
||||
open("parameters");
|
||||
store_parm("reflectance",material->reflectance);
|
||||
store_parm("backScattering",material->backScattering);
|
||||
store_parm("horizonScatteringColor",material->horizonScatteringColor);
|
||||
store_parm("horizonScatteringFallOff",material->horizonScatteringFallOff);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<DielectricMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Dielectric");
|
||||
open("parameters");
|
||||
store_parm("transmissionOutside",material->transmissionOutside);
|
||||
store_parm("transmission",material->transmissionInside);
|
||||
store_parm("etaOutside",material->etaOutside);
|
||||
store_parm("etaInside",material->etaInside);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<MetallicPaintMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","MetallicPaint");
|
||||
open("parameters");
|
||||
store_parm("shadeColor",material->shadeColor);
|
||||
store_parm("glitterColor",material->glitterColor);
|
||||
store_parm("glitterSpread",material->glitterSpread);
|
||||
store_parm("eta",material->eta);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<HairMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Hair");
|
||||
open("parameters");
|
||||
store_parm("Kr",material->Kr);
|
||||
store_parm("Kt",material->Kt);
|
||||
store_parm("nx",material->nx);
|
||||
store_parm("ny",material->ny);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::MaterialNode> mnode)
|
||||
{
|
||||
/* let materials reference by their name, allows separate bindings of materials */
|
||||
if (referenceMaterials) {
|
||||
tab(); xml << "<material id=\""+mnode->name+"\"/>" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> node = mnode.dynamicCast<SceneGraph::Node>();
|
||||
if (nodeMap.find(node) != nodeMap.end()) {
|
||||
tab(); xml << "<material id=\"" << nodeMap[node] << "\"/>" << std::endl;
|
||||
return;
|
||||
}
|
||||
const ssize_t id = nodeMap[node] = currentNodeID++;
|
||||
|
||||
if (Ref<OBJMaterial> m = mnode.dynamicCast<OBJMaterial>()) store(m,id);
|
||||
else if (Ref<ThinDielectricMaterial> m = mnode.dynamicCast<ThinDielectricMaterial>()) store(m,id);
|
||||
else if (Ref<MetalMaterial> m = mnode.dynamicCast<MetalMaterial>()) store(m,id);
|
||||
else if (Ref<VelvetMaterial> m = mnode.dynamicCast<VelvetMaterial>()) store(m,id);
|
||||
else if (Ref<DielectricMaterial> m = mnode.dynamicCast<DielectricMaterial>()) store(m,id);
|
||||
else if (Ref<MetallicPaintMaterial> m = mnode.dynamicCast<MetallicPaintMaterial>()) store(m,id);
|
||||
else if (Ref<MatteMaterial> m = mnode.dynamicCast<MatteMaterial>()) store(m,id);
|
||||
else if (Ref<MirrorMaterial> m = mnode.dynamicCast<MirrorMaterial>()) store(m,id);
|
||||
else if (Ref<ReflectiveMetalMaterial> m = mnode.dynamicCast<ReflectiveMetalMaterial>()) store(m,id);
|
||||
else if (Ref<HairMaterial> m = mnode.dynamicCast<HairMaterial>()) store(m,id);
|
||||
else throw std::runtime_error("unsupported material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::TriangleMeshNode> mesh, ssize_t id)
|
||||
{
|
||||
open("TriangleMesh",id);
|
||||
store(mesh->material);
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_positions");
|
||||
for (const auto& p : mesh->positions) store("positions",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_positions");
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_normals");
|
||||
for (const auto& p : mesh->normals) store("normals",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_normals");
|
||||
|
||||
store("texcoords",mesh->texcoords);
|
||||
store("triangles",mesh->triangles);
|
||||
close("TriangleMesh");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::QuadMeshNode> mesh, ssize_t id)
|
||||
{
|
||||
open("QuadMesh",id);
|
||||
store(mesh->material);
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_positions");
|
||||
for (const auto& p : mesh->positions) store("positions",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_positions");
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_normals");
|
||||
for (const auto& p : mesh->normals) store("normals",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_normals");
|
||||
|
||||
store("texcoords",mesh->texcoords);
|
||||
store("indices",mesh->quads);
|
||||
close("QuadMesh");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::SubdivMeshNode> mesh, ssize_t id)
|
||||
{
|
||||
open("SubdivisionMesh",id);
|
||||
store(mesh->material);
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_positions");
|
||||
for (const auto& p : mesh->positions) store("positions",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_positions");
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_normals");
|
||||
for (const auto& p : mesh->normals) store("normals",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_normals");
|
||||
|
||||
store("texcoords",mesh->texcoords);
|
||||
store("position_indices",mesh->position_indices);
|
||||
store("normal_indices",mesh->normal_indices);
|
||||
store("texcoord_indices",mesh->texcoord_indices);
|
||||
store("faces",mesh->verticesPerFace);
|
||||
store("holes",mesh->holes);
|
||||
store("edge_creases",mesh->edge_creases);
|
||||
store("edge_crease_weights",mesh->edge_crease_weights);
|
||||
store("vertex_creases",mesh->vertex_creases);
|
||||
store("vertex_crease_weights",mesh->vertex_crease_weights);
|
||||
close("SubdivisionMesh");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::HairSetNode> mesh, ssize_t id)
|
||||
{
|
||||
std::string str_type = "";
|
||||
std::string str_subtype = "";
|
||||
|
||||
switch (mesh->type) {
|
||||
case RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE:
|
||||
str_type = "linear";
|
||||
str_subtype = "flat";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE:
|
||||
str_type = "bezier";
|
||||
str_subtype = "round";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE:
|
||||
str_type = "bezier";
|
||||
str_subtype = "flat";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE:
|
||||
str_type = "bezier";
|
||||
str_subtype = "oriented";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE:
|
||||
str_type = "bspline";
|
||||
str_subtype = "round";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE:
|
||||
str_type = "bspline";
|
||||
str_subtype = "flat";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE:
|
||||
str_type = "bspline";
|
||||
str_subtype = "oriented";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("invalid curve type");
|
||||
}
|
||||
|
||||
std::vector<int> indices(mesh->hairs.size());
|
||||
std::vector<int> hairid(mesh->hairs.size());
|
||||
for (size_t i=0; i<mesh->hairs.size(); i++) {
|
||||
indices[i] = mesh->hairs[i].vertex;
|
||||
hairid[i] = mesh->hairs[i].id;
|
||||
}
|
||||
|
||||
open("Curves type=\""+str_subtype+"\" basis=\""+str_type+"\"",id);
|
||||
store(mesh->material);
|
||||
if (mesh->numTimeSteps() != 1) open("animated_positions");
|
||||
for (const auto& p : mesh->positions) store("positions",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_positions");
|
||||
if (mesh->normals.size()) {
|
||||
if (mesh->numTimeSteps() != 1) open("animated_normals");
|
||||
for (const auto& p : mesh->normals) store("normals",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_normals");
|
||||
}
|
||||
store("indices",indices);
|
||||
store("hairid",hairid);
|
||||
close("Curves");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::PerspectiveCameraNode> camera, ssize_t id)
|
||||
{
|
||||
tab();
|
||||
xml << "<PerspectiveCamera " <<
|
||||
"id=\"" << id << "\" " <<
|
||||
"name=\"" << camera->name << "\" " <<
|
||||
"from=\"" << camera->data.from.x << " " << camera->data.from.y << " " << camera->data.from.z << "\" " <<
|
||||
"to=\"" << camera->data.to.x << " " << camera->data.to.y << " " << camera->data.to.z << "\" " <<
|
||||
"up=\"" << camera->data.up.x << " " << camera->data.up.y << " " << camera->data.up.z << "\" " <<
|
||||
"fov=\"" << camera->data.fov << "\" " << "/>" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::AnimatedPerspectiveCameraNode> camera, ssize_t id)
|
||||
{
|
||||
open(std::string("AnimatedPerspectiveCamera ")+
|
||||
"name=\"" + camera->name + "\" "
|
||||
"time_range=\""+std::to_string(camera->time_range.lower)+" "+std::to_string(camera->time_range.upper)+"\"");
|
||||
|
||||
for (size_t i=0; i<camera->size(); i++)
|
||||
store(camera->cameras[i].dynamicCast<SceneGraph::Node>());
|
||||
|
||||
close("AnimatedPerspectiveCamera");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::TransformNode> node, ssize_t id)
|
||||
{
|
||||
if (node->spaces.size() == 1)
|
||||
{
|
||||
open("Transform",id);
|
||||
store("AffineSpace",node->spaces[0]);
|
||||
store(node->child);
|
||||
close("Transform");
|
||||
}
|
||||
else
|
||||
{
|
||||
open("TransformAnimation",id);
|
||||
for (size_t i=0; i<node->spaces.size(); i++)
|
||||
store("AffineSpace",node->spaces[i]);
|
||||
store(node->child);
|
||||
close("TransformAnimation");
|
||||
}
|
||||
}
|
||||
|
||||
void XMLWriter::store(std::vector<Ref<SceneGraph::TransformNode>> nodes)
|
||||
{
|
||||
if (nodes.size() == 0)
|
||||
return;
|
||||
|
||||
if (nodes.size() == 1) {
|
||||
store(nodes[0].dynamicCast<SceneGraph::Node>());
|
||||
return;
|
||||
}
|
||||
|
||||
open("MultiTransform");
|
||||
std::streampos offset = bin.tellg();
|
||||
tab(); xml << "<AffineSpace3f ofs=\"" << offset << "\" size=\"" << nodes.size() << "\"/>" << std::endl;
|
||||
for (size_t i=0; i<nodes.size(); i++) {
|
||||
assert(nodes[i]->spaces.size() == 1);
|
||||
assert(nodes[i]->child == nodes[0]->child);
|
||||
bin.write((char*)&nodes[i]->spaces[0].l.vx,sizeof(Vec3f));
|
||||
bin.write((char*)&nodes[i]->spaces[0].l.vy,sizeof(Vec3f));
|
||||
bin.write((char*)&nodes[i]->spaces[0].l.vz,sizeof(Vec3f));
|
||||
bin.write((char*)&nodes[i]->spaces[0].p,sizeof(Vec3f));
|
||||
}
|
||||
store(nodes[0]->child);
|
||||
close("MultiTransform");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::GroupNode> group, ssize_t id)
|
||||
{
|
||||
open("Group",id);
|
||||
|
||||
std::map<Ref<SceneGraph::Node>,std::vector<Ref<SceneGraph::TransformNode>>> object_to_transform_map;
|
||||
for (size_t i=0; i<group->children.size(); i++)
|
||||
{
|
||||
/* compress transformation of the same object into MultiTransform nodes if possible */
|
||||
if (Ref<SceneGraph::TransformNode> xfmNode = group->children[i].dynamicCast<SceneGraph::TransformNode>())
|
||||
{
|
||||
/* we can only compress non-animated transform nodes and only ones that are referenced once */
|
||||
if (xfmNode->spaces.size() == 1 && xfmNode->indegree == 1)
|
||||
{
|
||||
Ref<SceneGraph::Node> child = xfmNode->child;
|
||||
if (object_to_transform_map.find(child) == object_to_transform_map.end()) {
|
||||
object_to_transform_map[child] = std::vector<Ref<SceneGraph::TransformNode>>();
|
||||
}
|
||||
object_to_transform_map[child].push_back(xfmNode);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
store(group->children[i]);
|
||||
}
|
||||
|
||||
/* store all compressed transform nodes */
|
||||
for (auto& i : object_to_transform_map)
|
||||
store(i.second);
|
||||
|
||||
close("Group");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::Node> node)
|
||||
{
|
||||
if (nodeMap.find(node) != nodeMap.end()) {
|
||||
tab(); xml << "<ref id=\"" << nodeMap[node] << "\"/>" << std::endl; return;
|
||||
}
|
||||
|
||||
const ssize_t id = nodeMap[node] = currentNodeID++;
|
||||
if (node->fileName != "") {
|
||||
tab(); xml << "<extern id=\"" << id << "\" src=\"" << node->fileName << "\"/>" << std::endl; return;
|
||||
}
|
||||
|
||||
if (Ref<SceneGraph::AnimatedLightNode> cnode = node.dynamicCast<SceneGraph::AnimatedLightNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::LightNode> cnode = node.dynamicCast<SceneGraph::LightNode>()) store(cnode,id);
|
||||
//else if (Ref<SceneGraph::MaterialNode> cnode = node.dynamicCast<SceneGraph::MaterialNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::TriangleMeshNode> cnode = node.dynamicCast<SceneGraph::TriangleMeshNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::QuadMeshNode> cnode = node.dynamicCast<SceneGraph::QuadMeshNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::SubdivMeshNode> cnode = node.dynamicCast<SceneGraph::SubdivMeshNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::HairSetNode> cnode = node.dynamicCast<SceneGraph::HairSetNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::AnimatedPerspectiveCameraNode> cnode = node.dynamicCast<SceneGraph::AnimatedPerspectiveCameraNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::PerspectiveCameraNode> cnode = node.dynamicCast<SceneGraph::PerspectiveCameraNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::TransformNode> cnode = node.dynamicCast<SceneGraph::TransformNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::GroupNode> cnode = node.dynamicCast<SceneGraph::GroupNode>()) store(cnode,id);
|
||||
else throw std::runtime_error("unknown node type");
|
||||
}
|
||||
|
||||
XMLWriter::XMLWriter(Ref<SceneGraph::Node> root, const FileName& fileName, bool embedTextures, bool referenceMaterials, bool binaryFormat)
|
||||
: ident(0), currentNodeID(0), embedTextures(embedTextures), referenceMaterials(referenceMaterials), binaryFormat(binaryFormat)
|
||||
{
|
||||
xml.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
xml.open (fileName, std::fstream::out);
|
||||
|
||||
if (binaryFormat)
|
||||
{
|
||||
const FileName binFileName = fileName.addExt(".bin");
|
||||
bin.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
bin.open (binFileName, std::fstream::out | std::fstream::binary);
|
||||
}
|
||||
|
||||
xml << "<?xml version=\"1.0\"?>" << std::endl;
|
||||
root->calculateInDegree();
|
||||
open("scene");
|
||||
store(root);
|
||||
close("scene");
|
||||
root->resetInDegree();
|
||||
}
|
||||
|
||||
void SceneGraph::storeXML(Ref<SceneGraph::Node> root, const FileName& fileName, bool embedTextures, bool referenceMaterials, bool binaryFormat) {
|
||||
XMLWriter(root,fileName,embedTextures,referenceMaterials,binaryFormat);
|
||||
}
|
||||
}
|
||||
15
Framework/external/embree/tutorials/common/scenegraph/xml_writer.h
vendored
Normal file
15
Framework/external/embree/tutorials/common/scenegraph/xml_writer.h
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
void storeXML(Ref<SceneGraph::Node> root, const FileName& fileName, bool embedTextures, bool referenceMaterials, bool binaryFormat);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue