shared_ptr<TileSheet> TileSheet::create(const Any& any) { shared_ptr<TileSheet> tileSheet(new TileSheet()); AnyTableReader r(any); Any legend; r.getIfPresent("legend", legend); for (Table<String, Any>::Iterator it = legend.table().begin(); it.hasMore(); ++it) { const String& mapLabel = it.key(); const shared_ptr<Tile>& tile = Tile::create(mapLabel, it.value()); // TODO: Switch to report debugAssertM(! tileSheet->m_tileByID.containsKey(tile->id()), "Duplicate tile ID"); tileSheet->m_tileByID.set(tile->id(), tile); tileSheet->m_tileByMapLabel.set(tile->mapLabel(), tile); } r.getFilenameIfPresent("color", tileSheet->m_colorFilename); r.getFilenameIfPresent("blueprint", tileSheet->m_blueprintFilename); // Even though we lazy load these (since the server can't load graphics), // we check immediately to ensure that the files exist if (! FileSystem::exists(tileSheet->m_colorFilename)) { report("File not found: \"" + tileSheet->m_colorFilename + "\".", ReportLevel::ERROR); } if (! FileSystem::exists(tileSheet->m_blueprintFilename)) { report("File not found: \"" + tileSheet->m_blueprintFilename + "\".", ReportLevel::ERROR); } r.verifyDone(); return tileSheet; }
PhysicsFrame::PhysicsFrame(const Any& a) { const std::string& n = toLower(a.name()); *this = PhysicsFrame(); if (beginsWith(n, "vector3")) { *this = PhysicsFrame(Vector3(a)); } else if (beginsWith(n, "matrix3")) { *this = PhysicsFrame(Matrix3(a)); } else if (beginsWith(n, "cframe") || beginsWith(n, "coordinateframe")) { *this = PhysicsFrame(CoordinateFrame(a)); } else if (beginsWith(n, "pframe") || beginsWith(n, "physicsframe")) { if (a.type() == Any::ARRAY) { a.verifySize(2); rotation = a[0]; translation = a[1]; } else { for (Any::AnyTable::Iterator it = a.table().begin(); it.hasMore(); ++it) { const std::string& n = toLower(it->key); if (n == "translation") { translation = it->value; } else if (n == "rotation") { rotation = it->value; } else { a.verify(false, "Illegal table key: " + it->key); } } } } }
ArticulatedModel::PoseSpline::PoseSpline(const Any& any) : castsShadows(true) { any.verifyName("ArticulatedModel::PoseSpline"); for (Any::AnyTable::Iterator it = any.table().begin(); it.isValid(); ++it) { if (it->key == "castsShadows") { castsShadows = it->value; } else { partSpline.getCreate(it->key) = it->value; } } }
BumpMapPreprocess::BumpMapPreprocess(const Any& any) { *this = BumpMapPreprocess(); for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) { const std::string& key = toLower(it->key); if (key == "lowpassfilter") { lowPassFilter = it->value; } else if (key == "zextentpixels") { zExtentPixels = it->value; } else if (key == "scalezbynz") { scaleZByNz = it->value; } else { any.verify(false, "Illegal key: " + it->key); } } }
BumpMap::Settings::Settings(const Any& any) { *this = Settings(); any.verifyName("BumpMap::Settings"); for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) { const std::string& key = toLower(it->key); if (key == "iterations") { iterations = iMax(0, iRound(it->value.number())); } else if (key == "scale") { scale = it->value; } else if (key == "bias") { bias = it->value; } else { any.verify(false, "Illegal key: " + it->key); } } }
Texture::Preprocess::Preprocess(const Any& any) { *this = Preprocess::defaults(); any.verifyNameBeginsWith("Texture::Preprocess"); if (any.type() == Any::TABLE) { for (Any::AnyTable::Iterator it = any.table().begin(); it.isValid(); ++it) { const String& key = it->key; if (key == "modulate") { modulate = Color4(it->value); } else if (key == "gammaAdjust") { gammaAdjust = it->value; } else if (key == "scaleFactor") { scaleFactor = it->value; } else if (key == "computeMinMaxMean") { computeMinMaxMean = it->value; } else if (key == "computeNormalMap") { computeNormalMap = it->value; } else if (key == "convertToPremultipliedAlpha") { convertToPremultipliedAlpha = it->value; } else if (key == "bumpMapPreprocess") { bumpMapPreprocess = it->value; } else { any.verify(false, "Illegal key: " + it->key); } } } else { const String& n = any.name(); if (n == "Texture::Preprocess::defaults") { any.verifySize(0); } else if (n == "Texture::Preprocess::gamma") { any.verifySize(1); *this = Texture::Preprocess::gamma(any[0]); } else if (n == "Texture::preprocess::none") { any.verifySize(0); *this = Texture::Preprocess::none(); } else if (n == "Texture::Preprocess::quake") { any.verifySize(0); *this = Texture::Preprocess::quake(); } else if (n == "Texture::Preprocess::normalMap") { any.verifySize(0); *this = Texture::Preprocess::normalMap(); } else { any.verify(false, "Unrecognized name for Texture::Preprocess constructor or factory method."); } } }
CoordinateFrame::CoordinateFrame(const Any& any) { *this = CFrame(); const std::string& n = toUpper(any.name()); if (beginsWith(n, "VECTOR3")) { translation = any; } else if (beginsWith(n, "MATRIX3")) { rotation = any; } else if ((n == "CFRAME") || (n == "COORDINATEFRAME")) { any.verifyType(Any::TABLE, Any::ARRAY); if (any.type() == Any::ARRAY) { any.verifySize(2); rotation = any[0]; translation = any[1]; } else { for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) { const std::string& n = toLower(it->key); if (n == "translation") { translation = Vector3(it->value); } else if (n == "rotation") { rotation = Matrix3(it->value); } else { any.verify(false, "Illegal table key: " + it->key); } } } } else if (beginsWith(n, "PHYSICSFRAME") || beginsWith(n, "PFRAME")) { *this = PhysicsFrame(any); } else { any.verifyName("CFrame::fromXYZYPRDegrees", "CoordinateFrame::fromXYZYPRDegrees"); any.verifyType(Any::ARRAY); any.verifySize(3, 6); int s = any.size(); *this = fromXYZYPRDegrees(any[0], any[1], any[2], (s > 3) ? any[3].number() : 0.0f, (s > 4) ? any[4].number() : 0.0f, (s > 5) ? any[5].number() : 0.0f); } }
BumpMap::Specification::Specification(const Any& any) { if (any.type() == Any::STRING) { // Treat as a filename texture.filename = any.resolveStringAsFilename(); texture.preprocess = Texture::Preprocess::normalMap(); } else { for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) { const std::string& key = toLower(it->key); if (key == "texture") { texture = it->value; if (it->value.type() == Any::STRING) { // Set bump map defaults texture.preprocess = Texture::Preprocess::normalMap(); } } else if (key == "settings") { settings = it->value; } else { any.verify(false, "Illegal key: " + it->key); } } } }
Any Scene::load(const std::string& scene) { std::string filename; clear(); m_modelTable.clear(); m_name = scene; bool isFilename = endsWith(toLower(scene), ".scn.any") || endsWith(toLower(scene), ".Scene.Any"); if (isFilename) { filename = scene; } else { const std::string* f = filenameTable().getPointer(scene); if (f == NULL) { throw "No scene with name '" + scene + "' found in (" + stringJoin(filenameTable().getKeys(), ", ") + ")"; } filename = *f; } Any any; any.load(filename); { const std::string& n = any.get("name", filename); // Ensure that this name appears in the filename table if it does not already, // so that it can be loaded by name in the future. if (! filenameTable().containsKey(n)) { filenameTable().set(n, filename); } } m_sourceAny = any; // Load the lighting environment (do this before loading entities, since some of them may // be lights that will enter this array) bool hasEnvironmentMap = false; if (any.containsKey("localLightingEnvironment")) { m_localLightingEnvironment = any["localLightingEnvironment"]; hasEnvironmentMap = any["localLightingEnvironment"].containsKey("environmentMap"); } // Load the models if (any.containsKey("models")) { Any models = any["models"]; if (models.size() > 0) { for (Any::AnyTable::Iterator it = models.table().begin(); it.isValid(); ++it) { const std::string name = it->key; Any v = it->value; createModel(v, name); } } } // Instance the models if (any.containsKey("entities")) { Any entities = any["entities"]; if (entities.size() > 0) { for (Table<std::string, Any>::Iterator it = entities.table().begin(); it.isValid(); ++it) { const std::string& name = it->key; const std::string& entityType = it->value.name(); createEntity(entityType, name, it->value); } } } shared_ptr<Texture> skyboxTexture = Texture::whiteCube(); Any skyAny; // Use the environment map as a skybox if there isn't one already, and vice versa Array<shared_ptr<Skybox> > skyboxes; getTypedEntityArray<Skybox>(skyboxes); if ( skyboxes.size() == 0 ) { if (any.containsKey("skybox")) { createEntity("Skybox", "skybox", any["skybox"]); m_skybox = typedEntity<Skybox>("skybox"); } else if (hasEnvironmentMap) { m_skybox = Skybox::create("skybox", this, Array<ScaledTexture>(m_localLightingEnvironment.environmentMapArray[0]), Array<SimTime>(0.0), 0, SplineExtrapolationMode::CLAMP, false, false); insert(m_skybox); } else { m_skybox = Skybox::create("skybox", this, Array<ScaledTexture>(ScaledTexture(Texture::whiteCube(), 1.0f)), Array<SimTime>(0.0), 0, SplineExtrapolationMode::CLAMP, false, false); insert(m_skybox); } } if (any.containsKey("environmentMap")) { throw std::string("environmentMap field has been replaced with localLightingEnvironment"); } // Default to using the skybox as an environment map if none is specified. if (! hasEnvironmentMap) { m_localLightingEnvironment.environmentMapArray.append(ScaledTexture(m_skybox->keyframeArray()[0].texture, m_skybox->keyframeArray()[0].constant)); } ////////////////////////////////////////////////////// if (m_cameraArray.size() == 0) { // Create a default camera, back it up from the origin m_cameraArray.append(Camera::create("camera")); m_cameraArray.last()->setFrame(CFrame::fromXYZYPRDegrees(0,1,-5,0,-5)); } setTime(any.get("time", 0.0)); m_lastVisibleChangeTime = m_lastLightChangeTime = m_lastStructuralChangeTime = System::time(); m_defaultCameraName = (std::string)any.get("defaultCamera", ""); // Set the initial positions, repeating a few times to allow // objects defined relative to others to reach a fixed point for (int i = 0; i < 3; ++i) { for (int e = 0; e < m_entityArray.size(); ++e) { m_entityArray[e]->onSimulation(m_time, nan()); } } // Pose objects so that they have bounds. { Array< shared_ptr<Surface> > ignore; onPose(ignore); } return any; }
GLight::GLight(const Any& any) { any.verifyName("GLight"); if (any.type() == Any::TABLE) { *this = GLight(); Vector3 spotTarget; bool hasSpotTarget = false; for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) { const std::string& key = toLower(it->key); if (key == "position") { position = it->value; } else if (key == "rightdirection") { rightDirection = it->value; } else if (key == "spotdirection") { spotDirection = Vector3(it->value).directionOrZero(); } else if (key == "spottarget") { spotTarget = it->value; hasSpotTarget = true; } else if (key == "spotcutoff") { spotCutoff = it->value.number(); } else if (key == "spotsquare") { spotSquare = it->value.boolean(); } else if (key == "attenuation") { attenuation[0] = it->value[0].number(); attenuation[1] = it->value[1].number(); attenuation[2] = it->value[2].number(); } else if (key == "color") { color = it->value; } else if (key == "enabled") { enabled = it->value.boolean(); } else if (key == "specular") { specular = it->value.boolean(); } else if (key == "diffuse") { diffuse = it->value.boolean(); } else { any.verify(false, "Illegal key: " + it->key); } } if (hasSpotTarget) { spotDirection = (spotTarget - position.xyz()).direction(); } } else if (toLower(any.name()) == "glight::directional") { *this = directional(any[0], any[1], (any.size() > 2) ? any[2] : Any(true), (any.size() > 3) ? any[3] : Any(true)); } else if (toLower(any.name()) == "glight::point") { *this = point(any[0], any[1], (any.size() > 2) ? any[2] : Any(1), (any.size() > 3) ? any[3] : Any(0), (any.size() > 4) ? any[4] : Any(0.5f), (any.size() > 5) ? any[5] : Any(true), (any.size() > 6) ? any[6] : Any(true)); } else if (toLower(any.name()) == "glight::spot") { *this = spot(any[0], any[1], any[2], any[3], (any.size() > 4) ? any[4] : Any(1), (any.size() > 5) ? any[5] : Any(0), (any.size() > 6) ? any[6] : Any(0), (any.size() > 7) ? any[7] : Any(true), (any.size() > 8) ? any[8] : Any(true)); } else { any.verify(false, "Unrecognized name"); } }
Scene::Ref Scene::create(const std::string& scene, GCamera& camera) { if (scene == "") { return NULL; } Scene::Ref s = new Scene(); const std::string* f = filenameTable().getPointer(scene); if (f == NULL) { throw "No scene with name '" + scene + "' found in (" + stringJoin(filenameTable().getKeys(), ", ") + ")"; } const std::string& filename = *f; Any any; any.load(filename); // Load the lighting s->m_lighting = Lighting::create(any.get("lighting", Lighting::Specification())); // Load the models Any models = any["models"]; typedef ReferenceCountedPointer<ReferenceCountedObject> ModelRef; Table< std::string, ModelRef > modelTable; for (Any::AnyTable::Iterator it = models.table().begin(); it.hasMore(); ++it) { ModelRef m; Any v = it->value; if (v.nameBeginsWith("ArticulatedModel")) { m = ArticulatedModel::create(v); } else if (v.nameBeginsWith("MD2Model")) { m = MD2Model::create(v); } else if (v.nameBeginsWith("MD3Model")) { m = MD3Model::create(v); } else { debugAssertM(false, "Unrecognized model type: " + v.name()); } modelTable.set(it->key, m); } // Instance the models Any entities = any["entities"]; for (Table<std::string, Any>::Iterator it = entities.table().begin(); it.hasMore(); ++it) { const std::string& name = it->key; const Any& modelArgs = it->value; modelArgs.verifyType(Any::ARRAY); const ModelRef* model = modelTable.getPointer(modelArgs.name()); modelArgs.verify((model != NULL), "Can't instantiate undefined model named " + modelArgs.name() + "."); PhysicsFrameSpline frameSpline; ArticulatedModel::PoseSpline poseSpline; if (modelArgs.size() >= 1) { frameSpline = modelArgs[0]; if (modelArgs.size() >= 2) { // Poses poseSpline = modelArgs[1]; } } ArticulatedModel::Ref artModel = model->downcast<ArticulatedModel>(); MD2Model::Ref md2Model = model->downcast<MD2Model>(); MD3Model::Ref md3Model = model->downcast<MD3Model>(); if (artModel.notNull()) { s->m_entityArray.append(Entity::create(name, frameSpline, artModel, poseSpline)); } else if (md2Model.notNull()) { s->m_entityArray.append(Entity::create(name, frameSpline, md2Model)); } else if (md3Model.notNull()) { s->m_entityArray.append(Entity::create(name, frameSpline, md3Model)); } } // Load the camera camera = any["camera"]; if (any.containsKey("skybox")) { Any sky = any["skyBox"]; s->m_skyBoxConstant = sky.get("constant", 1.0f); if (sky.containsKey("texture")) { s->m_skyBoxTexture = Texture::create(sky["texture"]); } } else { s->m_skyBoxTexture = s->m_lighting->environmentMapTexture; s->m_skyBoxConstant = s->m_lighting->environmentMapConstant; } // Default to using the skybox as an environment map if none is specified. if (s->m_skyBoxTexture.notNull() && s->m_lighting->environmentMapTexture.isNull()) { s->m_lighting->environmentMapTexture = s->m_skyBoxTexture; s->m_lighting->environmentMapConstant = s->m_skyBoxConstant; } return s; }