SharedPtr<Animation> Animation::Clone(const String& cloneName) const { SharedPtr<Animation> ret(new Animation(context_)); ret->SetName(cloneName); ret->SetAnimationName(animationName_); ret->length_ = length_; ret->tracks_ = tracks_; ret->triggers_ = triggers_; ret->SetMemoryUse(GetMemoryUse()); return ret; }
SharedPtr<ParticleEffect2D> ParticleEffect2D::Clone(const String& cloneName) const { SharedPtr<ParticleEffect2D> ret(new ParticleEffect2D(context_)); ret->SetName(cloneName); ret->sprite_ = sprite_; ret->sourcePositionVariance_ = sourcePositionVariance_; ret->speed_ = speed_; ret->speedVariance_ = speedVariance_; ret->particleLifeSpan_ = particleLifeSpan_; ret->particleLifespanVariance_ = particleLifespanVariance_; ret->angle_ = angle_; ret->angleVariance_ = angleVariance_; ret->gravity_ = gravity_; ret->radialAcceleration_ = radialAcceleration_; ret->tangentialAcceleration_ = tangentialAcceleration_; ret->radialAccelVariance_ = radialAccelVariance_; ret->tangentialAccelVariance_ = tangentialAccelVariance_; ret->startColor_ = startColor_; ret->startColorVariance_ = startColorVariance_; ret->finishColor_ = finishColor_; ret->finishColorVariance_ = finishColorVariance_; ret->maxParticles_ = maxParticles_; ret->startParticleSize_ = startParticleSize_; ret->startParticleSizeVariance_ = startParticleSizeVariance_; ret->finishParticleSize_ = finishParticleSize_; ret->finishParticleSizeVariance_ = finishParticleSizeVariance_; ret->duration_ = duration_; ret->emitterType_ = emitterType_; ret->maxRadius_ = maxRadius_; ret->maxRadiusVariance_ = maxRadiusVariance_; ret->minRadius_ = minRadius_; ret->minRadiusVariance_ = minRadiusVariance_; ret->rotatePerSecond_ = rotatePerSecond_; ret->rotatePerSecondVariance_ = rotatePerSecondVariance_; ret->blendMode_ = blendMode_; ret->rotationStart_ = rotationStart_; ret->rotationStartVariance_ = rotationStartVariance_; ret->rotationEnd_ = rotationEnd_; ret->rotationEndVariance_ = rotationEndVariance_; /// \todo Zero if source was created programmatically ret->SetMemoryUse(GetMemoryUse()); return ret; }
SharedPtr<ParticleEffect> ParticleEffect::Clone(const String& cloneName) const { SharedPtr<ParticleEffect> ret(new ParticleEffect(context_)); ret->SetName(cloneName); ret->material_ = material_; ret->numParticles_ = numParticles_; ret->updateInvisible_ = updateInvisible_; ret->relative_ = relative_; ret->scaled_ = scaled_; ret->sorted_ = sorted_; ret->fixedScreenSize_ = fixedScreenSize_; ret->animationLodBias_ = animationLodBias_; ret->emitterType_ = emitterType_; ret->emitterSize_ = emitterSize_; ret->directionMin_ = directionMin_; ret->directionMax_ = directionMax_; ret->constantForce_ = constantForce_; ret->dampingForce_ = dampingForce_; ret->activeTime_ = activeTime_; ret->inactiveTime_ = inactiveTime_; ret->emissionRateMin_ = emissionRateMin_; ret->emissionRateMax_ = emissionRateMax_; ret->sizeMin_ = sizeMin_; ret->sizeMax_ = sizeMax_; ret->timeToLiveMin_ = timeToLiveMin_; ret->timeToLiveMax_ = timeToLiveMax_; ret->velocityMin_ = velocityMin_; ret->velocityMax_ = velocityMax_; ret->rotationMin_ = rotationMin_; ret->rotationMax_ = rotationMax_; ret->rotationSpeedMin_ = rotationSpeedMin_; ret->rotationSpeedMax_ = rotationSpeedMax_; ret->sizeAdd_ = sizeAdd_; ret->sizeMul_ = sizeMul_; ret->colorFrames_ = colorFrames_; ret->textureFrames_ = textureFrames_; ret->faceCameraMode_ = faceCameraMode_; /// \todo Zero if source was created programmatically ret->SetMemoryUse(GetMemoryUse()); return ret; }
SharedPtr<Model> Model::Clone(const String& cloneName) const { SharedPtr<Model> ret(new Model(context_)); ret->SetName(cloneName); ret->boundingBox_ = boundingBox_; ret->skeleton_ = skeleton_; ret->geometryBoneMappings_ = geometryBoneMappings_; ret->geometryCenters_ = geometryCenters_; ret->morphs_ = morphs_; ret->morphRangeStarts_ = morphRangeStarts_; ret->morphRangeCounts_ = morphRangeCounts_; // Deep copy vertex/index buffers HashMap<VertexBuffer*, VertexBuffer*> vbMapping; for (Vector<SharedPtr<VertexBuffer> >::ConstIterator i = vertexBuffers_.Begin(); i != vertexBuffers_.End(); ++i) { VertexBuffer* origBuffer = *i; SharedPtr<VertexBuffer> cloneBuffer; if (origBuffer) { cloneBuffer = new VertexBuffer(context_); cloneBuffer->SetSize(origBuffer->GetVertexCount(), origBuffer->GetElementMask(), origBuffer->IsDynamic()); cloneBuffer->SetShadowed(origBuffer->IsShadowed()); if (origBuffer->IsShadowed()) cloneBuffer->SetData(origBuffer->GetShadowData()); else { void* origData = origBuffer->Lock(0, origBuffer->GetVertexCount()); if (origData) cloneBuffer->SetData(origData); else URHO3D_LOGERROR("Failed to lock original vertex buffer for copying"); } vbMapping[origBuffer] = cloneBuffer; } ret->vertexBuffers_.Push(cloneBuffer); } HashMap<IndexBuffer*, IndexBuffer*> ibMapping; for (Vector<SharedPtr<IndexBuffer> >::ConstIterator i = indexBuffers_.Begin(); i != indexBuffers_.End(); ++i) { IndexBuffer* origBuffer = *i; SharedPtr<IndexBuffer> cloneBuffer; if (origBuffer) { cloneBuffer = new IndexBuffer(context_); cloneBuffer->SetSize(origBuffer->GetIndexCount(), origBuffer->GetIndexSize() == sizeof(unsigned), origBuffer->IsDynamic()); cloneBuffer->SetShadowed(origBuffer->IsShadowed()); if (origBuffer->IsShadowed()) cloneBuffer->SetData(origBuffer->GetShadowData()); else { void* origData = origBuffer->Lock(0, origBuffer->GetIndexCount()); if (origData) cloneBuffer->SetData(origData); else URHO3D_LOGERROR("Failed to lock original index buffer for copying"); } ibMapping[origBuffer] = cloneBuffer; } ret->indexBuffers_.Push(cloneBuffer); } // Deep copy all the geometry LOD levels and refer to the copied vertex/index buffers ret->geometries_.Resize(geometries_.Size()); for (unsigned i = 0; i < geometries_.Size(); ++i) { ret->geometries_[i].Resize(geometries_[i].Size()); for (unsigned j = 0; j < geometries_[i].Size(); ++j) { SharedPtr<Geometry> cloneGeometry; Geometry* origGeometry = geometries_[i][j]; if (origGeometry) { cloneGeometry = new Geometry(context_); cloneGeometry->SetIndexBuffer(ibMapping[origGeometry->GetIndexBuffer()]); unsigned numVbs = origGeometry->GetNumVertexBuffers(); for (unsigned k = 0; k < numVbs; ++k) { cloneGeometry->SetVertexBuffer(k, vbMapping[origGeometry->GetVertexBuffer(k)]); } cloneGeometry->SetDrawRange(origGeometry->GetPrimitiveType(), origGeometry->GetIndexStart(), origGeometry->GetIndexCount(), origGeometry->GetVertexStart(), origGeometry->GetVertexCount(), false); cloneGeometry->SetLodDistance(origGeometry->GetLodDistance()); } ret->geometries_[i][j] = cloneGeometry; } } // Deep copy the morph data (if any) to allow modifying it for (Vector<ModelMorph>::Iterator i = ret->morphs_.Begin(); i != ret->morphs_.End(); ++i) { ModelMorph& morph = *i; for (HashMap<unsigned, VertexBufferMorph>::Iterator j = morph.buffers_.Begin(); j != morph.buffers_.End(); ++j) { VertexBufferMorph& vbMorph = j->second_; if (vbMorph.dataSize_) { SharedArrayPtr<unsigned char> cloneData(new unsigned char[vbMorph.dataSize_]); memcpy(cloneData.Get(), vbMorph.morphData_.Get(), vbMorph.dataSize_); vbMorph.morphData_ = cloneData; } } } ret->SetMemoryUse(GetMemoryUse()); return ret; }
ShaderVariation* Shader::GetVariation(ShaderType type, const String& name) { StringHash nameHash(name); if (type == VS) { if (vsParser_.HasCombination(name)) { HashMap<StringHash, SharedPtr<ShaderVariation> >::Iterator i = vsVariations_.Find(nameHash); // Create the shader variation now if not created yet if (i == vsVariations_.End()) { ShaderCombination combination = vsParser_.GetCombination(name); i = vsVariations_.Insert(MakePair(nameHash, SharedPtr<ShaderVariation>(new ShaderVariation(this, VS)))); String path, fileName, extension; SplitPath(GetName(), path, fileName, extension); String fullName = path + fileName + "_" + name; if (fullName.EndsWith("_")) fullName.Resize(fullName.Length() - 1); i->second_->SetName(fullName); i->second_->SetSourceCode(vsSourceCode_, vsSourceCodeLength_); i->second_->SetDefines(combination.defines_, combination.defineValues_); SetMemoryUse(GetMemoryUse() + sizeof(ShaderVariation)); } return i->second_; } else return 0; } else { if (psParser_.HasCombination(name)) { HashMap<StringHash, SharedPtr<ShaderVariation> >::Iterator i = psVariations_.Find(nameHash); // Create the shader variation now if not created yet if (i == psVariations_.End()) { ShaderCombination combination = psParser_.GetCombination(name); i = psVariations_.Insert(MakePair(nameHash, SharedPtr<ShaderVariation>(new ShaderVariation(this, PS)))); String path, fileName, extension; SplitPath(GetName(), path, fileName, extension); String fullName = path + fileName + "_" + name; if (fullName.EndsWith("_")) fullName.Resize(fullName.Length() - 1); i->second_->SetName(fullName); i->second_->SetSourceCode(psSourceCode_, psSourceCodeLength_); i->second_->SetDefines(combination.defines_, combination.defineValues_); SetMemoryUse(GetMemoryUse() + sizeof(ShaderVariation)); } return i->second_; } else return 0; } }
bool ScriptFile::AddScriptSection(asIScriptEngine* engine, Deserializer& source) { ResourceCache* cache = GetSubsystem<ResourceCache>(); unsigned dataSize = source.GetSize(); SharedArrayPtr<char> buffer(new char[dataSize]); source.Read((void*)buffer.Get(), dataSize); // Pre-parse for includes // Adapted from Angelscript's scriptbuilder add-on Vector<String> includeFiles; unsigned pos = 0; while(pos < dataSize) { int len; asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_COMMENT || t == asTC_WHITESPACE) { pos += len; continue; } // Is this a preprocessor directive? if (buffer[pos] == '#') { int start = pos++; asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_IDENTIFIER) { String token(&buffer[pos], len); if (token == "include") { pos += len; t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_WHITESPACE) { pos += len; t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); } if (t == asTC_VALUE && len > 2 && buffer[pos] == '"') { // Get the include file String includeFile(&buffer[pos+1], len - 2); pos += len; // If the file is not found as it is, add the path of current file but only if it is found there if (!cache->Exists(includeFile)) { String prefixedIncludeFile = GetPath(GetName()) + includeFile; if (cache->Exists(prefixedIncludeFile)) includeFile = prefixedIncludeFile; } String includeFileLower = includeFile.ToLower(); // If not included yet, store it for later processing if (!includeFiles_.Contains(includeFileLower)) { includeFiles_.Insert(includeFileLower); includeFiles.Push(includeFile); } // Overwrite the include directive with space characters to avoid compiler error memset(&buffer[start], ' ', pos - start); } } } } // Don't search includes within statement blocks or between tokens in statements else { int len; // Skip until ; or { whichever comes first while (pos < dataSize && buffer[pos] != ';' && buffer[pos] != '{') { engine->ParseToken(&buffer[pos], 0, &len); pos += len; } // Skip entire statement block if (pos < dataSize && buffer[pos] == '{') { ++pos; // Find the end of the statement block int level = 1; while (level > 0 && pos < dataSize) { asETokenClass t = engine->ParseToken(&buffer[pos], 0, &len); if (t == asTC_KEYWORD) { if (buffer[pos] == '{') ++level; else if(buffer[pos] == '}') --level; } pos += len; } } else ++pos; } } // Process includes first for (unsigned i = 0; i < includeFiles.Size(); ++i) { cache->StoreResourceDependency(this, includeFiles[i]); SharedPtr<File> file = cache->GetFile(includeFiles[i]); if (file) { if (!AddScriptSection(engine, *file)) return false; } else { LOGERROR("Could not process all the include directives in " + GetName() + ": missing " + includeFiles[i]); return false; } } // Then add this section if (scriptModule_->AddScriptSection(source.GetName().CString(), (const char*)buffer.Get(), dataSize) < 0) { LOGERROR("Failed to add script section " + source.GetName()); return false; } SetMemoryUse(GetMemoryUse() + dataSize); return true; }