//---------------------------------------------------------------------------- Object* Object::Copy(const std::string& uniqueNameAppend) { // Save the object to a memory buffer. OutStream saveStream; saveStream.Insert((Object*)this); int bufferSize = 0; char* buffer = 0; saveStream.Save(bufferSize, buffer, BufferIO::BM_DEFAULT_WRITE); // Load the object from the memory buffer. InStream loadStream; loadStream.Load(bufferSize, buffer, BufferIO::BM_DEFAULT_READ); delete1(buffer); if (uniqueNameAppend != "") { int numObjects = loadStream.GetNumObjects(); for (int i = 0; i < numObjects; i++) { PX2::Object *obj = loadStream.GetObjectAt(i); std::string name = obj->GetName(); if (name.length() > 0) { name += uniqueNameAppend; obj->SetName(name); } } } return loadStream.GetObjectAt(0); }
//---------------------------------------------------------------------------- bool EditMap::LoadScene (const char *pathname) { EditSystem::GetSingleton().Reset(); InStream inStream; if (inStream.Load(pathname)) { Object *object = inStream.GetObjectAt(0); Scene *scene = DynamicCast<Scene>(object); if (scene) { EditSystem::GetSingleton().Reset(); if (mScene) mScene->GoOutFromEventWorld(); mScene = scene; mScene->ComeInToEventWorld(); Project::GetSingleton().SetScene(mScene); Project::GetSingleton().SetSceneFilename(pathname); Event *event = EditorEventSpace::CreateEventX( EditorEventSpace::LoadedScene); EventWorld::GetSingleton().BroadcastingLocalEvent(event); return true; } } return false; }
//---------------------------------------------------------------------------- bool ResourceManager::LoadCachedResource (const std::string &filename) { ScopedCS scopeCS(mResTableMutex); InStream inPut; if (inPut.Load(filename)) { int numObjects = inPut.GetNumObjects(); for (int i=0; i<numObjects; i++) { Object *obj = inPut.GetObjectAt(i); if (obj) { std::string filename = obj->GetResourcePath(); LoadRecord rec; rec.Filename = filename; rec.Obj = obj; mResTable.insert(std::pair<std::string, LoadRecord>(filename, rec)); } } return true; } return false; }
//---------------------------------------------------------------------------- Object* Object::Copy (const std::string& uniqueNameAppend) const { // Save the object to a memory buffer. OutStream saveStream; saveStream.Insert((Object*)this); int bufferSize = 0; char* buffer = 0; saveStream.Save(bufferSize, buffer, BufferIO::BM_DEFAULT_WRITE); // Load the object from the memory buffer. InStream loadStream; loadStream.Load(bufferSize, buffer, BufferIO::BM_DEFAULT_READ); delete1(buffer); if (uniqueNameAppend != "") { // The names of the input scene were copied as is. Generate unique // names for the output scene. int numObjects = loadStream.GetNumObjects(); for (int i=0; i<numObjects; i++) { PX2::Object *obj = loadStream.GetObjectAt(i); std::string name = obj->GetName(); if (name.length() > 0) { // The object has a name. Append a string to make the name // unique. TODO: This code does not ensure that the // appended name is some other name in the copied scene. To // do this would require building a set of names and verifying // that the appended names are not in this set. For now we // think this is not worth the effort, but maybe later we can // add code to do this. name += uniqueNameAppend; obj->SetName(name); } } } return loadStream.GetObjectAt(0); }
//---------------------------------------------------------------------------- void ProjectedTextures::CreateScene () { mScene = new0 Node(); mTrnNode = new0 Node(); mScene->AttachChild(mTrnNode); // Load the face model. #ifdef WM5_LITTLE_ENDIAN std::string path = Environment::GetPathR("FacePN.wmof"); #else std::string path = Environment::GetPathR("FacePN.be.wmof"); #endif InStream inStream; inStream.Load(path); TriMesh* mesh = StaticCast<TriMesh>(inStream.GetObjectAt(0)); // Create a camera to project the texture. Projector* projector = new0 Projector(Camera::PM_DEPTH_ZERO_TO_ONE); projector->SetFrustum(1.0f, 10.0f, -0.4125f, 0.4125f, -0.55f, 0.55f); AVector proDVector(0.0f, 1.0f, 0.0f); AVector proUVector(0.0f, 0.0f, 1.0f); AVector proRVector = proDVector.Cross(proUVector); APoint proPosition = APoint::ORIGIN - 303.0f*proDVector; projector->SetFrame(proPosition, proDVector, proUVector, proRVector); // Create a directional light for the face. Light* light = new0 Light(Light::LT_DIRECTIONAL); light->Ambient = Float4(0.25f, 0.25f, 0.25f, 1.0f); light->Diffuse = Float4(1.0f, 1.0f, 1.0f, 1.0f); light->Specular = Float4(0.0f, 0.0f, 0.0f, 1.0f); light->DVector = AVector::UNIT_Y; // scene-camera direction // Create a material for the face. Material* material = new0 Material(); material->Emissive = Float4(0.0f, 0.0f, 0.0f, 1.0f); material->Ambient = Float4(0.5f, 0.5f, 0.5f, 1.0f); material->Diffuse = Float4(0.99607f, 0.83920f, 0.67059f, 1.0f); material->Specular = Float4(0.8f, 0.8f, 0.8f, 0.0f); // Create the effect. std::string effectFile = Environment::GetPathR("ProjectedTexture.wmfx"); ProjectedTextureEffect* effect = new0 ProjectedTextureEffect(effectFile); std::string projectedName = Environment::GetPathR("Magician.wmtf"); Texture2D* projectedTexture = Texture2D::LoadWMTF(projectedName); mesh->SetEffectInstance(effect->CreateInstance(projector, light, material, projectedTexture)); mTrnNode->AttachChild(mesh); }
//---------------------------------------------------------------------------- void ReflectionsAndShadows::LoadBiped () { #ifdef WM5_LITTLE_ENDIAN std::string path = Environment::GetPathR("SkinnedBipedPN.wmof"); #else std::string path = Environment::GetPathR("SkinnedBipedPN.be.wmof"); #endif InStream source; source.Load(path); mBiped = (Node*)source.GetObjectAt(0); // This guarantees that the reflection is drawn, even when the biped is // not visible to the camera. mBiped->Culling = Spatial::CULL_NEVER; }
//---------------------------------------------------------------------------- Object *ResourceManager::_LoadObject (const std::string &filename) { Object *obj = 0; string::size_type pos = filename.find("."); if (pos == string::npos) return 0; std::string outPath; std::string outBaseName; std::string outExtention; StringHelp::SplitFullFilename(filename, outPath, outBaseName, outExtention); char *buffer = 0; int bufferSize = 0; if (GetBuffer(filename, bufferSize, buffer)) { if ("png"==outExtention || "PNG"==outExtention) { obj = LoadTexFormOtherImagefile(outExtention, bufferSize, buffer); } else { InStream inStream; inStream.Load1(bufferSize, buffer); obj = inStream.GetObjectAt(0); } delete1(buffer); bufferSize = 0; } if (obj) { obj->SetResourcePath(filename); } return obj; }
//---------------------------------------------------------------------------- void ScreenPolygons::CreateScene () { // The screen camera is designed to map (x,y,z) in [0,1]^3 to (x',y,'z') // in [-1,1]^2 x [0,1]. mScreenCamera = new0 Camera(false); mScreenCamera->SetFrustum(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); mScreenCamera->SetFrame(APoint::ORIGIN, AVector::UNIT_Z, AVector::UNIT_Y, AVector::UNIT_X); // Load the biped just for some model to display. #ifdef WM5_LITTLE_ENDIAN std::string path = Environment::GetPathR("SkinnedBipedPN.wmof"); #else std::string path = Environment::GetPathR("SkinnedBipedPN.be.wmof"); #endif InStream source; source.Load(path); mScene = DynamicCast<Node>(source.GetObjectAt(0)); assertion(mScene != 0, "Error in biped stream.\n"); // The background is a textured screen polygon (z = 1). VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(4, vstride); VertexBufferAccessor vba(vformat, vbuffer); vba.Position<Float3>(0) = Float3(0.0f, 0.0f, 1.0f); vba.Position<Float3>(1) = Float3(1.0f, 0.0f, 1.0f); vba.Position<Float3>(2) = Float3(1.0f, 1.0f, 1.0f); vba.Position<Float3>(3) = Float3(0.0f, 1.0f, 1.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(1.0f, 1.0f); vba.TCoord<Float2>(0, 3) = Float2(0.0f, 1.0f); IndexBuffer* ibuffer = new0 IndexBuffer(6, sizeof(int)); int* indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; mBackPoly = new0 TriMesh(vformat, vbuffer, ibuffer); path = Environment::GetPathR("RedSky.wmtf"); Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); Texture2D* texture = Texture2D::LoadWMTF(path); mBackPoly->SetEffectInstance(effect->CreateInstance(texture)); // The middle polygon, which may be translated via '+' or '-'. vbuffer = new0 VertexBuffer(4, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(0.0f, 0.3f, 0.0f); vba.Position<Float3>(1) = Float3(1.0f, 0.3f, 0.0f); vba.Position<Float3>(2) = Float3(1.0f, 0.7f, 0.0f); vba.Position<Float3>(3) = Float3(0.0f, 0.7f, 0.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.3f); vba.TCoord<Float2>(0, 1) = Float2(1.0f, 0.3f); vba.TCoord<Float2>(0, 2) = Float2(1.0f, 0.7f); vba.TCoord<Float2>(0, 3) = Float2(0.0f, 0.7f); mMidPoly = new0 TriMesh(vformat, vbuffer, ibuffer); path = Environment::GetPathR("BallTexture.wmtf"); texture = Texture2D::LoadWMTF(path); mMidPoly->SetEffectInstance(effect->CreateInstance(texture)); mLinearZ = 1.0f; mDepthZ = 1.0f; mMidPoly->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, mLinearZ)); // A portion of the foreground is a textured screen polygon (z = 0). vbuffer = new0 VertexBuffer(5, vstride); vba.ApplyTo(vformat, vbuffer); vba.Position<Float3>(0) = Float3(0.0f, 0.0f, 0.0f); vba.Position<Float3>(1) = Float3(0.5f, 0.0f, 0.0f); vba.Position<Float3>(2) = Float3(0.75f, 0.5f, 0.0f); vba.Position<Float3>(3) = Float3(0.5f, 0.75f, 0.0f); vba.Position<Float3>(4) = Float3(0.0f, 0.5f, 0.0f); vba.TCoord<Float2>(0, 0) = Float2(0.0f, 0.0f); vba.TCoord<Float2>(0, 1) = Float2(0.67f, 0.0f); vba.TCoord<Float2>(0, 2) = Float2(1.0f, 0.67f); vba.TCoord<Float2>(0, 3) = Float2(0.67f, 1.0f); vba.TCoord<Float2>(0, 4) = Float2(0.0f, 0.67f); ibuffer = new0 IndexBuffer(9, sizeof(int)); indices = (int*)ibuffer->GetData(); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; indices[6] = 0; indices[7] = 3; indices[8] = 4; mForePoly = new0 TriMesh(vformat, vbuffer, ibuffer); path = Environment::GetPathR("Flower.wmtf"); Texture2DEffect* foreEffect = new0 Texture2DEffect(Shader::SF_LINEAR); texture = Texture2D::LoadWMTF(path); mForePoly->SetEffectInstance(foreEffect->CreateInstance(texture)); // Make the foreground semitransparent. foreEffect->GetAlphaState(0, 0)->BlendEnabled = true; }
//---------------------------------------------------------------------------- void ClodMeshes::CreateScene () { mScene = new0 Node(); mTrnNode = new0 Node(); mScene->AttachChild(mTrnNode); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // Load the face model. #ifdef WM5_LITTLE_ENDIAN std::string path = Environment::GetPathR("FacePN.wmof"); #else std::string path = Environment::GetPathR("FacePN.be.wmof"); #endif InStream inStream; inStream.Load(path); TriMeshPtr mesh = StaticCast<TriMesh>(inStream.GetObjectAt(0)); VertexBufferAccessor vba0(mesh); // Remove the normals and add texture coordinates. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(vba0.GetNumVertices(), vstride); VertexBufferAccessor vba1(vformat, vbuffer); float xmin = Mathf::MAX_REAL, xmax = -Mathf::MAX_REAL; float ymin = Mathf::MAX_REAL, ymax = -Mathf::MAX_REAL; int i; for (i = 0; i < vba0.GetNumVertices(); ++i) { Float3 position = vba0.Position<Float3>(i); vba1.Position<Float3>(i) = position; float x = position[0]; float y = position[2]; vba1.TCoord<Float2>(0, i) = Float2(x, y); if (x < xmin) { xmin = x; } if (x > xmax) { xmax = x; } if (y < ymin) { ymin = y; } if (y > ymax) { ymax = y; } } float xmult = 1.0f/(xmax - xmin); float ymult = 1.0f/(ymax - ymin); for (i = 0; i < vba1.GetNumVertices(); ++i) { Float2 tcoord = vba1.TCoord<Float2>(0, i); vba1.TCoord<Float2>(0,i) = Float2( (tcoord[0] - xmin)*xmult, (tcoord[1] - ymin)*ymult); } mesh->SetVertexFormat(vformat); mesh->SetVertexBuffer(vbuffer); // Create a texture for the face. Use the generated texture coordinates. Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); path = Environment::GetPathR("Magician.wmtf"); Texture2D* texture = Texture2D::LoadWMTF(path); #ifdef USE_CLOD_MESH // Create the collapse records to be shared by two CLOD meshes. int numRecords = 0; CollapseRecord* records = 0; CreateClodMesh ccm(mesh, numRecords, records); CollapseRecordArray* recordArray = new0 CollapseRecordArray(numRecords, records); mClod[0] = new0 ClodMesh(mesh, recordArray); mClod[0]->LocalTransform = mesh->LocalTransform; mClod[0]->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() - 150.0f*AVector::UNIT_X); mClod[0]->SetEffectInstance(effect->CreateInstance(texture)); mTrnNode->AttachChild(mClod[0]); mClod[1] = new0 ClodMesh(mesh, recordArray); mClod[1]->LocalTransform = mesh->LocalTransform; mClod[1]->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() + 150.0f*AVector::UNIT_X - 100.0f*AVector::UNIT_Y); mClod[1]->SetEffectInstance(effect->CreateInstance(texture)); mTrnNode->AttachChild(mClod[1]); mActive = mClod[0]; #else IndexBuffer* ibuffer = mesh->GetIndexBuffer(); TriMesh* face = new0 TriMesh(vformat, vbuffer,ibuffer); face->LocalTransform = mesh->LocalTransform; face->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() - 150.0f*AVector::UNIT_X); face->SetEffectInstance(effect->CreateInstance(texture)); mTrnNode->AttachChild(face); face = new0 TriMesh(vformat, vbuffer, ibuffer); face->LocalTransform = mesh->LocalTransform; face->LocalTransform.SetTranslate(mesh->LocalTransform.GetTranslate() + 150.0f*AVector::UNIT_X); face->SetEffectInstance(effect->CreateInstance(texture)); mTrnNode->AttachChild(face); #endif }
//---------------------------------------------------------------------------- void RenderToTexture::CreateScene () { // Create the root of the scene. mScene = new0 Node(); mTrnNode = new0 Node(); mScene->AttachChild(mTrnNode); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); // Create a screen-space camera to use with the render target. mScreenCamera = ScreenTarget::CreateCamera(); // Create a screen polygon to use with the render target. VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); const int rtWidth = 256, rtHeight = 256; mScreenPolygon = ScreenTarget::CreateRectangle(vformat, rtWidth, rtHeight, 0.0f, 0.2f, 0.0f, 0.2f, 0.0f); // Create the render target. //Texture::Format tformat = Texture::TF_A8B8G8R8; // DX9 fails Texture::Format tformat = Texture::TF_A8R8G8B8; //Texture::Format tformat = Texture::TF_A16B16G16R16; //Texture::Format tformat = Texture::TF_A16B16G16R16F; //Texture::Format tformat = Texture::TF_A32B32G32R32F; mRenderTarget = new0 RenderTarget(1, tformat, rtWidth, rtHeight, false, false); // Attach the render target texture to the screen polygon mesh. mScreenPolygon->SetEffectInstance(Texture2DEffect::CreateUniqueInstance( mRenderTarget->GetColorTexture(0), Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE)); // Load the face model and use multitexturing. #ifdef WM5_LITTLE_ENDIAN std::string path = Environment::GetPathR("FacePN.wmof"); #else std::string path = Environment::GetPathR("FacePN.be.wmof"); #endif InStream inStream; inStream.Load(path); TriMeshPtr mesh = DynamicCast<TriMesh>(inStream.GetObjectAt(0)); // Create texture coordinates for the face. Based on knowledge of the // mesh, the (x,z) values of the model-space vertices may be mapped to // (s,t) in [0,1]^2. VertexBufferAccessor vba0(mesh); const int numVertices = vba0.GetNumVertices(); float xmin = Mathf::MAX_REAL, xmax = -Mathf::MAX_REAL; float zmin = Mathf::MAX_REAL, zmax = -Mathf::MAX_REAL; int i; for (i = 1; i < numVertices; ++i) { Float3 position = vba0.Position<Float3>(i); float x = position[0]; if (x < xmin) { xmin = x; } if (x > xmax) { xmax = x; } float z = position[2]; if (z < zmin) { zmin = z; } if (z > zmax) { zmax = z; } } float invXRange = 1.0f/(xmax - xmin); float invZRange = 1.0f/(zmax - zmin); // Strip out the normal vectors, because there is no lighting in this // sample. Add in two texture coordinate channels for a multiplicative // texture effect. vformat = VertexFormat::Create(3, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 1); int vstride = vformat->GetStride(); VertexBuffer* vbuffer = new0 VertexBuffer(numVertices, vstride); VertexBufferAccessor vba1(vformat, vbuffer); for (i = 0; i < numVertices; ++i) { Float3 position = vba0.Position<Float3>(i); Float2 tcoord( (position[0] - xmin)*invXRange, (position[2] - zmin)*invZRange); vba1.Position<Float3>(i) = position; vba1.TCoord<Float2>(0, i) = tcoord; vba1.TCoord<Float2>(1, i) = tcoord; } mesh->SetVertexFormat(vformat); mesh->SetVertexBuffer(vbuffer); path = Environment::GetPathR("Leaf.wmtf"); Texture2D* texture0 = Texture2D::LoadWMTF(path); path = Environment::GetPathR("Water.wmtf"); Texture2D* texture1 = Texture2D::LoadWMTF(path); VisualEffectInstance* instance = Texture2AddEffect::CreateUniqueInstance( texture0, Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE, texture1, Shader::SF_LINEAR, Shader::SC_CLAMP_EDGE, Shader::SC_CLAMP_EDGE); mesh->SetEffectInstance(instance); mTrnNode->AttachChild(mesh); }