| 1895 | } |
| 1896 | |
| 1897 | bool SceneGraph::AddDynamicDecal(DecalObject* decal) { |
| 1898 | if (dynamic_decals.size() >= kMaxDynamicDecals) { |
| 1899 | DecalObject* obj = dynamic_decals.front(); |
| 1900 | obj->SetParent(NULL); |
| 1901 | UnlinkObject(obj); |
| 1902 | obj->Dispose(); |
| 1903 | delete (obj); |
| 1904 | } |
| 1905 | // make sure we don't clump too many decals into one place |
| 1906 | vec3 my_pos = decal->GetTranslation(); |
| 1907 | |
| 1908 | // find nearest decal which is same type |
| 1909 | // c++11 auto would be really helpful here |
| 1910 | float nearest_dist_sq = FLT_MAX; |
| 1911 | |
| 1912 | Object* nearest_obj = NULL; |
| 1913 | decal_deque::iterator e = dynamic_decals.end(); |
| 1914 | for (decal_deque::iterator it = dynamic_decals.begin(); it != e; ++it) { |
| 1915 | DecalObject* obj = *it; |
| 1916 | |
| 1917 | LOG_ASSERT(obj != NULL); |
| 1918 | if (obj->decal_file_ref->color_map != "Data/Textures/bloodsplat_c.tga" || obj->obj_file != decal->obj_file) { |
| 1919 | // not the same kind of decal, don't consider |
| 1920 | continue; |
| 1921 | } |
| 1922 | |
| 1923 | vec3 other_pos = obj->GetTranslation(); |
| 1924 | float dist_sq = length_squared(my_pos - other_pos); |
| 1925 | if (dist_sq < nearest_dist_sq) { |
| 1926 | nearest_dist_sq = dist_sq; |
| 1927 | nearest_obj = obj; |
| 1928 | } |
| 1929 | } |
| 1930 | |
| 1931 | vec3 scale = decal->GetScale(); |
| 1932 | float my_radius = min(scale.x(), min(scale.y(), scale.z())); |
| 1933 | float my_radius_sq = my_radius * my_radius; |
| 1934 | float other_radius_sq = 0.0f; |
| 1935 | if (nearest_obj) { |
| 1936 | scale = nearest_obj->GetScale(); |
| 1937 | float other_radius = min(scale.x(), min(scale.y(), scale.z())); |
| 1938 | other_radius_sq = other_radius * other_radius; |
| 1939 | } |
| 1940 | if (nearest_dist_sq > my_radius_sq && nearest_dist_sq > other_radius_sq) { |
| 1941 | if (ActorsEditor_AddEntity(this, decal, NULL, false)) { |
| 1942 | dynamic_decals.push_back(decal); |
| 1943 | } else { |
| 1944 | LOGE << "Failed to add dynamic decal to scenegraph" << std::endl; |
| 1945 | return false; |
| 1946 | } |
| 1947 | } else { |
| 1948 | vec3 cur_scale = nearest_obj->GetScale(); |
| 1949 | vec3 add_scale = decal->GetScale(); |
| 1950 | float cur_volume = cur_scale[0] * cur_scale[1]; |
| 1951 | float add_volume = add_scale[0] * add_scale[1]; |
| 1952 | if (cur_scale[0] < cur_scale[1]) { |
| 1953 | float square_vol = cur_scale[1] * cur_scale[1]; |
| 1954 | if (cur_volume + add_volume > square_vol) { |
no test coverage detected