diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 74049c01f..98a38611d 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -1065,7 +1065,14 @@ void EditorComponent::Update(float dt) for (auto& x : savedParents) { *archive << x.first->GetID(); - *archive << x.second->GetID(); + if (x.second == nullptr) + { + *archive << Transform::INVALID_ID; + } + else + { + *archive << x.second->GetID(); + } } if (picked->transform != nullptr) @@ -1117,7 +1124,14 @@ void EditorComponent::Update(float dt) for (auto& x : savedParents) { *archive << x.first->GetID(); - *archive << x.second->GetID(); + if (x.second == nullptr) + { + *archive << Transform::INVALID_ID; + } + else + { + *archive << x.second->GetID(); + } } } @@ -1732,6 +1746,16 @@ void ConsumeHistoryOperation(bool undo) decal->SetID(id); model->Add(decal); } + + // force field + *archive >> tmp; + if (tmp) + { + ForceField* force = new ForceField; + force->Serialize(*archive); + force->SetID(id); + model->Add(force); + } } if (undo) diff --git a/WickedEngine/ShaderInterop_EmittedParticle.h b/WickedEngine/ShaderInterop_EmittedParticle.h index 310688f29..922718c1f 100644 --- a/WickedEngine/ShaderInterop_EmittedParticle.h +++ b/WickedEngine/ShaderInterop_EmittedParticle.h @@ -29,11 +29,12 @@ CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE) uint xEmitCount; uint xEmitterMeshIndexCount; uint xEmitterMeshVertexPositionStride; - float xEmitterRandomness; + float xParticleSize; float xParticleScaling; float xParticleRotation; + uint xParticleColor; float xParticleRandomFactor; float xParticleNormalFactor; @@ -41,8 +42,7 @@ CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE) float xParticleLifeSpanRandomness; float xParticleMotionBlurAmount; - uint xParticleColor; - float2 xPadding_EmitterCB; + float3 xPadding_EmitterCB; }; CBUFFER(SortConstants, 0) diff --git a/WickedEngine/wiLoader.cpp b/WickedEngine/wiLoader.cpp index 4a81e3b15..58bdbf55c 100644 --- a/WickedEngine/wiLoader.cpp +++ b/WickedEngine/wiLoader.cpp @@ -20,51 +20,54 @@ using namespace std; using namespace wiGraphicsTypes; -void LoadWiArmatures(const std::string& directory, const std::string& name, const std::string& identifier, list& armatures) +void LoadWiArmatures(const std::string& directory, const std::string& name, const std::string& identifier, unordered_set& armatures) { stringstream filename(""); filename<>line; - if(line[0]=='/' && line.substr(2,8)=="ARMATURE") { - armatures.push_back(new Armature(line.substr(11,strlen(line.c_str())-11),identifier) ); + if(line[0]=='/' && line.substr(2,8)=="ARMATURE") + { + armature = new Armature(line.substr(11, strlen(line.c_str()) - 11), identifier); + armatures.insert(armature); } - else{ - switch(line[0]){ + else + { + switch(line[0]) + { case 'r': file>>trans[0]>>trans[1]>>trans[2]>>trans[3]; - armatures.back()->rotation_rest = XMFLOAT4(trans[0],trans[1],trans[2],trans[3]); + armature->rotation_rest = XMFLOAT4(trans[0],trans[1],trans[2],trans[3]); break; case 's': file>>trans[0]>>trans[1]>>trans[2]; - armatures.back()->scale_rest = XMFLOAT3(trans[0], trans[1], trans[2]); + armature->scale_rest = XMFLOAT3(trans[0], trans[1], trans[2]); break; case 't': file>>trans[0]>>trans[1]>>trans[2]; - armatures.back()->translation_rest = XMFLOAT3(trans[0], trans[1], trans[2]); + armature->translation_rest = XMFLOAT3(trans[0], trans[1], trans[2]); { - XMMATRIX world = XMMatrixScalingFromVector(XMLoadFloat3(&armatures.back()->scale))*XMMatrixRotationQuaternion(XMLoadFloat4(&armatures.back()->rotation))*XMMatrixTranslationFromVector(XMLoadFloat3(&armatures.back()->translation)); - XMStoreFloat4x4( &armatures.back()->world_rest,world ); + XMMATRIX world = XMMatrixScalingFromVector(XMLoadFloat3(&armature->scale))*XMMatrixRotationQuaternion(XMLoadFloat4(&armature->rotation))*XMMatrixTranslationFromVector(XMLoadFloat3(&armature->translation)); + XMStoreFloat4x4( &armature->world_rest,world ); } break; case 'b': { string boneName; file>>boneName; - armatures.back()->boneCollection.push_back(new Bone(boneName)); - //stringstream ss(""); - //ss<name<<"_"<boneCollection.push_back(new Bone(ss.str())); - //transforms.insert(pair(armatures.back()->boneCollection.back()->name,armatures.back()->boneCollection.back())); + armature->boneCollection.push_back(new Bone(boneName)); } break; case 'p': - file>>armatures.back()->boneCollection.back()->parentName; + file>>armature->boneCollection.back()->parentName; break; case 'l': { @@ -77,26 +80,18 @@ void LoadWiArmatures(const std::string& directory, const std::string& name, cons XMMATRIX frame; frame= XMMatrixRotationQuaternion(quaternion) * XMMatrixTranslationFromVector(translation) ; - XMStoreFloat3(&armatures.back()->boneCollection.back()->translation_rest,translation); - XMStoreFloat4(&armatures.back()->boneCollection.back()->rotation_rest,quaternion); - XMStoreFloat4x4(&armatures.back()->boneCollection.back()->world_rest,frame); - XMStoreFloat4x4(&armatures.back()->boneCollection.back()->restInv,XMMatrixInverse(0,frame)); - - /*XMStoreFloat3( &armatures.back()->boneCollection.back().position,translationInverse ); - XMStoreFloat4( &armatures.back()->boneCollection.back().rotation,quaternionInverse );*/ - - /*XMVECTOR sca,rot,tra; - XMMatrixDecompose(&sca,&rot,&tra,XMMatrixInverse(0,XMMatrixTranspose(frame))*XMLoadFloat4x4(&armatures.back()->world)); - XMStoreFloat3( &armatures.back()->boneCollection.back().position,tra ); - XMStoreFloat4( &armatures.back()->boneCollection.back().rotation,rot );*/ + XMStoreFloat3(&armature->boneCollection.back()->translation_rest,translation); + XMStoreFloat4(&armature->boneCollection.back()->rotation_rest,quaternion); + XMStoreFloat4x4(&armature->boneCollection.back()->world_rest,frame); + XMStoreFloat4x4(&armature->boneCollection.back()->restInv,XMMatrixInverse(0,frame)); } break; case 'c': - armatures.back()->boneCollection.back()->connected=true; + armature->boneCollection.back()->connected=true; break; case 'h': - file>>armatures.back()->boneCollection.back()->length; + file>>armature->boneCollection.back()->length; break; default: break; } @@ -108,7 +103,8 @@ void LoadWiArmatures(const std::string& directory, const std::string& name, cons //CREATE FAMILY - for(Armature* armature : armatures){ + for(Armature* armature : armatures) + { armature->CreateFamily(); } @@ -286,8 +282,8 @@ void LoadWiMaterialLibrary(const std::string& directory, const std::string& name } } -void LoadWiObjects(const std::string& directory, const std::string& name, const std::string& identifier, list& objects - , list& armatures +void LoadWiObjects(const std::string& directory, const std::string& name, const std::string& identifier, unordered_set& objects + , unordered_set& armatures , MeshCollection& meshes, const MaterialCollection& materials) { @@ -295,45 +291,56 @@ void LoadWiObjects(const std::string& directory, const std::string& name, const filename<>line; - if(line[0]=='/' && !strcmp(line.substr(2,6).c_str(),"OBJECT")) { + if(line[0]=='/' && !strcmp(line.substr(2,6).c_str(),"OBJECT")) + { stringstream identified_name(""); identified_name<>meshName; stringstream identified_mesh(""); identified_mesh<meshfile = identified_mesh.str(); + object->meshfile = identified_mesh.str(); MeshCollection::iterator iter = meshes.find(identified_mesh.str()); - if(line[1]=='b'){ //binary load mesh in place if not present - - if(iter==meshes.end()){ + if(line[1]=='b') + { + //binary load mesh in place if not present + if(iter==meshes.end()) + { stringstream meshFileName(""); meshFileName<LoadFromFile(identified_mesh.str(),meshFileName.str(),materials,armatures,identifier); - objects.back()->mesh=mesh; + object->mesh=mesh; meshes.insert(pair(identified_mesh.str(),mesh)); } - else{ - objects.back()->mesh=iter->second; + else + { + object->mesh=iter->second; } } - else{ - if(iter!=meshes.end()) { - objects.back()->mesh=iter->second; - //objects.back()->mesh->usedBy.push_back(objects.size()-1); + else + { + if (iter != meshes.end()) + { + object->mesh = iter->second; } } } @@ -344,31 +351,14 @@ void LoadWiObjects(const std::string& directory, const std::string& name, const file>>parentName; stringstream identified_parentName(""); identified_parentName<parentName = identified_parentName.str(); - //for(Armature* a : armatures){ - // if(!a->name.compare(identified_parentName.str())){ - // objects.back()->parentName=identified_parentName.str(); - // objects.back()->parent=a; - // objects.back()->attachTo(a,1,1,1); - // objects.back()->armatureDeform=true; - // } - //} + object->parentName = identified_parentName.str(); } break; case 'b': { string bone=""; file>>bone; - objects.back()->boneParent = bone; - //if(objects.back()->parent!=nullptr){ - // for(Bone* b : ((Armature*)objects.back()->parent)->boneCollection){ - // if(!bone.compare(b->name)){ - // objects.back()->parent=b; - // objects.back()->armatureDeform=false; - // break; - // } - // } - //} + object->boneParent = bone; } break; case 'I': @@ -376,7 +366,7 @@ void LoadWiObjects(const std::string& directory, const std::string& name, const XMFLOAT3 s,t; XMFLOAT4 r; file>>t.x>>t.y>>t.z>>r.x>>r.y>>r.z>>r.w>>s.x>>s.y>>s.z; - XMStoreFloat4x4(&objects.back()->parent_inv_rest + XMStoreFloat4x4(&object->parent_inv_rest , XMMatrixScalingFromVector(XMLoadFloat3(&s)) * XMMatrixRotationQuaternion(XMLoadFloat4(&r)) * XMMatrixTranslationFromVector(XMLoadFloat3(&t)) @@ -385,23 +375,15 @@ void LoadWiObjects(const std::string& directory, const std::string& name, const break; case 'r': file>>trans[0]>>trans[1]>>trans[2]>>trans[3]; - objects.back()->Rotate(XMFLOAT4(trans[0], trans[1], trans[2],trans[3])); - //objects.back()->rotation_rest = XMFLOAT4(trans[0],trans[1],trans[2],trans[3]); + object->Rotate(XMFLOAT4(trans[0], trans[1], trans[2],trans[3])); break; case 's': file>>trans[0]>>trans[1]>>trans[2]; - objects.back()->Scale(XMFLOAT3(trans[0], trans[1], trans[2])); - //objects.back()->scale_rest = XMFLOAT3(trans[0], trans[1], trans[2]); + object->Scale(XMFLOAT3(trans[0], trans[1], trans[2])); break; case 't': file>>trans[0]>>trans[1]>>trans[2]; - objects.back()->Translate(XMFLOAT3(trans[0], trans[1], trans[2])); - //objects.back()->translation_rest = XMFLOAT3(trans[0], trans[1], trans[2]); - //XMStoreFloat4x4( &objects.back()->world_rest, XMMatrixScalingFromVector(XMLoadFloat3(&objects.back()->scale_rest)) - // *XMMatrixRotationQuaternion(XMLoadFloat4(&objects.back()->rotation_rest)) - // *XMMatrixTranslationFromVector(XMLoadFloat3(&objects.back()->translation_rest)) - // ); - //objects.back()->world=objects.back()->world_rest; + object->Translate(XMFLOAT3(trans[0], trans[1], trans[2])); break; case 'E': { @@ -412,18 +394,16 @@ void LoadWiObjects(const std::string& directory, const std::string& name, const float scaleX,scaleY,rot; file>>systemName>>visibleEmitter>>materialName>>size>>randfac>>norfac>>count>>life>>randlife; file>>scaleX>>scaleY>>rot; - - //if(visibleEmitter) objects.back()->emitterType=Object::EMITTER_VISIBLE; - //else if(objects.back()->emitterType ==Object::NO_EMITTER) objects.back()->emitterType =Object::EMITTER_INVISIBLE; if(wiRenderer::EMITTERSENABLED){ stringstream identified_materialName(""); identified_materialName<mesh){ - objects.back()->eParticleSystems.push_back( - new wiEmittedParticle(identified_systemName.str(),identified_materialName.str(),objects.back(),size,randfac,norfac,count,life,randlife,scaleX,scaleY,rot) + if(object->mesh) + { + object->eParticleSystems.push_back( + new wiEmittedParticle(identified_systemName.str(),identified_materialName.str(),object,size,randfac,norfac,count,life,randlife,scaleX,scaleY,rot) ); } } @@ -439,18 +419,18 @@ void LoadWiObjects(const std::string& directory, const std::string& name, const if(wiRenderer::HAIRPARTICLEENABLED){ stringstream identified_materialName(""); identified_materialName<hParticleSystems.push_back(new wiHairParticle(name,len,count,identified_materialName.str(),objects.back(),densityG,lenG) ); + object->hParticleSystems.push_back(new wiHairParticle(name,len,count,identified_materialName.str(),object,densityG,lenG) ); } } break; case 'P': - objects.back()->rigidBody = true; - file>>objects.back()->collisionShape>>objects.back()->mass>> - objects.back()->friction>>objects.back()->restitution>>objects.back()->damping>>objects.back()->physicsType>> - objects.back()->kinematic; + object->rigidBody = true; + file>>object->collisionShape>>object->mass>> + object->friction>>object->restitution>>object->damping>>object->physicsType>> + object->kinematic; break; case 'T': - file >> objects.back()->transparency; + file >> object->transparency; break; default: break; } @@ -459,34 +439,9 @@ void LoadWiObjects(const std::string& directory, const std::string& name, const } file.close(); - //for (unsigned int i = 0; imesh){ - // if(objects[i]->mesh->trailInfo.base>=0 && objects[i]->mesh->trailInfo.tip>=0){ - // //objects[i]->trail.resize(MAX_RIBBONTRAILS); - // GPUBufferDesc bd; - // ZeroMemory( &bd, sizeof(bd) ); - // bd.Usage = USAGE_DYNAMIC; - // bd.ByteWidth = sizeof( RibbonVertex ) * 1000; - // bd.BindFlags = BIND_VERTEX_BUFFER; - // bd.CPUAccessFlags = CPU_ACCESS_WRITE; - // wiRenderer::GetDevice()->CreateBuffer( &bd, NULL, &objects[i]->trailBuff ); - // objects[i]->trailTex = wiTextureHelper::getInstance()->getTransparent(); - // objects[i]->trailDistortTex = wiTextureHelper::getInstance()->getNormalMapDefault(); - // } - // } - //} - - //for (MeshCollection::iterator iter = meshes.begin(); iter != meshes.end(); ++iter){ - // Mesh* iMesh = iter->second; - - // iMesh->CreateVertexArrays(); - // iMesh->Optimize(); - // iMesh->CreateBuffers(); - //} - } void LoadWiMeshes(const std::string& directory, const std::string& name, const std::string& identifier, MeshCollection& meshes, - const list& armatures, const MaterialCollection& materials) + const unordered_set& armatures, const MaterialCollection& materials) { int meshI=(int)(meshes.size()-1); Mesh* currentMesh = NULL; @@ -496,7 +451,8 @@ void LoadWiMeshes(const std::string& directory, const std::string& name, const s ifstream file(filename.str().c_str()); if(file){ - while(!file.eof()){ + while(!file.eof()) + { float trans[] = { 0,0,0,0 }; string line=""; file>>line; @@ -507,8 +463,10 @@ void LoadWiMeshes(const std::string& directory, const std::string& name, const s meshes.insert( pair(currentMesh->name,currentMesh) ); meshI++; } - else{ - switch(line[0]){ + else + { + switch(line[0]) + { case 'p': { string parentArmature=""; @@ -517,10 +475,6 @@ void LoadWiMeshes(const std::string& directory, const std::string& name, const s stringstream identified_parentArmature(""); identified_parentArmature<parent=identified_parentArmature.str(); - //for (unsigned int i = 0; iname.c_str(),currentMesh->parent.c_str())){ - // currentMesh->armature=armatures[i]; - // } for (auto& a : armatures) { if (!a->name.compare(currentMesh->parent)) @@ -552,7 +506,6 @@ void LoadWiMeshes(const std::string& directory, const std::string& name, const s case 'u': file >> currentMesh->vertices_FULL.back().tex.x; file >> currentMesh->vertices_FULL.back().tex.y; - //texCoordFill++; break; case 'w': { @@ -560,23 +513,9 @@ void LoadWiMeshes(const std::string& directory, const std::string& name, const s float weight=0; int BONEINDEX=0; file>>nameB>>weight; - //bool gotArmature=false; bool gotBone=false; - //int i=0; - //while(!gotArmature && i<(int)armatures.size()){ //SEARCH FOR PARENT ARMATURE - // if(!strcmp(armatures[i]->name.c_str(),currentMesh->parent.c_str())) - // gotArmature=true; - // else i++; - //} if(currentMesh->armature != nullptr){ int j=0; - //while(!gotBone && j<(int)currentMesh->armature->boneCollection.size()){ - // if(!armatures[i]->boneCollection[j]->name.compare(nameB)){ - // gotBone=true; - // BONEINDEX=j; //GOT INDEX OF BONE OF THE WEIGHT IN THE PARENT ARMATURE - // } - // j++; - //} for (auto& b : currentMesh->armature->boneCollection) { if (!b->name.compare(nameB)) @@ -587,7 +526,9 @@ void LoadWiMeshes(const std::string& directory, const std::string& name, const s j++; } } - if (gotBone) { //ONLY PROCEED IF CORRESPONDING BONE WAS FOUND + if (gotBone) + { + //ONLY PROCEED IF CORRESPONDING BONE WAS FOUND if (!currentMesh->vertices_FULL.back().wei.x) { currentMesh->vertices_FULL.back().wei.x = weight; currentMesh->vertices_FULL.back().ind.x = (float)BONEINDEX; @@ -725,7 +666,7 @@ void LoadWiMeshes(const std::string& directory, const std::string& name, const s meshes.insert( pair(currentMesh->name,currentMesh) ); } -void LoadWiActions(const std::string& directory, const std::string& name, const std::string& identifier, list& armatures) +void LoadWiActions(const std::string& directory, const std::string& name, const std::string& identifier, unordered_set& armatures) { Armature* armatureI=nullptr; Bone* boneI=nullptr; @@ -816,44 +757,50 @@ void LoadWiActions(const std::string& directory, const std::string& name, const } file.close(); } -void LoadWiLights(const std::string& directory, const std::string& name, const std::string& identifier, list& lights) +void LoadWiLights(const std::string& directory, const std::string& name, const std::string& identifier, unordered_set& lights) { stringstream filename(""); filename<>line; - switch(line[0]){ + switch(line[0]) + { case 'P': { - lights.push_back(new Light()); - lights.back()->SetType(Light::POINT); + light = new Light(); + lights.insert(light); + light->SetType(Light::POINT); string lname = ""; - file>>lname>> lights.back()->shadow; + file>>lname>> light->shadow; stringstream identified_name(""); identified_name<name=identified_name.str(); - + light->name=identified_name.str(); } break; case 'D': { - lights.push_back(new Light()); - lights.back()->SetType(Light::DIRECTIONAL); - file>>lights.back()->name; - lights.back()->shadow = true; + light = new Light(); + lights.insert(light); + light->SetType(Light::DIRECTIONAL); + file>>light->name; + light->shadow = true; } break; case 'S': { - lights.push_back(new Light()); - lights.back()->SetType(Light::SPOT); - file>>lights.back()->name; - file>>lights.back()->shadow>>lights.back()->enerDis.z; + light = new Light(); + lights.insert(light); + light->SetType(Light::SPOT); + file>>light->name; + file>>light->shadow>>light->enerDis.z; } break; case 'p': @@ -863,28 +810,14 @@ void LoadWiLights(const std::string& directory, const std::string& name, const s stringstream identified_parentName(""); identified_parentName<parentName=identified_parentName.str(); - //for(std::map::iterator it=transforms.begin();it!=transforms.end();++it){ - // if(!it->second->name.compare(lights.back()->parentName)){ - // lights.back()->parent=it->second; - // lights.back()->attachTo(it->second,1,1,1); - // break; - // } - //} + light->parentName=identified_parentName.str(); } break; case 'b': { string parentBone=""; file>>parentBone; - lights.back()->boneParent = parentBone; - - //for(Bone* b : ((Armature*)lights.back()->parent)->boneCollection){ - // if(!b->name.compare(parentBone)){ - // lights.back()->parent=b; - // lights.back()->attachTo(b,1,1,1); - // } - //} + light->boneParent = parentBone; } break; case 'I': @@ -892,7 +825,7 @@ void LoadWiLights(const std::string& directory, const std::string& name, const s XMFLOAT3 s,t; XMFLOAT4 r; file>>t.x>>t.y>>t.z>>r.x>>r.y>>r.z>>r.w>>s.x>>s.y>>s.z; - XMStoreFloat4x4(&lights.back()->parent_inv_rest + XMStoreFloat4x4(&light->parent_inv_rest , XMMatrixScalingFromVector(XMLoadFloat3(&s)) * XMMatrixRotationQuaternion(XMLoadFloat4(&r)) * XMMatrixTranslationFromVector(XMLoadFloat3(&t)) @@ -903,34 +836,31 @@ void LoadWiLights(const std::string& directory, const std::string& name, const s { float x,y,z; file>>x>>y>>z; - lights.back()->Translate(XMFLOAT3(x, y, z)); - //lights.back()->translation_rest=XMFLOAT3(x,y,z); + light->Translate(XMFLOAT3(x, y, z)); break; } case 'r': { float x,y,z,w; file>>x>>y>>z>>w; - lights.back()->Rotate(XMFLOAT4(x, y, z, w)); - //lights.back()->rotation_rest=XMFLOAT4(x,y,z,w); + light->Rotate(XMFLOAT4(x, y, z, w)); break; } case 'c': { float r,g,b; file>>r>>g>>b; - lights.back()->color=XMFLOAT4(r,g,b,0); + light->color=XMFLOAT4(r,g,b,0); break; } case 'e': - file>>lights.back()->enerDis.x; + file>>light->enerDis.x; break; case 'd': - file>>lights.back()->enerDis.y; - //lights.back()->enerDis.y *= XMVectorGetX( world.r[0] )*0.1f; + file>>light->enerDis.y; break; case 'n': - lights.back()->noHalo=true; + light->noHalo=true; break; case 'l': { @@ -940,8 +870,8 @@ void LoadWiLights(const std::string& directory, const std::string& name, const s rim<add(rim.str())) != nullptr){ - lights.back()->lensFlareRimTextures.push_back(tex); - lights.back()->lensFlareNames.push_back(rim.str()); + light->lensFlareRimTextures.push_back(tex); + light->lensFlareNames.push_back(rim.str()); } } break; @@ -949,21 +879,11 @@ void LoadWiLights(const std::string& directory, const std::string& name, const s } } - //for(MeshCollection::iterator iter=lightGwiRenderer.begin(); iter!=lightGwiRenderer.end(); ++iter){ - // Mesh* iMesh = iter->second; - // GPUBufferDesc bd; - // ZeroMemory( &bd, sizeof(bd) ); - // bd.Usage = USAGE_DYNAMIC; - // bd.ByteWidth = sizeof( Instance )*iMesh->usedBy.size(); - // bd.BindFlags = BIND_VERTEX_BUFFER; - // bd.CPUAccessFlags = CPU_ACCESS_WRITE; - // wiRenderer::GetDevice()->CreateBuffer( &bd, 0, &iMesh->meshInstanceBuffer ); - //} } file.close(); } void LoadWiHitSpheres(const std::string& directory, const std::string& name, const std::string& identifier, std::vector& spheres - ,const list& armatures) + ,const unordered_set& armatures) { stringstream filename(""); filename<& cameras - ,const list& armatures){ + ,const unordered_set& armatures) +{ stringstream filename(""); filename<& decals){ +void LoadWiDecals(const std::string&directory, const std::string& name, const std::string& texturesDir, unordered_set& decals) +{ stringstream filename(""); filename<>voidStr; - while(!file.eof()){ + while(!file.eof()) + { string line=""; file>>line; - switch(line[0]){ + switch(line[0]) + { case 'd': { string name; XMFLOAT3 loc,scale; XMFLOAT4 rot; file>>name>>scale.x>>scale.y>>scale.z>>loc.x>>loc.y>>loc.z>>rot.x>>rot.y>>rot.z>>rot.w; - Decal* decal = new Decal(); + decal = new Decal(loc, scale, rot); decal->name=name; - decal->translation_rest=loc; - decal->scale_rest=scale; - decal->rotation_rest=rot; - decals.push_back(new Decal(loc,scale,rot)); + decals.insert(decal); } break; case 't': @@ -1216,7 +1138,7 @@ void LoadWiDecals(const std::string&directory, const std::string& name, const st file>>tex; stringstream ss(""); ss<addTexture(ss.str()); + decal->addTexture(ss.str()); } break; case 'n': @@ -1225,7 +1147,7 @@ void LoadWiDecals(const std::string&directory, const std::string& name, const st file>>tex; stringstream ss(""); ss<addNormal(ss.str()); + decal->addNormal(ss.str()); } break; default:break; @@ -1669,7 +1591,7 @@ GPUBuffer Mesh::impostorVB_POS; GPUBuffer Mesh::impostorVB_TEX; void Mesh::LoadFromFile(const std::string& newName, const std::string& fname - , const MaterialCollection& materialColl, const list& armatures, const std::string& identifier) { + , const MaterialCollection& materialColl, const unordered_set& armatures, const std::string& identifier) { name = newName; BYTE* buffer; @@ -2783,7 +2705,7 @@ void Model::UpdateModel() x->UpdateLight(); } - list::iterator iter = decals.begin(); + unordered_set::iterator iter = decals.begin(); while (iter != decals.end()) { Decal* decal = *iter; @@ -2803,7 +2725,7 @@ void Model::Add(Object* value) { if (value != nullptr) { - objects.push_back(value); + objects.insert(value); if (value->mesh != nullptr) { meshes.insert(pair(value->mesh->name, value->mesh)); @@ -2819,41 +2741,41 @@ void Model::Add(Armature* value) { if (value != nullptr) { - armatures.push_back(value); + armatures.insert(value); } } void Model::Add(Light* value) { if (value != nullptr) { - lights.push_back(value); + lights.insert(value); } } void Model::Add(Decal* value) { if (value != nullptr) { - decals.push_back(value); + decals.insert(value); } } void Model::Add(ForceField* value) { if (value != nullptr) { - forces.push_back(value); + forces.insert(value); } } void Model::Add(Model* value) { if (value != nullptr) { - objects.insert(objects.begin(), value->objects.begin(), value->objects.end()); - armatures.insert(armatures.begin(), value->armatures.begin(), value->armatures.end()); - decals.insert(decals.begin(), value->decals.begin(), value->decals.end()); - lights.insert(lights.begin(), value->lights.begin(), value->lights.end()); + objects.insert(value->objects.begin(), value->objects.end()); + armatures.insert(value->armatures.begin(), value->armatures.end()); + decals.insert(value->decals.begin(), value->decals.end()); + lights.insert(value->lights.begin(), value->lights.end()); meshes.insert(value->meshes.begin(), value->meshes.end()); materials.insert(value->materials.begin(), value->materials.end()); - forces.insert(forces.begin(), value->forces.begin(), value->forces.end()); + forces.insert(value->forces.begin(), value->forces.end()); } } void Model::Serialize(wiArchive& archive) @@ -2869,7 +2791,7 @@ void Model::Serialize(wiArchive& archive) { Object* x = new Object; x->Serialize(archive); - objects.push_back(x); + objects.insert(x); } archive >> meshCount; @@ -2893,7 +2815,7 @@ void Model::Serialize(wiArchive& archive) { Armature* x = new Armature; x->Serialize(archive); - armatures.push_back(x); + armatures.insert(x); } archive >> lightsCount; @@ -2901,7 +2823,7 @@ void Model::Serialize(wiArchive& archive) { Light* x = new Light; x->Serialize(archive); - lights.push_back(x); + lights.insert(x); } archive >> decalsCount; @@ -2909,7 +2831,7 @@ void Model::Serialize(wiArchive& archive) { Decal* x = new Decal; x->Serialize(archive); - decals.push_back(x); + decals.insert(x); } if (archive.GetVersion() >= 10) @@ -2919,7 +2841,7 @@ void Model::Serialize(wiArchive& archive) { ForceField* x = new ForceField; x->Serialize(archive); - forces.push_back(x); + forces.insert(x); } } diff --git a/WickedEngine/wiLoader.h b/WickedEngine/wiLoader.h index 6dc4cbbc9..b77433057 100644 --- a/WickedEngine/wiLoader.h +++ b/WickedEngine/wiLoader.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -444,7 +445,7 @@ public: } ~Mesh() {} void LoadFromFile(const std::string& newName, const std::string& fname - , const MaterialCollection& materialColl, const std::list& armatures, const std::string& identifier=""); + , const MaterialCollection& materialColl, const std::unordered_set& armatures, const std::string& identifier=""); bool buffersComplete; void Optimize(); // Object is needed in CreateBuffers because how else would we know if the mesh needs to be deformed? @@ -1170,13 +1171,13 @@ struct ForceField : public Transform struct Model : public Transform { - std::list objects; + std::unordered_set objects; MeshCollection meshes; MaterialCollection materials; - std::list armatures; - std::list lights; - std::list decals; - std::list forces; + std::unordered_set armatures; + std::unordered_set lights; + std::unordered_set decals; + std::unordered_set forces; Model(); virtual ~Model(); diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index e9e0fac50..e8f129e85 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -1484,7 +1484,15 @@ Transform* wiRenderer::getTransformByName(const std::string& get) } Transform* wiRenderer::getTransformByID(uint64_t id) { - return GetScene().GetWorldNode()->find(id); + for (Model* model : GetScene().models) + { + Transform* found = model->find(id); + if (found != nullptr) + { + return found; + } + } + return nullptr; } Armature* wiRenderer::getArmatureByName(const std::string& get) { @@ -2317,7 +2325,7 @@ void wiRenderer::ManageImages() } void wiRenderer::PutDecal(Decal* decal) { - GetScene().GetWorldNode()->decals.push_back(decal); + GetScene().GetWorldNode()->decals.insert(decal); } void wiRenderer::PutWaterRipple(const std::string& image, const XMFLOAT3& pos) { @@ -6126,7 +6134,7 @@ void wiRenderer::LoadDefaultLighting() Model* model = new Model; model->name = "_WickedEngine_DefaultLight_Holder_"; - model->lights.push_back(defaultLight); + model->lights.insert(defaultLight); GetScene().models.push_back(model); if (spTree_lights) { @@ -6422,83 +6430,84 @@ void wiRenderer::AddRenderableBox(const XMFLOAT4X4& boxMatrix, const XMFLOAT4& c void wiRenderer::AddModel(Model* model) { - GetDevice()->LOCK(); - GetScene().AddModel(model); FixedUpdate(); - Add(model->objects); - Add(model->lights); + // add object batch + { + vector collection(model->objects.begin(), model->objects.end()); + if (spTree != nullptr) + { + spTree->AddObjects(spTree->root, collection); + } + else + { + spTree = new Octree(collection); + } + } - //UpdateRenderData(nullptr); + // add light batch + { + vector collection(model->lights.begin(), model->lights.end()); + if (spTree_lights != nullptr) + { + spTree_lights->AddObjects(spTree_lights->root, collection); + } + else + { + spTree_lights = new Octree(collection); + } + } SetUpCubes(); SetUpBoneLines(); - - GetDevice()->UNLOCK(); } void wiRenderer::Add(Object* value) { - list collection(0); + GetScene().GetWorldNode()->Add(value); + if (value->parent == nullptr) + { + value->attachTo(GetScene().GetWorldNode()); + } + + vector collection(0); collection.push_back(value); - Add(collection); + if (spTree != nullptr) + { + spTree->AddObjects(spTree->root, collection); + } + else + { + spTree = new Octree(collection); + } } void wiRenderer::Add(Light* value) { - list collection(0); + GetScene().GetWorldNode()->Add(value); + if (value->parent == nullptr) + { + value->attachTo(GetScene().GetWorldNode()); + } + + vector collection(0); collection.push_back(value); - Add(collection); + if (spTree_lights != nullptr) + { + spTree_lights->AddObjects(spTree_lights->root, collection); + } + else + { + spTree_lights = new Octree(collection); + } } void wiRenderer::Add(ForceField* value) { - list collection(0); - collection.push_back(value); - Add(collection); -} -void wiRenderer::Add(const list& objects) -{ - for (Object* x : objects) + GetScene().GetWorldNode()->Add(value); + if (value->parent == nullptr) { - if (x->parent == nullptr) - { - GetScene().GetWorldNode()->Add(x); - } - } - if (spTree) { - spTree->AddObjects(spTree->root, std::vector(objects.begin(), objects.end())); - } - else - { - spTree = new Octree(std::vector(objects.begin(), objects.end())); - } -} -void wiRenderer::Add(const list& lights) -{ - for (Light* x : lights) - { - if (x->parent == nullptr) - { - GetScene().GetWorldNode()->Add(x); - } - } - if (spTree_lights) { - spTree_lights->AddObjects(spTree_lights->root, std::vector(lights.begin(), lights.end())); - } - else - { - spTree_lights = new Octree(std::vector(lights.begin(), lights.end())); - } -} -void wiRenderer::Add(const list& forces) -{ - for (ForceField* x : forces) - { - if (x->parent == nullptr) - { - GetScene().GetWorldNode()->Add(x); - } + value->attachTo(GetScene().GetWorldNode()); } } @@ -6508,7 +6517,7 @@ void wiRenderer::Remove(Object* value) { for (auto& x : GetScene().models) { - x->objects.remove(value); + x->objects.erase(value); } spTree->Remove(value); value->detach(); @@ -6520,7 +6529,7 @@ void wiRenderer::Remove(Light* value) { for (auto& x : GetScene().models) { - x->lights.remove(value); + x->lights.erase(value); } spTree_lights->Remove(value); value->detach(); @@ -6532,7 +6541,7 @@ void wiRenderer::Remove(Decal* value) { for (auto& x : GetScene().models) { - x->decals.remove(value); + x->decals.erase(value); } value->detach(); } @@ -6551,7 +6560,7 @@ void wiRenderer::Remove(ForceField* value) { for (auto& x : GetScene().models) { - x->forces.remove(value); + x->forces.erase(value); } value->detach(); } diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 940b5c3ee..adbad4517 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -560,16 +560,12 @@ public: // Add model to the scene static void AddModel(Model* value); - // Add Object Instance static void Add(Object* value); - static void Add(const std::list& objects); // Add Light Instance static void Add(Light* value); - static void Add(const std::list& lights); // Add Force Field Instance static void Add(ForceField* value); - static void Add(const std::list& forces); // Remove from the scene static void Remove(Object* value); diff --git a/WickedEngine/wiTransform.cpp b/WickedEngine/wiTransform.cpp index 709652443..03277b23b 100644 --- a/WickedEngine/wiTransform.cpp +++ b/WickedEngine/wiTransform.cpp @@ -3,12 +3,11 @@ #include -uint64_t Node::__Unique_ID_Counter = 0; +std::atomic Node::__Unique_ID_Counter = 0; Node::Node() { name = ""; - ID = __Unique_ID_Counter; - __Unique_ID_Counter++; + ID = __Unique_ID_Counter.fetch_add(1); } diff --git a/WickedEngine/wiTransform.h b/WickedEngine/wiTransform.h index 2879f56c0..7cd80a483 100644 --- a/WickedEngine/wiTransform.h +++ b/WickedEngine/wiTransform.h @@ -2,6 +2,7 @@ #define _TRANSFORM_H_ #include "CommonInclude.h" +#include #include class wiArchive; @@ -9,7 +10,7 @@ class wiArchive; struct Node { private: - static uint64_t __Unique_ID_Counter; + static std::atomic __Unique_ID_Counter; uint64_t ID; public: std::string name; @@ -20,6 +21,7 @@ public: std::string GetLayerID(); uint64_t GetID() { return ID; } void SetID(uint64_t newID) { ID = newID; } + static const uint64_t INVALID_ID = UINT64_MAX; void Serialize(wiArchive& archive); }; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 9f1853421..bbb739803 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 13; // minor bug fixes, alterations, refactors, updates - const int revision = 91; + const int revision = 92; long GetVersion()